Skip to content

Commit 3518606

Browse files
Only make GAT ambiguous in match_projection_projections considering shallow resolvability
1 parent ddba1dc commit 3518606

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

compiler/rustc_trait_selection/src/traits/select/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1778,9 +1778,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17781778
// If this type is a GAT, and of the GAT args resolve to something new,
17791779
// that means that we must have newly inferred something about the GAT.
17801780
// We should give up in that case.
1781+
// FIXME(generic-associated-types): This only detects one layer of inference,
1782+
// which is probably not what we actually want, but fixing it causes some ambiguity:
1783+
// <https://github.com/rust-lang/rust/issues/125196>.
17811784
if !generics.own_params.is_empty()
17821785
&& obligation.predicate.args[generics.parent_count..].iter().any(|&p| {
1783-
p.has_non_region_infer() && self.infcx.resolve_vars_if_possible(p) != p
1786+
p.has_non_region_infer()
1787+
&& match p.unpack() {
1788+
ty::GenericArgKind::Const(ct) => {
1789+
self.infcx.shallow_resolve_const(ct) != ct
1790+
}
1791+
ty::GenericArgKind::Type(ty) => self.infcx.shallow_resolve(ty) != ty,
1792+
ty::GenericArgKind::Lifetime(_) => false,
1793+
}
17841794
})
17851795
{
17861796
ProjectionMatchesProjection::Ambiguous
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Fix for <https://github.com/rust-lang/rust/issues/125196>.
2+
3+
trait Tr {
4+
type Gat<T>;
5+
}
6+
7+
struct W<T>(T);
8+
9+
fn foo<T: Tr>() where for<'a> &'a T: Tr<Gat<W<i32>> = i32> {
10+
let x: <&T as Tr>::Gat<W<_>> = 1i32;
11+
// Previously, `match_projection_projections` only checked that
12+
// `shallow_resolve(W<?0>) = W<?0>`. This won't prevent *all* inference guidance
13+
// from projection predicates in the environment, just ones that guide the
14+
// outermost type of each GAT constructor. This is definitely wrong, but there is
15+
// code that relies on it in the wild :/
16+
}
17+
18+
fn main() {}

0 commit comments

Comments
 (0)