From 48491c182be06aad6db5edfd60bdcab0917cb79d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 30 Oct 2023 20:15:25 +0000 Subject: [PATCH] Also consider TAIT to be uncomputable if the MIR body is tainted --- .../src/collect/type_of/opaque.rs | 14 +++++++++++--- .../unconstrained-due-to-bad-pattern.rs | 14 ++++++++++++++ .../unconstrained-due-to-bad-pattern.stderr | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs create mode 100644 tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index e8d5264c2b8fe..e8ab2651d7282 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -183,9 +183,17 @@ impl TaitConstraintLocator<'_> { }; // Use borrowck to get the type with unerased regions. - let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types; - debug!(?concrete_opaque_types); - if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) { + let borrowck_results = &self.tcx.mir_borrowck(item_def_id); + + // If the body was tainted, then assume the opaque may have been constrained and just set it to error. + if let Some(guar) = borrowck_results.tainted_by_errors { + self.found = + Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(self.tcx, guar) }); + return; + } + + debug!(?borrowck_results.concrete_opaque_types); + if let Some(&concrete_type) = borrowck_results.concrete_opaque_types.get(&self.def_id) { debug!(?concrete_type, "found constraint"); if let Some(prev) = &mut self.found { if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() { diff --git a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs new file mode 100644 index 0000000000000..ae3d317ab4649 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +type Tait = impl Copy; +// Make sure that this TAIT isn't considered unconstrained... + +fn empty_opaque() -> Tait { + if false { + match empty_opaque() {} + //~^ ERROR non-empty + } + 0u8 +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr new file mode 100644 index 0000000000000..6cc5b7a8a0a88 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr @@ -0,0 +1,17 @@ +error[E0004]: non-exhaustive patterns: type `Tait` is non-empty + --> $DIR/unconstrained-due-to-bad-pattern.rs:8:15 + | +LL | match empty_opaque() {} + | ^^^^^^^^^^^^^^ + | + = note: the matched value is of type `Tait` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match empty_opaque() { +LL + _ => todo!(), +LL + } + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`.