Skip to content

Trait bound on associated type not induced recursively #22446

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
milibopp opened this issue Feb 17, 2015 · 3 comments
Closed

Trait bound on associated type not induced recursively #22446

milibopp opened this issue Feb 17, 2015 · 3 comments
Labels
A-trait-system Area: Trait system A-type-system Area: Type system

Comments

@milibopp
Copy link
Contributor

Consider the following code:

trait TraitA {
    type AssocType;
    fn other(&self) -> Self::AssocType;
}

trait TraitB: TraitA
    where Self::AssocType: TraitB
{
    fn stuff(&self) {
        self.other().stuff()
    }
}

This does not compile, because the trait TraitB is not implemented for the type <<Self as TraitA>::AssocType as TraitA>::AssocType [E0277].

However, my reasoning from the above trait definition would be: when a type T implements TraitB then T::AssocType also implements TraitB. By replacing T with T::AssocType::... (n times) in this theorem, we can conclude that T::AssocType::... (n+1 times) implements TraitB, if its predecessor does so. Thus, by induction all T::AssocType::... (n times) should implement TraitB for all n.

Note, that this is not a problem for concrete implementations of TraitB. But abstract default methods cannot be implemented like that and users of TraitB also can't rely on the recursive trait bound.

Is there any way to make the compiler realize this? Or am I wrong?

@milibopp
Copy link
Contributor Author

This might be related to #20671.

@soltanmm
Copy link

Note that translating the associated type to a type parameter allows the preceding example to compile:

trait TraitA<Type> {
    fn other(&self) -> Type;
}

trait TraitB<Type>: TraitA<Type>
    where Type: TraitB<Type>
{
    fn stuff(&self) {
        self.other().stuff()
    }
}

This seems inconsistent. Even though the 'home' of the parameter moved between the two examples (Type in TraitB lives in TraitB's type parameter list and AssocType in TraitB's where clause lives in TraitA), I believe they should be treated the same.

@arielb1
Copy link
Contributor

arielb1 commented Oct 25, 2015

This is another case of "non-supertrait predicates are not elaborated". closing.

@arielb1 arielb1 closed this as completed Oct 25, 2015
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-trait-system Area: Trait system A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

4 participants