Skip to content

Commit ff4653a

Browse files
Use fulfillment, not evaluate, during method probe
1 parent c13af7d commit ff4653a

27 files changed

+328
-407
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
889889
[candidate] => format!(
890890
"the method of the same name on {} `{}`",
891891
match candidate.kind {
892-
probe::CandidateKind::InherentImplCandidate(..) => "the inherent impl for",
892+
probe::CandidateKind::InherentImplCandidate(_) => "the inherent impl for",
893893
_ => "trait",
894894
},
895895
self.tcx.def_path_str(candidate.item.container_id(self.tcx))

compiler/rustc_hir_typeck/src/method/probe.rs

+130-301
Large diffs are not rendered by default.

compiler/rustc_trait_selection/src/traits/engine.rs

+13
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,19 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
129129
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
130130
}
131131

132+
pub fn eq_no_opaques<T: ToTrace<'tcx>>(
133+
&self,
134+
cause: &ObligationCause<'tcx>,
135+
param_env: ty::ParamEnv<'tcx>,
136+
expected: T,
137+
actual: T,
138+
) -> Result<(), TypeError<'tcx>> {
139+
self.infcx
140+
.at(cause, param_env)
141+
.eq(DefineOpaqueTypes::No, expected, actual)
142+
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
143+
}
144+
132145
/// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
133146
pub fn sub<T: ToTrace<'tcx>>(
134147
&self,

tests/ui/derives/issue-91550.stderr

