about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs6
-rw-r--r--tests/crashes/132127.rs9
-rw-r--r--tests/ui/dyn-star/illegal.rs16
-rw-r--r--tests/ui/dyn-star/illegal.stderr27
5 files changed, 52 insertions, 18 deletions
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 59c06cbc5b5..8190095971b 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -721,13 +721,11 @@ impl<'a, 'tcx> CastCheck<'tcx> {
         use rustc_middle::ty::cast::IntTy::*;
 
         if self.cast_ty.is_dyn_star() {
-            if fcx.tcx.features().dyn_star() {
-                span_bug!(self.span, "should be handled by `coerce`");
-            } else {
-                // Report "casting is invalid" rather than "non-primitive cast"
-                // if the feature is not enabled.
-                return Err(CastError::IllegalCast);
-            }
+            // This coercion will fail if the feature is not enabled, OR
+            // if the coercion is (currently) illegal (e.g. `dyn* Foo + Send`
+            // to `dyn* Foo`). Report "casting is invalid" rather than
+            // "non-primitive cast".
+            return Err(CastError::IllegalCast);
         }
 
         let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty))
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 541e16e42a7..f9e4a592d92 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -737,8 +737,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             return Err(TypeError::Mismatch);
         }
 
-        if let ty::Dynamic(a_data, _, _) = a.kind()
-            && let ty::Dynamic(b_data, _, _) = b.kind()
+        // FIXME(dyn_star): We should probably allow things like casting from
+        // `dyn* Foo + Send` to `dyn* Foo`.
+        if let ty::Dynamic(a_data, _, ty::DynStar) = a.kind()
+            && let ty::Dynamic(b_data, _, ty::DynStar) = b.kind()
             && a_data.principal_def_id() == b_data.principal_def_id()
         {
             return self.unify_and(a, b, |_| vec![]);
diff --git a/tests/crashes/132127.rs b/tests/crashes/132127.rs
deleted file mode 100644
index cca354b9876..00000000000
--- a/tests/crashes/132127.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #132127
-#![feature(dyn_star)]
-
-trait Trait {}
-
-fn main() {
-    let x: dyn* Trait + Send = 1usize;
-    x as dyn* Trait;
-}
diff --git a/tests/ui/dyn-star/illegal.rs b/tests/ui/dyn-star/illegal.rs
new file mode 100644
index 00000000000..ce0d784fcd2
--- /dev/null
+++ b/tests/ui/dyn-star/illegal.rs
@@ -0,0 +1,16 @@
+#![feature(dyn_star)]
+//~^ WARN the feature `dyn_star` is incomplete
+
+trait Foo {}
+
+pub fn lol(x: dyn* Foo + Send) {
+    x as dyn* Foo;
+    //~^ ERROR casting `(dyn* Foo + Send + 'static)` as `dyn* Foo` is invalid
+}
+
+fn lol2(x: &dyn Foo) {
+    *x as dyn* Foo;
+    //~^ ERROR `dyn Foo` needs to have the same ABI as a pointer
+}
+
+fn main() {}
diff --git a/tests/ui/dyn-star/illegal.stderr b/tests/ui/dyn-star/illegal.stderr
new file mode 100644
index 00000000000..fdf3c813a23
--- /dev/null
+++ b/tests/ui/dyn-star/illegal.stderr
@@ -0,0 +1,27 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/illegal.rs:1:12
+   |
+LL | #![feature(dyn_star)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0606]: casting `(dyn* Foo + Send + 'static)` as `dyn* Foo` is invalid
+  --> $DIR/illegal.rs:7:5
+   |
+LL |     x as dyn* Foo;
+   |     ^^^^^^^^^^^^^
+
+error[E0277]: `dyn Foo` needs to have the same ABI as a pointer
+  --> $DIR/illegal.rs:12:5
+   |
+LL |     *x as dyn* Foo;
+   |     ^^ `dyn Foo` needs to be a pointer-like type
+   |
+   = help: the trait `PointerLike` is not implemented for `dyn Foo`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0277, E0606.
+For more information about an error, try `rustc --explain E0277`.