about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/method/confirm.rs26
-rw-r--r--src/test/ui/methods/issues/issue-61525.rs20
-rw-r--r--src/test/ui/methods/issues/issue-61525.stderr39
3 files changed, 74 insertions, 11 deletions
diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs
index d8cdc9275f4..b14f3d6de4e 100644
--- a/compiler/rustc_typeck/src/check/method/confirm.rs
+++ b/compiler/rustc_typeck/src/check/method/confirm.rs
@@ -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.
diff --git a/src/test/ui/methods/issues/issue-61525.rs b/src/test/ui/methods/issues/issue-61525.rs
new file mode 100644
index 00000000000..c5ca0326e43
--- /dev/null
+++ b/src/test/ui/methods/issues/issue-61525.rs
@@ -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() {}
diff --git a/src/test/ui/methods/issues/issue-61525.stderr b/src/test/ui/methods/issues/issue-61525.stderr
new file mode 100644
index 00000000000..aec968d7c44
--- /dev/null
+++ b/src/test/ui/methods/issues/issue-61525.stderr
@@ -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`.