Skip to content

Commit 7fae1aa

Browse files
committed
Test whether we use DeepRejectCtxt
1 parent ccec360 commit 7fae1aa

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -492,10 +492,14 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
492492
// because it allows `impl<T> Foo<T>` to unify with `Foo<u8>::IAT`, while also disallowing
493493
// `Foo<T>::IAT` from unifying with `impl Foo<u8>`.
494494
//
495-
// We don't really care about a depth limit here because we're only working with user-written types
496-
// and if they wrote a type that would take hours to walk then that's kind of on them. On the other
497-
// hand the default depth limit is relatively low and could realistically be hit by users in normal
498-
// cases.
495+
// We don't really care about a depth limit here because we're only working with user-written
496+
// types and if they wrote a type that would take hours to walk then that's kind of on them. On
497+
// the other hand the default depth limit is relatively low and could realistically be hit by
498+
// users in normal cases.
499+
//
500+
// `DeepRejectCtxt` leads to slightly worse IAT resolution than real type equality in cases
501+
// where the `impl_ty` has repeated uses of generic parameters. E.g. `impl<T> Foo<T, T>` would
502+
// be considered a valid candidate when resolving `Foo<u8, u16>::IAT`.
499503
ty::DeepRejectCtxt::relate_rigid_infer(self.tcx)
500504
.types_may_unify_with_depth(self_ty, impl_ty, usize::MAX)
501505
})
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#![feature(inherent_associated_types)]
2+
#![expect(incomplete_features)]
3+
4+
// Test whether IAT resolution in item signatures will actually instantiate the
5+
// impl's params with infers before equating self types, or if we "cheat" and
6+
// use a heuristic (e.g. DeepRejectCtxt).
7+
8+
struct Foo<T, U, V>(T, U, V);
9+
10+
impl<T> Foo<T, T, u8> {
11+
type IAT = u8;
12+
}
13+
14+
impl<T, U> Foo<T, U, u16> {
15+
type IAT = u16;
16+
}
17+
18+
trait Identity {
19+
type This;
20+
}
21+
impl<T> Identity for T {
22+
type This = T;
23+
}
24+
25+
struct Bar<T, U> {
26+
// It would be illegal to resolve to `Foo<T, T, u8>::IAT` as `T` and `U` are
27+
// different types. However, currently we treat all impl-side params sort of like
28+
// they're infers and assume they can unify with anything, so we consider it a
29+
// valid candidate.
30+
field: Foo<T, U, <u16 as Identity>::This>::IAT,
31+
//~^ ERROR: multiple applicable items in scope
32+
}
33+
34+
fn main() {}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0034]: multiple applicable items in scope
2+
--> $DIR/impl_params_are_infers.rs:30:48
3+
|
4+
LL | field: Foo<T, U, <u16 as Identity>::This>::IAT,
5+
| ^^^ multiple `IAT` found
6+
|
7+
note: candidate #1 is defined in an impl for the type `Foo<T, T, u8>`
8+
--> $DIR/impl_params_are_infers.rs:11:5
9+
|
10+
LL | type IAT = u8;
11+
| ^^^^^^^^
12+
note: candidate #2 is defined in an impl for the type `Foo<T, U, u16>`
13+
--> $DIR/impl_params_are_infers.rs:15:5
14+
|
15+
LL | type IAT = u16;
16+
| ^^^^^^^^
17+
18+
error: aborting due to 1 previous error
19+
20+
For more information about this error, try `rustc --explain E0034`.

0 commit comments

Comments
 (0)