Skip to content

Commit 741f3cf

Browse files
authored
Rollup merge of #103386 - compiler-errors:no-coerceunsized-to-dynstar, r=eholk
Don't allow `CoerceUnsized` into `dyn*` (except for trait upcasting) This makes sure we don't accidentally allow coercions like `Box<T>` -> `Box<dyn* Trait>`, or in the case of this ICE, `&T` to `&dyn* Trait`. These coercions don't make sense, at least not via the `CoerceUnsized` trait. Fixes #102172 Fixes #102429
2 parents 3e59657 + 4f978db commit 741f3cf

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
780780

781781
match (source.kind(), target.kind()) {
782782
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
783-
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
783+
(&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b))
784+
if dyn_a == dyn_b =>
785+
{
784786
// Upcast coercions permit several things:
785787
//
786788
// 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
@@ -841,7 +843,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
841843
}
842844

843845
// `T` -> `Trait`
844-
(_, &ty::Dynamic(..)) => {
846+
(_, &ty::Dynamic(_, _, ty::Dyn)) => {
845847
candidates.vec.push(BuiltinUnsizeCandidate);
846848
}
847849

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
912912
let mut nested = vec![];
913913
match (source.kind(), target.kind()) {
914914
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
915-
(&ty::Dynamic(ref data_a, r_a, ty::Dyn), &ty::Dynamic(ref data_b, r_b, ty::Dyn)) => {
915+
(&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b))
916+
if dyn_a == dyn_b =>
917+
{
916918
// See `assemble_candidates_for_unsizing` for more info.
917919
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
918920
let iter = data_a
@@ -931,7 +933,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
931933
.map(ty::Binder::dummy),
932934
);
933935
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
934-
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, ty::Dyn);
936+
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a);
935937

936938
// Require that the traits involved in this upcast are **equal**;
937939
// only the **lifetime bound** is changed.
@@ -1140,7 +1142,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11401142
}));
11411143
}
11421144

1143-
_ => bug!(),
1145+
_ => bug!("source: {source}, target: {target}"),
11441146
};
11451147

11461148
Ok(ImplSourceBuiltinData { nested })
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// check-pass
2+
3+
#![feature(dyn_star)]
4+
#![allow(incomplete_features)]
5+
6+
trait AddOne {
7+
fn add1(&mut self) -> usize;
8+
}
9+
10+
impl AddOne for usize {
11+
fn add1(&mut self) -> usize {
12+
*self += 1;
13+
*self
14+
}
15+
}
16+
17+
fn add_one(i: &mut (dyn* AddOne + '_)) -> usize {
18+
i.add1()
19+
}
20+
21+
fn main() {
22+
let mut x = 42usize as dyn* AddOne;
23+
24+
println!("{}", add_one(&mut x));
25+
println!("{}", add_one(&mut x));
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(dyn_star)]
2+
#![allow(incomplete_features)]
3+
4+
use std::fmt::Debug;
5+
6+
fn main() {
7+
let i = 42 as &dyn* Debug;
8+
//~^ ERROR non-primitive cast: `i32` as `&dyn* Debug`
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0605]: non-primitive cast: `i32` as `&dyn* Debug`
2+
--> $DIR/unsize-into-ref-dyn-star.rs:7:13
3+
|
4+
LL | let i = 42 as &dyn* Debug;
5+
| ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0605`.

0 commit comments

Comments
 (0)