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
This commit is contained in:
commit
741f3cf383
5 changed files with 53 additions and 5 deletions
|
@ -780,7 +780,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
|
|
||||||
match (source.kind(), target.kind()) {
|
match (source.kind(), target.kind()) {
|
||||||
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
|
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
|
||||||
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
|
(&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b))
|
||||||
|
if dyn_a == dyn_b =>
|
||||||
|
{
|
||||||
// Upcast coercions permit several things:
|
// Upcast coercions permit several things:
|
||||||
//
|
//
|
||||||
// 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
|
// 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
|
||||||
|
@ -841,7 +843,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// `T` -> `Trait`
|
// `T` -> `Trait`
|
||||||
(_, &ty::Dynamic(..)) => {
|
(_, &ty::Dynamic(_, _, ty::Dyn)) => {
|
||||||
candidates.vec.push(BuiltinUnsizeCandidate);
|
candidates.vec.push(BuiltinUnsizeCandidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -912,7 +912,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
let mut nested = vec![];
|
let mut nested = vec![];
|
||||||
match (source.kind(), target.kind()) {
|
match (source.kind(), target.kind()) {
|
||||||
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
|
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
|
||||||
(&ty::Dynamic(ref data_a, r_a, ty::Dyn), &ty::Dynamic(ref data_b, r_b, ty::Dyn)) => {
|
(&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b))
|
||||||
|
if dyn_a == dyn_b =>
|
||||||
|
{
|
||||||
// See `assemble_candidates_for_unsizing` for more info.
|
// See `assemble_candidates_for_unsizing` for more info.
|
||||||
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
|
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
|
||||||
let iter = data_a
|
let iter = data_a
|
||||||
|
@ -931,7 +933,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
.map(ty::Binder::dummy),
|
.map(ty::Binder::dummy),
|
||||||
);
|
);
|
||||||
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
|
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
|
||||||
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, ty::Dyn);
|
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a);
|
||||||
|
|
||||||
// Require that the traits involved in this upcast are **equal**;
|
// Require that the traits involved in this upcast are **equal**;
|
||||||
// only the **lifetime bound** is changed.
|
// only the **lifetime bound** is changed.
|
||||||
|
@ -1140,7 +1142,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => bug!(),
|
_ => bug!("source: {source}, target: {target}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(ImplSourceBuiltinData { nested })
|
Ok(ImplSourceBuiltinData { nested })
|
||||||
|
|
26
src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs
Normal file
26
src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(dyn_star)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait AddOne {
|
||||||
|
fn add1(&mut self) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddOne for usize {
|
||||||
|
fn add1(&mut self) -> usize {
|
||||||
|
*self += 1;
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_one(i: &mut (dyn* AddOne + '_)) -> usize {
|
||||||
|
i.add1()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut x = 42usize as dyn* AddOne;
|
||||||
|
|
||||||
|
println!("{}", add_one(&mut x));
|
||||||
|
println!("{}", add_one(&mut x));
|
||||||
|
}
|
9
src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs
Normal file
9
src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#![feature(dyn_star)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let i = 42 as &dyn* Debug;
|
||||||
|
//~^ ERROR non-primitive cast: `i32` as `&dyn* Debug`
|
||||||
|
}
|
9
src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr
Normal file
9
src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0605]: non-primitive cast: `i32` as `&dyn* Debug`
|
||||||
|
--> $DIR/unsize-into-ref-dyn-star.rs:7:13
|
||||||
|
|
|
||||||
|
LL | let i = 42 as &dyn* Debug;
|
||||||
|
| ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0605`.
|
Loading…
Add table
Add a link
Reference in a new issue