about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-05-13 00:40:28 +0200
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-05-20 09:16:08 +0200
commit5a5017ec634cef0ff11b40dd08fdd4572d605d01 (patch)
treeb629e5f974ac6f504b096b76fd04ab2d29e75c7e
parentecab35b45a0d6d33beecbd11d7be50f2511cc4f0 (diff)
downloadrust-5a5017ec634cef0ff11b40dd08fdd4572d605d01.tar.gz
rust-5a5017ec634cef0ff11b40dd08fdd4572d605d01.zip
Be more conservative concerning `structural_match`
-rw-r--r--src/librustc_mir_build/hair/pattern/const_to_pat.rs9
-rw-r--r--src/librustc_trait_selection/traits/structural_match.rs40
2 files changed, 28 insertions, 21 deletions
diff --git a/src/librustc_mir_build/hair/pattern/const_to_pat.rs b/src/librustc_mir_build/hair/pattern/const_to_pat.rs
index 67e24a1333a..9e3f75fdc07 100644
--- a/src/librustc_mir_build/hair/pattern/const_to_pat.rs
+++ b/src/librustc_mir_build/hair/pattern/const_to_pat.rs
@@ -124,9 +124,18 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                     traits::NonStructuralMatchTy::Dynamic => {
                         "trait objects cannot be used in patterns".to_string()
                     }
+                    traits::NonStructuralMatchTy::Opaque => {
+                        "opaque types cannot be used in patterns".to_string()
+                    }
+                    traits::NonStructuralMatchTy::Generator => {
+                        "generators cannot be used in patterns".to_string()
+                    }
                     traits::NonStructuralMatchTy::Param => {
                         bug!("use of a constant whose type is a parameter inside a pattern")
                     }
+                    traits::NonStructuralMatchTy::Projection => {
+                        bug!("use of a constant whose type is a projection inside a pattern")
+                    }
                     traits::NonStructuralMatchTy::Foreign => {
                         bug!("use of a value of a foreign type inside a pattern")
                     }
diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/src/librustc_trait_selection/traits/structural_match.rs
index da207cf7d38..71fa46ccded 100644
--- a/src/librustc_trait_selection/traits/structural_match.rs
+++ b/src/librustc_trait_selection/traits/structural_match.rs
@@ -14,6 +14,9 @@ pub enum NonStructuralMatchTy<'tcx> {
     Param,
     Dynamic,
     Foreign,
+    Opaque,
+    Generator,
+    Projection,
 }
 
 /// This method traverses the structure of `ty`, trying to find an
@@ -148,6 +151,18 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
                 self.found = Some(NonStructuralMatchTy::Foreign);
                 return true; // Stop visiting
             }
+            ty::Opaque(..) => {
+                self.found = Some(NonStructuralMatchTy::Opaque);
+                return true;
+            }
+            ty::Projection(..) => {
+                self.found = Some(NonStructuralMatchTy::Projection);
+                return true;
+            }
+            ty::Generator(..) | ty::GeneratorWitness(..) => {
+                self.found = Some(NonStructuralMatchTy::Generator);
+                return true;
+            }
             ty::RawPtr(..) => {
                 // structural-match ignores substructure of
                 // `*const _`/`*mut _`, so skip `super_visit_with`.
@@ -181,39 +196,22 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
                 // for empty array.
                 return false;
             }
-            ty::Bool
-            | ty::Char
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Str
-            | ty::Never => {
+            ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => {
                 // These primitive types are always structural match.
                 //
                 // `Never` is kind of special here, but as it is not inhabitable, this should be fine.
                 return false;
             }
 
-            ty::Array(..)
-            | ty::Slice(_)
-            | ty::Ref(..)
-            | ty::Closure(..)
-            | ty::Generator(..)
-            | ty::Tuple(..)
-            | ty::Projection(..)
-            | ty::Opaque(..)
-            | ty::GeneratorWitness(..) => {
+            ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => {
                 ty.super_visit_with(self);
                 return false;
             }
-            | ty::Infer(_)
-            | ty::Placeholder(_)
-            | ty::UnnormalizedProjection(..)
-            | ty::Bound(..) => {
+            ty::Closure(..) | ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => {
                 bug!("unexpected type during structural-match checking: {:?}", ty);
             }
             ty::Error => {
-                self.tcx().delay_span_bug(self.span, "ty::Error in structural-match check");
+                self.tcx().sess.delay_span_bug(self.span, "ty::Error in structural-match check");
                 // We still want to check other types after encountering an error,
                 // as this may still emit relevant errors.
                 return false;