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
I'm going to open an issue or a PR if this doesn't get fixed within the next 6 months (today is 2026-02-08)
we consider impl F() -> impl X + Y, impl F() -> dyn X + Y etc. ambiguous but not impl Fn() -> for<> X + Y
super minor, maybe not even a bug? my head is spinning
(obviously impl Fn() -> X + Y is intentionally not considered ambiguous)
similarly, dyn F() -> fn() -> X + Y is not considered ambiguous
in conclusion, it's quite an artificial & specialized restriction
more weirdly even, we're allowing fn f<T: F() -> 'a + Copy>(){} and counting the Copy as a sibling of F, not of 'a; so it gets parsed as (Fn() -> 'a+) + Copy, not Fn() -> ('a + Copy)
that happens because we check for the presence of + when encountering 'a in type position without checking whether "+ is allowed" in this context (it isn't)
we accept (use<>)+ as a bare trait object type even though you're not allowed to parenthesize use<…> in "normal" bounds
renames in delegation items can't be _ (discarded) contrary to use items
e.g., the following snippets get rejected: reuse x as _;, reuse f::{x as _};
'r#static is legal but 'r#_ isn't (2021+); that doesn't make any sense
that would imply 'k#static being invalid and 'k#_ being valid
both static and _ denote "special" lifetimes, don't they?
or is static less special? just a normal lifetime that's predefined?
that argument doesn't hold because users can't rebind 'static (e.g., type X<'static> = (); is invalid)
contrary to _ that's a stand-in for other lifetimes
S { 0 }is legal as a pattern but not as an expressionS { 0: 0 }where both0s are identifiersS { 0 }in expressions just to achieve consistency$expr.0usizeis illegal (since very recently) but$expr.0x0,$expr.0e1(but not$expr.0e+1thankfully) etc. is still legal$expr.1!=$expr.01and$expr.0!=$expr.0_,so it all doesn't really matter(X)builtin # offset_of(…)/core::mem::offset_of!(…)$extpath { 0x1: … }which is legal (however$extpath { 0e1: … }is illegal thankfully unlike$expr.0e1)_and leading0s in all numeric fields (w/ exception of number0ofc)match () { X }is accepted but notmatch () { X, }(under featurenever_patterns),→|recovery in patternsconstblocks rust-lang/rust#149226pub const _: … = …;nowfn f() { pub const {} }already anywayimpl F() -> impl X + Y,impl F() -> dyn X + Yetc. ambiguous but notimpl Fn() -> for<> X + Yimpl Fn() -> X + Yis intentionally not considered ambiguous)dyn F() -> fn() -> X + Yis not considered ambiguousfn f<T: F() -> 'a + Copy>(){}and counting theCopyas a sibling ofF, not of'a; so it gets parsed as(Fn() -> 'a+) + Copy, notFn() -> ('a + Copy)+when encountering'ain type position without checking whether "+is allowed" in this context (it isn't)(use<>)+as a bare trait object type even though you're not allowed to parenthesizeuse<…>in "normal" bounds_(discarded) contrary to use itemsreuse x as _;,reuse f::{x as _};'r#staticis legal but'r#_isn't (2021+); that doesn't make any sense'k#staticbeing invalid and'k#_being validstaticand_denote "special" lifetimes, don't they?staticless special? just a normal lifetime that's predefined?'static(e.g.,type X<'static> = ();is invalid)_that's a stand-in for other lifetimes