From 46ecb23198fa83136a266cb5a18675d2d342ab18 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sun, 15 Sep 2024 16:47:42 +0200 Subject: [PATCH] unify dyn* coercions with other pointer coercions --- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/base.rs | 6 ++++- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- .../src/check_consts/check.rs | 12 +++++----- .../rustc_const_eval/src/interpret/cast.rs | 2 +- compiler/rustc_hir_typeck/src/cast.rs | 22 +++++++++---------- compiler/rustc_hir_typeck/src/coercion.rs | 5 ++++- .../rustc_hir_typeck/src/expr_use_visitor.rs | 7 ++---- compiler/rustc_middle/src/mir/statement.rs | 1 - compiler/rustc_middle/src/mir/syntax.rs | 2 -- compiler/rustc_middle/src/ty/adjustment.rs | 6 ++--- compiler/rustc_middle/src/ty/cast.rs | 6 ----- compiler/rustc_mir_build/src/thir/cx/expr.rs | 1 - .../src/mentioned_items.rs | 6 ++--- compiler/rustc_mir_transform/src/validate.rs | 6 ++--- compiler/rustc_monomorphize/src/collector.rs | 6 ++--- .../rustc_smir/src/rustc_smir/convert/mir.rs | 3 ++- .../rustc_smir/src/rustc_smir/convert/ty.rs | 1 + compiler/stable_mir/src/mir/body.rs | 1 + .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- tests/ui/dyn-star/dyn-to-rigid.rs | 2 +- tests/ui/dyn-star/dyn-to-rigid.stderr | 6 ++--- tests/ui/dyn-star/enum-cast.rs | 18 +++++++++++++++ 23 files changed, 70 insertions(+), 55 deletions(-) create mode 100644 tests/ui/dyn-star/enum-cast.rs diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 4056b423548..29a0c5bdf57 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2139,7 +2139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } - CastKind::DynStar => { + CastKind::PointerCoercion(PointerCoercion::DynStar) => { // get the constraints from the target type (`dyn* Clone`) // // apply them to prove that the source type `Foo` implements `Clone` etc diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index dc342e151f3..876466e79bc 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -770,7 +770,11 @@ fn codegen_stmt<'tcx>( let operand = codegen_operand(fx, operand); crate::unsize::coerce_unsized_into(fx, operand, lval); } - Rvalue::Cast(CastKind::DynStar, ref operand, _) => { + Rvalue::Cast( + CastKind::PointerCoercion(PointerCoercion::DynStar), + ref operand, + _, + ) => { let operand = codegen_operand(fx, operand); crate::unsize::coerce_dyn_star(fx, operand, lval); } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index ad0e03fc263..dc5377bf9d4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -526,7 +526,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("unexpected non-pair operand"); } } - mir::CastKind::DynStar => { + mir::CastKind::PointerCoercion(PointerCoercion::DynStar) => { let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra); diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 2c33ff9d219..dc7cdee00b2 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -447,8 +447,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // These are all okay; they only change the type, not the data. } - Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), _, _) => { - // Unsizing is implemented for CTFE. + Rvalue::Cast( + CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar), + _, + _, + ) => { + // Unsizing and `dyn*` coercions are implemented for CTFE. } Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => { @@ -458,10 +462,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Since no pointer can ever get exposed (rejected above), this is easy to support. } - Rvalue::Cast(CastKind::DynStar, _, _) => { - // `dyn*` coercion is implemented for CTFE. - } - Rvalue::Cast(_, _, _) => {} Rvalue::NullaryOp( diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 70d074cfdc5..25fb5f12d61 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -125,7 +125,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::DynStar => { + CastKind::PointerCoercion(PointerCoercion::DynStar) => { if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() { // Initial cast from sized to dyn trait let vtable = self.get_vtable_ptr(src.layout.ty, data)?; diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index aab0c4c116a..9e20e1d9745 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -33,12 +33,12 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; use rustc_hir::{self as hir, ExprKind}; use rustc_macros::{TypeFoldable, TypeVisitable}; -use rustc_middle::bug; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; @@ -674,6 +674,16 @@ impl<'a, 'tcx> CastCheck<'tcx> { use rustc_middle::ty::cast::CastTy::*; use rustc_middle::ty::cast::IntTy::*; + if self.cast_ty.is_dyn_star() { + if fcx.tcx.features().dyn_star { + span_bug!(self.span, "should be handled by `coerce`"); + } else { + // Report "casting is invalid" rather than "non-primitive cast" + // if the feature is not enabled. + return Err(CastError::IllegalCast); + } + } + let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty)) { (Some(t_from), Some(t_cast)) => (t_from, t_cast), @@ -780,16 +790,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { (Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast), (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast), - - (_, DynStar) => { - if fcx.tcx.features().dyn_star { - bug!("should be handled by `coerce`") - } else { - Err(CastError::IllegalCast) - } - } - - (DynStar, _) => Err(CastError::IllegalCast), } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 7be91d78e19..b08c5bc6d9a 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -769,7 +769,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { )); Ok(InferOk { - value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b), + value: ( + vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }], + b, + ), obligations, }) } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 29feed56290..bb5f3511373 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -759,9 +759,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx for adjustment in adjustments { debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); match adjustment.kind { - adjustment::Adjust::NeverToAny - | adjustment::Adjust::Pointer(_) - | adjustment::Adjust::DynStar => { + adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => { // Creating a closure/fn-pointer or unsizing consumes // the input and stores it into the resulting rvalue. self.consume_or_copy(&place_with_id, place_with_id.hir_id); @@ -1296,8 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) | adjustment::Adjust::Borrow(_) - | adjustment::Adjust::ReborrowPin(..) - | adjustment::Adjust::DynStar => { + | adjustment::Adjust::ReborrowPin(..) => { // Result is an rvalue. Ok(self.cat_rvalue(expr.hir_id, target)) } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index bc7dfa6205e..c3891e70e93 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -434,7 +434,6 @@ impl<'tcx> Rvalue<'tcx> { | CastKind::PtrToPtr | CastKind::PointerCoercion(_) | CastKind::PointerWithExposedProvenance - | CastKind::DynStar | CastKind::Transmute, _, _, diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 231eb198983..ff7360f06ed 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1404,8 +1404,6 @@ pub enum CastKind { /// /// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR. PointerCoercion(PointerCoercion), - /// Cast into a dyn* object. - DynStar, IntToInt, FloatToInt, FloatToFloat, diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 5a32078760e..41a20e89cbf 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -35,6 +35,9 @@ pub enum PointerCoercion { /// type. Codegen backends and miri figure out what has to be done /// based on the precise source/target type at hand. Unsize, + + /// Go from a pointer-like type to a `dyn*` object. + DynStar, } /// Represents coercing a value to a different type of value. @@ -102,9 +105,6 @@ pub enum Adjust<'tcx> { Pointer(PointerCoercion), - /// Cast into a dyn* object. - DynStar, - /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`. ReborrowPin(ty::Region<'tcx>, hir::Mutability), } diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 46f37659536..b1316ceef5a 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -34,15 +34,12 @@ pub enum CastTy<'tcx> { FnPtr, /// Raw pointers. Ptr(ty::TypeAndMut<'tcx>), - /// Casting into a `dyn*` value. - DynStar, } /// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html) /// (or rustc_hir_analysis/check/cast.rs). #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub enum CastKind { - CoercionCast, PtrPtrCast, PtrAddrCast, AddrPtrCast, @@ -53,7 +50,6 @@ pub enum CastKind { ArrayPtrCast, FnPtrPtrCast, FnPtrAddrCast, - DynStarCast, } impl<'tcx> CastTy<'tcx> { @@ -71,7 +67,6 @@ impl<'tcx> CastTy<'tcx> { ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)), ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })), ty::FnPtr(..) => Some(CastTy::FnPtr), - ty::Dynamic(_, _, ty::DynStar) => Some(CastTy::DynStar), _ => None, } } @@ -86,7 +81,6 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin mir::CastKind::PointerExposeProvenance } (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance, - (_, Some(CastTy::DynStar)) => mir::CastKind::DynStar, (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt, (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr, diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 55236933922..a3764b5d312 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -146,7 +146,6 @@ impl<'tcx> Cx<'tcx> { Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => { ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) } } - Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) }, Adjust::ReborrowPin(region, mutbl) => { debug!("apply ReborrowPin adjustment"); // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }` diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs index f24de609e6b..9f9b39b02d3 100644 --- a/compiler/rustc_mir_transform/src/mentioned_items.rs +++ b/compiler/rustc_mir_transform/src/mentioned_items.rs @@ -70,11 +70,11 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { match *rvalue { // We need to detect unsizing casts that required vtables. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize) + | mir::CastKind::PointerCoercion(PointerCoercion::DynStar), ref operand, target_ty, - ) - | mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => { + ) => { // This isn't monomorphized yet so we can't tell what the actual types are -- just // add everything that may involve a vtable. let source_ty = operand.ty(self.body, self.tcx); diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 914dddc1a56..2b6498409d0 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1128,9 +1128,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { Rvalue::Cast(kind, operand, target_type) => { let op_ty = operand.ty(self.body, self.tcx); match kind { - CastKind::DynStar => { - // FIXME(dyn-star): make sure nothing needs to be done here. - } // FIXME: Add Checks for these CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {} CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { @@ -1208,6 +1205,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // This is used for all `CoerceUnsized` types, // not just pointers/references, so is hard to check. } + CastKind::PointerCoercion(PointerCoercion::DynStar) => { + // FIXME(dyn-star): make sure nothing needs to be done here. + } CastKind::IntToInt | CastKind::IntToFloat => { let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool(); let target_valid = target_type.is_numeric() || target_type.is_char(); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8d137b8d8f9..986d0030a24 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -665,11 +665,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { // have to instantiate all methods of the trait being cast to, so we // can build the appropriate vtable. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize) + | mir::CastKind::PointerCoercion(PointerCoercion::DynStar), ref operand, target_ty, - ) - | mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => { + ) => { let source_ty = operand.ty(self.body, self.tcx); // *Before* monomorphizing, record that we already handled this mention. self.used_mentioned_items diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index f4c7fd7c900..e7025037242 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -282,11 +282,12 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { type T = stable_mir::mir::CastKind; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { use rustc_middle::mir::CastKind::*; + use rustc_middle::ty::adjustment::PointerCoercion; match self { PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress, PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, + PointerCoercion(PointerCoercion::DynStar) => stable_mir::mir::CastKind::DynStar, PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), - DynStar => stable_mir::mir::CastKind::DynStar, IntToInt => stable_mir::mir::CastKind::IntToInt, FloatToInt => stable_mir::mir::CastKind::FloatToInt, FloatToFloat => stable_mir::mir::CastKind::FloatToFloat, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index e54ab1f7e24..ac9a0235762 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -119,6 +119,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { } PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer, PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize, + PointerCoercion::DynStar => unreachable!("represented as `CastKind::DynStar` in smir"), } } } diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 7c09fe1a085..ab9fc218d19 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -960,6 +960,7 @@ pub enum CastKind { PointerExposeAddress, PointerWithExposedProvenance, PointerCoercion(PointerCoercion), + // FIXME(smir-rename): change this to PointerCoercion(DynStar) DynStar, IntToInt, FloatToInt, diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index d9befb3c157..6434c2f42cf 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -154,7 +154,7 @@ fn check_rvalue<'tcx>( Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => { Err((span, "casting pointers to ints is unstable in const fn".into())) }, - Rvalue::Cast(CastKind::DynStar, _, _) => { + Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar), _, _) => { // FIXME(dyn-star) unimplemented!() }, diff --git a/tests/ui/dyn-star/dyn-to-rigid.rs b/tests/ui/dyn-star/dyn-to-rigid.rs index e80ee15902e..dc33e288f24 100644 --- a/tests/ui/dyn-star/dyn-to-rigid.rs +++ b/tests/ui/dyn-star/dyn-to-rigid.rs @@ -5,7 +5,7 @@ trait Tr {} fn f(x: dyn* Tr) -> usize { x as usize - //~^ ERROR casting `(dyn* Tr + 'static)` as `usize` is invalid + //~^ ERROR non-primitive cast: `(dyn* Tr + 'static)` as `usize` } fn main() {} diff --git a/tests/ui/dyn-star/dyn-to-rigid.stderr b/tests/ui/dyn-star/dyn-to-rigid.stderr index b198c5245de..49b8f268aa4 100644 --- a/tests/ui/dyn-star/dyn-to-rigid.stderr +++ b/tests/ui/dyn-star/dyn-to-rigid.stderr @@ -1,9 +1,9 @@ -error[E0606]: casting `(dyn* Tr + 'static)` as `usize` is invalid +error[E0605]: non-primitive cast: `(dyn* Tr + 'static)` as `usize` --> $DIR/dyn-to-rigid.rs:7:5 | LL | x as usize - | ^^^^^^^^^^ + | ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0606`. +For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/dyn-star/enum-cast.rs b/tests/ui/dyn-star/enum-cast.rs new file mode 100644 index 00000000000..6e895e9527a --- /dev/null +++ b/tests/ui/dyn-star/enum-cast.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// This used to ICE, because the compiler confused a pointer-like to dyn* coercion +// with a c-like enum to integer cast. + +#![feature(dyn_star)] +#![expect(incomplete_features)] + +enum E { + Num(usize), +} + +trait Trait {} +impl Trait for E {} + +fn main() { + let _ = E::Num(42) as dyn* Trait; +}