Skip to content

Commit c620a97

Browse files
Disable dyn* upcasting
1 parent 70f8737 commit c620a97

File tree

7 files changed

+75
-35
lines changed

7 files changed

+75
-35
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+12-26
Original file line numberDiff line numberDiff line change
@@ -755,20 +755,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
755755

756756
if let ty::Dynamic(a_data, _, _) = a.kind()
757757
&& let ty::Dynamic(b_data, _, _) = b.kind()
758+
&& a_data.principal_def_id() == b_data.principal_def_id()
758759
{
759-
if a_data.principal_def_id() == b_data.principal_def_id() {
760-
return self.unify_and(a, b, |_| vec![]);
761-
} else if !self.tcx().features().trait_upcasting {
762-
let mut err = feature_err(
763-
&self.tcx.sess.parse_sess,
764-
sym::trait_upcasting,
765-
self.cause.span,
766-
&format!(
767-
"cannot cast `{a}` to `{b}`, trait upcasting coercion is experimental"
768-
),
769-
);
770-
err.emit();
771-
}
760+
return self.unify_and(a, b, |_| vec![]);
772761
}
773762

774763
// Check the obligations of the cast -- for example, when casting
@@ -796,19 +785,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
796785
])
797786
.collect();
798787

799-
// Enforce that the type is `usize`/pointer-sized. For now, only those
800-
// can be coerced to `dyn*`, except for `dyn* -> dyn*` upcasts.
801-
if !a.is_dyn_star() {
802-
obligations.push(Obligation::new(
803-
self.tcx,
804-
self.cause.clone(),
805-
self.param_env,
806-
ty::Binder::dummy(
807-
self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
808-
)
809-
.to_poly_trait_predicate(),
810-
));
811-
}
788+
// Enforce that the type is `usize`/pointer-sized.
789+
obligations.push(Obligation::new(
790+
self.tcx,
791+
self.cause.clone(),
792+
self.param_env,
793+
ty::Binder::dummy(
794+
self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
795+
)
796+
.to_poly_trait_predicate(),
797+
));
812798

813799
Ok(InferOk {
814800
value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -776,9 +776,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
776776

777777
match (source.kind(), target.kind()) {
778778
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
779-
(&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b))
780-
if dyn_a == dyn_b =>
781-
{
779+
(&ty::Dynamic(ref data_a, _, ty::Dyn), &ty::Dynamic(ref data_b, _, ty::Dyn)) => {
782780
// Upcast coercions permit several things:
783781
//
784782
// 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -803,9 +803,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
803803
let upcast_trait_ref;
804804
match (source.kind(), target.kind()) {
805805
// TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion).
806-
(&ty::Dynamic(ref data_a, r_a, repr_a), &ty::Dynamic(ref data_b, r_b, repr_b))
807-
if repr_a == repr_b =>
808-
{
806+
(
807+
&ty::Dynamic(ref data_a, r_a, repr_a @ ty::Dyn),
808+
&ty::Dynamic(ref data_b, r_b, ty::Dyn),
809+
) => {
809810
// See `assemble_candidates_for_unsizing` for more info.
810811
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
811812
let principal_a = data_a.principal().unwrap();
@@ -831,7 +832,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
831832
.map(ty::Binder::dummy),
832833
);
833834
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
834-
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_b);
835+
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_a);
835836

836837
// Require that the traits involved in this upcast are **equal**;
837838
// only the **lifetime bound** is changed.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(dyn_star, trait_upcasting)]
2+
//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
3+
4+
trait A: B {}
5+
trait B {}
6+
impl A for usize {}
7+
impl B for usize {}
8+
9+
fn main() {
10+
let x: Box<dyn* A> = Box::new(1usize as dyn* A);
11+
let y: Box<dyn* B> = x;
12+
//~^ ERROR mismatched types
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/no-unsize-coerce-dyn-trait.rs:1:12
3+
|
4+
LL | #![feature(dyn_star, trait_upcasting)]
5+
| ^^^^^^^^
6+
|
7+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0308]: mismatched types
11+
--> $DIR/no-unsize-coerce-dyn-trait.rs:11:26
12+
|
13+
LL | let y: Box<dyn* B> = x;
14+
| ----------- ^ expected trait `B`, found trait `A`
15+
| |
16+
| expected due to this
17+
|
18+
= note: expected struct `Box<dyn* B>`
19+
found struct `Box<dyn* A>`
20+
21+
error: aborting due to previous error; 1 warning emitted
22+
23+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/dyn-star/upcast.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
// run-pass
1+
// known-bug: unknown
22

33
#![feature(dyn_star, trait_upcasting)]
4-
#![allow(incomplete_features)]
54

65
trait Foo: Bar {
76
fn hello(&self);

src/test/ui/dyn-star/upcast.stderr

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/upcast.rs:3:12
3+
|
4+
LL | #![feature(dyn_star, trait_upcasting)]
5+
| ^^^^^^^^
6+
|
7+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0277]: `dyn* Foo` needs to be a pointer-sized type
11+
--> $DIR/upcast.rs:30:23
12+
|
13+
LL | let w: dyn* Bar = w;
14+
| ^ `dyn* Foo` needs to be a pointer-sized type
15+
|
16+
= help: the trait `PointerSized` is not implemented for `dyn* Foo`
17+
18+
error: aborting due to previous error; 1 warning emitted
19+
20+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)