diff options
| author | Michael Goulet <michael@errs.io> | 2024-11-19 17:08:52 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-11-22 16:54:40 +0000 |
| commit | 20882608529a969bd878ad787cf0038716c021df (patch) | |
| tree | 2fcb9b0c14a63b6dac1975c57c86294d33a06552 | |
| parent | b75c1c3dd64d6846d670adca10ebd3735b48dc6a (diff) | |
| download | rust-20882608529a969bd878ad787cf0038716c021df.tar.gz rust-20882608529a969bd878ad787cf0038716c021df.zip | |
Gate const drop behind const_destruct feature, and fix const_precise_live_drops post-drop-elaboration check
28 files changed, 366 insertions, 109 deletions
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 1129b5caec5..a088a210e26 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -24,7 +24,7 @@ use rustc_span::{Span, Symbol, sym}; use rustc_trait_selection::traits::{ Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt, }; -use tracing::{debug, instrument, trace}; +use tracing::{instrument, trace}; use super::ops::{self, NonConstOp, Status}; use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop}; @@ -47,7 +47,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { /// Returns `true` if `local` is `NeedsDrop` at the given `Location`. /// /// Only updates the cursor if absolutely necessary - fn needs_drop( + pub(crate) fn needs_drop( &mut self, ccx: &'mir ConstCx<'mir, 'tcx>, local: Local, @@ -324,6 +324,14 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { } } + /// Emits an error at the given `span` if an expression cannot be evaluated in the current + /// context. This is meant for use in a post-const-checker pass such as the const precise + /// live drops lint. + pub fn check_op_spanned_post<O: NonConstOp<'tcx>>(mut self, op: O, span: Span) { + self.check_op_spanned(op, span); + assert!(self.secondary_errors.is_empty()); + } + fn check_static(&mut self, def_id: DefId, span: Span) { if self.tcx.is_thread_local_static(def_id) { self.tcx.dcx().span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`"); @@ -869,12 +877,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let mut err_span = self.span; let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty; - let ty_needs_non_const_drop = - qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place); - - debug!(?ty_of_dropped_place, ?ty_needs_non_const_drop); - - if !ty_needs_non_const_drop { + let needs_drop = if let Some(local) = dropped_place.as_local() { + self.qualifs.needs_drop(self.ccx, local, location) + } else { + qualifs::NeedsDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place) + }; + // If this type doesn't need a drop at all, then there's nothing to enforce. + if !needs_drop { return; } @@ -883,18 +892,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { err_span = self.body.local_decls[local].source_info.span; self.qualifs.needs_non_const_drop(self.ccx, local, location) } else { - true + qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place) }; - if needs_non_const_drop { - self.check_op_spanned( - ops::LiveDrop { - dropped_at: Some(terminator.source_info.span), - dropped_ty: ty_of_dropped_place, - }, - err_span, - ); - } + self.check_op_spanned( + ops::LiveDrop { + dropped_at: Some(terminator.source_info.span), + dropped_ty: ty_of_dropped_place, + needs_non_const_drop, + }, + err_span, + ); } TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm), diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 8ba6b89aad4..c8d6358161f 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -461,15 +461,41 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm { pub(crate) struct LiveDrop<'tcx> { pub dropped_at: Option<Span>, pub dropped_ty: Ty<'tcx>, + pub needs_non_const_drop: bool, } impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> { + fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status { + if self.needs_non_const_drop { + Status::Forbidden + } else { + Status::Unstable { + gate: sym::const_destruct, + gate_already_checked: false, + safe_to_expose_on_stable: false, + is_function_call: false, + } + } + } + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - ccx.dcx().create_err(errors::LiveDrop { - span, - dropped_ty: self.dropped_ty, - kind: ccx.const_kind(), - dropped_at: self.dropped_at, - }) + if self.needs_non_const_drop { + ccx.dcx().create_err(errors::LiveDrop { + span, + dropped_ty: self.dropped_ty, + kind: ccx.const_kind(), + dropped_at: self.dropped_at, + }) + } else { + ccx.tcx.sess.create_feature_err( + errors::LiveDrop { + span, + dropped_ty: self.dropped_ty, + kind: ccx.const_kind(), + dropped_at: self.dropped_at, + }, + sym::const_destruct, + ) + } } } diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index f6eb130fbd3..c3a9aad6421 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -1,14 +1,15 @@ use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{self, BasicBlock, Location}; -use rustc_middle::ty::{Ty, TyCtxt}; -use rustc_span::Span; +use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; use tracing::trace; use super::ConstCx; use super::check::Qualifs; -use super::ops::{self, NonConstOp}; +use super::ops::{self}; use super::qualifs::{NeedsNonConstDrop, Qualif}; +use crate::check_consts::check::Checker; +use crate::check_consts::qualifs::NeedsDrop; use crate::check_consts::rustc_allow_const_fn_unstable; /// Returns `true` if we should use the more precise live drop checker that runs after drop @@ -64,12 +65,6 @@ impl<'mir, 'tcx> std::ops::Deref for CheckLiveDrops<'mir, 'tcx> { } } -impl<'tcx> CheckLiveDrops<'_, 'tcx> { - fn check_live_drop(&self, span: Span, dropped_ty: Ty<'tcx>) { - ops::LiveDrop { dropped_at: None, dropped_ty }.build_error(self.ccx, span).emit(); - } -} - impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> { fn visit_basic_block_data(&mut self, bb: BasicBlock, block: &mir::BasicBlockData<'tcx>) { trace!("visit_basic_block_data: bb={:?} is_cleanup={:?}", bb, block.is_cleanup); @@ -87,28 +82,39 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> { match &terminator.kind { mir::TerminatorKind::Drop { place: dropped_place, .. } => { - let dropped_ty = dropped_place.ty(self.body, self.tcx).ty; - - if !NeedsNonConstDrop::in_any_value_of_ty(self.ccx, dropped_ty) { - // Instead of throwing a bug, we just return here. This is because we have to - // run custom `const Drop` impls. + let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty; + + let needs_drop = if let Some(local) = dropped_place.as_local() { + self.qualifs.needs_drop(self.ccx, local, location) + } else { + NeedsDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place) + }; + // If this type doesn't need a drop at all, then there's nothing to enforce. + if !needs_drop { return; } - if dropped_place.is_indirect() { - self.check_live_drop(terminator.source_info.span, dropped_ty); - return; - } - - // Drop elaboration is not precise enough to accept code like - // `tests/ui/consts/control-flow/drop-pass.rs`; e.g., when an `Option<Vec<T>>` is - // initialized with `None` and never changed, it still emits drop glue. - // Hence we additionally check the qualifs here to allow more code to pass. - if self.qualifs.needs_non_const_drop(self.ccx, dropped_place.local, location) { - // Use the span where the dropped local was declared for the error. - let span = self.body.local_decls[dropped_place.local].source_info.span; - self.check_live_drop(span, dropped_ty); - } + let mut err_span = terminator.source_info.span; + + let needs_non_const_drop = if let Some(local) = dropped_place.as_local() { + // Use the span where the local was declared as the span of the drop error. + err_span = self.body.local_decls[local].source_info.span; + self.qualifs.needs_non_const_drop(self.ccx, local, location) + } else { + NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place) + }; + + // I know it's not great to be creating a new const checker, but I'd + // rather use it so we can deduplicate the error emitting logic that + // it contains. + Checker::new(self.ccx).check_op_spanned_post( + ops::LiveDrop { + dropped_at: Some(terminator.source_info.span), + dropped_ty: ty_of_dropped_place, + needs_non_const_drop, + }, + err_span, + ); } mir::TerminatorKind::UnwindTerminate(_) diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index df19ff2c16a..29fd3aa7d4d 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -62,12 +62,12 @@ pub trait Qualif { /// It also determines the `Qualif`s for primitive types. fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool; - /// Returns `true` if the `Qualif` is structural in an ADT's fields, i.e. that we may - /// recurse into an operand if we know what it is. + /// Returns `true` if the `Qualif` is structural in an ADT's fields, i.e. if we may + /// recurse into an operand *value* to determine whether it has this `Qualif`. /// /// If this returns false, `in_any_value_of_ty` will be invoked to determine the /// final qualif for this ADT. - fn is_structural_in_adt<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool; + fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool; } /// Constant containing interior mutability (`UnsafeCell<T>`). @@ -123,7 +123,7 @@ impl Qualif for HasMutInterior { !errors.is_empty() } - fn is_structural_in_adt<'tcx>(_cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { + fn is_structural_in_adt_value<'tcx>(_cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { // Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently. // It arises structurally for all other types. !adt.is_unsafe_cell() @@ -140,6 +140,7 @@ pub struct NeedsDrop; impl Qualif for NeedsDrop { const ANALYSIS_NAME: &'static str = "flow_needs_drop"; const IS_CLEARED_ON_MOVE: bool = true; + const ALLOW_PROMOTED: bool = true; fn in_qualifs(qualifs: &ConstQualifs) -> bool { qualifs.needs_drop @@ -149,7 +150,7 @@ impl Qualif for NeedsDrop { ty.needs_drop(cx.tcx, cx.typing_env) } - fn is_structural_in_adt<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { + fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { !adt.has_dtor(cx.tcx) } } @@ -179,34 +180,30 @@ impl Qualif for NeedsNonConstDrop { // that the components of this type are also `~const Destruct`. This // amounts to verifying that there are no values in this ADT that may have // a non-const drop. - if cx.tcx.features().const_trait_impl() { - let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span)); - let infcx = - cx.tcx.infer_ctxt().build(TypingMode::from_param_env(cx.typing_env.param_env)); - let ocx = ObligationCtxt::new(&infcx); - ocx.register_obligation(Obligation::new( - cx.tcx, - ObligationCause::misc(cx.body.span, cx.def_id()), - cx.typing_env.param_env, - ty::Binder::dummy(ty::TraitRef::new(cx.tcx, destruct_def_id, [ty])) - .to_host_effect_clause(cx.tcx, match cx.const_kind() { - rustc_hir::ConstContext::ConstFn => ty::BoundConstness::Maybe, - rustc_hir::ConstContext::Static(_) - | rustc_hir::ConstContext::Const { .. } => ty::BoundConstness::Const, - }), - )); - !ocx.select_all_or_error().is_empty() - } else { - NeedsDrop::in_any_value_of_ty(cx, ty) - } + let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span)); + let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env); + let ocx = ObligationCtxt::new(&infcx); + ocx.register_obligation(Obligation::new( + cx.tcx, + ObligationCause::misc(cx.body.span, cx.def_id()), + param_env, + ty::Binder::dummy(ty::TraitRef::new(cx.tcx, destruct_def_id, [ty])) + .to_host_effect_clause(cx.tcx, match cx.const_kind() { + rustc_hir::ConstContext::ConstFn => ty::BoundConstness::Maybe, + rustc_hir::ConstContext::Static(_) | rustc_hir::ConstContext::Const { .. } => { + ty::BoundConstness::Const + } + }), + )); + !ocx.select_all_or_error().is_empty() } - fn is_structural_in_adt<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { + fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { // As soon as an ADT has a destructor, then the drop becomes non-structural // in its value since: - // 1. The destructor may have `~const` bounds that need to be satisfied on - // top of checking that the components of a specific operand are const-drop. - // While this could be instead satisfied by checking that the `~const Drop` + // 1. The destructor may have `~const` bounds which are not present on the type. + // Someone needs to check that those are satisfied. + // While this could be done instead satisfied by checking that the `~const Drop` // impl holds (i.e. replicating part of the `in_any_value_of_ty` logic above), // even in this case, we have another problem, which is, // 2. The destructor may *modify* the operand being dropped, so even if we @@ -271,7 +268,7 @@ where // then we cannot recurse on its fields. Instead, // we fall back to checking the qualif for *any* value // of the ADT. - if def.is_union() || !Q::is_structural_in_adt(cx, def) { + if def.is_union() || !Q::is_structural_in_adt_value(cx, def) { return Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)); } } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e3dc73c1401..b9a75fedcbe 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -426,6 +426,8 @@ declare_features! ( (unstable, const_async_blocks, "1.53.0", Some(85368)), /// Allows `const || {}` closures in const contexts. (incomplete, const_closures, "1.68.0", Some(106003)), + /// Uwu + (unstable, const_destruct, "CURRENT_RUSTC_VERSION", Some(133214)), /// Allows `for _ in _` loops in const contexts. (unstable, const_for, "1.56.0", Some(87575)), /// Be more precise when looking for live drops in a const context. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a2d9859645f..c7c29abc3cb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -610,6 +610,7 @@ symbols! { const_compare_raw_pointers, const_constructor, const_deallocate, + const_destruct, const_eval_limit, const_eval_select, const_evaluatable_checked, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index c8ea52a1fb0..bd1a8a02dbf 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -953,7 +953,7 @@ marker_impls! { /// /// This should be used for `~const` bounds, /// as non-const bounds will always hold for every type. -#[unstable(feature = "const_trait_impl", issue = "67792")] +#[unstable(feature = "const_destruct", issue = "10")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] #[rustc_deny_explicit_impl(implement_via_object = false)] diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr index 5e24959146b..3b8f6b63591 100644 --- a/tests/ui/consts/const-block-const-bound.stderr +++ b/tests/ui/consts/const-block-const-bound.stderr @@ -1,3 +1,23 @@ +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/const-block-const-bound.rs:6:5 + | +LL | use std::marker::Destruct; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/const-block-const-bound.rs:8:22 + | +LL | const fn f<T: ~const Destruct>(x: T) {} + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-block-const-bound.rs:8:15 | @@ -20,6 +40,7 @@ LL | const fn f<T: ~const Destruct>(x: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0493, E0658. +For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/control-flow/drop-fail.precise.stderr b/tests/ui/consts/control-flow/drop-fail.precise.stderr index 93b5f257efb..32afc51c3ee 100644 --- a/tests/ui/consts/control-flow/drop-fail.precise.stderr +++ b/tests/ui/consts/control-flow/drop-fail.precise.stderr @@ -1,14 +1,20 @@ error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:8:9 + --> $DIR/drop-fail.rs:9:9 | LL | let x = Some(Vec::new()); | ^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:39:9 + --> $DIR/drop-fail.rs:40:9 | LL | let mut tmp = None; | ^^^^^^^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here error: aborting due to 2 previous errors diff --git a/tests/ui/consts/control-flow/drop-fail.rs b/tests/ui/consts/control-flow/drop-fail.rs index 25afe5d08d9..2b73e37b23d 100644 --- a/tests/ui/consts/control-flow/drop-fail.rs +++ b/tests/ui/consts/control-flow/drop-fail.rs @@ -1,5 +1,6 @@ //@ revisions: stock precise +#![feature(const_destruct)] #![cfg_attr(precise, feature(const_precise_live_drops))] // `x` is *not* always moved into the final value and may be dropped inside the initializer. diff --git a/tests/ui/consts/control-flow/drop-fail.stock.stderr b/tests/ui/consts/control-flow/drop-fail.stock.stderr index 2cc8568026e..8fe60fd7367 100644 --- a/tests/ui/consts/control-flow/drop-fail.stock.stderr +++ b/tests/ui/consts/control-flow/drop-fail.stock.stderr @@ -1,5 +1,5 @@ error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:8:9 + --> $DIR/drop-fail.rs:9:9 | LL | let x = Some(Vec::new()); | ^ the destructor for this type cannot be evaluated in constants @@ -8,7 +8,7 @@ LL | }; | - value is dropped here error[E0493]: destructor of `(Vec<i32>,)` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:21:9 + --> $DIR/drop-fail.rs:22:9 | LL | let vec_tuple = (Vec::new(),); | ^^^^^^^^^ the destructor for this type cannot be evaluated in constants @@ -17,7 +17,7 @@ LL | }; | - value is dropped here error[E0493]: destructor of `Result<Vec<i32>, Vec<i32>>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:29:9 + --> $DIR/drop-fail.rs:30:9 | LL | let x: Result<_, Vec<i32>> = Ok(Vec::new()); | ^ the destructor for this type cannot be evaluated in constants @@ -26,7 +26,7 @@ LL | }; | - value is dropped here error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time - --> $DIR/drop-fail.rs:39:9 + --> $DIR/drop-fail.rs:40:9 | LL | let mut tmp = None; | ^^^^^^^ the destructor for this type cannot be evaluated in constants diff --git a/tests/ui/consts/drop_zst.stderr b/tests/ui/consts/drop_zst.stderr index e3c6785290d..4d1af7ef935 100644 --- a/tests/ui/consts/drop_zst.stderr +++ b/tests/ui/consts/drop_zst.stderr @@ -3,6 +3,8 @@ error[E0493]: destructor of `S` cannot be evaluated at compile-time | LL | let s = S; | ^ the destructor for this type cannot be evaluated in constant functions +LL | } + | - value is dropped here error: aborting due to 1 previous error diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index a686bc23c0f..15d3ae98c7e 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -1,3 +1,53 @@ +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/fn_trait_refs.rs:9:5 + | +LL | use std::marker::Destruct; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/fn_trait_refs.rs:13:31 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/fn_trait_refs.rs:20:34 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/fn_trait_refs.rs:34:31 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/fn_trait_refs.rs:48:34 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0635]: unknown feature `const_fn_trait_ref_impls` --> $DIR/fn_trait_refs.rs:3:12 | @@ -264,7 +314,7 @@ LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output) LL | } | - value is dropped here -error: aborting due to 34 previous errors +error: aborting due to 39 previous errors -Some errors have detailed explanations: E0015, E0493, E0635. +Some errors have detailed explanations: E0015, E0493, E0635, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/promoted_const_call2.stderr b/tests/ui/consts/promoted_const_call2.stderr index 177f7aed17d..bdb43385d20 100644 --- a/tests/ui/consts/promoted_const_call2.stderr +++ b/tests/ui/consts/promoted_const_call2.stderr @@ -22,7 +22,9 @@ error[E0493]: destructor of `String` cannot be evaluated at compile-time --> $DIR/promoted_const_call2.rs:4:30 | LL | let _: &'static _ = &id(&String::new()); - | ^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants + | ^^^^^^^^^^^^^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constants error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_call2.rs:11:26 diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr index 433dfba2257..f706b7cf699 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr +++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr @@ -3,6 +3,9 @@ error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time | LL | let mut x = None; | ^^^^^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL @@ -26,6 +29,8 @@ error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time | LL | let _z = x; | ^^ the destructor for this type cannot be evaluated in constants +LL | }; + | - value is dropped here error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL @@ -49,42 +54,62 @@ error[E0493]: destructor of `(u32, Option<String>)` cannot be evaluated at compi | LL | let mut a: (u32, Option<String>) = (0, None); | ^^^^^ the destructor for this type cannot be evaluated in constant functions +LL | let _ = &mut a.1; +LL | } + | - value is dropped here error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:34:9 | LL | let x: Option<T> = None; | ^ the destructor for this type cannot be evaluated in constant functions +LL | let _ = x.is_some(); +LL | } + | - value is dropped here error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:42:9 | LL | let _y = x; | ^^ the destructor for this type cannot be evaluated in constant functions +LL | } + | - value is dropped here error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:50:9 | LL | let mut y: Option<String> = None; | ^^^^^ the destructor for this type cannot be evaluated in constant functions +LL | std::ptr::addr_of_mut!(y); +LL | } + | - value is dropped here error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:47:9 | LL | let mut x: Option<String> = None; | ^^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:60:9 | LL | let y: Option<String> = None; | ^ the destructor for this type cannot be evaluated in constant functions +LL | std::ptr::addr_of!(y); +LL | } + | - value is dropped here error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:57:9 | LL | let x: Option<String> = None; | ^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here error: aborting due to 11 previous errors diff --git a/tests/ui/impl-trait/normalize-tait-in-const.rs b/tests/ui/impl-trait/normalize-tait-in-const.rs index 134b202d655..1fd543b72e7 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.rs +++ b/tests/ui/impl-trait/normalize-tait-in-const.rs @@ -1,7 +1,7 @@ //@ known-bug: #103507 #![feature(type_alias_impl_trait)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_destruct)] use std::marker::Destruct; diff --git a/tests/ui/traits/const-traits/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr index 3f718645433..530b23975ad 100644 --- a/tests/ui/traits/const-traits/const-drop-bound.stderr +++ b/tests/ui/traits/const-traits/const-drop-bound.stderr @@ -1,3 +1,43 @@ +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/const-drop-bound.rs:7:5 + | +LL | use std::marker::Destruct; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/const-drop-bound.rs:9:68 + | +LL | const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct { + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/const-drop-bound.rs:20:15 + | +LL | T: ~const Destruct, + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/const-drop-bound.rs:21:15 + | +LL | E: ~const Destruct, + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-bound.rs:9:61 | @@ -44,8 +84,11 @@ error[E0493]: destructor of `E` cannot be evaluated at compile-time --> $DIR/const-drop-bound.rs:12:13 | LL | Err(_e) => None, - | ^^ the destructor for this type cannot be evaluated in constant functions + | ^^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 7 previous errors +error: aborting due to 11 previous errors -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0493, E0658. +For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr index fde106599c2..83c72efb7eb 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.stderr @@ -1,3 +1,23 @@ +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/const-drop-fail-2.rs:5:19 + | +LL | use std::marker::{Destruct, PhantomData}; + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `const_destruct` + --> $DIR/const-drop-fail-2.rs:20:26 + | +LL | const fn check<T: ~const Destruct>(_: T) {} + | ^^^^^^^^ + | + = note: see issue #10 <https://github.com/rust-lang/rust/issues/10> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` --> $DIR/const-drop-fail-2.rs:39:25 | @@ -35,7 +55,7 @@ LL | const fn check<T: ~const Destruct>(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0277, E0493. +Some errors have detailed explanations: E0277, E0493, E0658. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr index 859fdfae81a..91ca60b750d 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr @@ -25,7 +25,9 @@ error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop-fail.rs:23:36 | LL | const fn check<T: ~const Destruct>(_: T) {} - | ^ the destructor for this type cannot be evaluated in constant functions + | ^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL diff --git a/tests/ui/traits/const-traits/const-drop-fail.rs b/tests/ui/traits/const-traits/const-drop-fail.rs index 5a98c32e838..c61afc0e17a 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.rs +++ b/tests/ui/traits/const-traits/const-drop-fail.rs @@ -1,7 +1,7 @@ //@ known-bug: #110395 //@ revisions: stock precise -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_destruct)] #![cfg_attr(precise, feature(const_precise_live_drops))] use std::marker::{Destruct, PhantomData}; diff --git a/tests/ui/traits/const-traits/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr index 4f673187d49..51a66396c4b 100644 --- a/tests/ui/traits/const-traits/const-drop.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop.precise.stderr @@ -76,13 +76,17 @@ error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time --> $DIR/const-drop.rs:23:13 | LL | let _ = S(&mut c); - | ^^^^^^^^^ the destructor for this type cannot be evaluated in constant functions + | ^^^^^^^^^- value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop.rs:18:32 | LL | const fn a<T: ~const Destruct>(_: T) {} - | ^ the destructor for this type cannot be evaluated in constant functions + | ^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied --> $DIR/const-drop.rs:69:13 diff --git a/tests/ui/traits/const-traits/const-drop.rs b/tests/ui/traits/const-traits/const-drop.rs index 5bd81fb3ab6..8bf1dd68b5c 100644 --- a/tests/ui/traits/const-traits/const-drop.rs +++ b/tests/ui/traits/const-traits/const-drop.rs @@ -1,7 +1,7 @@ // FIXME run-pass //@ known-bug: #110395 //@ revisions: stock precise -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_destruct)] #![feature(never_type)] #![cfg_attr(precise, feature(const_precise_live_drops))] diff --git a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs index 498e698ef1c..660fb432594 100644 --- a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs @@ -11,7 +11,8 @@ rustc_attrs, fundamental, marker_trait_attr, - const_trait_impl + const_trait_impl, + const_destruct, )] #![allow(internal_features, incomplete_features)] #![no_std] diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs b/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs index 57c39d2c1a1..274e5db21c4 100644 --- a/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs +++ b/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs @@ -1,7 +1,7 @@ //@ aux-build:minicore.rs //@ compile-flags: --crate-type=lib -Znext-solver -#![feature(no_core, const_trait_impl)] +#![feature(no_core, const_trait_impl, const_destruct)] #![no_std] #![no_core] diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr new file mode 100644 index 00000000000..a6dcc38816a --- /dev/null +++ b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr @@ -0,0 +1,15 @@ +error[E0493]: destructor of `ConstDrop` cannot be evaluated at compile-time + --> $DIR/minicore-drop-without-feature-gate.rs:23:13 + | +LL | let _ = ConstDrop; + | ^^^^^^^^^- value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + | + = note: see issue #133214 <https://github.com/rust-lang/rust/issues/133214> for more information + = help: add `#![feature(const_destruct)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs new file mode 100644 index 00000000000..06014ad1291 --- /dev/null +++ b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs @@ -0,0 +1,25 @@ +//@ aux-build:minicore.rs +//@ compile-flags: --crate-type=lib -Znext-solver +//@ revisions: yes no +//@[yes] check-pass + +#![feature(no_core, const_trait_impl)] +#![cfg_attr(yes, feature(const_destruct))] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +struct ConstDrop; +impl const Drop for ConstDrop { + fn drop(&mut self) {} +} + +// Make sure that `ConstDrop` can only be dropped when the `const_drop` +// feature gate is enabled. Otherwise, we should error if there is a drop +// impl at all. +const fn test() { + let _ = ConstDrop; + //[no]~^ ERROR destructor of `ConstDrop` cannot be evaluated at compile-time +} diff --git a/tests/ui/traits/const-traits/issue-92111.rs b/tests/ui/traits/const-traits/issue-92111.rs index 64fa32156c3..64bf0f20e91 100644 --- a/tests/ui/traits/const-traits/issue-92111.rs +++ b/tests/ui/traits/const-traits/issue-92111.rs @@ -3,7 +3,7 @@ //@ known-bug: #110395 // FIXME check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_destruct)] use std::marker::Destruct; diff --git a/tests/ui/traits/next-solver/destruct.rs b/tests/ui/traits/next-solver/destruct.rs index f595cb30db8..fd14132124c 100644 --- a/tests/ui/traits/next-solver/destruct.rs +++ b/tests/ui/traits/next-solver/destruct.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Znext-solver //@ check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_destruct)] fn foo(_: impl std::marker::Destruct) {} |
