Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 05483d5

Browse files
Relate receiver invariantly in method probe for Mode::Path
1 parent 8c2c9a9 commit 05483d5

17 files changed

+141
-56
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,10 +1388,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13881388
// This also occurs for an enum variant on a type alias.
13891389
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
13901390
let self_ty = self.normalize(span, self_ty);
1391-
match self.at(&self.misc(span), self.param_env).sub(
1391+
match self.at(&self.misc(span), self.param_env).eq(
13921392
DefineOpaqueTypes::Yes,
1393-
self_ty,
13941393
impl_ty,
1394+
self_ty,
13951395
) {
13961396
Ok(ok) => self.register_infer_ok_obligations(ok),
13971397
Err(_) => {

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
621621
self.unsatisfied_predicates.borrow_mut().clear();
622622
}
623623

624+
/// When we're looking up a method by path (UFCS), we relate the receiver
625+
/// types invariantly. When we are looking up a method by the `.` operator,
626+
/// we relate them covariantly.
627+
fn variance(&self) -> ty::Variance {
628+
match self.mode {
629+
Mode::MethodCall => ty::Covariant,
630+
Mode::Path => ty::Invariant,
631+
}
632+
}
633+
624634
///////////////////////////////////////////////////////////////////////////
625635
// CANDIDATE ASSEMBLY
626636

@@ -1443,7 +1453,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14431453
(xform_self_ty, xform_ret_ty) =
14441454
self.xform_self_ty(probe.item, impl_ty, impl_args);
14451455
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
1446-
match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
1456+
match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
1457+
{
14471458
Ok(()) => {}
14481459
Err(err) => {
14491460
debug!("--> cannot relate self-types {:?}", err);
@@ -1514,7 +1525,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15141525
{
15151526
return ProbeResult::NoMatch;
15161527
}
1517-
_ => match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
1528+
_ => match ocx.relate(
1529+
cause,
1530+
self.param_env,
1531+
self.variance(),
1532+
self_ty,
1533+
xform_self_ty,
1534+
) {
15181535
Ok(()) => {}
15191536
Err(err) => {
15201537
debug!("--> cannot relate self-types {:?}", err);
@@ -1560,7 +1577,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15601577
(xform_self_ty, xform_ret_ty) =
15611578
self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
15621579
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
1563-
match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
1580+
match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
1581+
{
15641582
Ok(()) => {}
15651583
Err(err) => {
15661584
debug!("--> cannot relate self-types {:?}", err);
@@ -1603,7 +1621,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16031621
}
16041622

16051623
debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty);
1606-
match ocx.sup(cause, self.param_env, return_ty, xform_ret_ty) {
1624+
match ocx.relate(cause, self.param_env, self.variance(), xform_ret_ty, return_ty) {
16071625
Ok(()) => {}
16081626
Err(_) => {
16091627
result = ProbeResult::BadReturnType;

tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ impl Fail<i32> {
77

88
fn main() {
99
Fail::<()>::C
10+
//~^ ERROR no associated item named `C` found for struct `Fail<()>` in the current scope
1011
}

tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ LL | struct Fail<T>;
77
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
88
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
99

10-
error: aborting due to 1 previous error
10+
error[E0599]: no associated item named `C` found for struct `Fail<()>` in the current scope
11+
--> $DIR/wrong-projection-self-ty-invalid-bivariant-arg.rs:9:17
12+
|
13+
LL | struct Fail<T>;
14+
| -------------- associated item `C` not found for this struct
15+
...
16+
LL | Fail::<()>::C
17+
| ^ associated item not found in `Fail<()>`
18+
|
19+
= note: the associated item was found for
20+
- `Fail<i32>`
21+
22+
error: aborting due to 2 previous errors
1123

12-
For more information about this error, try `rustc --explain E0392`.
24+
Some errors have detailed explanations: E0392, E0599.
25+
For more information about an error, try `rustc --explain E0392`.

tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ impl Fail<i32, i32> {
1414
fn main() {
1515
Fail::<i32, u32>::C
1616
//~^ ERROR: type mismatch
17+
//~| ERROR no associated item named `C` found for struct `Fail<i32, u32>` in the current scope
1718
}

tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
error[E0599]: no associated item named `C` found for struct `Fail<i32, u32>` in the current scope
2+
--> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:23
3+
|
4+
LL | struct Fail<T: Proj<Assoc = U>, U>(T);
5+
| ---------------------------------- associated item `C` not found for this struct
6+
...
7+
LL | Fail::<i32, u32>::C
8+
| ^ associated item not found in `Fail<i32, u32>`
9+
|
10+
= note: the associated item was found for
11+
- `Fail<i32, i32>`
12+
113
error[E0271]: type mismatch resolving `<i32 as Proj>::Assoc == u32`
214
--> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:5
315
|
@@ -15,6 +27,7 @@ note: required by a bound in `Fail`
1527
LL | struct Fail<T: Proj<Assoc = U>, U>(T);
1628
| ^^^^^^^^^ required by this bound in `Fail`
1729

18-
error: aborting due to 1 previous error
30+
error: aborting due to 2 previous errors
1931

20-
For more information about this error, try `rustc --explain E0271`.
32+
Some errors have detailed explanations: E0271, E0599.
33+
For more information about an error, try `rustc --explain E0271`.

tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/ui/coercion/coerce-issue-49593-box-never.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@ revisions: nofallback fallback
2-
//@check-fail
2+
//@[fallback] check-pass
33

44
#![feature(never_type)]
55
#![cfg_attr(fallback, feature(never_type_fallback))]
@@ -13,10 +13,10 @@ fn raw_ptr_box<T>(t: T) -> *mut T {
1313
}
1414

1515
fn foo(x: !) -> Box<dyn Error> {
16-
// Subtyping during method resolution will generate new inference vars and
17-
// subtype them. Thus fallback will not fall back to `!`, but `()` instead.
16+
// Method resolution will generate new inference vars and relate them.
17+
// Thus fallback will not fall back to `!`, but `()` instead.
1818
Box::<_ /* ! */>::new(x)
19-
//~^ ERROR trait bound `(): std::error::Error` is not satisfied
19+
//[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
2020
}
2121

2222
fn foo_raw_ptr(x: !) -> *mut dyn Error {

tests/ui/const-generics/generic_arg_infer/issue-91614.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ note: required by a const generic parameter in `Mask::<T, N>::splat`
88
--> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
99
help: consider giving `y` an explicit type, where the value of const parameter `N` is specified
1010
|
11-
LL | let y: Mask<T, N> = Mask::<_, _>::splat(false);
11+
LL | let y: Mask<_, N> = Mask::<_, _>::splat(false);
1212
| ++++++++++++
1313

1414
error[E0284]: type annotations needed for `Mask<_, _>`
@@ -21,7 +21,7 @@ note: required by a const generic parameter in `Mask`
2121
--> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
2222
help: consider giving `y` an explicit type, where the value of const parameter `N` is specified
2323
|
24-
LL | let y: Mask<T, N> = Mask::<_, _>::splat(false);
24+
LL | let y: Mask<_, N> = Mask::<_, _>::splat(false);
2525
| ++++++++++++
2626

2727
error: aborting due to 2 previous errors

tests/ui/impl-trait/issues/issue-62742.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use std::marker::PhantomData;
22

33
fn a() {
44
WrongImpl::foo(0i32);
5-
//~^ ERROR overflow assigning `_` to `[_]`
5+
//~^ ERROR the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied
6+
//~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
67
}
78

89
fn b() {

0 commit comments

Comments
 (0)