diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6a0ad2d19c45e..19affac7970b9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1778,9 +1778,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // If this type is a GAT, and of the GAT args resolve to something new, // that means that we must have newly inferred something about the GAT. // We should give up in that case. + // FIXME(generic-associated-types): This only detects one layer of inference, + // which is probably not what we actually want, but fixing it causes some ambiguity: + // . if !generics.own_params.is_empty() && obligation.predicate.args[generics.parent_count..].iter().any(|&p| { - p.has_non_region_infer() && self.infcx.resolve_vars_if_possible(p) != p + p.has_non_region_infer() + && match p.unpack() { + ty::GenericArgKind::Const(ct) => { + self.infcx.shallow_resolve_const(ct) != ct + } + ty::GenericArgKind::Type(ty) => self.infcx.shallow_resolve(ty) != ty, + ty::GenericArgKind::Lifetime(_) => false, + } }) { ProjectionMatchesProjection::Ambiguous diff --git a/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs b/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs new file mode 100644 index 0000000000000..f3770d5584029 --- /dev/null +++ b/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs @@ -0,0 +1,18 @@ +// Fix for . + +trait Tr { + type Gat; +} + +struct W(T); + +fn foo() where for<'a> &'a T: Tr> = i32> { + let x: <&T as Tr>::Gat> = 1i32; + // Previously, `match_projection_projections` only checked that + // `shallow_resolve(W) = W`. This won't prevent *all* inference guidance + // from projection predicates in the environment, just ones that guide the + // outermost type of each GAT constructor. This is definitely wrong, but there is + // code that relies on it in the wild :/ +} + +fn main() {}