Skip to content

Commit 46ecb23

Browse files
author
Lukas Markeffsky
committed
unify dyn* coercions with other pointer coercions
1 parent 67bb749 commit 46ecb23

File tree

23 files changed

+70
-55
lines changed

23 files changed

+70
-55
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2139,7 +2139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21392139
);
21402140
}
21412141

2142-
CastKind::DynStar => {
2142+
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
21432143
// get the constraints from the target type (`dyn* Clone`)
21442144
//
21452145
// apply them to prove that the source type `Foo` implements `Clone` etc

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,11 @@ fn codegen_stmt<'tcx>(
770770
let operand = codegen_operand(fx, operand);
771771
crate::unsize::coerce_unsized_into(fx, operand, lval);
772772
}
773-
Rvalue::Cast(CastKind::DynStar, ref operand, _) => {
773+
Rvalue::Cast(
774+
CastKind::PointerCoercion(PointerCoercion::DynStar),
775+
ref operand,
776+
_,
777+
) => {
774778
let operand = codegen_operand(fx, operand);
775779
crate::unsize::coerce_dyn_star(fx, operand, lval);
776780
}

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
526526
bug!("unexpected non-pair operand");
527527
}
528528
}
529-
mir::CastKind::DynStar => {
529+
mir::CastKind::PointerCoercion(PointerCoercion::DynStar) => {
530530
let (lldata, llextra) = operand.val.pointer_parts();
531531
let (lldata, llextra) =
532532
base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);

compiler/rustc_const_eval/src/check_consts/check.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
447447
// These are all okay; they only change the type, not the data.
448448
}
449449

450-
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), _, _) => {
451-
// Unsizing is implemented for CTFE.
450+
Rvalue::Cast(
451+
CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar),
452+
_,
453+
_,
454+
) => {
455+
// Unsizing and `dyn*` coercions are implemented for CTFE.
452456
}
453457

454458
Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
@@ -458,10 +462,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
458462
// Since no pointer can ever get exposed (rejected above), this is easy to support.
459463
}
460464

461-
Rvalue::Cast(CastKind::DynStar, _, _) => {
462-
// `dyn*` coercion is implemented for CTFE.
463-
}
464-
465465
Rvalue::Cast(_, _, _) => {}
466466

467467
Rvalue::NullaryOp(

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
125125
}
126126
}
127127

128-
CastKind::DynStar => {
128+
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
129129
if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() {
130130
// Initial cast from sized to dyn trait
131131
let vtable = self.get_vtable_ptr(src.layout.ty, data)?;

compiler/rustc_hir_typeck/src/cast.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ use rustc_errors::codes::*;
3333
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
3434
use rustc_hir::{self as hir, ExprKind};
3535
use rustc_macros::{TypeFoldable, TypeVisitable};
36-
use rustc_middle::bug;
3736
use rustc_middle::mir::Mutability;
3837
use rustc_middle::ty::adjustment::AllowTwoPhase;
3938
use rustc_middle::ty::cast::{CastKind, CastTy};
4039
use rustc_middle::ty::error::TypeError;
4140
use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef};
41+
use rustc_middle::{bug, span_bug};
4242
use rustc_session::lint;
4343
use rustc_span::def_id::LOCAL_CRATE;
4444
use rustc_span::symbol::sym;
@@ -674,6 +674,16 @@ impl<'a, 'tcx> CastCheck<'tcx> {
674674
use rustc_middle::ty::cast::CastTy::*;
675675
use rustc_middle::ty::cast::IntTy::*;
676676

677+
if self.cast_ty.is_dyn_star() {
678+
if fcx.tcx.features().dyn_star {
679+
span_bug!(self.span, "should be handled by `coerce`");
680+
} else {
681+
// Report "casting is invalid" rather than "non-primitive cast"
682+
// if the feature is not enabled.
683+
return Err(CastError::IllegalCast);
684+
}
685+
}
686+
677687
let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty))
678688
{
679689
(Some(t_from), Some(t_cast)) => (t_from, t_cast),
@@ -780,16 +790,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
780790
(Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
781791

782792
(Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
783-
784-
(_, DynStar) => {
785-
if fcx.tcx.features().dyn_star {
786-
bug!("should be handled by `coerce`")
787-
} else {
788-
Err(CastError::IllegalCast)
789-
}
790-
}
791-
792-
(DynStar, _) => Err(CastError::IllegalCast),
793793
}
794794
}
795795

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
769769
));
770770

