Skip to content
1 change: 1 addition & 0 deletions compiler/rustc_attr_ir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ language_item_table! {

Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None;
Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None;
DestructDropInPlace, sym::destruct_drop_in_place, destruct_drop_in_place, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::None;
AsyncDropInPlace, sym::async_drop_in_place, async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1);

Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_codegen_cranelift/example/mini_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ pub trait MetaSized: PointeeSized {}
pub trait Sized: MetaSized {}

#[lang = "destruct"]
pub trait Destruct {}
pub trait Destruct {
/// Entrypoint for drop
///
/// Generated by default if not implemented manually.
#[lang = "destruct_drop_in_place"]
unsafe fn drop_in_place(_to_drop: &mut Self);
}

#[lang = "tuple_trait"]
pub trait Tuple {}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ pub(crate) fn codegen_drop<'tcx>(
unwind: UnwindAction,
) {
let ty = drop_place.layout().ty;
let drop_instance = Instance::resolve_drop_glue(fx.tcx, ty);
let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty);
let ret_block = fx.get_block(target);

// AsyncDropGlueCtorShim can't be here
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_codegen_gcc/example/mini_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ pub trait MetaSized: PointeeSized {}
pub trait Sized: MetaSized {}

#[lang = "destruct"]
pub trait Destruct {}
pub trait Destruct {
/// Entrypoint for drop
///
/// Generated by default if not implemented manually.
#[lang = "destruct_drop_in_place"]
unsafe fn drop_in_place(_to_drop: &mut Self);
}

