Skip to content

Commit 807a75a

Browse files
authored
Rollup merge of #99146 - compiler-errors:issue-61525, r=lcnr
Do not error during method probe on `Sized` predicates for types that aren't the method receiver Fixes #61525 This is safe even though we're skipping an error because we end up confirming the method, which means we're still checking the `Sized` predicate in the end. It just means that we don't emit an erroneous message as below: ``` error: the `query` method cannot be invoked on a trait object --> src/lib.rs:14:11 | 14 | 1.query::<dyn ToString>("") | ^^^^^ | = note: another candidate was found in the following trait, perhaps add a `use` for it: `use crate::Example;` ``` Also fixes erroneously suggesting the same trait over again, as seen in the `issue-35976.rs` UI test.
2 parents 28428d5 + 88f2140 commit 807a75a

File tree

5 files changed

+77
-18
lines changed

5 files changed

+77
-18
lines changed

compiler/rustc_typeck/src/check/method/confirm.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,25 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
8181
let rcvr_substs = self.fresh_receiver_substs(self_ty, &pick);
8282
let all_substs = self.instantiate_method_substs(&pick, segment, rcvr_substs);
8383

84-
debug!("all_substs={:?}", all_substs);
84+
debug!("rcvr_substs={rcvr_substs:?}, all_substs={all_substs:?}");
8585

8686
// Create the final signature for the method, replacing late-bound regions.
8787
let (method_sig, method_predicates) = self.instantiate_method_sig(&pick, all_substs);
8888

89+
// If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that
90+
// something which derefs to `Self` actually implements the trait and the caller
91+
// wanted to make a static dispatch on it but forgot to import the trait.
92+
// See test `src/test/ui/issue-35976.rs`.
93+
//
94+
// In that case, we'll error anyway, but we'll also re-run the search with all traits
95+
// in scope, and if we find another method which can be used, we'll output an
96+
// appropriate hint suggesting to import the trait.
97+
let filler_substs = rcvr_substs
98+
.extend_to(self.tcx, pick.item.def_id, |def, _| self.tcx.mk_param_from_def(def));
99+
let illegal_sized_bound = self.predicates_require_illegal_sized_bound(
100+
&self.tcx.predicates_of(pick.item.def_id).instantiate(self.tcx, filler_substs),
101+
);
102+
89103
// Unify the (adjusted) self type with what the method expects.
90104
//
91105
// SUBTLE: if we want good error messages, because of "guessing" while matching
@@ -106,16 +120,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
106120
// Make sure nobody calls `drop()` explicitly.
107121
self.enforce_illegal_method_limitations(&pick);
108122

109-
// If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that
110-
// something which derefs to `Self` actually implements the trait and the caller
111-
// wanted to make a static dispatch on it but forgot to import the trait.
112-
// See test `src/test/ui/issue-35976.rs`.
113-
//
114-
// In that case, we'll error anyway, but we'll also re-run the search with all traits
115-
// in scope, and if we find another method which can be used, we'll output an
116-
// appropriate hint suggesting to import the trait.
117-
let illegal_sized_bound = self.predicates_require_illegal_sized_bound(&method_predicates);
118-
119123
// Add any trait/regions obligations specified on the method's type parameters.
120124
// We won't add these if we encountered an illegal sized bound, so that we can use
121125
// a custom error in that case.

compiler/rustc_typeck/src/check/method/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use rustc_hir::def_id::DefId;
2020
use rustc_infer::infer::{self, InferOk};
2121
use rustc_middle::ty::subst::Subst;
2222
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
23-
use rustc_middle::ty::GenericParamDefKind;
2423
use rustc_middle::ty::{self, ToPredicate, Ty, TypeVisitable};
24+
use rustc_middle::ty::{DefIdTree, GenericParamDefKind};
2525
use rustc_span::symbol::Ident;
2626
use rustc_span::Span;
2727
use rustc_trait_selection::traits;
@@ -221,7 +221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
221221
}
222222

223223
// We probe again, taking all traits into account (not only those in scope).
224-
let candidates = match self.lookup_probe(
224+
let mut candidates = match self.lookup_probe(
225225
span,
226226
segment.ident,
227227
self_ty,
@@ -243,6 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
243243
.collect(),
244244
_ => Vec::new(),
245245
};
246+
candidates.retain(|candidate| *candidate != self.tcx.parent(result.callee.def_id));
246247

247248
return Err(IllegalSizedBound(candidates, needs_mut, span));
248249
}

src/test/ui/issues/issue-35976.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ LL | fn wait(&self) where Self: Sized;
66
...
77
LL | arg.wait();
88
| ^^^^
9-
|
10-
help: another candidate was found in the following trait, perhaps add a `use` for it:
11-
|
12-
LL | use private::Future;
13-
|
149

1510
error: aborting due to previous error
1611

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
pub trait Example {
2+
fn query<Q>(self, q: Q);
3+
}
4+
5+
impl Example for i32 {
6+
fn query<Q>(self, _: Q) {
7+
unimplemented!()
8+
}
9+
}
10+
11+
mod nested {
12+
use super::Example;
13+
fn example() {
14+
1.query::<dyn ToString>("")
15+
//~^ ERROR the size for values of type `dyn ToString` cannot be known at compilation time
16+
//~| ERROR mismatched types
17+
}
18+
}
19+
20+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0277]: the size for values of type `dyn ToString` cannot be known at compilation time
2+
--> $DIR/issue-61525.rs:14:33
3+
|
4+
LL | 1.query::<dyn ToString>("")
5+
| ----- ^^ doesn't have a size known at compile-time
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `Sized` is not implemented for `dyn ToString`
10+
note: required by a bound in `Example::query`
11+
--> $DIR/issue-61525.rs:2:14
12+
|
13+
LL | fn query<Q>(self, q: Q);
14+
| ^ required by this bound in `Example::query`
15+
help: consider relaxing the implicit `Sized` restriction
16+
|
17+
LL | fn query<Q: ?Sized>(self, q: Q);
18+
| ++++++++
19+
20+
error[E0308]: mismatched types
21+
--> $DIR/issue-61525.rs:14:33
22+
|
23+
LL | 1.query::<dyn ToString>("")
24+
| --------------------- ^^ expected trait object `dyn ToString`, found `&str`
25+
| |
26+
| arguments to this function are incorrect
27+
|
28+
= note: expected trait object `dyn ToString`
29+
found reference `&'static str`
30+
note: associated function defined here
31+
--> $DIR/issue-61525.rs:2:8
32+
|
33+
LL | fn query<Q>(self, q: Q);
34+
| ^^^^^
35+
36+
error: aborting due to 2 previous errors
37+
38+
Some errors have detailed explanations: E0277, E0308.
39+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)