+4-23
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ error[E0599]: the method `insert` exists for struct `HashSet<Value>`, but its tr
22
--> $DIR/issue-91550.rs:8:8
33
|
44
LL | struct Value(u32);
5-
| ------------ doesn't satisfy `Value: Eq`, `Value: Hash` or `Value: PartialEq`
5+
| ------------ doesn't satisfy `Value: Eq` or `Value: Hash`
66
...
77
LL | hs.insert(Value(0));
88
| ^^^^^^
99
|
1010
= note: the following trait bounds were not satisfied:
1111
`Value: Eq`
12-
`Value: PartialEq`
13-
which is required by `Value: Eq`
1412
`Value: Hash`
1513
help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]`
1614
|
@@ -22,7 +20,7 @@ error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its
2220
--> $DIR/issue-91550.rs:26:9
2321
|
2422
LL | pub struct NoDerives;
25-
| -------------------- doesn't satisfy `NoDerives: Eq` or `NoDerives: PartialEq`
23+
| -------------------- doesn't satisfy `NoDerives: Eq`
2624
LL |
2725
LL | struct Object<T>(T);
2826
| ---------------- method `use_eq` not found for this struct
@@ -37,9 +35,6 @@ LL | impl<T: Eq> Object<T> {
3735
| ^^ ---------
3836
| |
3937
| unsatisfied trait bound introduced here
40-
= note: the following trait bounds were not satisfied:
41-
`NoDerives: PartialEq`
42-
which is required by `NoDerives: Eq`
4338
help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]`
4439
|
4540
LL + #[derive(Eq, PartialEq)]
@@ -50,7 +45,7 @@ error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but it
5045
--> $DIR/issue-91550.rs:27:9
5146
|
5247
LL | pub struct NoDerives;
53-
| -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
48+
| -------------------- doesn't satisfy `NoDerives: Ord`
5449
LL |
5550
LL | struct Object<T>(T);
5651
| ---------------- method `use_ord` not found for this struct
@@ -65,13 +60,6 @@ LL | impl<T: Ord> Object<T> {
6560
| ^^^ ---------
6661
| |
6762
| unsatisfied trait bound introduced here
68-
= note: the following trait bounds were not satisfied:
69-
`NoDerives: PartialOrd`
70-
which is required by `NoDerives: Ord`
71-
`NoDerives: PartialEq`
72-
which is required by `NoDerives: Ord`
73-
`NoDerives: Eq`
74-
which is required by `NoDerives: Ord`
7563
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
7664
|
7765
LL + #[derive(Eq, Ord, PartialEq, PartialOrd)]
@@ -82,7 +70,7 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoD
8270
--> $DIR/issue-91550.rs:28:9
8371
|
8472
LL | pub struct NoDerives;
85-
| -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
73+
| -------------------- doesn't satisfy `NoDerives: Ord` or `NoDerives: PartialOrd`
8674
LL |
8775
LL | struct Object<T>(T);
8876
| ---------------- method `use_ord_and_partial_ord` not found for this struct
@@ -100,13 +88,6 @@ LL | impl<T: Ord + PartialOrd> Object<T> {
10088
| | |
10189
| | unsatisfied trait bound introduced here
10290
| unsatisfied trait bound introduced here
103-
= note: the following trait bounds were not satisfied:
104-
`NoDerives: PartialEq`
105-
which is required by `NoDerives: Ord`
106-
`NoDerives: Eq`
107-
which is required by `NoDerives: Ord`
108-
`NoDerives: PartialEq`
109-
which is required by `NoDerives: PartialOrd`
11091
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
11192
|
11293
LL + #[derive(Eq, Ord, PartialEq, PartialOrd)]

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::marker::PhantomData;
33
fn _alias_check() {
44
WrongImpl::foo(0i32);
55
//~^ ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
6-
//~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
6+
//~| ERROR the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied
77
WrongImpl::<()>::foo(0i32);
88
//~^ ERROR the trait bound `RawImpl<()>: Raw<()>` is not satisfied
99
//~| ERROR trait bounds were not satisfied

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

+30-20
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
1-
error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
2-
--> $DIR/issue-62742.rs:4:5
1+
error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied
2+
--> $DIR/issue-62742.rs:4:16
33
|
44
LL | WrongImpl::foo(0i32);
5-
| ^^^^^^^^^^^^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
5+
| ^^^ function or associated item cannot be called on `SafeImpl<_, RawImpl<_>>` due to unsatisfied trait bounds
6+
...
7+
LL | pub struct RawImpl<T>(PhantomData<T>);
8+
| --------------------- doesn't satisfy `RawImpl<_>: Raw<_>`
9+
...
10+
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
11+
| ----------------------------------------- function or associated item `foo` not found for this struct
612
|
7-
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
8-
note: required by a bound in `SafeImpl::<T, A>::foo`
13+
note: trait bound `RawImpl<_>: Raw<_>` was not satisfied
914
--> $DIR/issue-62742.rs:29:20
1015
|
1116
LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
12-
| ^^^^^^ required by this bound in `SafeImpl::<T, A>::foo`
13-
LL | pub fn foo(value: A::Value) {}
14-
| --- required by a bound in this associated function
15-
16-
error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
17-
--> $DIR/issue-62742.rs:4:5
18-
|
19-
LL | WrongImpl::foo(0i32);
20-
| ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
21-
|
22-
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
23-
note: required by a bound in `SafeImpl`
24-
--> $DIR/issue-62742.rs:27:35
17+
| ^^^^^^ --------------
18+
| |
19+
| unsatisfied trait bound introduced here
20+
note: the trait `Raw` must be implemented
21+
--> $DIR/issue-62742.rs:13:1
2522
|
26-
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
27-
| ^^^^^^ required by this bound in `SafeImpl`
23+
LL | pub trait Raw<T: ?Sized> {
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^
2825

2926
error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied
3027
--> $DIR/issue-62742.rs:7:22
@@ -51,6 +48,19 @@ note: the trait `Raw` must be implemented
5148
LL | pub trait Raw<T: ?Sized> {
5249
| ^^^^^^^^^^^^^^^^^^^^^^^^
5350

51+
error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
52+
--> $DIR/issue-62742.rs:4:5
53+
|
54+
LL | WrongImpl::foo(0i32);
55+
| ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
56+
|
57+
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
58+
note: required by a bound in `SafeImpl`
59+
--> $DIR/issue-62742.rs:27:35
60+
|
61+
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
62+
| ^^^^^^ required by this bound in `SafeImpl`
63+
5464
error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied
5565
--> $DIR/issue-62742.rs:7:5
5666
|

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ where
2929
}
3030

3131
fn main() {
32-
Race::new(|race| race.when()); //~ ERROR overflow assigning `_` to `Option<_>`
32+
Race::new(|race| race.when());
33+
//~^ ERROR the method `when` exists for struct `RaceBuilder<_, Never<_>>`, but its trait bounds were not satisfied
3334
}
+24-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
1-
error[E0275]: overflow assigning `_` to `Option<_>`
2-
--> $DIR/issue-84073.rs:32:22
1+
error[E0599]: the method `when` exists for struct `RaceBuilder<_, Never<_>>`, but its trait bounds were not satisfied
2+
--> $DIR/issue-84073.rs:32:27
33
|
4+
LL | pub struct Never<T>(PhantomData<T>);
5+
| ------------------- doesn't satisfy `Never<_>: StatefulFuture<Option<_>>`
6+
...
7+
LL | pub struct RaceBuilder<F, S> {
8+
| ---------------------------- method `when` not found for this struct
9+
...
410
LL | Race::new(|race| race.when());
5-
| ^^^^
11+
| ^^^^ method cannot be called on `RaceBuilder<_, Never<_>>` due to unsatisfied trait bounds
12+
|
13+
note: trait bound `Never<_>: StatefulFuture<Option<_>>` was not satisfied
14+
--> $DIR/issue-84073.rs:14:8
15+
|
16+
LL | impl<T, F> RaceBuilder<T, F>
17+
| -----------------
18+
LL | where
19+
LL | F: StatefulFuture<Option<T>>,
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
21+
note: the trait `StatefulFuture` must be implemented
22+
--> $DIR/issue-84073.rs:3:1
23+
|
24+
LL | pub trait StatefulFuture<S> {}
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
626

727
error: aborting due to 1 previous error
828

9-
For more information about this error, try `rustc --explain E0275`.
29+
For more information about this error, try `rustc --explain E0599`.

tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let _result = &Some(42).as_deref();
66
|
77
= note: the following trait bounds were not satisfied:
88
`{integer}: Deref`
9+
which is required by `<{integer} as Deref>::Target = _`
910

1011
error: aborting due to 1 previous error
1112

tests/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let _result = &mut Some(42).as_deref_mut();
66
|
77
= note: the following trait bounds were not satisfied:
88
`{integer}: Deref`
9+
which is required by `<{integer} as Deref>::Target = _`
910

1011
error: aborting due to 1 previous error
1112

tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let _result = &Ok(42).as_deref();
66
|
77
= note: the following trait bounds were not satisfied:
88
`{integer}: Deref`
9+
which is required by `<{integer} as Deref>::Target = _`
910

1011
error: aborting due to 1 previous error
1112

tests/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let _result = &mut Ok(42).as_deref_mut();
66
|
77
= note: the following trait bounds were not satisfied:
88
`{integer}: Deref`
9+
which is required by `<{integer} as Deref>::Target = _`
910

1011
error: aborting due to 1 previous error
1112

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Tests that using fulfillment in the trait solver means that we detect that a
2+
// method is impossible, leading to no ambiguity.
3+
//@ check-pass
4+
//@ revisions: current next
5+
//@ ignore-compare-mode-next-solver (explicit revisions)
6+
//@[next] compile-flags: -Znext-solver
7+
8+
#[derive(Default)]
9+
struct W<A, B>(A, B);
10+
11+
trait Constrain {
12+
type Output;
13+
}
14+
15+
impl Constrain for i32 {
16+
type Output = u32;
17+
}
18+
19+
trait Impossible {}
20+
21+
impl<A, B> W<A, B> where A: Constrain<Output = B>, B: Impossible {
22+
fn method(&self) {}
23+
}
24+
25+
impl W<i32, u32> {
26+
fn method(&self) {}
27+
}
28+
29+
fn main() {
30+
let w: W<i32, _> = W::default();
31+
w.method();
32+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Tests that using fulfillment in the trait solver means that we detect that a
2+
// method is impossible, leading to no ambiguity.
3+
//@ check-pass
4+
//@ revisions: current next
5+
//@ ignore-compare-mode-next-solver (explicit revisions)
6+
//@[next] compile-flags: -Znext-solver
7+
8+
struct W<T, U>(Option<T>, Option<U>);
9+
10+
impl<'a> W<fn(&'a ()), u32> {
11+
fn method(&self) {}
12+
}
13+
14+
trait Leak {}
15+
impl<T: Fn(&())> Leak for T {}
16+
17+
impl<T: Leak> W<T, i32> {
18+
fn method(&self) {}
19+
}
20+
21+
fn test<'a>() {
22+
let x: W<fn(&'a ()), _> = W(None, None);
23+
x.method();
24+
}
25+
26+
fn main() {}

tests/ui/mismatched_types/issue-36053-2.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,16 @@ error[E0599]: the method `count` exists for struct `Filter<Fuse<Once<&str>>, {cl
2121
LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
2222
| --------- ^^^^^ method cannot be called due to unsatisfied trait bounds
2323
| |
24-
| doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool` or `_: FnMut<(&&str,)>`
24+
| doesn't satisfy `_: FnMut<(&&str,)>` or `_: FnOnce<(&&str,)>`
2525
|
2626
= note: the following trait bounds were not satisfied:
27-
`<{closure@$DIR/issue-36053-2.rs:7:39: 7:48} as FnOnce<(&&str,)>>::Output = bool`
28-
which is required by `Filter<Fuse<std::iter::Once<&str>>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator`
2927
`{closure@$DIR/issue-36053-2.rs:7:39: 7:48}: FnMut<(&&str,)>`
3028
which is required by `Filter<Fuse<std::iter::Once<&str>>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator`
31-
`Filter<Fuse<std::iter::Once<&str>>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator`
29+
`{closure@$DIR/issue-36053-2.rs:7:39: 7:48}: FnOnce<(&&str,)>`
30+
which is required by `Filter<Fuse<std::iter::Once<&str>>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator`
31+
`{closure@$DIR/issue-36053-2.rs:7:39: 7:48}: FnMut<(&&str,)>`
32+
which is required by `&mut Filter<Fuse<std::iter::Once<&str>>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator`
33+
`{closure@$DIR/issue-36053-2.rs:7:39: 7:48}: FnOnce<(&&str,)>`
3234
which is required by `&mut Filter<Fuse<std::iter::Once<&str>>, {closure@$DIR/issue-36053-2.rs:7:39: 7:48}>: Iterator`
3335

3436
error: aborting due to 2 previous errors

tests/ui/missing-trait-bounds/issue-35677.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ LL | this.is_subset(other)
66
|
77
= note: the following trait bounds were not satisfied:
88
`T: Eq`
9-
`T: PartialEq`
10-
which is required by `T: Eq`
119
`T: Hash`
1210
help: consider restricting the type parameters to satisfy the trait bounds
1311
|

tests/ui/nll/issue-57362-2.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ impl<'a> X for fn(&'a ()) {
1919
}
2020

2121
fn g() {
22-
let x = <fn (&())>::make_g(); //~ ERROR the function
22+
let x = <fn (&())>::make_g();
23+
//~^ ERROR no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope
2324
}
2425

2526
fn main() {}

tests/ui/nll/issue-57362-2.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
error[E0599]: the function or associated item `make_g` exists for fn pointer `fn(&())`, but its trait bounds were not satisfied
1+
error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope
22
--> $DIR/issue-57362-2.rs:22:25
33
|
44
LL | let x = <fn (&())>::make_g();
5-
| ^^^^^^ function or associated item cannot be called on `fn(&())` due to unsatisfied trait bounds
5+
| ^^^^^^ function or associated item not found in `fn(&())`
66
|
7-
= note: the following trait bounds were not satisfied:
8-
`for<'a> fn(&'a ()): X`
97
= help: items from traits can only be used if the trait is implemented and in scope
108
note: `X` defines an item `make_g`, perhaps you need to implement it
119
--> $DIR/issue-57362-2.rs:8:1

tests/ui/nll/issue-57642-higher-ranked-subtype.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ impl<T> Y for fn(T) {
2828
}
2929

3030
fn higher_ranked_region_has_lost_its_binder() {
31-
let x = <fn (&())>::make_g(); //~ ERROR the function
31+
let x = <fn (&())>::make_g();
32+
//~^ ERROR no function or associated item named `make_g` found for fn pointer `for<'a> fn(&'a ())` in the current scope
3233
}
3334

3435
fn magical() {

0 commit comments

Comments
 (0)