Skip to content

Remove support for dyn* from the compiler #143036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2577,8 +2577,7 @@ pub enum TyPatKind {
pub enum TraitObjectSyntax {
// SAFETY: When adding new variants make sure to update the `Tag` impl.
Dyn = 0,
DynStar = 1,
None = 2,
None = 1,
}

/// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means
Expand All @@ -2594,8 +2593,7 @@ unsafe impl Tag for TraitObjectSyntax {
unsafe fn from_usize(tag: usize) -> Self {
match tag {
0 => TraitObjectSyntax::Dyn,
1 => TraitObjectSyntax::DynStar,
2 => TraitObjectSyntax::None,
1 => TraitObjectSyntax::None,
_ => unreachable!(),
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
);
gate_all!(associated_const_equality, "associated const equality is incomplete");
gate_all!(yeet_expr, "`do yeet` expression is experimental");
gate_all!(dyn_star, "`dyn*` trait objects are experimental");
gate_all!(const_closures, "const closures are experimental");
gate_all!(builtin_syntax, "`builtin #` syntax is unstable");
gate_all!(ergonomic_clones, "ergonomic clones are experimental");
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,6 @@ impl<'a> State<'a> {
ast::TyKind::TraitObject(bounds, syntax) => {
match syntax {
ast::TraitObjectSyntax::Dyn => self.word_nbsp("dyn"),
ast::TraitObjectSyntax::DynStar => self.word_nbsp("dyn*"),
ast::TraitObjectSyntax::None => {}
}
self.print_type_bounds(bounds);
Expand Down
38 changes: 3 additions & 35 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::{
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
Dynamic, GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt,
TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions,
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, TypeVisitableExt,
UserArgs, UserTypeAnnotationIndex, fold_regions,
};
use rustc_middle::{bug, span_bug};
use rustc_mir_dataflow::move_paths::MoveData;
Expand Down Expand Up @@ -1233,38 +1233,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
);
}

CastKind::PointerCoercion(PointerCoercion::DynStar, coercion_source) => {
// get the constraints from the target type (`dyn* Clone`)
//
// apply them to prove that the source type `Foo` implements `Clone` etc
let (existential_predicates, region) = match ty.kind() {
Dynamic(predicates, region, ty::DynStar) => (predicates, region),
_ => panic!("Invalid dyn* cast_ty"),
};

let self_ty = op.ty(self.body, tcx);

let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
self.prove_predicates(
existential_predicates
.iter()
.map(|predicate| predicate.with_self_ty(tcx, self_ty)),
location.to_locations(),
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
);

let outlives_predicate = tcx.mk_predicate(Binder::dummy(
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
ty::OutlivesPredicate(self_ty, *region),
)),
));
self.prove_predicate(
outlives_predicate,
location.to_locations(),
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
);
}

CastKind::PointerCoercion(
PointerCoercion::MutToConstPointer,
coercion_source,
Expand Down
45 changes: 0 additions & 45 deletions compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,51 +753,6 @@ pub(crate) fn codegen_drop<'tcx>(
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
fx.bcx.ins().jump(ret_block, &[]);
}
ty::Dynamic(_, _, ty::DynStar) => {
// IN THIS ARM, WE HAVE:
// ty = *mut (dyn* Trait)
// which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>)
//
// args = [ * ]
// |
// v
// ( Data, Vtable )
// |
// v
// /-------\
// | ... |
// \-------/
//
//
// WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING
//
// data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer)
// vtable = (*args[0]).1 // loads the vtable out
// (data, vtable) // an equivalent Rust `*mut dyn Trait`
//
// SO THEN WE CAN USE THE ABOVE CODE.
let (data, vtable) = drop_place.to_cvalue(fx).dyn_star_force_data_on_stack(fx);
let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable);

let is_null = fx.bcx.ins().icmp_imm(IntCC::Equal, drop_fn, 0);
let target_block = fx.get_block(target);
let continued = fx.bcx.create_block();
fx.bcx.ins().brif(is_null, target_block, &[], continued, &[]);
fx.bcx.switch_to_block(continued);

let virtual_drop = Instance {
def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0),
args: drop_instance.args,
};
let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx)
.fn_abi_of_instance(virtual_drop, ty::List::empty());

let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
let sig = fx.bcx.import_signature(sig);
fx.bcx.ins().call_indirect(sig, drop_fn, &[data]);
// FIXME implement cleanup on exceptions
fx.bcx.ins().jump(ret_block, &[]);
}
_ => {
assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _)));

Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,14 +778,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
let operand = codegen_operand(fx, operand);
crate::unsize::coerce_unsized_into(fx, operand, lval);
}
Rvalue::Cast(
CastKind::PointerCoercion(PointerCoercion::DynStar, _),
ref operand,
_,
) => {
let operand = codegen_operand(fx, operand);
crate::unsize::coerce_dyn_star(fx, operand, lval);
}
Rvalue::Cast(CastKind::Transmute, ref operand, _to_ty) => {
let operand = codegen_operand(fx, operand);
lval.write_cvalue_transmute(fx, operand);
Expand Down
33 changes: 0 additions & 33 deletions compiler/rustc_codegen_cranelift/src/unsize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,6 @@ fn unsize_ptr<'tcx>(
}
}

/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type.
pub(crate) fn cast_to_dyn_star<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
src: Value,
src_ty_and_layout: TyAndLayout<'tcx>,
dst_ty: Ty<'tcx>,
old_info: Option<Value>,
) -> (Value, Value) {
assert!(
matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
"destination type must be a dyn*"
);
(src, unsized_info(fx, src_ty_and_layout.ty, dst_ty, old_info))
}

