diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index a088a210e2640..9f21c8644876f 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -324,14 +324,6 @@ 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>(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`"); @@ -429,6 +421,43 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { true } + + pub fn check_drop_terminator( + &mut self, + dropped_place: Place<'tcx>, + location: Location, + terminator_span: Span, + ) { + 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 { + 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; + } + + let mut err_span = self.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 { + qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place) + }; + + self.check_op_spanned( + ops::LiveDrop { + dropped_at: terminator_span, + dropped_ty: ty_of_dropped_place, + needs_non_const_drop, + }, + err_span, + ); + } } impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { @@ -874,35 +903,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { return; } - let mut err_span = self.span; - 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 { - 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; - } - - 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 { - qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place) - }; - - 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, - ); + self.check_drop_terminator(*dropped_place, location, terminator.source_info.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 c8d6358161fca..ab81e60a33f23 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -459,7 +459,7 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm { #[derive(Debug)] pub(crate) struct LiveDrop<'tcx> { - pub dropped_at: Option, + pub dropped_at: Span, pub dropped_ty: Ty<'tcx>, pub needs_non_const_drop: bool, } 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 c3a9aad642129..951e19b470bab 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 @@ -5,11 +5,7 @@ use rustc_span::symbol::sym; use tracing::trace; use super::ConstCx; -use super::check::Qualifs; -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 @@ -46,23 +42,16 @@ pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) { return; } - let mut visitor = CheckLiveDrops { ccx: &ccx, qualifs: Qualifs::default() }; + // 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. + let mut visitor = CheckLiveDrops { checker: Checker::new(&ccx) }; visitor.visit_body(body); } struct CheckLiveDrops<'mir, 'tcx> { - ccx: &'mir ConstCx<'mir, 'tcx>, - qualifs: Qualifs<'mir, 'tcx>, -} - -// So we can access `body` and `tcx`. -impl<'mir, 'tcx> std::ops::Deref for CheckLiveDrops<'mir, 'tcx> { - type Target = ConstCx<'mir, 'tcx>; - - fn deref(&self) -> &Self::Target { - self.ccx - } + checker: Checker<'mir, 'tcx>, } impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> { @@ -82,38 +71,10 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> { match &terminator.kind { mir::TerminatorKind::Drop { place: dropped_place, .. } => { - 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; - } - - 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, + self.checker.check_drop_terminator( + *dropped_place, + location, + terminator.source_info.span, ); } diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 29fd3aa7d4de2..accce883e39dd 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -306,11 +306,10 @@ where return false; } - // This is currently unconditionally true for all qualifs, since we do - // not recurse into the pointer of a deref projection, but that may change - // in the future. If that changes, each qualif should be required to - // specify whether it operates structurally for deref projections, just like - // we do for `Qualif::is_structural_in_adt`. + // `Deref` currently unconditionally "qualifies" if `in_any_value_of_ty` returns true, + // i.e., we treat all qualifs as non-structural for deref projections. Generally, + // we can say very little about `*ptr` even if we know that `ptr` satisfies all + // sorts of properties. if matches!(elem, ProjectionElem::Deref) { // We have to assume that this qualifies. return true; diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 604e5ed61a35b..80236ee05b7ff 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -411,7 +411,7 @@ pub struct LiveDrop<'tcx> { pub kind: ConstContext, pub dropped_ty: Ty<'tcx>, #[label(const_eval_dropped_at_label)] - pub dropped_at: Option, + pub dropped_at: Span, } #[derive(Diagnostic)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index bd1a8a02dbf47..acbad07746bb9 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_destruct", issue = "10")] +#[unstable(feature = "const_destruct", issue = "133214")] #[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 3b8f6b6359123..9dd6a96686f36 100644 --- a/tests/ui/consts/const-block-const-bound.stderr +++ b/tests/ui/consts/const-block-const-bound.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | use std::marker::Destruct; | ^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -14,7 +14,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | const fn f(x: T) {} | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index 15d3ae98c7e2b..c84e604793621 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | use std::marker::Destruct; | ^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -14,7 +14,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -24,7 +24,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -34,7 +34,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -44,7 +44,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr index 530b23975ad00..9abfa630e4def 100644 --- a/tests/ui/traits/const-traits/const-drop-bound.stderr +++ b/tests/ui/traits/const-traits/const-drop-bound.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | use std::marker::Destruct; | ^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -14,7 +14,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | const fn foo(res: Result) -> Option where E: ~const Destruct { | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -24,7 +24,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | T: ~const Destruct, | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -34,7 +34,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | E: ~const Destruct, | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 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 83c72efb7eb4d..d871f4d425d5d 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | use std::marker::{Destruct, PhantomData}; | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 @@ -14,7 +14,7 @@ error[E0658]: use of unstable library feature `const_destruct` LL | const fn check(_: T) {} | ^^^^^^^^ | - = note: see issue #10 for more information + = note: see issue #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 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 index a6dcc38816a12..218f3661e39d4 100644 --- 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 @@ -1,5 +1,5 @@ error[E0493]: destructor of `ConstDrop` cannot be evaluated at compile-time - --> $DIR/minicore-drop-without-feature-gate.rs:23:13 + --> $DIR/minicore-drop-without-feature-gate.rs:24:13 | LL | let _ = ConstDrop; | ^^^^^^^^^- value is dropped here 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 index 06014ad1291aa..e75bf3db007f0 100644 --- 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 @@ -2,6 +2,7 @@ //@ compile-flags: --crate-type=lib -Znext-solver //@ revisions: yes no //@[yes] check-pass +// gate-test-const_destruct #![feature(no_core, const_trait_impl)] #![cfg_attr(yes, feature(const_destruct))]