Move special &str
handling to Constructor
and Fields
This commit is contained in:
parent
035c5213ae
commit
5853399aee
2 changed files with 21 additions and 21 deletions
|
@ -660,9 +660,10 @@ impl<'tcx> Constructor<'tcx> {
|
||||||
} else {
|
} else {
|
||||||
match pat.ty.kind() {
|
match pat.ty.kind() {
|
||||||
ty::Float(_) => FloatRange(value, value, RangeEnd::Included),
|
ty::Float(_) => FloatRange(value, value, RangeEnd::Included),
|
||||||
// In `expand_pattern`, we convert string literals to `&CONST` patterns with
|
// We make `&str` constants behave like `Deref` patterns, to be compatible
|
||||||
// `CONST` a pattern of type `str`. In truth this contains a constant of type
|
// with other `Deref` patterns. See also `Fields::extract_pattern_arguments`.
|
||||||
// `&str`.
|
ty::Ref(_, t, _) if t.is_str() => Single,
|
||||||
|
// In truth this carries a constant of type `&str`.
|
||||||
ty::Str => Str(value),
|
ty::Str => Str(value),
|
||||||
// All constants that can be structurally matched have already been expanded
|
// All constants that can be structurally matched have already been expanded
|
||||||
// into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
|
// into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
|
||||||
|
@ -1393,6 +1394,19 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
|
||||||
self.fields[i] = pat
|
self.fields[i] = pat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PatKind::Constant { .. } => match pat.ty.kind() {
|
||||||
|
ty::Ref(_, t, _) if t.is_str() => {
|
||||||
|
assert_eq!(self.len(), 1);
|
||||||
|
// We want a `&str` constant to behave like a `Deref` pattern, to be compatible
|
||||||
|
// with other `Deref` patterns. This could have been done in `const_to_pat`,
|
||||||
|
// but that causes issues with the rest of the matching code.
|
||||||
|
// The outer constructor is `&`, and the inner one carries the str value.
|
||||||
|
let mut new_pat = pat.clone();
|
||||||
|
new_pat.ty = t; // `t` is `str`, not `&str`
|
||||||
|
self.fields[0] = &*cx.pattern_arena.alloc(new_pat);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
self
|
self
|
||||||
|
|
|
@ -365,23 +365,9 @@ struct LiteralExpander;
|
||||||
impl<'tcx> PatternFolder<'tcx> for LiteralExpander {
|
impl<'tcx> PatternFolder<'tcx> for LiteralExpander {
|
||||||
fn fold_pattern(&mut self, pat: &Pat<'tcx>) -> Pat<'tcx> {
|
fn fold_pattern(&mut self, pat: &Pat<'tcx>) -> Pat<'tcx> {
|
||||||
debug!("fold_pattern {:?} {:?} {:?}", pat, pat.ty.kind(), pat.kind);
|
debug!("fold_pattern {:?} {:?} {:?}", pat, pat.ty.kind(), pat.kind);
|
||||||
match (pat.ty.kind(), pat.kind.as_ref()) {
|
match pat.kind.as_ref() {
|
||||||
(_, PatKind::Binding { subpattern: Some(s), .. }) => s.fold_with(self),
|
PatKind::Binding { subpattern: Some(s), .. } => s.fold_with(self),
|
||||||
(_, PatKind::AscribeUserType { subpattern: s, .. }) => s.fold_with(self),
|
PatKind::AscribeUserType { subpattern: s, .. } => s.fold_with(self),
|
||||||
(ty::Ref(_, t, _), PatKind::Constant { .. }) if t.is_str() => {
|
|
||||||
// Treat string literal patterns as deref patterns to a `str` constant, i.e.
|
|
||||||
// `&CONST`. This expands them like other const patterns. This could have been done
|
|
||||||
// in `const_to_pat`, but that causes issues with the rest of the matching code.
|
|
||||||
let mut new_pat = pat.super_fold_with(self);
|
|
||||||
// Make a fake const pattern of type `str` (instead of `&str`). That the carried
|
|
||||||
// constant value still knows it is of type `&str`.
|
|
||||||
new_pat.ty = t;
|
|
||||||
Pat {
|
|
||||||
kind: Box::new(PatKind::Deref { subpattern: new_pat }),
|
|
||||||
span: pat.span,
|
|
||||||
ty: pat.ty,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => pat.super_fold_with(self),
|
_ => pat.super_fold_with(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1183,7 +1169,7 @@ fn is_useful<'p, 'tcx>(
|
||||||
let ctor_wild_subpatterns = Fields::wildcards(pcx.cx, pcx.ty, &ctor);
|
let ctor_wild_subpatterns = Fields::wildcards(pcx.cx, pcx.ty, &ctor);
|
||||||
let spec_matrix =
|
let spec_matrix =
|
||||||
start_matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns);
|
start_matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns);
|
||||||
let v = v.pop_head_constructor(pcx.cx, &ctor_wild_subpatterns);
|
let v = v.pop_head_constructor(cx, &ctor_wild_subpatterns);
|
||||||
let usefulness =
|
let usefulness =
|
||||||
is_useful(cx, &spec_matrix, &v, witness_preference, hir_id, is_under_guard, false);
|
is_useful(cx, &spec_matrix, &v, witness_preference, hir_id, is_under_guard, false);
|
||||||
let usefulness =
|
let usefulness =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue