You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Associated type item bounds - This allows constraining the nested rigid projections that are associated with a trait's associated types. e.g. trait Trait { type Assoc: Trait2<Assoc2: Copy>; }.
trait A: B<Assoc: C> {} should be able to imply both Self: B and <Self as B>::Assoc: C.
For normal associated types, this is definitely the case, but for bounds on associated types of supertraits, and bounds on associated types of associated types, these two forms are demonstrably not equivalent:
This compiles:
// A trait which has bounds on a nested associated type,// using shorthand associated type bounds syntax.// Associated type bounds ARE implied elsewhere.pubtraitNestedSugar{// Sufficient.typeOutput:Iterator<Item:Clone>;fnmake() -> Self::Output;}pubfnnested_sugar<T>() -> <T::OutputasIterator>::ItemwhereT:NestedSugar,// `No <T::Output as Iterator>::Item: Clone` required.{T::make().next().unwrap().clone()}
And this compiles:
// Supertrait with bounds on the associated type of the subtrait,// using shorthand associated type bounds syntax.// Supertrait associated type bounds ARE implied elsewhere.pubtraitSuperSugarwhereSelf:Iterator<Item:PartialEq>,{fnsuper_next_sugar(&self) -> <SelfasIterator>::Item;}pubfntake_sugar<I>(iter:I) -> boolwhereI:SuperSugar,// No `<I as Iterator>::Item: PartialEq` required.{let first = iter.super_next_sugar();let second = iter.super_next_sugar();
first == second
}
But this does not compile:
// A trait which has bounds on a nested associated type,// using a where clause.// The associated type bounds are NOT implied elsewhere.pubtraitNestedWherewhereSelf::Output:Iterator,// Not sufficient.
<Self::OutputasIterator>::Item:Clone,{typeOutput;// GAT-ish syntax is also not sufficient://type Output: Iterator where <Self::Output as Iterator>::Item: Clone;fnmake() -> Self::Output;}pubfnnested_where<T>() -> <T::OutputasIterator>::ItemwhereT:NestedWhere,// Required. Does not compile without this line://<T::Output as Iterator>::Item: Clone,// error[E0277]: the trait bound `<<T as NestedWhere>::Output as Iterator>::Item: Clone` is not satisfied{T::make().next().unwrap().clone()}
Nor does this:
// Supertrait with bounds on the associated type of the subtrait,// using a where clause.// Associated type bounds are NOT implied elsewhere.pubtraitSuperWherewhereSelf:Iterator,// Not sufficient.
<SelfasIterator>::Item:PartialEq,{fnsuper_next_where(&self) -> <SelfasIterator>::Item;}pubfntake_where<I>(iter:I) -> boolwhereI:SuperWhere,// Required. Does not compile without this line://<I as Iterator>::Item: PartialEq,// error[E0277]: can't compare `<I as Iterator>::Item` with `<I as Iterator>::Item`// help: the trait `PartialEq` is not implemented for `<I as Iterator>::Item`{let first = iter.super_next_where();let second = iter.super_next_where();
first == second
}
All of those issues talk about type bounds not being implied in one case or another, but as far as I can tell there is no issue about the discrepancy of implied bounds between these two syntaxes. And again I am not sure if this is a bug or a documentation (and possibly diagnostics) issue.
The text was updated successfully, but these errors were encountered:
The first failing (NestedWhere) is fixed by #120752.
The second example (SuperWhere) is not, and could be considered a bug, though it's somewhat different in character. In the absence of a bug, though, this discrepancy is a underspecification of the reference, which doesn't explain how supertraits and item bounds interact with associated type bounds.
I am not sure if this is a bug or a documentation issue.
The Rust Reference states:
This matches the associated type bounds RFC:
The stabilization PR says almost the same thing, but with a subtle difference:
(Emphasis mine.)
However, the PR linked in that second bullet, Make associated type bounds in supertrait position implied, implies that this
where
clause implies the same bounds as theB<Assoc: C>
syntax:For normal associated types, this is definitely the case, but for bounds on associated types of supertraits, and bounds on associated types of associated types, these two forms are demonstrably not equivalent:
This compiles:
And this compiles:
But this does not compile:
Nor does this:
Playground
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=faec69dd74703073da0a6183cceb9afd
See also
where
ontrait
declaration should be provided when the trait is an input bound, but is instead a requirementAll of those issues talk about type bounds not being implied in one case or another, but as far as I can tell there is no issue about the discrepancy of implied bounds between these two syntaxes. And again I am not sure if this is a bug or a documentation (and possibly diagnostics) issue.
The text was updated successfully, but these errors were encountered: