Skip to content
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

Create a new TyKind::DynStar variant #107908

Closed
wants to merge 8 commits into from
Closed
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: 3 additions & 3 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
@@ -32,8 +32,8 @@ use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueHiddenType,
OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
};
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::{Span, DUMMY_SP};
@@ -1928,7 +1928,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
//
// 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),
ty::DynStar(predicates, region) => (predicates, region),
_ => panic!("Invalid dyn* cast_ty"),
};

4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
@@ -578,7 +578,7 @@ pub(crate) fn codegen_drop<'tcx>(
// we don't actually need to drop anything
} else {
match ty.kind() {
ty::Dynamic(_, _, ty::Dyn) => {
ty::Dynamic(_, _) => {
// IN THIS ARM, WE HAVE:
// ty = *mut (dyn Trait)
// which is: exists<T> ( *mut T, Vtable<T: Trait> )
@@ -608,7 +608,7 @@ pub(crate) fn codegen_drop<'tcx>(
let sig = fx.bcx.import_signature(sig);
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
}
ty::Dynamic(_, _, ty::DynStar) => {
ty::DynStar(_, _) => {
// IN THIS ARM, WE HAVE:
// ty = *mut (dyn* Trait)
// which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>)
15 changes: 4 additions & 11 deletions compiler/rustc_codegen_cranelift/src/unsize.rs
Original file line number Diff line number Diff line change
@@ -25,12 +25,8 @@ pub(crate) fn unsized_info<'tcx>(
.bcx
.ins()
.iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
(
&ty::Dynamic(ref data_a, _, src_dyn_kind),
&ty::Dynamic(ref data_b, _, target_dyn_kind),
) => {
assert_eq!(src_dyn_kind, target_dyn_kind);

(&ty::Dynamic(ref data_a, _), &ty::Dynamic(ref data_b, _))
| (&ty::DynStar(ref data_a, _), &ty::DynStar(ref data_b, _)) => {
let old_info =
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
if data_a.principal_def_id() == data_b.principal_def_id() {
@@ -114,10 +110,7 @@ pub(crate) fn cast_to_dyn_star<'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*"
);
assert!(matches!(dst_ty.kind(), ty::DynStar(..)), "destination type must be a dyn*");
(src, unsized_info(fx, src_ty_and_layout.ty, dst_ty, old_info))
}

@@ -172,7 +165,7 @@ pub(crate) fn coerce_dyn_star<'tcx>(
src: CValue<'tcx>,
dst: CPlace<'tcx>,
) {
let (data, extra) = if let ty::Dynamic(_, _, ty::DynStar) = src.layout().ty.kind() {
let (data, extra) = if let ty::DynStar(_, _) = src.layout().ty.kind() {
let (data, vtable) = src.load_scalar_pair(fx);
(data, Some(vtable))
} else {
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_cranelift/src/value_and_place.rs
Original file line number Diff line number Diff line change
@@ -875,7 +875,7 @@ pub(crate) fn assert_assignable<'tcx>(
);
// fn(&T) -> for<'l> fn(&'l T) is allowed
}
(&ty::Dynamic(from_traits, _, _from_kind), &ty::Dynamic(to_traits, _, _to_kind)) => {
(&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => {
// FIXME(dyn-star): Do the right thing with DynKinds
for (from, to) in from_traits.iter().zip(to_traits) {
let from =
@@ -889,6 +889,8 @@ pub(crate) fn assert_assignable<'tcx>(
}
// dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
}
// FIXME(dyn-star)
(&ty::DynStar(_from_traits, _), &ty::DynStar(_to_traits, _)) => unimplemented!(),
(&ty::Tuple(types_a), &ty::Tuple(types_b)) => {
let mut types_a = types_a.iter();
let mut types_b = types_b.iter();
34 changes: 21 additions & 13 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ use rustc_span::symbol::sym;
use rustc_span::Symbol;
use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType};
use rustc_target::abi::{Align, Size, VariantIdx};
use rustc_type_ir::DynKind;

use std::collections::BTreeSet;
use std::time::{Duration, Instant};
@@ -150,10 +151,8 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(&ty::Array(_, len), &ty::Slice(_)) => {
cx.const_usize(len.eval_usize(cx.tcx(), ty::ParamEnv::reveal_all()))
}
(
&ty::Dynamic(ref data_a, _, src_dyn_kind),
&ty::Dynamic(ref data_b, _, target_dyn_kind),
) if src_dyn_kind == target_dyn_kind => {
(&ty::Dynamic(ref data_a, _), &ty::Dynamic(ref data_b, _))
| (&ty::DynStar(ref data_a, _), &ty::DynStar(ref data_b, _)) => {
let old_info =
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
if data_a.principal_def_id() == data_b.principal_def_id() {
@@ -169,7 +168,15 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
if let Some(entry_idx) = vptr_entry_idx {
let ptr_ty = cx.type_i8p();
let ptr_align = cx.tcx().data_layout.pointer_align.abi;
let vtable_ptr_ty = vtable_ptr_ty(cx, target, target_dyn_kind);
let vtable_ptr_ty = vtable_ptr_ty(
cx,
target,
match target.kind() {
ty::Dynamic(..) => DynKind::Dyn,
ty::DynStar(..) => DynKind::DynStar,
_ => unreachable!(),
},
);
let llvtable = bx.pointercast(old_info, bx.type_ptr_to(ptr_ty));
let gep = bx.inbounds_gep(
ptr_ty,
@@ -185,8 +192,12 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
old_info
}
}
(_, &ty::Dynamic(ref data, _, target_dyn_kind)) => {
let vtable_ptr_ty = vtable_ptr_ty(cx, target, target_dyn_kind);
(_, &ty::Dynamic(ref data, _)) => {
let vtable_ptr_ty = vtable_ptr_ty(cx, target, DynKind::Dyn);
cx.const_ptrcast(meth::get_vtable(cx, source, data.principal()), vtable_ptr_ty)
}
(_, &ty::DynStar(ref data, _)) => {
let vtable_ptr_ty = vtable_ptr_ty(cx, target, DynKind::DynStar);
cx.const_ptrcast(meth::get_vtable(cx, source, data.principal()), vtable_ptr_ty)
}
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
@@ -202,9 +213,9 @@ fn vtable_ptr_ty<'tcx, Cx: CodegenMethods<'tcx>>(
cx.scalar_pair_element_backend_type(
cx.layout_of(match kind {
// vtable is the second field of `*mut dyn Trait`
ty::Dyn => cx.tcx().mk_mut_ptr(target),
DynKind::Dyn => cx.tcx().mk_mut_ptr(target),
// vtable is the second field of `dyn* Trait`
ty::DynStar => target,
DynKind::DynStar => target,
}),
1,
true,
@@ -269,10 +280,7 @@ pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, '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*"
);
assert!(matches!(dst_ty.kind(), ty::DynStar(_, _)), "destination type must be a dyn*");
// FIXME(dyn-star): this is probably not the best way to check if this is
// a pointer, and really we should ensure that the value is a suitable
// pointer earlier in the compilation process.
10 changes: 6 additions & 4 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
@@ -209,19 +209,21 @@ fn push_debuginfo_type_name<'tcx>(
output.push(']');
}
}
ty::Dynamic(ref trait_data, ..) => {
// ty::DynStar(..) => unimplemented!(),
ty::Dynamic(ref trait_data, ..) | ty::DynStar(ref trait_data, ..) => {
let auto_traits: SmallVec<[DefId; 4]> = trait_data.auto_traits().collect();
let is_dyn_star = t.is_dyn_star();

let has_enclosing_parens = if cpp_like_debuginfo {
output.push_str("dyn$<");
output.push_str(if is_dyn_star { "dyns$<" } else { "dyn$<" });
false
} else {
if trait_data.len() > 1 && auto_traits.len() != 0 {
// We need enclosing parens because there is more than one trait
output.push_str("(dyn ");
output.push_str(if is_dyn_star { "(dyn* " } else { "(dyn " });
true
} else {
output.push_str("dyn ");
output.push_str(if is_dyn_star { "dyn* " } else { "dyn " });
false
}
};
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/meth.rs
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ impl<'a, 'tcx> VirtualIndex {
fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
for arg in ty.peel_refs().walk() {
if let GenericArgKind::Type(ty) = arg.unpack() {
if let ty::Dynamic(data, _, _) = ty.kind() {
if let ty::Dynamic(data, _) | ty::DynStar(data, _) = ty.kind() {
return data.principal().expect("expected principal trait object");
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
@@ -455,7 +455,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (drop_fn, fn_abi) = match ty.kind() {
// FIXME(eddyb) perhaps move some of this logic into
// `Instance::resolve_drop_in_place`?
ty::Dynamic(_, _, ty::Dyn) => {
ty::Dynamic(_, _) => {
// IN THIS ARM, WE HAVE:
// ty = *mut (dyn Trait)
// which is: exists<T> ( *mut T, Vtable<T: Trait> )
@@ -485,7 +485,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
fn_abi,
)
}
ty::Dynamic(_, _, ty::DynStar) => {
ty::DynStar(..) => {
// IN THIS ARM, WE HAVE:
// ty = *mut (dyn* Trait)
// which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>)
5 changes: 3 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
@@ -118,7 +118,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
// resolving their backing type, even if we can do that at const eval time. We may
// hypothetically be able to allow `dyn StructuralEq` trait objects in the future,
// but it is unclear if this is useful.
ty::Dynamic(..) => Err(ValTreeCreationError::NonSupportedType),
ty::Dynamic(..) | ty::DynStar(..) => Err(ValTreeCreationError::NonSupportedType),

ty::Tuple(elem_tys) => {
branches(ecx, place, elem_tys.len(), None, num_nodes)
@@ -319,7 +319,8 @@ pub fn valtree_to_const_value<'tcx>(
| ty::RawPtr(_)
| ty::Str
| ty::Slice(_)
| ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
| ty::Dynamic(..)
| ty::DynStar(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
}
}

4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/cast.rs
Original file line number Diff line number Diff line change
@@ -121,7 +121,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

DynStar => {
if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() {
if let ty::DynStar(data, _) = cast_ty.kind() {
// Initial cast from sized to dyn trait
let vtable = self.get_vtable_ptr(src.layout.ty, data.principal())?;
let vtable = Scalar::from_maybe_pointer(vtable, self);
@@ -347,7 +347,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let new_vptr = self.get_vtable_ptr(ty, data_b.principal())?;
self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest)
}
(_, &ty::Dynamic(data, _, ty::Dyn)) => {
(_, &ty::Dynamic(data, _)) => {
// Initial cast from sized to dyn trait
let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?;
let ptr = self.read_scalar(src)?;
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -97,7 +97,8 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(_)
| ty::Dynamic(_, _, _)
| ty::Dynamic(_, _)
| ty::DynStar(_, _)
| ty::Closure(_, _)
| ty::Generator(_, _, _)
| ty::GeneratorWitness(_)
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
@@ -592,6 +592,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
| ty::Slice(..)
| ty::Str
| ty::Dynamic(..)
| ty::DynStar(..)
| ty::Closure(..)
| ty::Generator(..) => Ok(false),
// Some types only occur during typechecking, they have no layout.
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/util/type_name.rs
Original file line number Diff line number Diff line change
@@ -47,7 +47,8 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
| ty::FnPtr(_)
| ty::Never
| ty::Tuple(_)
| ty::Dynamic(_, _, _) => self.pretty_print_type(ty),
| ty::Dynamic(_, _)
| ty::DynStar(_, _) => self.pretty_print_type(ty),

// Placeholders (all printed as `_` to uniformize them).
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => {
13 changes: 9 additions & 4 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@ use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
use rustc_middle::ty::EarlyBinder;
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{self, Const, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeVisitable};
use rustc_middle::ty::{DynKind, EarlyBinder};
use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
use rustc_span::edition::Edition;
use rustc_span::lev_distance::find_best_match_for_name;
@@ -46,6 +46,7 @@ use rustc_trait_selection::traits::error_reporting::{
};
use rustc_trait_selection::traits::wf::object_region_bounds;

use rustc_type_ir::DynKind;
use smallvec::{smallvec, SmallVec};
use std::collections::BTreeSet;
use std::slice;
@@ -1628,7 +1629,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
};
debug!("region_bound: {:?}", region_bound);

let ty = tcx.mk_dynamic(existential_predicates, region_bound, representation);
let ty = match representation {
DynKind::Dyn => tcx.mk_dynamic(existential_predicates, region_bound),
DynKind::DynStar => tcx.mk_dyn_star(existential_predicates, region_bound),
};

debug!("trait_object_type: {:?}", ty);
ty
}
@@ -2879,8 +2884,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
self.maybe_lint_bare_trait(ast_ty, in_path);
let repr = match repr {
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
TraitObjectSyntax::DynStar => ty::DynStar,
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => DynKind::Dyn,
TraitObjectSyntax::DynStar => DynKind::DynStar,
};
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
}
Original file line number Diff line number Diff line change
@@ -197,7 +197,7 @@ impl<'tcx> InherentCollect<'tcx> {
ty::Dynamic(data, ..) if data.principal_def_id().is_some() => {
self.check_def_id(item, self_ty, data.principal_def_id().unwrap());
}
ty::Dynamic(..) => {
ty::Dynamic(..) | ty::DynStar(..) => {
struct_span_err!(
self.tcx.sess,
ty.span,
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
@@ -181,7 +181,7 @@ fn do_orphan_check_impl<'tcx>(
),

// impl AutoTrait for dyn Trait {}
ty::Dynamic(..) => (
ty::Dynamic(..) | ty::DynStar(..) => (
LocalImpl::Disallow { problematic_kind: "trait object" },
NonlocalImpl::DisallowOther,
),
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
@@ -256,7 +256,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_invariant_substs(current, data.substs, variance);
}

ty::Dynamic(data, r, _) => {
ty::Dynamic(data, r) | ty::DynStar(data, r) => {
// The type `dyn Trait<T> +'a` is covariant w/r/t `'a`:
self.add_constraints_from_region(current, r, variance);

8 changes: 3 additions & 5 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
@@ -102,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

Ok(match *t.kind() {
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
ty::Dynamic(ref tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())),
ty::Dynamic(ref tty, _) => Some(PointerKind::VTable(tty.principal_def_id())),
ty::Adt(def, substs) if def.is_struct() => match def.non_enum_variant().fields.last() {
None => Some(PointerKind::Thin),
Some(f) => {
@@ -139,7 +139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Generator(..)
| ty::Adt(..)
| ty::Never
| ty::Dynamic(_, _, ty::DynStar)
| ty::DynStar(_, _)
| ty::Error(_) => {
let reported = self
.tcx
@@ -218,9 +218,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
// cases now. We do a more thorough check at the end, once
// inference is more completely known.
match cast_ty.kind() {
ty::Dynamic(_, _, ty::Dyn) | ty::Slice(..) => {
Err(check.report_cast_to_unsized_type(fcx))
}
ty::Dynamic(_, _) | ty::Slice(..) => Err(check.report_cast_to_unsized_type(fcx)),
_ => Ok(check),
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
@@ -105,7 +105,7 @@ pub(super) fn check_fn<'a, 'tcx>(

fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);

if let ty::Dynamic(_, _, ty::Dyn) = declared_ret_ty.kind() {
if let ty::Dynamic(_, _) = declared_ret_ty.kind() {
// FIXME: We need to verify that the return type is `Sized` after the return expression has
// been evaluated so that we have types available for all the nodes being returned, but that
// requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
Loading