]> git.lizzy.rs Git - rust.git/commitdiff
Disable dyn* upcasting
authorMichael Goulet <michael@errs.io>
Sat, 19 Nov 2022 04:48:01 +0000 (04:48 +0000)
committerMichael Goulet <michael@errs.io>
Thu, 24 Nov 2022 01:10:24 +0000 (01:10 +0000)
compiler/rustc_hir_typeck/src/coercion.rs
compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.rs [new file with mode: 0644]
src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr [new file with mode: 0644]
src/test/ui/dyn-star/upcast.rs
src/test/ui/dyn-star/upcast.stderr [new file with mode: 0644]

index 3f0d0a76027f45ca49a0bc3473037f465bfe799c..ea842af1e7f64bb8020484133b746d1ffe8e28e7 100644 (file)
@@ -755,20 +755,9 @@ fn coerce_dyn_star(
 
         if let ty::Dynamic(a_data, _, _) = a.kind()
             && let ty::Dynamic(b_data, _, _) = b.kind()
+            && a_data.principal_def_id() == b_data.principal_def_id()
         {
-            if a_data.principal_def_id() == b_data.principal_def_id() {
-                return self.unify_and(a, b, |_| vec![]);
-            } else if !self.tcx().features().trait_upcasting {
-                let mut err = feature_err(
-                    &self.tcx.sess.parse_sess,
-                    sym::trait_upcasting,
-                    self.cause.span,
-                    &format!(
-                        "cannot cast `{a}` to `{b}`, trait upcasting coercion is experimental"
-                    ),
-                );
-                err.emit();
-            }
+            return self.unify_and(a, b, |_| vec![]);
         }
 
         // Check the obligations of the cast -- for example, when casting
@@ -796,19 +785,16 @@ fn coerce_dyn_star(
             ])
             .collect();
 
-        // Enforce that the type is `usize`/pointer-sized. For now, only those
-        // can be coerced to `dyn*`, except for `dyn* -> dyn*` upcasts.
-        if !a.is_dyn_star() {
-            obligations.push(Obligation::new(
-                self.tcx,
-                self.cause.clone(),
-                self.param_env,
-                ty::Binder::dummy(
-                    self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
-                )
-                .to_poly_trait_predicate(),
-            ));
-        }
+        // Enforce that the type is `usize`/pointer-sized.
+        obligations.push(Obligation::new(
+            self.tcx,
+            self.cause.clone(),
+            self.param_env,
+            ty::Binder::dummy(
+                self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
+            )
+            .to_poly_trait_predicate(),
+        ));
 
         Ok(InferOk {
             value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),
index 3b107d9570f149fbe53f77aa3b8ec7c37f9d81d1..9d899da9bba248392567de5e1af22fca69421393 100644 (file)
@@ -776,9 +776,7 @@ fn assemble_candidates_for_unsizing(
 
         match (source.kind(), target.kind()) {
             // Trait+Kx+'a -> Trait+Ky+'b (upcasts).
-            (&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b))
-                if dyn_a == dyn_b =>
-            {
+            (&ty::Dynamic(ref data_a, _, ty::Dyn), &ty::Dynamic(ref data_b, _, ty::Dyn)) => {
                 // Upcast coercions permit several things:
                 //
                 // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
index 2ec5d925b6900af0959b518f8379ffdd30659224..3cffd2bb7801766ee6d1a9f7884b09ae13bccd5d 100644 (file)
@@ -803,9 +803,10 @@ fn confirm_trait_upcasting_unsize_candidate(
         let upcast_trait_ref;
         match (source.kind(), target.kind()) {
             // TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion).
-            (&ty::Dynamic(ref data_a, r_a, repr_a), &ty::Dynamic(ref data_b, r_b, repr_b))
-                if repr_a == repr_b =>
-            {
+            (
+                &ty::Dynamic(ref data_a, r_a, repr_a @ ty::Dyn),
+                &ty::Dynamic(ref data_b, r_b, ty::Dyn),
+            ) => {
                 // See `assemble_candidates_for_unsizing` for more info.
                 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
                 let principal_a = data_a.principal().unwrap();
@@ -831,7 +832,7 @@ fn confirm_trait_upcasting_unsize_candidate(
                             .map(ty::Binder::dummy),
                     );
                 let existential_predicates = tcx.mk_poly_existential_predicates(iter);
-                let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_b);
+                let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_a);
 
                 // Require that the traits involved in this upcast are **equal**;
                 // only the **lifetime bound** is changed.
diff --git a/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.rs b/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.rs
new file mode 100644 (file)
index 0000000..a4eb669
--- /dev/null
@@ -0,0 +1,13 @@
+#![feature(dyn_star, trait_upcasting)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait A: B {}
+trait B {}
+impl A for usize {}
+impl B for usize {}
+
+fn main() {
+    let x: Box<dyn* A> = Box::new(1usize as dyn* A);
+    let y: Box<dyn* B> = x;
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr b/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr
new file mode 100644 (file)
index 0000000..2fc751b
--- /dev/null
@@ -0,0 +1,23 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/no-unsize-coerce-dyn-trait.rs:1:12
+   |
+LL | #![feature(dyn_star, trait_upcasting)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+  --> $DIR/no-unsize-coerce-dyn-trait.rs:11:26
+   |
+LL |     let y: Box<dyn* B> = x;
+   |            -----------   ^ expected trait `B`, found trait `A`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `Box<dyn* B>`
+              found struct `Box<dyn* A>`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0308`.
index cee76ada7df3bb445047eb343d00d4814b4808a7..24c077047e94996f05d43fc52125cbc58f0c25f5 100644 (file)
@@ -1,7 +1,6 @@
-// run-pass
+// known-bug: unknown
 
 #![feature(dyn_star, trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo: Bar {
     fn hello(&self);
diff --git a/src/test/ui/dyn-star/upcast.stderr b/src/test/ui/dyn-star/upcast.stderr
new file mode 100644 (file)
index 0000000..6a95f77
--- /dev/null
@@ -0,0 +1,20 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/upcast.rs:3:12
+   |
+LL | #![feature(dyn_star, trait_upcasting)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `dyn* Foo` needs to be a pointer-sized type
+  --> $DIR/upcast.rs:30:23
+   |
+LL |     let w: dyn* Bar = w;
+   |                       ^ `dyn* Foo` needs to be a pointer-sized type
+   |
+   = help: the trait `PointerSized` is not implemented for `dyn* Foo`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.