From 5a5017ec634cef0ff11b40dd08fdd4572d605d01 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 13 May 2020 00:40:28 +0200 Subject: [PATCH] Be more conservative concerning `structural_match` --- .../hair/pattern/const_to_pat.rs | 9 +++++ .../traits/structural_match.rs | 40 +++++++++---------- 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 @@ fn to_pat( 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 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { 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 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { // 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;