Skip to content

Commit

Permalink
Be more conservative concerning structural_match
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed May 20, 2020
1 parent ecab35b commit 5a5017e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
9 changes: 9 additions & 0 deletions src/librustc_mir_build/hair/pattern/const_to_pat.rs
Expand Up @@ -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")
}
Expand Down
40 changes: 19 additions & 21 deletions src/librustc_trait_selection/traits/structural_match.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 5a5017e

Please sign in to comment.