771771
Ok(InferOk {
772-
value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),
772+
value: (
773+
vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }],
774+
b,
775+
),
773776
obligations,
774777
})
775778
}

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -759,9 +759,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
759759
for adjustment in adjustments {
760760
debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
761761
match adjustment.kind {
762-
adjustment::Adjust::NeverToAny
763-
| adjustment::Adjust::Pointer(_)
764-
| adjustment::Adjust::DynStar => {
762+
adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => {
765763
// Creating a closure/fn-pointer or unsizing consumes
766764
// the input and stores it into the resulting rvalue.
767765
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
12961294
adjustment::Adjust::NeverToAny
12971295
| adjustment::Adjust::Pointer(_)
12981296
| adjustment::Adjust::Borrow(_)
1299-
| adjustment::Adjust::ReborrowPin(..)
1300-
| adjustment::Adjust::DynStar => {
1297+
| adjustment::Adjust::ReborrowPin(..) => {
13011298
// Result is an rvalue.
13021299
Ok(self.cat_rvalue(expr.hir_id, target))
13031300
}

compiler/rustc_middle/src/mir/statement.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@ impl<'tcx> Rvalue<'tcx> {
434434
| CastKind::PtrToPtr
435435
| CastKind::PointerCoercion(_)
436436
| CastKind::PointerWithExposedProvenance
437-
| CastKind::DynStar
438437
| CastKind::Transmute,
439438
_,
440439
_,

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,8 +1404,6 @@ pub enum CastKind {
14041404
///
14051405
/// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR.
14061406
PointerCoercion(PointerCoercion),
1407-
/// Cast into a dyn* object.
1408-
DynStar,
14091407
IntToInt,
14101408
FloatToInt,
14111409
FloatToFloat,

compiler/rustc_middle/src/ty/adjustment.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ pub enum PointerCoercion {
3535
/// type. Codegen backends and miri figure out what has to be done
3636
/// based on the precise source/target type at hand.
3737
Unsize,
38+
39+
/// Go from a pointer-like type to a `dyn*` object.
40+
DynStar,
3841
}
3942

4043
/// Represents coercing a value to a different type of value.
@@ -102,9 +105,6 @@ pub enum Adjust<'tcx> {
102105

103106
Pointer(PointerCoercion),
104107

105-
/// Cast into a dyn* object.
106-
DynStar,
107-
108108
/// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
109109
ReborrowPin(ty::Region<'tcx>, hir::Mutability),
110110
}

compiler/rustc_middle/src/ty/cast.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,12 @@ pub enum CastTy<'tcx> {
3434
FnPtr,
3535
/// Raw pointers.
3636
Ptr(ty::TypeAndMut<'tcx>),
37-
/// Casting into a `dyn*` value.
38-
DynStar,
3937
}
4038

4139
/// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html)
4240
/// (or rustc_hir_analysis/check/cast.rs).
4341
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
4442
pub enum CastKind {
45-
CoercionCast,
4643
PtrPtrCast,
4744
PtrAddrCast,
4845
AddrPtrCast,
@@ -53,7 +50,6 @@ pub enum CastKind {
5350
ArrayPtrCast,
5451
FnPtrPtrCast,
5552
FnPtrAddrCast,
56-
DynStarCast,
5753
}
5854

5955
impl<'tcx> CastTy<'tcx> {
@@ -71,7 +67,6 @@ impl<'tcx> CastTy<'tcx> {
7167
ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)),
7268
ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })),
7369
ty::FnPtr(..) => Some(CastTy::FnPtr),
74-
ty::Dynamic(_, _, ty::DynStar) => Some(CastTy::DynStar),
7570
_ => None,
7671
}
7772
}
@@ -86,7 +81,6 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin
8681
mir::CastKind::PointerExposeProvenance
8782
}
8883
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance,
89-
(_, Some(CastTy::DynStar)) => mir::CastKind::DynStar,
9084
(Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt,
9185
(Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr,
9286

compiler/rustc_mir_build/src/thir/cx/expr.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ impl<'tcx> Cx<'tcx> {
146146
Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
147147
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
148148
}
149-
Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) },
150149
Adjust::ReborrowPin(region, mutbl) => {
151150
debug!("apply ReborrowPin adjustment");
152151
// Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`

compiler/rustc_mir_transform/src/mentioned_items.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> {
7070
match *rvalue {
7171
// We need to detect unsizing casts that required vtables.
7272
mir::Rvalue::Cast(
73-
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
73+
mir::CastKind::PointerCoercion(PointerCoercion::Unsize)
74+
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar),
7475
ref operand,
7576
target_ty,
76-
)
77-
| mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => {
77+
) => {
7878
// This isn't monomorphized yet so we can't tell what the actual types are -- just
7979
// add everything that may involve a vtable.
8080
let source_ty = operand.ty(self.body, self.tcx);

compiler/rustc_mir_transform/src/validate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,9 +1128,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11281128
Rvalue::Cast(kind, operand, target_type) => {
11291129
let op_ty = operand.ty(self.body, self.tcx);
11301130
match kind {
1131-
CastKind::DynStar => {
1132-
// FIXME(dyn-star): make sure nothing needs to be done here.
1133-
}
11341131
// FIXME: Add Checks for these
11351132
CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {}
11361133
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
@@ -1208,6 +1205,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
12081205
// This is used for all `CoerceUnsized` types,
12091206
// not just pointers/references, so is hard to check.
12101207
}
1208+
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
1209+
// FIXME(dyn-star): make sure nothing needs to be done here.
1210+
}
12111211
CastKind::IntToInt | CastKind::IntToFloat => {
12121212
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
12131213
let target_valid = target_type.is_numeric() || target_type.is_char();

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -665,11 +665,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
665665
// have to instantiate all methods of the trait being cast to, so we
666666
// can build the appropriate vtable.
667667
mir::Rvalue::Cast(
668-
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
668+
mir::CastKind::PointerCoercion(PointerCoercion::Unsize)
669+
| mir::CastKind::PointerCoercion(PointerCoercion::DynStar),
669670
ref operand,
670671
target_ty,
671-
)
672-
| mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => {
672+
) => {
673673
let source_ty = operand.ty(self.body, self.tcx);
674674
// *Before* monomorphizing, record that we already handled this mention.
675675
self.used_mentioned_items

compiler/rustc_smir/src/rustc_smir/convert/mir.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,12 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
282282
type T = stable_mir::mir::CastKind;
283283
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
284284
use rustc_middle::mir::CastKind::*;
285+
use rustc_middle::ty::adjustment::PointerCoercion;
285286
match self {
286287
PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
287288
PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
289+
PointerCoercion(PointerCoercion::DynStar) => stable_mir::mir::CastKind::DynStar,
288290
PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
289-
DynStar => stable_mir::mir::CastKind::DynStar,
290291
IntToInt => stable_mir::mir::CastKind::IntToInt,
291292
FloatToInt => stable_mir::mir::CastKind::FloatToInt,
292293
FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,

compiler/rustc_smir/src/rustc_smir/convert/ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
119119
}
120120
PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
121121
PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
122+
PointerCoercion::DynStar => unreachable!("represented as `CastKind::DynStar` in smir"),
122123
}
123124
}
124125
}

compiler/stable_mir/src/mir/body.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ pub enum CastKind {
960960
PointerExposeAddress,
961961
PointerWithExposedProvenance,
962962
PointerCoercion(PointerCoercion),
963+
// FIXME(smir-rename): change this to PointerCoercion(DynStar)
963964
DynStar,
964965
IntToInt,
965966
FloatToInt,

src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ fn check_rvalue<'tcx>(
154154
Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
155155
Err((span, "casting pointers to ints is unstable in const fn".into()))
156156
},
157-
Rvalue::Cast(CastKind::DynStar, _, _) => {
157+
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar), _, _) => {
158158
// FIXME(dyn-star)
159159
unimplemented!()
160160
},

tests/ui/dyn-star/dyn-to-rigid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ trait Tr {}
55

66
fn f(x: dyn* Tr) -> usize {
77
x as usize
8-
//~^ ERROR casting `(dyn* Tr + 'static)` as `usize` is invalid
8+
//~^ ERROR non-primitive cast: `(dyn* Tr + 'static)` as `usize`
99
}
1010

1111
fn main() {}

tests/ui/dyn-star/dyn-to-rigid.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
error[E0606]: casting `(dyn* Tr + 'static)` as `usize` is invalid
1+
error[E0605]: non-primitive cast: `(dyn* Tr + 'static)` as `usize`
22
--> $DIR/dyn-to-rigid.rs:7:5
33
|
44
LL | x as usize
5-
| ^^^^^^^^^^
5+
| ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
66

77
error: aborting due to 1 previous error
88

9-
For more information about this error, try `rustc --explain E0606`.
9+
For more information about this error, try `rustc --explain E0605`.

tests/ui/dyn-star/enum-cast.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ check-pass
2+
3+
// This used to ICE, because the compiler confused a pointer-like to dyn* coercion
4+
// with a c-like enum to integer cast.
5+
6+
#![feature(dyn_star)]
7+
#![expect(incomplete_features)]
8+
9+
enum E {
10+
Num(usize),
11+
}
12+
13+
trait Trait {}
14+
impl Trait for E {}
15+
16+
fn main() {
17+
let _ = E::Num(42) as dyn* Trait;
18+
}

0 commit comments

Comments
 (0)