From 126dcc618d065e97887113926f63986bd0a9e681 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 2 Apr 2024 14:22:22 +0000 Subject: [PATCH] Use less fragile error handling --- .../src/const_eval/eval_queries.rs | 8 +++--- .../rustc_const_eval/src/interpret/intern.rs | 26 ++++++++----------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index a3e0ea5c1e210..40afd9f162f4e 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -98,14 +98,16 @@ fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>( // Only report this after validation, as validaiton produces much better diagnostics. // FIXME: ensure validation always reports this and stop making interning care about it. - if let Err(InternResult { found_bad_mutable_pointer, found_dangling_pointer }) = intern_result { - if found_dangling_pointer { + match intern_result { + Ok(()) => {} + Err(InternResult::FoundDanglingPointer) => { return Err(ecx .tcx .dcx() .emit_err(DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind }) .into()); - } else if found_bad_mutable_pointer { + } + Err(InternResult::FoundBadMutablePointer) => { // only report mutable pointers if there were no dangling pointers let err_diag = errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind }; ecx.tcx.emit_node_span_lint( diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 3828351db0a3e..d4168273f29fb 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -132,17 +132,10 @@ pub enum InternKind { Promoted, } -#[derive(Default, Debug)] -pub struct InternResult { - pub found_bad_mutable_pointer: bool, - pub found_dangling_pointer: bool, -} - -impl InternResult { - fn has_errors(&self) -> bool { - let Self { found_bad_mutable_pointer, found_dangling_pointer } = *self; - found_bad_mutable_pointer || found_dangling_pointer - } +#[derive(Debug)] +pub enum InternResult { + FoundBadMutablePointer, + FoundDanglingPointer, } /// Intern `ret` and everything it references. @@ -212,7 +205,7 @@ pub fn intern_const_alloc_recursive< // Whether we encountered a bad mutable pointer. // We want to first report "dangling" and then "mutable", so we need to delay reporting these // errors. - let mut result = InternResult::default(); + let mut result = Ok(()); // Keep interning as long as there are things to intern. // We show errors if there are dangling pointers, or mutable pointers in immutable contexts @@ -262,7 +255,10 @@ pub fn intern_const_alloc_recursive< // on the promotion analysis not screwing up to ensure that it is sound to intern // promoteds as immutable. trace!("found bad mutable pointer"); - result.found_bad_mutable_pointer = true; + // Prefer dangling pointer errors over mutable pointer errors + if result.is_ok() { + result = Err(InternResult::FoundBadMutablePointer); + } } if ecx.tcx.try_get_global_alloc(alloc_id).is_some() { // Already interned. @@ -284,11 +280,11 @@ pub fn intern_const_alloc_recursive< Ok(nested) => todo.extend(nested), Err(()) => { ecx.tcx.dcx().delayed_bug("found dangling pointer during const interning"); - result.found_dangling_pointer = true + result = Err(InternResult::FoundDanglingPointer); } } } - if result.has_errors() { Err(result) } else { Ok(()) } + result } /// Intern `ret`. This function assumes that `ret` references no other allocation.