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
])
.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),
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`
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();
.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.
--- /dev/null
+#![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
+}
--- /dev/null
+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`.
-// run-pass
+// known-bug: unknown
#![feature(dyn_star, trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo: Bar {
fn hello(&self);
--- /dev/null
+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`.