diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index d41e568060219..e35ff6b996ee0 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -81,6 +81,12 @@ impl From for InterpErrorInfo<'_> { } } +impl From for InterpErrorInfo<'_> { + fn from(err: ErrorReported) -> Self { + InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err)).into() + } +} + impl<'tcx> From> for InterpErrorInfo<'tcx> { fn from(kind: InterpError<'tcx>) -> Self { let capture_backtrace = tls::with_opt(|tcx| { @@ -115,8 +121,8 @@ pub enum InvalidProgramInfo<'tcx> { /// Cannot compute this constant because it depends on another one /// which already produced an error. ReferencedConstant, - /// Abort in case type errors are reached. - TypeckError(ErrorReported), + /// Abort in case errors are already reported. + AlreadyReported(ErrorReported), /// An error occurred during layout computation. Layout(layout::LayoutError<'tcx>), /// An invalid transmute happened. @@ -129,7 +135,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { match self { TooGeneric => write!(f, "encountered overly generic constant"), ReferencedConstant => write!(f, "referenced constant has errors"), - TypeckError(ErrorReported) => { + AlreadyReported(ErrorReported) => { write!(f, "encountered constants with type errors, stopping evaluation") } Layout(ref err) => write!(f, "{}", err), diff --git a/compiler/rustc_mir/src/const_eval/error.rs b/compiler/rustc_mir/src/const_eval/error.rs index 044d27a6a9dc3..39358e03e7590 100644 --- a/compiler/rustc_mir/src/const_eval/error.rs +++ b/compiler/rustc_mir/src/const_eval/error.rs @@ -141,7 +141,7 @@ impl<'tcx> ConstEvalErr<'tcx> { err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { return ErrorHandled::TooGeneric; } - err_inval!(TypeckError(error_reported)) => { + err_inval!(AlreadyReported(error_reported)) => { return ErrorHandled::Reported(error_reported); } // We must *always* hard error on these, even if the caller wants just a lint. diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 7b9a4ec873d0a..438704d0f4d6d 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -67,7 +67,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( None => InternKind::Constant, } }; - intern_const_alloc_recursive(ecx, intern_kind, ret); + intern_const_alloc_recursive(ecx, intern_kind, ret)?; debug!("eval_body_using_ecx done: {:?}", *ret); Ok(ret) diff --git a/compiler/rustc_mir/src/const_eval/mod.rs b/compiler/rustc_mir/src/const_eval/mod.rs index 11a211ef7b351..9dd2a8592a7e0 100644 --- a/compiler/rustc_mir/src/const_eval/mod.rs +++ b/compiler/rustc_mir/src/const_eval/mod.rs @@ -29,7 +29,9 @@ pub(crate) fn const_caller_location( let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), false); let loc_place = ecx.alloc_caller_location(file, line, col); - intern_const_alloc_recursive(&mut ecx, InternKind::Constant, loc_place); + if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, loc_place).is_err() { + bug!("intern_const_alloc_recursive should not error in this case") + } ConstValue::Scalar(loc_place.ptr) } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index ec1195d3703b4..1ec2e3b7c5a8f 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -471,7 +471,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if let Some(def) = def.as_local() { if self.tcx.has_typeck_results(def.did) { if let Some(error_reported) = self.tcx.typeck_opt_const_arg(def).tainted_by_errors { - throw_inval!(TypeckError(error_reported)) + throw_inval!(AlreadyReported(error_reported)) } } } @@ -527,8 +527,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(Some(instance)) => Ok(instance), Ok(None) => throw_inval!(TooGeneric), - // FIXME(eddyb) this could be a bit more specific than `TypeckError`. - Err(error_reported) => throw_inval!(TypeckError(error_reported)), + // FIXME(eddyb) this could be a bit more specific than `AlreadyReported`. + Err(error_reported) => throw_inval!(AlreadyReported(error_reported)), } } diff --git a/compiler/rustc_mir/src/interpret/intern.rs b/compiler/rustc_mir/src/interpret/intern.rs index 5e5c74a372374..413be427339f3 100644 --- a/compiler/rustc_mir/src/interpret/intern.rs +++ b/compiler/rustc_mir/src/interpret/intern.rs @@ -16,6 +16,7 @@ use super::validity::RefTracking; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_middle::mir::interpret::InterpResult; use rustc_middle::ty::{self, layout::TyAndLayout, Ty}; @@ -285,11 +286,13 @@ pub enum InternKind { /// tracks where in the value we are and thus can show much better error messages. /// Any errors here would anyway be turned into `const_err` lints, whereas validation failures /// are hard errors. +#[tracing::instrument(skip(ecx))] pub fn intern_const_alloc_recursive>( ecx: &mut InterpCx<'mir, 'tcx, M>, intern_kind: InternKind, ret: MPlaceTy<'tcx>, -) where +) -> Result<(), ErrorReported> +where 'tcx: 'mir, { let tcx = ecx.tcx; @@ -405,12 +408,14 @@ pub fn intern_const_alloc_recursive>( // Codegen does not like dangling pointers, and generally `tcx` assumes that // all allocations referenced anywhere actually exist. So, make sure we error here. ecx.tcx.sess.span_err(ecx.tcx.span, "encountered dangling pointer in final constant"); + return Err(ErrorReported); } else if ecx.tcx.get_global_alloc(alloc_id).is_none() { // We have hit an `AllocId` that is neither in local or global memory and isn't // marked as dangling by local memory. That should be impossible. span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); } } + Ok(()) } impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 3c68b1c8355d5..ba59ac14f9f91 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -550,7 +550,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Early-return cases. let val_val = match val.val { ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), - ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)), + ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)), ty::ConstKind::Unevaluated(def, substs, promoted) => { let instance = self.resolve(def, substs)?; return Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into()); diff --git a/src/test/ui/consts/issue-78655.rs b/src/test/ui/consts/issue-78655.rs new file mode 100644 index 0000000000000..066764bc46fc4 --- /dev/null +++ b/src/test/ui/consts/issue-78655.rs @@ -0,0 +1,10 @@ +const FOO: *const u32 = { //~ ERROR encountered dangling pointer in final constant + let x; + &x //~ ERROR borrow of possibly-uninitialized variable: `x` +}; + +fn main() { + let FOO = FOO; + //~^ ERROR could not evaluate constant pattern + //~| ERROR could not evaluate constant pattern +} diff --git a/src/test/ui/consts/issue-78655.stderr b/src/test/ui/consts/issue-78655.stderr new file mode 100644 index 0000000000000..cf3fe18f802fb --- /dev/null +++ b/src/test/ui/consts/issue-78655.stderr @@ -0,0 +1,30 @@ +error[E0381]: borrow of possibly-uninitialized variable: `x` + --> $DIR/issue-78655.rs:3:5 + | +LL | &x + | ^^ use of possibly-uninitialized `x` + +error: encountered dangling pointer in final constant + --> $DIR/issue-78655.rs:1:1 + | +LL | / const FOO: *const u32 = { +LL | | let x; +LL | | &x +LL | | }; + | |__^ + +error: could not evaluate constant pattern + --> $DIR/issue-78655.rs:7:9 + | +LL | let FOO = FOO; + | ^^^ + +error: could not evaluate constant pattern + --> $DIR/issue-78655.rs:7:9 + | +LL | let FOO = FOO; + | ^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0381`.