From 95c5b060004928984b6b76a9ef67a3ca7147568c Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sun, 11 Feb 2024 23:26:06 +0100 Subject: [PATCH] fix ICE for deref coercions with type errors --- compiler/rustc_hir_analysis/src/autoderef.rs | 8 ++++---- .../rustc_hir_analysis/src/check/wfcheck.rs | 10 +++++++--- tests/ui/coercion/type-errors.rs | 19 +++++++++++++++---- tests/ui/coercion/type-errors.stderr | 14 +++++++++++++- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 5bc904e5930ce..f2ceb4702643a 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -91,10 +91,6 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> { return None; }; - if new_ty.references_error() { - return None; - } - self.state.steps.push((self.state.cur_ty, kind)); debug!( "autoderef stage #{:?} is {:?} from {:?}", @@ -137,6 +133,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { debug!("overloaded_deref_ty({:?})", ty); let tcx = self.infcx.tcx; + if ty.references_error() { + return None; + } + // let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]); let cause = traits::ObligationCause::misc(self.span, self.body_id); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 646a84b043c82..bf22c70ebfd57 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1635,6 +1635,12 @@ fn check_method_receiver<'tcx>( let receiver_ty = sig.inputs()[0]; let receiver_ty = wfcx.normalize(span, None, receiver_ty); + // If the receiver already has errors reported, consider it valid to avoid + // unnecessary errors (#58712). + if receiver_ty.references_error() { + return Ok(()); + } + if tcx.features().arbitrary_self_types { if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) { // Report error; `arbitrary_self_types` was enabled. @@ -1749,9 +1755,7 @@ fn receiver_is_valid<'tcx>( } } else { debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty); - // If the receiver already has errors reported due to it, consider it valid to avoid - // unnecessary errors (#58712). - return receiver_ty.references_error(); + return false; } } diff --git a/tests/ui/coercion/type-errors.rs b/tests/ui/coercion/type-errors.rs index a2f0e55f1b931..a86789907a055 100644 --- a/tests/ui/coercion/type-errors.rs +++ b/tests/ui/coercion/type-errors.rs @@ -1,15 +1,26 @@ -// Regression test for an ICE: https://github.com/rust-lang/rust/issues/120884 +// Test that we don't ICE for coercions with type errors. // We still need to properly go through coercions between types with errors instead of // shortcutting and returning success, because we need the adjustments for building the MIR. pub fn has_error() -> TypeError {} //~^ ERROR cannot find type `TypeError` in this scope +// https://github.com/rust-lang/rust/issues/120884 +// Casting a function item to a data pointer in valid in HIR, but invalid in MIR. +// We need an adjustment (ReifyFnPointer) to insert a cast from the function item +// to a function pointer as a separate MIR statement. pub fn cast() -> *const u8 { - // Casting a function item to a data pointer in valid in HIR, but invalid in MIR. - // We need an adjustment (ReifyFnPointer) to insert a cast from the function item - // to a function pointer as a separate MIR statement. has_error as *const u8 } +// https://github.com/rust-lang/rust/issues/120945 +// This one ICEd, because we skipped the builtin deref from `&TypeError` to `TypeError`. +pub fn autoderef_source(e: &TypeError) { + //~^ ERROR cannot find type `TypeError` in this scope + autoderef_target(e) +} + +pub fn autoderef_target(_: &TypeError) {} +//~^ ERROR cannot find type `TypeError` in this scope + fn main() {} diff --git a/tests/ui/coercion/type-errors.stderr b/tests/ui/coercion/type-errors.stderr index 489cd9ddf130e..14deb785f75aa 100644 --- a/tests/ui/coercion/type-errors.stderr +++ b/tests/ui/coercion/type-errors.stderr @@ -4,6 +4,18 @@ error[E0412]: cannot find type `TypeError` in this scope LL | pub fn has_error() -> TypeError {} | ^^^^^^^^^ not found in this scope -error: aborting due to 1 previous error +error[E0412]: cannot find type `TypeError` in this scope + --> $DIR/type-errors.rs:18:29 + | +LL | pub fn autoderef_source(e: &TypeError) { + | ^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `TypeError` in this scope + --> $DIR/type-errors.rs:23:29 + | +LL | pub fn autoderef_target(_: &TypeError) {} + | ^^^^^^^^^ not found in this scope + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0412`.