From 2d73597b93d27b94e1b534d84352f51629418380 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 8 Feb 2024 17:51:32 +0000 Subject: [PATCH] Bail out of drop elaboration when encountering error types --- .../src/move_paths/builder.rs | 5 ++++- tests/ui/drop/drop_elaboration_with_errors.rs | 20 +++++++++++++++++++ .../drop/drop_elaboration_with_errors.stderr | 14 +++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/ui/drop/drop_elaboration_with_errors.rs create mode 100644 tests/ui/drop/drop_elaboration_with_errors.stderr diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 30dd915521c..8c2690574e5 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -1,7 +1,7 @@ use rustc_index::IndexVec; use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState}; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use smallvec::{smallvec, SmallVec}; use std::mem; @@ -132,6 +132,9 @@ fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult { let body = self.builder.body; let tcx = self.builder.tcx; let place_ty = place_ref.ty(body, tcx).ty; + if place_ty.references_error() { + return MovePathResult::Error; + } match elem { ProjectionElem::Deref => match place_ty.kind() { ty::Ref(..) | ty::RawPtr(..) => { diff --git a/tests/ui/drop/drop_elaboration_with_errors.rs b/tests/ui/drop/drop_elaboration_with_errors.rs new file mode 100644 index 00000000000..77862762e87 --- /dev/null +++ b/tests/ui/drop/drop_elaboration_with_errors.rs @@ -0,0 +1,20 @@ +// can't use build-fail, because this also fails check-fail, but +// the ICE from #120787 only reproduces on build-fail. +// compile-flags: --emit=mir + +#![feature(type_alias_impl_trait)] + +struct Foo { + field: String, +} + +type Tait = impl Sized; + +fn ice_cold(beverage: Tait) { + let Foo { field } = beverage; + _ = field; +} + +fn main() { + Ok(()) //~ ERROR mismatched types +} diff --git a/tests/ui/drop/drop_elaboration_with_errors.stderr b/tests/ui/drop/drop_elaboration_with_errors.stderr new file mode 100644 index 00000000000..bec229631e1 --- /dev/null +++ b/tests/ui/drop/drop_elaboration_with_errors.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/drop_elaboration_with_errors.rs:19:5 + | +LL | fn main() { + | - expected `()` because of default return type +LL | Ok(()) + | ^^^^^^ expected `()`, found `Result<(), _>` + | + = note: expected unit type `()` + found enum `Result<(), _>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.