Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has_non_region_infer is technically redundant

&& 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}