diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 6022194342d..b0311400e77 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -233,14 +233,15 @@ pub struct BorrowCheckResult<'tcx> { /// The result of the `mir_const_qualif` query. /// -/// Each field corresponds to an implementer of the `Qualif` trait in -/// `librustc_mir/transform/check_consts/qualifs.rs`. See that file for more information on each +/// Each field (except `error_occured`) corresponds to an implementer of the `Qualif` trait in +/// `rustc_mir/src/transform/check_consts/qualifs.rs`. See that file for more information on each /// `Qualif`. #[derive(Clone, Copy, Debug, Default, TyEncodable, TyDecodable, HashStable)] pub struct ConstQualifs { pub has_mut_interior: bool, pub needs_drop: bool, pub custom_eq: bool, + pub error_occured: bool, } /// After we borrow check a closure, we are left with various diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 0cac7c087d4..90b610428cf 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -9,6 +9,7 @@ use crate::interpret::{ use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; +use rustc_errors::ErrorReported; use rustc_middle::traits::Reveal; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, subst::Subst, TyCtxt}; @@ -274,6 +275,10 @@ pub fn eval_to_allocation_raw_provider<'tcx>( return Err(ErrorHandled::Reported(error_reported)); } } + let qualif = tcx.mir_const_qualif_opt_const_arg(def); + if qualif.error_occured { + return Err(ErrorHandled::Reported(ErrorReported {})); + } } let is_static = tcx.is_static(def.did); diff --git a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs index b3d9beb3742..c57b49b69ce 100644 --- a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs @@ -9,11 +9,12 @@ use rustc_trait_selection::traits; use super::ConstCx; -pub fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> ConstQualifs { +pub fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>, error_occured: bool) -> ConstQualifs { ConstQualifs { has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty), needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty), custom_eq: CustomEq::in_any_value_of_ty(cx, ty), + error_occured, } } diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 4139b544998..50617278044 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -123,7 +123,7 @@ impl Qualifs<'mir, 'tcx> { has_mut_interior.get().contains(local) || self.indirectly_mutable(ccx, local, location) } - fn in_return_place(&mut self, ccx: &'mir ConstCx<'mir, 'tcx>) -> ConstQualifs { + fn in_return_place(&mut self, ccx: &'mir ConstCx<'mir, 'tcx>, error_occured: bool) -> ConstQualifs { // Find the `Return` terminator if one exists. // // If no `Return` terminator exists, this MIR is divergent. Just return the conservative @@ -139,7 +139,7 @@ impl Qualifs<'mir, 'tcx> { .map(|(bb, _)| bb); let return_block = match return_block { - None => return qualifs::in_any_value_of_ty(ccx, ccx.body.return_ty()), + None => return qualifs::in_any_value_of_ty(ccx, ccx.body.return_ty(), error_occured), Some(bb) => bb, }; @@ -170,6 +170,7 @@ impl Qualifs<'mir, 'tcx> { needs_drop: self.needs_drop(ccx, RETURN_PLACE, return_loc), has_mut_interior: self.has_mut_interior(ccx, RETURN_PLACE, return_loc), custom_eq, + error_occured, } } } @@ -276,7 +277,7 @@ impl Validator<'mir, 'tcx> { } pub fn qualifs_in_return_place(&mut self) -> ConstQualifs { - self.qualifs.in_return_place(self.ccx) + self.qualifs.in_return_place(self.ccx, self.error_emitted) } /// Emits an error if an expression cannot be evaluated in the current context. diff --git a/src/test/ui/consts/issue-76064.rs b/src/test/ui/consts/issue-76064.rs new file mode 100644 index 00000000000..2da764b47c0 --- /dev/null +++ b/src/test/ui/consts/issue-76064.rs @@ -0,0 +1,3 @@ +struct Bug([u8; panic!(1)]); //~ ERROR panicking in constants is unstable + +fn main() {} diff --git a/src/test/ui/consts/issue-76064.stderr b/src/test/ui/consts/issue-76064.stderr new file mode 100644 index 00000000000..f939ff33975 --- /dev/null +++ b/src/test/ui/consts/issue-76064.stderr @@ -0,0 +1,13 @@ +error[E0658]: panicking in constants is unstable + --> $DIR/issue-76064.rs:1:17 + | +LL | struct Bug([u8; panic!(1)]); + | ^^^^^^^^^ + | + = note: see issue #51999 for more information + = help: add `#![feature(const_panic)]` to the crate attributes to enable + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`.