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.
This commit is contained in:
commit
5e223dc7b9
@ -81,11 +81,25 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
let rcvr_substs = self.fresh_receiver_substs(self_ty, &pick);
|
||||
let all_substs = self.instantiate_method_substs(&pick, segment, rcvr_substs);
|
||||
|
||||
debug!("all_substs={:?}", all_substs);
|
||||
debug!("rcvr_substs={rcvr_substs:?}, all_substs={all_substs:?}");
|
||||
|
||||
// Create the final signature for the method, replacing late-bound regions.
|
||||
let (method_sig, method_predicates) = self.instantiate_method_sig(&pick, all_substs);
|
||||
|
||||
// If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that
|
||||
// something which derefs to `Self` actually implements the trait and the caller
|
||||
// wanted to make a static dispatch on it but forgot to import the trait.
|
||||
// See test `src/test/ui/issue-35976.rs`.
|
||||
//
|
||||
// In that case, we'll error anyway, but we'll also re-run the search with all traits
|
||||
// in scope, and if we find another method which can be used, we'll output an
|
||||
// appropriate hint suggesting to import the trait.
|
||||
let filler_substs = rcvr_substs
|
||||
.extend_to(self.tcx, pick.item.def_id, |def, _| self.tcx.mk_param_from_def(def));
|
||||
let illegal_sized_bound = self.predicates_require_illegal_sized_bound(
|
||||
&self.tcx.predicates_of(pick.item.def_id).instantiate(self.tcx, filler_substs),
|
||||
);
|
||||
|
||||
// Unify the (adjusted) self type with what the method expects.
|
||||
//
|
||||
// SUBTLE: if we want good error messages, because of "guessing" while matching
|
||||
@ -106,16 +120,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
// Make sure nobody calls `drop()` explicitly.
|
||||
self.enforce_illegal_method_limitations(&pick);
|
||||
|
||||
// If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that
|
||||
// something which derefs to `Self` actually implements the trait and the caller
|
||||
// wanted to make a static dispatch on it but forgot to import the trait.
|
||||
// See test `src/test/ui/issue-35976.rs`.
|
||||
//
|
||||
// In that case, we'll error anyway, but we'll also re-run the search with all traits
|
||||
// in scope, and if we find another method which can be used, we'll output an
|
||||
// appropriate hint suggesting to import the trait.
|
||||
let illegal_sized_bound = self.predicates_require_illegal_sized_bound(&method_predicates);
|
||||
|
||||
// Add any trait/regions obligations specified on the method's type parameters.
|
||||
// We won't add these if we encountered an illegal sized bound, so that we can use
|
||||
// a custom error in that case.
|
||||
|
@ -20,8 +20,8 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::{self, InferOk};
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
|
||||
use rustc_middle::ty::GenericParamDefKind;
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TypeVisitable};
|
||||
use rustc_middle::ty::{DefIdTree, GenericParamDefKind};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits;
|
||||
@ -221,7 +221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// We probe again, taking all traits into account (not only those in scope).
|
||||
let candidates = match self.lookup_probe(
|
||||
let mut candidates = match self.lookup_probe(
|
||||
span,
|
||||
segment.ident,
|
||||
self_ty,
|
||||
@ -243,6 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.collect(),
|
||||
_ => Vec::new(),
|
||||
};
|
||||
candidates.retain(|candidate| *candidate != self.tcx.parent(result.callee.def_id));
|
||||
|
||||
return Err(IllegalSizedBound(candidates, needs_mut, span));
|
||||
}
|
||||
|
@ -6,11 +6,6 @@ LL | fn wait(&self) where Self: Sized;
|
||||
...
|
||||
LL | arg.wait();
|
||||
| ^^^^
|
||||
|
|
||||
help: another candidate was found in the following trait, perhaps add a `use` for it:
|
||||
|
|
||||
LL | use private::Future;
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
20
src/test/ui/methods/issues/issue-61525.rs
Normal file
20
src/test/ui/methods/issues/issue-61525.rs
Normal file
@ -0,0 +1,20 @@
|
||||
pub trait Example {
|
||||
fn query<Q>(self, q: Q);
|
||||
}
|
||||
|
||||
impl Example for i32 {
|
||||
fn query<Q>(self, _: Q) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
mod nested {
|
||||
use super::Example;
|
||||
fn example() {
|
||||
1.query::<dyn ToString>("")
|
||||
//~^ ERROR the size for values of type `dyn ToString` cannot be known at compilation time
|
||||
//~| ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
39
src/test/ui/methods/issues/issue-61525.stderr
Normal file
39
src/test/ui/methods/issues/issue-61525.stderr
Normal file
@ -0,0 +1,39 @@
|
||||
error[E0277]: the size for values of type `dyn ToString` cannot be known at compilation time
|
||||
--> $DIR/issue-61525.rs:14:33
|
||||
|
|
||||
LL | 1.query::<dyn ToString>("")
|
||||
| ----- ^^ doesn't have a size known at compile-time
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `dyn ToString`
|
||||
note: required by a bound in `Example::query`
|
||||
--> $DIR/issue-61525.rs:2:14
|
||||
|
|
||||
LL | fn query<Q>(self, q: Q);
|
||||
| ^ required by this bound in `Example::query`
|
||||
help: consider relaxing the implicit `Sized` restriction
|
||||
|
|
||||
LL | fn query<Q: ?Sized>(self, q: Q);
|
||||
| ++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-61525.rs:14:33
|
||||
|
|
||||
LL | 1.query::<dyn ToString>("")
|
||||
| --------------------- ^^ expected trait object `dyn ToString`, found `&str`
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
= note: expected trait object `dyn ToString`
|
||||
found reference `&'static str`
|
||||
note: associated function defined here
|
||||
--> $DIR/issue-61525.rs:2:8
|
||||
|
|
||||
LL | fn query<Q>(self, q: Q);
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
Loading…
x
Reference in New Issue
Block a user