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:
+            // <https://github.com/rust-lang/rust/issues/125196>.
             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..96a0f2f40bf49
--- /dev/null
+++ b/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs
@@ -0,0 +1,19 @@
+// Fix for <https://github.com/rust-lang/rust/issues/125196>.
+//@ check-pass
+
+trait Tr {
+    type Gat<T>;
+}
+
+struct W<T>(T);
+
+fn foo<T: Tr>() where for<'a> &'a T: Tr<Gat<W<i32>> = i32> {
+    let x: <&T as Tr>::Gat<W<_>> = 1i32;
+    // Previously, `match_projection_projections` only checked that
+    // `shallow_resolve(W<?0>) = W<?0>`. 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() {}