Skip to content

Commit

Permalink
exhaustively match during structural match checking
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed May 20, 2020
1 parent 692a26e commit 0385239
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
5 changes: 4 additions & 1 deletion src/librustc_mir_build/hair/pattern/const_to_pat.rs
Expand Up @@ -125,7 +125,10 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
"trait objects cannot be used in patterns".to_string()
}
traits::NonStructuralMatchTy::Param => {
bug!("use of constant whose type is a parameter inside a pattern")
bug!("use of a constant whose type is a parameter inside a pattern")
}
traits::NonStructuralMatchTy::Foreign => {
bug!("use of a value of a foreign type inside a pattern")
}
};

Expand Down
35 changes: 33 additions & 2 deletions src/librustc_trait_selection/traits/structural_match.rs
Expand Up @@ -13,6 +13,7 @@ pub enum NonStructuralMatchTy<'tcx> {
Adt(&'tcx AdtDef),
Param,
Dynamic,
Foreign,
}

/// This method traverses the structure of `ty`, trying to find an
Expand Down Expand Up @@ -143,6 +144,10 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
self.found = Some(NonStructuralMatchTy::Dynamic);
return true; // Stop visiting.
}
ty::Foreign(_) => {
self.found = Some(NonStructuralMatchTy::Foreign);
return true; // Stop visiting
}
ty::RawPtr(..) => {
// structural-match ignores substructure of
// `*const _`/`*mut _`, so skip `super_visit_with`.
Expand All @@ -163,7 +168,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
return false;
}
ty::FnDef(..) | ty::FnPtr(..) => {
// types of formals and return in `fn(_) -> _` are also irrelevant;
// Types of formals and return in `fn(_) -> _` are also irrelevant;
// so we do not recur into them via `super_visit_with`
//
// (But still tell caller to continue search.)
Expand All @@ -176,7 +181,33 @@ 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::Error => {
// 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::GeneratorWitness(..)
| ty::Tuple(..)
| ty::Projection(..)
| ty::UnnormalizedProjection(..)
| ty::Opaque(..)
| ty::Bound(..)
| ty::Placeholder(_)
| ty::Infer(_) => {
ty.super_visit_with(self);
return false;
}
Expand Down

0 comments on commit 0385239

Please sign in to comment.