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

Inconsistency in type checking where clauses in trait definition #28055

Closed
malbarbo opened this issue Aug 28, 2015 · 4 comments
Closed

Inconsistency in type checking where clauses in trait definition #28055

malbarbo opened this issue Aug 28, 2015 · 4 comments

Comments

@malbarbo
Copy link
Contributor

In this example, function f compiles, but g does not. To make g compiles it's necessary to repeat the C definition bound. For function f this is not necessary. This seems to be an inconsistency.

trait A {
    fn a(&self);
}

trait B where Self: A {
    fn b(&self);
}

trait C where for<'a> &'a Self: A {
    fn c(&self);
}

fn f<T>(x: &T) where T: B {
    x.b();
    x.a();
}

fn g<T>(x: &T) where T: C, /*for<'a> &'a T: A*/ { // uncomment to work
    x.c();
    x.a();
}

fn main() {}
<anon>:19:7: 19:10 error: the trait `for<'a> A` is not implemented for the type `&'a T` [E0277]
<anon>:19     x.c();
                ^~~
<anon>:20:7: 20:10 error: no method named `a` found for type `&T` in the current scope
<anon>:20     x.a();
                ^~~
<anon>:20:7: 20:10 help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `a`, perhaps you need to implement it:
<anon>:20:7: 20:10 help: candidate #1: `A`
error: aborting due to 2 previous errors
@arielb1
Copy link
Contributor

arielb1 commented Aug 28, 2015

This is how supertraits work. not a bug.

@arielb1 arielb1 closed this as completed Aug 28, 2015
@malbarbo
Copy link
Contributor Author

Could you give me some references to understanding this behavior?

@arielb1
Copy link
Contributor

arielb1 commented Aug 29, 2015

Supertraits: from the reference:

Trait bounds on Self are considered "supertraits". These are
required to be acyclic. Supertraits are somewhat different from other
constraints in that they affect what methods are available in the
vtable when the trait is used as a trait object.

The issue (elaboration) - this is part of the trait-system and mostly documented by the code comments. The thing is that we don't want too many bounds to be implicitly available for functions, as this can lead to fragility with distant changes causing functions to stop compiling. There are basically 3 kinds of bounds available to a function:

  • bounds from explicit where-clauses - e.g. T: B when you have that clause. This includes the "semi-explicit" Sized bound.
  • bounds from supertraits of explicit where-clauses - a where-clause adds bounds for its supertraits (as trait B: A, the T: B bound adds a T: A bound).
  • bounds from the lifetime properties of arguments (outlives/implicator/implied bounds). These are only lifetime bounds, and irrelevant for the current problem. [RFC] Clarify (and improve) rules for projections and well-formedness  rfcs#1214 involved them a great deal.

If your bound isn't in the list, you will have to add it explicitly if you want to use it. I guess this should be a FAQ entry.

jonysy added a commit to jonysy/hypospray that referenced this issue Dec 27, 2016
Trait bounds on Self are considered "supertraits". These are required
to be acyclic. Supertraits are somewhat different from other
constraints in that they affect what methods are available in the
vtable when the trait is used as a trait object.

Referencing rust-lang/rust#28055 and rust-lang/rust#34106
@seanmonstar
Copy link
Contributor

While the description of how bounds are added to a function makes sense, and is very useful, I'm still left with the question "why?"

If I have some trait C: B where <Self as B>::A: A {}, it seems that for any case where T: C could possibly be true, the other bounds would have to be true as well. Could that proof be added to the trait bounds resolver?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants