Repository navigation
#92917 breaks type inference on GATs #93874
Description
Activity
- addedC-bugCategory: This is a bug.Category: This is a bug.regression-untriagedUntriaged performance or correctness regression.Untriaged performance or correctness regression.
on Feb 10, 2022 - addedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Feb 10, 2022 Ah yeah, you also now have to make an existential type to name every unnameable type (e.g. types containing closures) if they go through a GAT (have to use
#![feature(type_alias_impl_trait)])#![feature(generic_associated_types)] #![feature(type_alias_impl_trait)] pub trait Build { type Output<O>; fn build<O>(self, input: O) -> Self::Output<O>; } pub struct IdentityBuild; impl Build for IdentityBuild { type Output<O> = O; fn build<O>(self, input: O) -> Self::Output<O> { input } } fn x() { let mut f = IdentityBuild.build(|| ()); (f)(); // ^type annotations needed // type must be known at this pointrustcE0282 // main.rs(17, 9): consider giving `x` a type } fn y() { type MyFn = impl FnOnce(); let f: MyFn = IdentityBuild.build(|| ()); (f)(); // Compiles } pub fn main() { x(); }
Reacted by Yiheng Du"type mismatch resolving
<IdentityBuild as Build>::Output<i32> == u8"I think this probably can be solved by normalizing somewhere where we aren't now; there aren't inference variables here.
"type annotations needed: cannot satisfy
<IdentityBuild as Build>::Output<Vec<_>> == Vec<u8>"This, I'm not sure about, since we do have an inference variable. Still, I think we can normalize still and end up with the
Vec<_> == Vec<u8>requirement - which is trivial.Does #93361 fix this?
You know what? It actually doesn't, sorry, should've checked first before I brought it up as a possibility.
The first error gets reported as
<IdentityBuild as Build>::Output<i32> == u8in the diagnostic, but theinfcx.eqinproject_and_unify_typeactually tries to equatei32 == u8. Other than the diagnostic being a bit wrong, I wonder why numeric fallback is occurring here...The second error ends up happening because of an ambiguity error during selection. I can look more into why that's failing.
Reacted by Jack HueySo the second error is ambiguous because that type variable can't be proved
Sized... (that obligation comes from a WF predicate I think?) 🤔- addedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Feb 17, 2022 - added a commit that references this issue
on Feb 18, 2022 - removedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Mar 10, 2022
Seems to be caused by #92917 @jackh726
So this regression seems to be intentional, but I want to make sure because even very basic inference fails now, making any use of GATs very fill up with explicit type annotations. It doesn't look so bad in this example, but with complex types it's bad, and I think there's a more complex example the compiler can't even tell what
_xis at all, but I'm still working on that.Code
I expected to see this happen: compiles without error
Instead, this happened: Type inference fails,
Output<O> = Oseems to be ignored or not understood by the compiler.Version it worked on
It most recently worked on:
Version with regression
rustc --version --verbose:Backtrace
(no crash)