Skip to content

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

New issue

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

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

Already on GitHub? # to your account

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

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 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.

# for free to join this conversation on GitHub. Already have an account? # 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
Projects
None yet
Development

No branches or pull requests

3 participants