Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should bounds on mut trait objects be covariant? #14985

Closed
nrc opened this issue Jun 17, 2014 · 6 comments · Fixed by #23515
Closed

Should bounds on mut trait objects be covariant? #14985

nrc opened this issue Jun 17, 2014 · 6 comments · Fixed by #23515
Labels
A-typesystem Area: The type system

Comments

@nrc
Copy link
Member

nrc commented Jun 17, 2014

Currently if Trait1 and Trait2 are traits, then &mut Trait1+Trait2 <: &mut Trait1. I.e., mutable trait objects are covariant. All other mutable references are invariant, that is &mut T <: &mut T' iff T /equiv T'.

Should trait objects also be invariant?

See also #12470, which is a similar issue but about lifetimes in the same situation (which must be invariant and not contravariant).

@pnkfelix
Copy link
Member

cc me

1 similar comment
@nikomatsakis
Copy link
Contributor

cc me

@nikomatsakis
Copy link
Contributor

Actually, I was thinking: if we were to permit multiple arbitrary traits (as I would eventually like to do) to occur in object expressions, then it is not clear that &mut A+B is a subtype of a &mut A (or &mut B)-- coercible, yes, but not a subtype. This is because the vtable will have to be swapped, since in the first case it must include methods for both A and B, and in the second only A (or B, respectively).

@steveklabnik steveklabnik added the A-typesystem Area: The type system label Jan 23, 2015
@nikomatsakis
Copy link
Contributor

triage: P-backcompat-lang (1.0 beta)

@nikomatsakis
Copy link
Contributor

Forgot about this little corner case. Hopefully now that #18737 is closed this should be easier to fix.

@nikomatsakis
Copy link
Contributor

Let me elaborate my plan (which... so far ... seems to be working). Just removing the subtype relation alone breaks code because various bits of code rely on the ability to upcast the region bound (i.e., &mut (Foo+'a) <: &mut (Foo+'b) if 'a : 'b). However, while this is actually sound in the case of trait objects, it is not generally sound for &mut T, which is typically invariant w/r/t T. The only reason it's ok for trait objects is that we can't assign to the reference of the &mut in that case. In any case, to solve this, I've extended the upcast relation so that &mut (Foo+'a) -> &mut (Foo+'b) if 'a : 'b (where -> means "is coercible to).

nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Mar 23, 2015
for `&mut (Trait+'a)` to `&mut (Trait+'b)` if `'a:'b`.

Fixes rust-lang#14985.
alexcrichton added a commit to alexcrichton/rust that referenced this issue Mar 23, 2015
…ping

Remove incorrect subtyping for `&mut Trait` and introduce coercion for `&mut (Trait+'a)` to `&mut (Trait+'b)` if `'a:'b`.

Fixes rust-lang#14985.

r? @nrc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-typesystem Area: The type system
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants