Skip to content
Draft
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
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 @@ -730,7 +730,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 @@ -430,15 +430,15 @@ 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() {
for (exported_symbol, _) in tcx.exported_generic_symbols(cnum).iter() {
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 @@ -491,7 +491,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 @@ -613,7 +613,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 @@ -644,7 +644,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 @@ -927,15 +927,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 @@ -606,7 +606,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
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,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
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 @@ -786,8 +786,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 @@ -798,6 +798,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 @@ -129,7 +129,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 @@ -946,7 +946,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 @@ -1066,6 +1066,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 @@ -472,37 +472,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 @@ -699,7 +699,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 @@ -813,6 +813,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