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

If trait Subtrait: Super where Clause { } then typeck should assume Clause, right? #29143

Closed
pnkfelix opened this issue Oct 18, 2015 · 6 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-type-system Area: Type system T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@pnkfelix
Copy link
Member

Consider the following code:

trait Bound { fn bound_m(&self, _: &str) { } }
trait Super { type A; fn mk(&self) -> Self::A; }
trait Sub: Super where Self::A: Bound { }
impl Super for () { type A = u32; fn mk(&self) -> u32 { 13 } }
impl Bound for u32 { }
impl Sub for () { }

fn main() { let s = (); foo(&s); }

fn foo<S:Sub+Default>(s: &S) where S::A: Bound {
    s.mk().bound_m("b.");
}

The above compiles and runs fine, but one might well ask: Why did I need to put that where-clause on fn foo? It is already present on the trait Sub: Super where Self::A: Bound, shouldn't the compiler thus infer that any S:Sub already satisfies that requirement?

Unfortunately, if you try that out, it doesn't work:

// #[cfg(doesnt_work)]
fn bar<S:Sub+Default>(s: &S) { s.mk().bound_m("c."); }

yields:

<anon>:15:39: 15:52 error: no method named `bound_m` found for type `<S as Super>::A` in the current scope
<anon>:15 fn bar<S:Sub+Default>(s: &S) { s.mk().bound_m("c."); }
                                                ^~~~~~~~~~~~~
<anon>:15:39: 15:52 help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `bound_m`, perhaps you need to implement it:
<anon>:15:39: 15:52 help: candidate #1: `Bound`
error: aborting due to previous error
playpen: application terminated with error code 101

playpen

@pnkfelix
Copy link
Member Author

cc @jroesch @rust-lang/lang

@pnkfelix pnkfelix added A-associated-items Area: Associated items (types, constants & functions) A-type-system Area: Type system T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Oct 18, 2015
@pnkfelix
Copy link
Member Author

@arielb1 (i mistyped it before) points out:

16:05:05 <arielby> pnkfelix: non-supertraits are not elaborated
16:05:18 <arielby> Self::A: Trait is not a supertrait
16:05:21 <arielby> therefore, it is not elaborated

However, I am still not convinced that the behavior I described above is by design. (But its certainly possible that trying to implement such a feature would invite further potential for our type-checking to fail to converge.)

@arielb1
Copy link
Contributor

arielb1 commented Oct 18, 2015

It's @arielb1 (or arielby). While there wasn't an RFC, this behaviour is completely by-design (supertrait bounds are only things of the form Self: Foo<..>, which means Self::A: Xyz is not a supertrait bound, and therefore it is not elaborated).

@pnkfelix
Copy link
Member Author

(I didn't choose my words very well. Lets pretend I instead said "I'm not convinced the behavior I described above is desirable." I remain unconvinced that we could not add such constraints to the process.)

@arielb1
Copy link
Contributor

arielb1 commented Oct 19, 2015

Which constraints? Projections from Self? Nested projections from Self? How much would this break?

@nikomatsakis
Copy link
Contributor

This is a dup of #20671, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-type-system Area: Type system T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants