diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index ab9d2a743739f..ec977806a4c72 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -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 {} diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 481fe5387e149..635f88568a0c1 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -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 {} diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 2460bf18b13d1..792f6b4f5fe5b 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -403,7 +403,7 @@ fn upstream_monomorphizations_provider( let mut instances: DefIdMap> = Default::default(); - let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_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() { @@ -465,7 +465,7 @@ fn upstream_drop_glue_for_provider<'tcx>( tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, ) -> Option { - let def_id = tcx.lang_items().drop_in_place_fn()?; + let def_id = tcx.lang_items().destruct_drop_in_place()?; tcx.upstream_monomorphizations_for(def_id)?.get(&args).cloned() } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index ea014e8a275b5..dd1bab725706c 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -183,6 +183,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); diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index d425ba7a99658..f3a7d2db7f01c 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -147,7 +147,7 @@ pub enum InstanceKind<'tcx> { /// Proxy shim for async drop of future (def_id, proxy_cor_ty, impl_cor_ty) FutureDropPollShim(DefId, Ty<'tcx>, Ty<'tcx>), - /// `core::ptr::drop_in_place::`. + /// `Destruct::drop_in_place()` /// /// The `DefId` is for `core::ptr::drop_in_place`. /// The `Option>` is either `Some(T)`, or `None` for empty drop @@ -717,7 +717,7 @@ impl<'tcx> Instance<'tcx> { } pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { - let def_id = tcx.require_lang_item(LangItem::DropInPlace, DUMMY_SP); + let def_id = tcx.require_lang_item(LangItem::DestructDropInPlace, DUMMY_SP); let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, @@ -728,6 +728,16 @@ impl<'tcx> Instance<'tcx> { ) } + pub fn try_resolve_drop_in_place( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, + ) -> Result>, 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()]); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f819ee42441a7..def42beeaf133 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1045,6 +1045,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::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; }; diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 5a73c99616815..1d7b16d01bd3a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -454,34 +454,47 @@ 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::Analysis { .. } - | TypingMode::Borrowck { .. } - | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => !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::Analysis { .. } + | TypingMode::Borrowck { .. } + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => !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 => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ddfe05e5c607d..0826e4461ef25 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -798,6 +798,7 @@ symbols! { derive_from, derive_smart_pointer, destruct, + destruct_drop_in_place, destructuring_assignment, diagnostic, diagnostic_namespace, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index f7614e7c9730a..0944358cb6919 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -113,7 +113,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. diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index c6e8ae49e4c9d..5be2bbc827c85 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -38,33 +38,7 @@ fn resolve_instance_raw<'tcx>( } else if tcx.is_lang_item(def_id, LangItem::DropInPlace) { let ty = args.type_at(0); - if ty.needs_drop(tcx, typing_env) { - debug!(" => nontrivial drop glue"); - match *ty.kind() { - ty::Coroutine(coroutine_def_id, ..) => { - // FIXME: sync drop of coroutine with async drop (generate both versions?) - // Currently just ignored - if tcx.optimized_mir(coroutine_def_id).coroutine_drop_async().is_some() { - ty::InstanceKind::DropGlue(def_id, None) - } else { - ty::InstanceKind::DropGlue(def_id, Some(ty)) - } - } - ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Tuple(..) - | ty::Adt(..) - | ty::Dynamic(..) - | ty::Array(..) - | ty::Slice(..) - | ty::UnsafeBinder(..) => ty::InstanceKind::DropGlue(def_id, Some(ty)), - // Drop shims can only be built from ADTs. - _ => return Ok(None), - } - } else { - debug!(" => trivial drop glue"); - ty::InstanceKind::DropGlue(def_id, None) - } + return ty::Instance::try_resolve_drop_in_place(tcx, typing_env, ty); } else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) { let ty = args.type_at(0); @@ -166,6 +140,20 @@ fn resolve_associated_item<'tcx>( if !eligible { return Ok(None); } + if tcx.is_lang_item(trait_ref.def_id, LangItem::Destruct) { + if !tcx.is_lang_item(trait_item_id, LangItem::DestructDropInPlace) { + bug!( + "unexpected associated item for built-in `{trait_ref}`: {}", + tcx.item_name(trait_item_id) + ); + } + + debug!("Got user Destruct impl"); + return Ok(Some(Instance { + def: ty::InstanceKind::Item(leaf_def.item.def_id), + args: rcvr_args, + })); + } let typing_env = typing_env.with_post_analysis_normalized(tcx); let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); @@ -403,6 +391,46 @@ fn resolve_associated_item<'tcx>( } else { bug!("unexpected associated associated item") } + } else if tcx.is_lang_item(trait_ref.def_id, LangItem::Destruct) { + debug!( + "resolving Destruct for ImplSource::Builtin: {:?}, {:?}, {:?}", + typing_env, trait_item_id, rcvr_args + ); + if !tcx.is_lang_item(trait_item_id, LangItem::DestructDropInPlace) { + bug!( + "unexpected associated item for built-in `{trait_ref}`: {}", + tcx.item_name(trait_item_id) + ); + } + + let self_ty = trait_ref.self_ty(); + + let def = if self_ty.needs_drop(tcx, typing_env) { + match *self_ty.kind() { + ty::Coroutine(coroutine_def_id, ..) => { + if tcx.optimized_mir(coroutine_def_id).coroutine_drop_async().is_some() + { + ty::InstanceKind::DropGlue(trait_item_id, None) + } else { + ty::InstanceKind::DropGlue(trait_item_id, Some(self_ty)) + } + } + ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Tuple(..) + | ty::Adt(..) + | ty::Dynamic(..) + | ty::Array(..) + | ty::Slice(..) + | ty::UnsafeBinder(..) => { + ty::InstanceKind::DropGlue(trait_item_id, Some(self_ty)) + } + _ => return Ok(None), + } + } else { + ty::InstanceKind::DropGlue(trait_item_id, None) + }; + Some(ty::Instance { def, args: rcvr_args }) } else { Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args) } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index f56a4d7308e90..fc07ea72fd0f0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1056,10 +1056,15 @@ marker_impls! { #[unstable(feature = "const_destruct", issue = "133214")] #[rustc_const_unstable(feature = "const_destruct", issue = "133214")] #[lang = "destruct"] -#[diagnostic::on_unimplemented(message = "can't drop `{Self}`")] -#[rustc_deny_explicit_impl] +#[rustc_on_unimplemented(message = "can't drop `{Self}`")] #[rustc_dyn_incompatible_trait] -pub const trait Destruct: PointeeSized {} +pub const trait Destruct: PointeeSized { + /// Entrypoint for drop + /// + /// Generated by default if not implemented manually. + #[lang = "destruct_drop_in_place"] + unsafe fn drop_in_place(_to_drop: *mut Self); +} /// A marker for tuple types. /// diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index e30fa779dac25..64e7bc6834c97 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2404,7 +2404,13 @@ impl const MyClone for i32 { } } #[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); +} "#, ); } diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 4830253e89d45..95eb208e0a418 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -66,7 +66,13 @@ pub trait Sized: MetaSized {} #[lang = "destruct"] #[diagnostic::on_unimplemented(message = "can't drop `{Self}`")] -pub trait Destruct: PointeeSized {} +pub trait Destruct: PointeeSized { + /// 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 = "legacy_receiver"] pub trait LegacyReceiver {} diff --git a/tests/ui/consts/const-eval/c-variadic-fail.stderr b/tests/ui/consts/const-eval/c-variadic-fail.stderr index d88ee9d6dd3c3..a23e2954e9b49 100644 --- a/tests/ui/consts/const-eval/c-variadic-fail.stderr +++ b/tests/ui/consts/const-eval/c-variadic-fail.stderr @@ -436,8 +436,8 @@ LL | drop(ap); | ^^^^^^^^ note: inside `std::mem::drop::>` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `drop_in_place::> - shim(Some(VaList<'_>))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(VaList<'_>))` + --> $SRC_DIR/core/src/marker.rs:LL:COL note: inside ` as Drop>::drop` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL @@ -468,8 +468,8 @@ LL | drop(ap); | ^^^^^^^^ note: inside `std::mem::drop::>` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `drop_in_place::> - shim(Some(VaList<'_>))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(VaList<'_>))` + --> $SRC_DIR/core/src/marker.rs:LL:COL note: inside ` as Drop>::drop` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL @@ -521,8 +521,8 @@ error[E0080]: pointer not dereferenceable: pointer must point to some allocation LL | } | ^ evaluation of `drop_of_invalid::{constant#0}` failed inside this call | -note: inside `drop_in_place::> - shim(Some(VaList<'_>))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(VaList<'_>))` + --> $SRC_DIR/core/src/marker.rs:LL:COL note: inside ` as Drop>::drop` --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL diff --git a/tests/ui/consts/miri_unleashed/assoc_const.stderr b/tests/ui/consts/miri_unleashed/assoc_const.stderr index 1ba4f3b2896ef..74ba2bee1b2b3 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const.stderr +++ b/tests/ui/consts/miri_unleashed/assoc_const.stderr @@ -4,10 +4,10 @@ error[E0080]: calling non-const function ` as Drop>::drop` LL | const F: u32 = (U::X, 42).1; | ^ evaluation of `, std::string::String>>::F` failed inside this call | -note: inside `drop_in_place::<(Vec, u32)> - shim(Some((Vec, u32)))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `drop_in_place::> - shim(Some(Vec))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `<(Vec, u32) as Destruct>::drop_in_place - shim(Some((Vec, u32)))` + --> $SRC_DIR/core/src/marker.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(Vec))` + --> $SRC_DIR/core/src/marker.rs:LL:COL note: erroneous constant encountered --> $DIR/assoc_const.rs:29:13 diff --git a/tests/ui/consts/miri_unleashed/drop.stderr b/tests/ui/consts/miri_unleashed/drop.stderr index a66422956bee3..e4636cbec08e0 100644 --- a/tests/ui/consts/miri_unleashed/drop.stderr +++ b/tests/ui/consts/miri_unleashed/drop.stderr @@ -4,8 +4,8 @@ error[E0080]: calling non-const function ` as Drop>::drop` LL | }; | ^ evaluation of `TEST_BAD` failed inside this call | -note: inside `drop_in_place::> - shim(Some(Vec))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(Vec))` + --> $SRC_DIR/core/src/marker.rs:LL:COL warning: skipping const checks | diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr index 79724ee8d6a17..6621f9a8aa35b 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr +++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr @@ -13,12 +13,12 @@ error[E0080]: calling non-const function ` as Drop>::drop` LL | }; | ^ evaluation of `A1` failed inside this call | -note: inside `drop_in_place::> - shim(Some(Option))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `drop_in_place:: - shim(Some(String))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `drop_in_place::> - shim(Some(Vec))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(Option))` + --> $SRC_DIR/core/src/marker.rs:LL:COL +note: inside `::drop_in_place - shim(Some(String))` + --> $SRC_DIR/core/src/marker.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(Vec))` + --> $SRC_DIR/core/src/marker.rs:LL:COL error[E0493]: destructor of `Option` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:28:9 @@ -34,12 +34,12 @@ error[E0080]: calling non-const function ` as Drop>::drop` LL | }; | ^ evaluation of `A2` failed inside this call | -note: inside `drop_in_place::> - shim(Some(Option))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `drop_in_place:: - shim(Some(String))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `drop_in_place::> - shim(Some(Vec))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(Option))` + --> $SRC_DIR/core/src/marker.rs:LL:COL +note: inside `::drop_in_place - shim(Some(String))` + --> $SRC_DIR/core/src/marker.rs:LL:COL +note: inside ` as Destruct>::drop_in_place - shim(Some(Vec))` + --> $SRC_DIR/core/src/marker.rs:LL:COL error[E0493]: destructor of `(u32, Option)` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:6:9 diff --git a/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr index 38e169c97016d..2727672dd4d40 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr @@ -11,7 +11,7 @@ LL | let _ = Fail::::C; | ^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn as Drop>::drop` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + --> $SRC_DIR/core/src/marker.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/consts/required-consts/collect-in-dead-drop.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-drop.opt.stderr index 38e169c97016d..2727672dd4d40 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-drop.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-drop.opt.stderr @@ -11,7 +11,7 @@ LL | let _ = Fail::::C; | ^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn as Drop>::drop` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + --> $SRC_DIR/core/src/marker.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr index 9f652e26f242f..19b41fb3e3ae6 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr @@ -11,7 +11,7 @@ LL | let _ = Fail::::C; | ^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn as Drop>::drop` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + --> $SRC_DIR/core/src/marker.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/consts/required-consts/collect-in-dead-move.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-move.opt.stderr index 9f652e26f242f..19b41fb3e3ae6 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-move.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-move.opt.stderr @@ -11,7 +11,7 @@ LL | let _ = Fail::::C; | ^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn as Drop>::drop` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + --> $SRC_DIR/core/src/marker.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/drop/custom_dtor_with_destruct.rs b/tests/ui/drop/custom_dtor_with_destruct.rs new file mode 100644 index 0000000000000..54ca01ca24fa1 --- /dev/null +++ b/tests/ui/drop/custom_dtor_with_destruct.rs @@ -0,0 +1,19 @@ +//@ run-pass +//@ check-stdout +//@ check-run-results + +#![feature(const_destruct)] +use std::marker::Destruct; +struct A { + _a: String, +} + +impl Destruct for A { + unsafe fn drop_in_place(_to_drop: *mut Self) { + println!("Hey i was dropped"); + } +} + +fn main() { + let _a = A { _a: String::new() }; +} diff --git a/tests/ui/drop/custom_dtor_with_destruct.run.stdout b/tests/ui/drop/custom_dtor_with_destruct.run.stdout new file mode 100644 index 0000000000000..e864173b60164 --- /dev/null +++ b/tests/ui/drop/custom_dtor_with_destruct.run.stdout @@ -0,0 +1 @@ +Hey i was dropped diff --git a/tests/ui/traits/const-traits/auxiliary/minicore.rs b/tests/ui/traits/const-traits/auxiliary/minicore.rs index 2e5df13d021d5..e14b740960e93 100644 --- a/tests/ui/traits/const-traits/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/auxiliary/minicore.rs @@ -12,7 +12,7 @@ fundamental, marker_trait_attr, const_trait_impl, - const_destruct, + const_destruct )] #![allow(internal_features, incomplete_features)] #![no_std] @@ -122,7 +122,13 @@ impl Receiver for T { } #[lang = "destruct"] -pub const trait Destruct {} +pub const 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 = "freeze"] pub unsafe auto trait Freeze {}