about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs2
-rw-r--r--src/test/ui/illegal-sized-bound/mutability-mismatch.rs34
-rw-r--r--src/test/ui/illegal-sized-bound/mutability-mismatch.stderr24
-rw-r--r--src/test/ui/illegal-sized-bound/regular.rs32
-rw-r--r--src/test/ui/illegal-sized-bound/regular.stderr20
5 files changed, 111 insertions, 1 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index b15c086ffad..a7eae392de1 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -209,7 +209,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ProbeScope::TraitsInScope,
                 ) {
                     Ok(ref new_pick) if pick.differs_from(new_pick) => {
-                        needs_mut = true;
+                        needs_mut = new_pick.self_ty.ref_mutability() != self_ty.ref_mutability();
                     }
                     _ => {}
                 }
diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch.rs b/src/test/ui/illegal-sized-bound/mutability-mismatch.rs
new file mode 100644
index 00000000000..deb84f6fe97
--- /dev/null
+++ b/src/test/ui/illegal-sized-bound/mutability-mismatch.rs
@@ -0,0 +1,34 @@
+struct MutType;
+
+pub trait MutTrait {
+    fn function(&mut self)
+    where
+        Self: Sized;
+    //~^ this has a `Sized` requirement
+}
+
+impl MutTrait for MutType {
+    fn function(&mut self) {}
+}
+
+struct Type;
+
+pub trait Trait {
+    fn function(&self)
+    where
+        Self: Sized;
+    //~^ this has a `Sized` requirement
+}
+
+impl Trait for Type {
+    fn function(&self) {}
+}
+
+fn main() {
+    (&MutType as &dyn MutTrait).function();
+    //~^ ERROR the `function` method cannot be invoked on a trait object
+    //~| NOTE you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
+    (&mut Type as &mut dyn Trait).function();
+    //~^ ERROR the `function` method cannot be invoked on a trait object
+    //~| NOTE you need `&dyn Trait` instead of `&mut dyn Trait`
+}
diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr b/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr
new file mode 100644
index 00000000000..dbbf79a4f1a
--- /dev/null
+++ b/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr
@@ -0,0 +1,24 @@
+error: the `function` method cannot be invoked on a trait object
+  --> $DIR/mutability-mismatch.rs:28:33
+   |
+LL |         Self: Sized;
+   |               ----- this has a `Sized` requirement
+...
+LL |     (&MutType as &dyn MutTrait).function();
+   |                                 ^^^^^^^^
+   |
+   = note: you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
+
+error: the `function` method cannot be invoked on a trait object
+  --> $DIR/mutability-mismatch.rs:31:35
+   |
+LL |         Self: Sized;
+   |               ----- this has a `Sized` requirement
+...
+LL |     (&mut Type as &mut dyn Trait).function();
+   |                                   ^^^^^^^^
+   |
+   = note: you need `&dyn Trait` instead of `&mut dyn Trait`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/illegal-sized-bound/regular.rs b/src/test/ui/illegal-sized-bound/regular.rs
new file mode 100644
index 00000000000..7abd27ef983
--- /dev/null
+++ b/src/test/ui/illegal-sized-bound/regular.rs
@@ -0,0 +1,32 @@
+struct MutType;
+
+pub trait MutTrait {
+    fn function(&mut self)
+    where
+        Self: Sized;
+    //~^ this has a `Sized` requirement
+}
+
+impl MutTrait for MutType {
+    fn function(&mut self) {}
+}
+
+struct Type;
+
+pub trait Trait {
+    fn function(&self)
+    where
+        Self: Sized;
+    //~^ this has a `Sized` requirement
+}
+
+impl Trait for Type {
+    fn function(&self) {}
+}
+
+fn main() {
+    (&mut MutType as &mut dyn MutTrait).function();
+    //~^ ERROR the `function` method cannot be invoked on a trait object
+    (&Type as &dyn Trait).function();
+    //~^ ERROR the `function` method cannot be invoked on a trait object
+}
diff --git a/src/test/ui/illegal-sized-bound/regular.stderr b/src/test/ui/illegal-sized-bound/regular.stderr
new file mode 100644
index 00000000000..7f3744145d9
--- /dev/null
+++ b/src/test/ui/illegal-sized-bound/regular.stderr
@@ -0,0 +1,20 @@
+error: the `function` method cannot be invoked on a trait object
+  --> $DIR/regular.rs:28:41
+   |
+LL |         Self: Sized;
+   |               ----- this has a `Sized` requirement
+...
+LL |     (&mut MutType as &mut dyn MutTrait).function();
+   |                                         ^^^^^^^^
+
+error: the `function` method cannot be invoked on a trait object
+  --> $DIR/regular.rs:30:27
+   |
+LL |         Self: Sized;
+   |               ----- this has a `Sized` requirement
+...
+LL |     (&Type as &dyn Trait).function();
+   |                           ^^^^^^^^
+
+error: aborting due to 2 previous errors
+