Skip to content

Commit afa75d6

Browse files
committed
exhaustively match during structural match checking
1 parent 769d12e commit afa75d6

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

src/librustc_mir_build/hair/pattern/const_to_pat.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
124124
"trait objects cannot be used in patterns".to_string()
125125
}
126126
traits::NonStructuralMatchTy::Param => {
127-
bug!("use of constant whose type is a parameter inside a pattern")
127+
bug!("use of a constant whose type is a parameter inside a pattern")
128+
}
129+
traits::NonStructuralMatchTy::Foreign => {
130+
bug!("use of a value of a foreign type inside a pattern")
128131
}
129132
};
130133

src/librustc_trait_selection/traits/structural_match.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub enum NonStructuralMatchTy<'tcx> {
1212
Adt(&'tcx AdtDef),
1313
Param,
1414
Dynamic,
15+
Foreign,
1516
}
1617

1718
/// This method traverses the structure of `ty`, trying to find an
@@ -142,6 +143,10 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
142143
self.found = Some(NonStructuralMatchTy::Dynamic);
143144
return true; // Stop visiting.
144145
}
146+
ty::Foreign(_) => {
147+
self.found = Some(NonStructuralMatchTy::Foreign);
148+
return true; // Stop visiting
149+
}
145150
ty::RawPtr(..) => {
146151
// structural-match ignores substructure of
147152
// `*const _`/`*mut _`, so skip `super_visit_with`.
@@ -162,7 +167,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
162167
return false;
163168
}
164169
ty::FnDef(..) | ty::FnPtr(..) => {
165-
// types of formals and return in `fn(_) -> _` are also irrelevant;
170+
// Types of formals and return in `fn(_) -> _` are also irrelevant;
166171
// so we do not recur into them via `super_visit_with`
167172
//
168173
// (But still tell caller to continue search.)
@@ -175,7 +180,33 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
175180
// for empty array.
176181
return false;
177182
}
178-
_ => {
183+
ty::Bool
184+
| ty::Char
185+
| ty::Int(_)
186+
| ty::Uint(_)
187+
| ty::Float(_)
188+
| ty::Str
189+
| ty::Never
190+
| ty::Error => {
191+
// These primitive types are always structural match.
192+
//
193+
// `Never` is kind of special here, but as it is not inhabitable, this should be fine.
194+
return false;
195+
}
196+
197+
ty::Array(..)
198+
| ty::Slice(_)
199+
| ty::Ref(..)
200+
| ty::Closure(..)
201+
| ty::Generator(..)
202+
| ty::GeneratorWitness(..)
203+
| ty::Tuple(..)
204+
| ty::Projection(..)
205+
| ty::UnnormalizedProjection(..)
206+
| ty::Opaque(..)
207+
| ty::Bound(..)
208+
| ty::Placeholder(_)
209+
| ty::Infer(_) => {
179210
ty.super_visit_with(self);
180211
return false;
181212
}

0 commit comments

Comments
 (0)