/// Coerce `src`, which is a reference to a value of type `src_ty`,
/// to a value of type `dst_ty` and store the result in `dst`
pub(crate) fn coerce_unsized_into<'tcx>(
Expand Down Expand Up @@ -174,24 +159,6 @@ pub(crate) fn coerce_unsized_into<'tcx>(
}
}

pub(crate) fn coerce_dyn_star<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
src: CValue<'tcx>,
dst: CPlace<'tcx>,
) {
let (data, extra) = if let ty::Dynamic(_, _, ty::DynStar) = src.layout().ty.kind() {
let (data, vtable) = src.load_scalar_pair(fx);
(data, Some(vtable))
} else {
let data = src.load_scalar(fx);
(data, None)
};

let (data, vtable) = cast_to_dyn_star(fx, data, src.layout(), dst.layout().ty, extra);

dst.write_cvalue(fx, CValue::by_val_pair(data, vtable, dst.layout()));
}

// Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs

pub(crate) fn size_and_align_of<'tcx>(
Expand Down
37 changes: 0 additions & 37 deletions compiler/rustc_codegen_cranelift/src/value_and_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,43 +121,6 @@ impl<'tcx> CValue<'tcx> {
}
}

// FIXME remove
/// Forces the data value of a dyn* value to the stack and returns a pointer to it as well as the
/// vtable pointer.
pub(crate) fn dyn_star_force_data_on_stack(
self,
fx: &mut FunctionCx<'_, '_, 'tcx>,
) -> (Value, Value) {
assert!(self.1.ty.is_dyn_star());

match self.0 {
CValueInner::ByRef(ptr, None) => {
let (a_scalar, b_scalar) = match self.1.backend_repr {
BackendRepr::ScalarPair(a, b) => (a, b),
_ => unreachable!("dyn_star_force_data_on_stack({:?})", self),
};
let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar);
let mut flags = MemFlags::new();
flags.set_notrap();
let vtable = ptr.offset(fx, b_offset).load(fx, clif_ty2, flags);
(ptr.get_addr(fx), vtable)
}
CValueInner::ByValPair(data, vtable) => {
let data_ptr = fx.create_stack_slot(
u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(),
u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(),
);
data_ptr.store(fx, data, MemFlags::trusted());

(data_ptr.get_addr(fx), vtable)
}
CValueInner::ByRef(_, Some(_)) | CValueInner::ByVal(_) => {
unreachable!("dyn_star_force_data_on_stack({:?})", self)
}
}
}

pub(crate) fn try_to_ptr(self) -> Option<(Pointer, Option<Value>)> {
match self.0 {
CValueInner::ByRef(ptr, meta) => Some((ptr, meta)),
Expand Down
40 changes: 14 additions & 26 deletions compiler/rustc_codegen_cranelift/src/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,34 +46,22 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
mut arg: CValue<'tcx>,
idx: usize,
) -> (Pointer, Value) {
let (ptr, vtable) = 'block: {
if let BackendRepr::Scalar(_) = arg.layout().backend_repr {
while !arg.layout().ty.is_raw_ptr() && !arg.layout().ty.is_ref() {
let (idx, _) = arg
.layout()
.non_1zst_field(fx)
.expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type");
arg = arg.value_field(fx, idx);
}
}

if let ty::Ref(_, ty, _) = arg.layout().ty.kind() {
if ty.is_dyn_star() {
let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap());
let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr();
let vtable = dyn_star.place_field(fx, FieldIdx::ONE).to_cvalue(fx).load_scalar(fx);
break 'block (ptr, vtable);
}
if let BackendRepr::Scalar(_) = arg.layout().backend_repr {
while !arg.layout().ty.is_raw_ptr() && !arg.layout().ty.is_ref() {
let (idx, _) = arg
.layout()
.non_1zst_field(fx)
.expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type");
arg = arg.value_field(fx, idx);
}
}

if let BackendRepr::ScalarPair(_, _) = arg.layout().backend_repr {
let (ptr, vtable) = arg.load_scalar_pair(fx);
(Pointer::new(ptr), vtable)
} else {
let (ptr, vtable) = arg.try_to_ptr().unwrap();
(ptr, vtable.unwrap())
}
let (ptr, vtable) = if let BackendRepr::ScalarPair(_, _) = arg.layout().backend_repr {
let (ptr, vtable) = arg.load_scalar_pair(fx);
(Pointer::new(ptr), vtable)
} else {
let (ptr, vtable) = arg.try_to_ptr().unwrap();
(ptr, vtable.unwrap())
};

let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes();
Expand Down
22 changes: 0 additions & 22 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,28 +262,6 @@ pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
}

/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type.
pub(crate) fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
src: Bx::Value,
src_ty_and_layout: TyAndLayout<'tcx>,
dst_ty: Ty<'tcx>,
old_info: Option<Bx::Value>,
) -> (Bx::Value, Bx::Value) {
debug!("cast_to_dyn_star: {:?} => {:?}", src_ty_and_layout.ty, dst_ty);
assert!(
matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
"destination type must be a dyn*"
);
let src = match bx.cx().type_kind(bx.cx().backend_type(src_ty_and_layout)) {
TypeKind::Pointer => src,
TypeKind::Integer => bx.inttoptr(src, bx.type_ptr()),
// FIXME(dyn-star): We probably have to do a bitcast first, then inttoptr.
kind => bug!("unexpected TypeKind for left-hand side of `dyn*` cast: {kind:?}"),
};
(src, unsized_info(bx, src_ty_and_layout.ty, dst_ty, old_info))
}

/// Coerces `src`, which is a reference to a value of type `src_ty`,
/// to a value of type `dst_ty`, and stores the result in `dst`.
pub(crate) fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
Expand Down
Loading
Loading