The following code gets erroneously accepted:
fn f<T>() where T: Trait<Ty: ?Sized> {}
// ^^^^^^ not good
trait Trait { type Ty/*: ?Sized*/; }
Relaxed1 bounds are only meant to be put on type parameters and associated types "declared in the immediate vicinity" which isn't the case here. This is supported by the fact that Trait<Ty:> (sic!) doesn't elaborate to Trait<Ty: Sized>.
Compare this to the snippet below which gets rightfully rejected:
fn f<T>() where T: Trait, T::Ty: ?Sized {}
// ^^^^^^
//~^^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
trait Trait { type Ty/*: ?Sized*/; }
Obviously a fix would be a breaking change. However I doubt anyone is writing such code (unless macro generated). In any case, we should run crater on the future PR.
The following code gets erroneously accepted:
Relaxed1 bounds are only meant to be put on type parameters and associated types "declared in the immediate vicinity" which isn't the case here. This is supported by the fact that
Trait<Ty:>(sic!) doesn't elaborate toTrait<Ty: Sized>.Compare this to the snippet below which gets rightfully rejected:
Obviously a fix would be a breaking change. However I doubt anyone is writing such code (unless macro generated). In any case, we should run crater on the future PR.
Footnotes
Also known as unbounds (an ancient name for them), maybe-bounds (colloquially) or "question mark bounds" (very colloquially). ↩