#[lang = "tuple_trait"]
pub trait Tuple {}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ fn upstream_monomorphizations_provider(

let mut instances: DefIdMap<UnordMap<_, _>> = Default::default();

let drop_glue_fn_def_id = tcx.lang_items().drop_glue_fn();
let drop_in_place_fn_def_id = tcx.lang_items().destruct_drop_in_place();
let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn();

for &cnum in cnums.iter() {
Expand All @@ -519,7 +519,7 @@ fn upstream_monomorphizations_provider(
let (def_id, args) = match *exported_symbol {
ExportedSymbol::Generic(def_id, args) => (def_id, args),
ExportedSymbol::DropGlue(ty) => {
if let Some(drop_in_place_fn_def_id) = drop_glue_fn_def_id {
if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
(drop_in_place_fn_def_id, tcx.mk_args(&[ty.into()]))
} else {
// `drop_glue` does not exist, don't try to use it.
Expand Down Expand Up @@ -572,7 +572,7 @@ fn upstream_drop_glue_for_provider<'tcx>(
tcx: TyCtxt<'tcx>,
args: GenericArgsRef<'tcx>,
) -> Option<CrateNum> {
let def_id = tcx.lang_items().drop_glue_fn()?;
let def_id = tcx.lang_items().destruct_drop_in_place()?;
tcx.upstream_monomorphizations_for(def_id)?.get(&args).cloned()
}

Expand Down Expand Up @@ -694,7 +694,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
}
ExportedSymbol::DropGlue(ty) => rustc_symbol_mangling::symbol_name_for_instance_in_crate(
tcx,
Instance::resolve_drop_glue(tcx, ty),
Instance::resolve_drop_in_place(tcx, ty),
instantiating_crate,
),
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) -> MergingSucc {
let ty = location.ty(self.mir, bx.tcx()).ty;
let ty = self.monomorphize(ty);
let drop_fn = Instance::resolve_drop_glue(bx.tcx(), ty);
let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty);

if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_fn.def {
// we don't actually need to drop anything.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,15 +1015,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
_ => {
debug_assert_eq!(
instance,
ty::Instance::resolve_drop_glue(*self.tcx, place.layout.ty)
ty::Instance::resolve_drop_in_place(*self.tcx, place.layout.ty)
);
place
}
};

let instance = {
let _trace = enter_trace_span!(M, resolve::resolve_drop_glue, ty = ?place.layout.ty);
ty::Instance::resolve_drop_glue(*self.tcx, place.layout.ty)
ty::Instance::resolve_drop_in_place(*self.tcx, place.layout.ty)
};
let fn_abi = self.fn_abi_of_instance_no_deduced_attrs(instance, ty::List::empty())?;

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let instance = {
let _trace =
enter_trace_span!(M, resolve::resolve_drop_glue, ty = ?place.layout.ty);
Instance::resolve_drop_glue(*self.tcx, place.layout.ty)
Instance::resolve_drop_in_place(*self.tcx, place.layout.ty)
};
if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = instance.def {
// This is the branch we enter if and only if the dropped type has no drop glue
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/middle/exported_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
tcx.symbol_name(ty::Instance::new_raw(def_id, args))
}
ExportedSymbol::DropGlue(ty) => {
tcx.symbol_name(ty::Instance::resolve_drop_glue(tcx, ty))
tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
}
ExportedSymbol::AsyncDropGlueCtorShim(ty) => {
tcx.symbol_name(ty::Instance::resolve_async_drop_in_place(tcx, ty))
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub enum ShimKind<'tcx> {
/// Proxy shim for async drop of future (def_id, proxy_cor_ty, impl_cor_ty)
FutureDropPoll(DefId, Ty<'tcx>, Ty<'tcx>),

/// `core::ptr::drop_glue::<T>`.
/// `Destruct::drop_in_place()`
///
/// The `DefId` is for `core::ptr::drop_glue`.
/// The `Option<Ty<'tcx>>` is either `Some(T)`, or `None` for empty drop glue.
Expand Down Expand Up @@ -796,8 +796,8 @@ impl<'tcx> Instance<'tcx> {
}
}

pub fn resolve_drop_glue(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
let def_id = tcx.require_lang_item(LangItem::DropGlue, DUMMY_SP);
pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
let def_id = tcx.require_lang_item(LangItem::DestructDropInPlace, DUMMY_SP);
let args = tcx.mk_args(&[ty.into()]);
Instance::expect_resolve(
tcx,
Expand All @@ -808,6 +808,16 @@ impl<'tcx> Instance<'tcx> {
)
}

pub fn try_resolve_drop_in_place(
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
let def_id = tcx.require_lang_item(LangItem::DestructDropInPlace, DUMMY_SP);
let args = tcx.mk_args(&[ty.into()]);
Instance::try_resolve(tcx, typing_env, def_id, args)
}

pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, DUMMY_SP);
let args = tcx.mk_args(&[ty.into()]);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
let scalar = match *entry {
VtblEntry::MetadataDropInPlace => {
if ty.needs_drop(tcx, ty::TypingEnv::fully_monomorphized()) {
let instance = ty::Instance::resolve_drop_glue(tcx, ty);
let instance = ty::Instance::resolve_drop_in_place(tcx, ty);
let fn_alloc_id = tcx.reserve_and_set_fn_alloc(instance, CTFE_ALLOC_SALT);
let fn_ptr = Pointer::from(fn_alloc_id);
Scalar::from_pointer(fn_ptr, &tcx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl RemoveNoopLandingPads {
extra.typing_env,
ty::EarlyBinder::bind(extra.tcx, ty),
);
let drop_fn = Instance::resolve_drop_glue(extra.tcx, ty);
let drop_fn = Instance::resolve_drop_in_place(extra.tcx, ty);
if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_fn.def {
// no need to drop anything, if all of our successors are also no-op then we
// can be skipped.
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_monomorphize/src/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ fn visit_drop_use<'tcx>(
source: Span,
output: &mut MonoItems<'tcx>,
) {
let instance = Instance::resolve_drop_glue(tcx, ty);
let instance = Instance::resolve_drop_in_place(tcx, ty);
visit_instance_use(tcx, instance, is_direct_call, source, output);
}

Expand Down Expand Up @@ -1074,6 +1074,9 @@ fn visit_instance_use<'tcx>(
/// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
/// can just link to the upstream crate and therefore don't need a mono item.
fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(_))) = instance.def {
return instance.upstream_monomorphization(tcx).is_none();
}
let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
return true;
};
Expand Down
71 changes: 42 additions & 29 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,37 +478,50 @@ where

match assemble_from {
AssembleCandidatesFrom::All => {
self.assemble_builtin_impl_candidates(goal, &mut candidates)?;
// For performance we only assemble impls if there are no candidates
// which would shadow them. This is necessary to avoid hangs in rayon,
// see trait-system-refactor-initiative#109 for more details.
//
// We always assemble builtin impls as trivial builtin impls have a higher
// priority than where-clauses.
//
// We only do this if any such candidate applies without any constraints
// as we may want to weaken inference guidance in the future and don't want
// to worry about causing major performance regressions when doing so.
// See trait-system-refactor-initiative#226 for some ideas here.
let assemble_impls = match self.typing_mode() {
TypingMode::Coherence => true,
TypingMode::Typeck { .. }
| TypingMode::PostTypeckUntilBorrowck { .. }
| TypingMode::Reflection
| TypingMode::PostBorrowck { .. }
| TypingMode::PostAnalysis
| TypingMode::Codegen
| TypingMode::ErasedNotCoherence(MayBeErased) => !candidates.iter().any(|c| {
matches!(
c.source,
CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)
| CandidateSource::AliasBound(_)
) && has_no_inference_or_external_constraints(c.result)
}),
};
if assemble_impls {
let trait_def_id = goal.predicate.trait_def_id(self.cx());
// Check if there are any user defined impls for Destruct. If there are,
// use those, and fallback to builtin drop glue impl if none are present
if self.cx().is_trait_lang_item(trait_def_id, SolverTraitLangItem::Destruct) {
self.assemble_impl_candidates(goal, &mut candidates)?;
let has_impl_candidate =
candidates.iter().any(|c| matches!(c.source, CandidateSource::Impl(_)));
if !has_impl_candidate {
self.assemble_builtin_impl_candidates(goal, &mut candidates)?;
}
self.assemble_object_bound_candidates(goal, &mut candidates);
} else {
self.assemble_builtin_impl_candidates(goal, &mut candidates)?;
// For performance we only assemble impls if there are no candidates
// which would shadow them. This is necessary to avoid hangs in rayon,
// see trait-system-refactor-initiative#109 for more details.
//
// We always assemble builtin impls as trivial builtin impls have a higher
// priority than where-clauses.
//
// We only do this if any such candidate applies without any constraints
// as we may want to weaken inference guidance in the future and don't want
// to worry about causing major performance regressions when doing so.
// See trait-system-refactor-initiative#226 for some ideas here.
let assemble_impls = match self.typing_mode() {
TypingMode::Coherence => true,
TypingMode::Typeck { .. }
| TypingMode::PostTypeckUntilBorrowck { .. }
| TypingMode::PostBorrowck { .. }
| TypingMode::Reflection
| TypingMode::PostAnalysis
| TypingMode::Codegen
| TypingMode::ErasedNotCoherence(_) => !candidates.iter().any(|c| {
matches!(
c.source,
CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)
| CandidateSource::AliasBound(_)
) && has_no_inference_or_external_constraints(c.result)
}),
};
if assemble_impls {
self.assemble_impl_candidates(goal, &mut candidates)?;
self.assemble_object_bound_candidates(goal, &mut candidates);
}
}
}
AssembleCandidatesFrom::EnvAndBounds => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_public_bridge/src/context/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> {

/// Resolve an instance for drop_in_place for the given type.
pub fn resolve_drop_in_place(&self, internal_ty: Ty<'tcx>) -> Instance<'tcx> {
let instance = Instance::resolve_drop_glue(self.tcx, internal_ty);
let instance = Instance::resolve_drop_in_place(self.tcx, internal_ty);
instance
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ symbols! {
derive_from,
derive_smart_pointer,
destruct,
destruct_drop_in_place,
destructuring_assignment,
diagnostic,
diagnostic_namespace,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
}
Some(LangItem::Destruct) => {
self.assemble_const_destruct_candidates(obligation, &mut candidates);
let before = candidates.vec.len();
self.assemble_candidates_from_impls(obligation, &mut candidates);
let added_impl =
candidates.vec[before..].iter().any(|c| matches!(c, ImplCandidate(_)));
if !added_impl {
self.assemble_const_destruct_candidates(obligation, &mut candidates);
}
}
Some(LangItem::TransmuteTrait) => {
// User-defined transmutability impls are permitted.
Expand Down
Loading
Loading