Skip to content
/ rust Public
forked from rust-lang/rust

Commit f08746a

Browse files
authored
Rollup merge of rust-lang#125214 - compiler-errors:gat-guide, r=lcnr
Only make GAT ambiguous in `match_projection_projections` considering shallow resolvability In rust-lang#123537, I tweaked the hack from rust-lang#93892 to use `resolve_vars_if_possible` instead of `shallow_resolve`. This considers more inference guidance ambiguous. This resulted in crater regressions in rust-lang#125196. I've effectively reverted the change to the old behavior. That being said, I don't *like* this behavior, but I'd rather keep it for now since rust-lang#123537 was not meant to make any behavioral changes. See the attached example. This also affects the new solver, for the record, which doesn't have any rules about not guiding inference from param-env candidates which may constrain GAT args as a side-effect. r? `@lcnr` or `@jackh726`
2 parents c00957a + fa829fe commit f08746a

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-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,19 @@
1+
// Fix for <https://github.com/rust-lang/rust/issues/125196>.
2+
//@ check-pass
3+
4+
trait Tr {
5+
type Gat<T>;
6+
}
7+
8+
struct W<T>(T);
9+
10+
fn foo<T: Tr>() where for<'a> &'a T: Tr<Gat<W<i32>> = i32> {
11+
let x: <&T as Tr>::Gat<W<_>> = 1i32;
12+
// Previously, `match_projection_projections` only checked that
13+
// `shallow_resolve(W<?0>) = W<?0>`. This won't prevent *all* inference guidance
14+
// from projection predicates in the environment, just ones that guide the
15+
// outermost type of each GAT constructor. This is definitely wrong, but there is
16+
// code that relies on it in the wild :/
17+
}
18+
19+
fn main() {}

0 commit comments

Comments
 (0)