Skip to content

Commit 0385239

Browse files
committed
exhaustively match during structural match checking
1 parent 692a26e commit 0385239

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

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

src/librustc_trait_selection/traits/structural_match.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub enum NonStructuralMatchTy<'tcx> {
1313
Adt(&'tcx AdtDef),
1414
Param,
1515
Dynamic,
16+
Foreign,
1617
}
1718

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

0 commit comments

Comments
 (0)