about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-10-30 20:15:25 +0000
committerMichael Goulet <michael@errs.io>2023-10-30 20:16:22 +0000
commit48491c182be06aad6db5edfd60bdcab0917cb79d (patch)
tree847f717c6ca063e18a2c1721a91b7837f4eb71d3
parente6e931dda5fffbae0fd87c5b1af753cc95556880 (diff)
downloadrust-48491c182be06aad6db5edfd60bdcab0917cb79d.tar.gz
rust-48491c182be06aad6db5edfd60bdcab0917cb79d.zip
Also consider TAIT to be uncomputable if the MIR body is tainted
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr17
3 files changed, 42 insertions, 3 deletions
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 e8d5264c2b8..e8ab2651d72 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 00000000000..ae3d317ab46
--- /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 00000000000..6cc5b7a8a0a
--- /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`.