mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Unify expanded constants and named constants in PatKind
This commit is contained in:
parent
a5b4d458a1
commit
f563efec15
@ -645,7 +645,7 @@ impl<'tcx> Pat<'tcx> {
|
|||||||
| Binding { subpattern: Some(subpattern), .. }
|
| Binding { subpattern: Some(subpattern), .. }
|
||||||
| Deref { subpattern }
|
| Deref { subpattern }
|
||||||
| DerefPattern { subpattern, .. }
|
| DerefPattern { subpattern, .. }
|
||||||
| InlineConstant { subpattern, .. } => subpattern.walk_(it),
|
| ExpandedConstant { subpattern, .. } => subpattern.walk_(it),
|
||||||
Leaf { subpatterns } | Variant { subpatterns, .. } => {
|
Leaf { subpatterns } | Variant { subpatterns, .. } => {
|
||||||
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
|
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
|
||||||
}
|
}
|
||||||
@ -786,16 +786,18 @@ pub enum PatKind<'tcx> {
|
|||||||
/// * `String`, if `string_deref_patterns` is enabled.
|
/// * `String`, if `string_deref_patterns` is enabled.
|
||||||
Constant {
|
Constant {
|
||||||
value: mir::Const<'tcx>,
|
value: mir::Const<'tcx>,
|
||||||
/// The `const` item this constant came from, if any.
|
|
||||||
opt_def: Option<DefId>,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Inline constant found while lowering a pattern.
|
/// Inline or named constant found while lowering a pattern.
|
||||||
InlineConstant {
|
ExpandedConstant {
|
||||||
/// [LocalDefId] of the constant, we need this so that we have a
|
/// [DefId] of the constant, we need this so that we have a
|
||||||
/// reference that can be used by unsafety checking to visit nested
|
/// reference that can be used by unsafety checking to visit nested
|
||||||
/// unevaluated constants.
|
/// unevaluated constants. If the `DefId` doesn't correspond to a local
|
||||||
def: LocalDefId,
|
/// crate, it points at the `const` item.
|
||||||
|
def_id: DefId,
|
||||||
|
/// If `false`, then `def_id` points at a `const` item, otherwise it
|
||||||
|
/// corresponds to a local inline const.
|
||||||
|
is_inline: bool,
|
||||||
/// If the inline constant is used in a range pattern, this subpattern
|
/// If the inline constant is used in a range pattern, this subpattern
|
||||||
/// represents the range (if both ends are inline constants, there will
|
/// represents the range (if both ends are inline constants, there will
|
||||||
/// be multiple InlineConstant wrappers).
|
/// be multiple InlineConstant wrappers).
|
||||||
@ -1086,8 +1088,8 @@ mod size_asserts {
|
|||||||
static_assert_size!(Block, 48);
|
static_assert_size!(Block, 48);
|
||||||
static_assert_size!(Expr<'_>, 64);
|
static_assert_size!(Expr<'_>, 64);
|
||||||
static_assert_size!(ExprKind<'_>, 40);
|
static_assert_size!(ExprKind<'_>, 40);
|
||||||
static_assert_size!(Pat<'_>, 72);
|
static_assert_size!(Pat<'_>, 64);
|
||||||
static_assert_size!(PatKind<'_>, 56);
|
static_assert_size!(PatKind<'_>, 48);
|
||||||
static_assert_size!(Stmt<'_>, 48);
|
static_assert_size!(Stmt<'_>, 48);
|
||||||
static_assert_size!(StmtKind<'_>, 48);
|
static_assert_size!(StmtKind<'_>, 48);
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
@ -246,8 +246,8 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
|
|||||||
visitor.visit_pat(&subpattern.pattern);
|
visitor.visit_pat(&subpattern.pattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constant { value: _, opt_def: _ } => {}
|
Constant { value: _ } => {}
|
||||||
InlineConstant { def: _, subpattern } => visitor.visit_pat(subpattern),
|
ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern),
|
||||||
Range(_) => {}
|
Range(_) => {}
|
||||||
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
|
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
|
||||||
for subpattern in prefix.iter() {
|
for subpattern in prefix.iter() {
|
||||||
|
@ -144,7 +144,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
|
|||||||
let mut targets = Vec::new();
|
let mut targets = Vec::new();
|
||||||
for arm in rest {
|
for arm in rest {
|
||||||
let arm = &self.thir[*arm];
|
let arm = &self.thir[*arm];
|
||||||
let PatKind::Constant { value, opt_def: _ } = arm.pattern.kind else {
|
let PatKind::Constant { value } = arm.pattern.kind else {
|
||||||
return Err(ParseError {
|
return Err(ParseError {
|
||||||
span: arm.pattern.span,
|
span: arm.pattern.span,
|
||||||
item_description: format!("{:?}", arm.pattern.kind),
|
item_description: format!("{:?}", arm.pattern.kind),
|
||||||
|
@ -129,7 +129,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Constant { value, opt_def: _ } => TestCase::Constant { value },
|
PatKind::Constant { value } => TestCase::Constant { value },
|
||||||
|
|
||||||
PatKind::AscribeUserType {
|
PatKind::AscribeUserType {
|
||||||
ascription: thir::Ascription { ref annotation, variance },
|
ascription: thir::Ascription { ref annotation, variance },
|
||||||
@ -162,7 +162,11 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
|
|||||||
TestCase::Irrefutable { ascription: None, binding }
|
TestCase::Irrefutable { ascription: None, binding }
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::InlineConstant { subpattern: ref pattern, def, .. } => {
|
PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
|
||||||
|
subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
|
||||||
|
default_irrefutable()
|
||||||
|
}
|
||||||
|
PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
|
||||||
// Apply a type ascription for the inline constant to the value at `match_pair.place`
|
// Apply a type ascription for the inline constant to the value at `match_pair.place`
|
||||||
let ascription = place.map(|source| {
|
let ascription = place.map(|source| {
|
||||||
let span = pattern.span;
|
let span = pattern.span;
|
||||||
@ -173,7 +177,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
|
|||||||
})
|
})
|
||||||
.args;
|
.args;
|
||||||
let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
|
let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
|
||||||
def.to_def_id(),
|
def_id,
|
||||||
ty::UserArgs { args, user_self_ty: None },
|
ty::UserArgs { args, user_self_ty: None },
|
||||||
));
|
));
|
||||||
let annotation = ty::CanonicalUserTypeAnnotation {
|
let annotation = ty::CanonicalUserTypeAnnotation {
|
||||||
|
@ -917,7 +917,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
self.visit_primary_bindings(subpattern, subpattern_user_ty, f)
|
self.visit_primary_bindings(subpattern, subpattern_user_ty, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::InlineConstant { ref subpattern, .. } => {
|
PatKind::ExpandedConstant { ref subpattern, .. } => {
|
||||||
self.visit_primary_bindings(subpattern, pattern_user_ty, f)
|
self.visit_primary_bindings(subpattern, pattern_user_ty, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||||||
PatKind::Wild |
|
PatKind::Wild |
|
||||||
// these just wrap other patterns, which we recurse on below.
|
// these just wrap other patterns, which we recurse on below.
|
||||||
PatKind::Or { .. } |
|
PatKind::Or { .. } |
|
||||||
PatKind::InlineConstant { .. } |
|
PatKind::ExpandedConstant { .. } |
|
||||||
PatKind::AscribeUserType { .. } |
|
PatKind::AscribeUserType { .. } |
|
||||||
PatKind::Error(_) => {}
|
PatKind::Error(_) => {}
|
||||||
}
|
}
|
||||||
@ -386,8 +386,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||||||
visit::walk_pat(self, pat);
|
visit::walk_pat(self, pat);
|
||||||
self.inside_adt = old_inside_adt;
|
self.inside_adt = old_inside_adt;
|
||||||
}
|
}
|
||||||
PatKind::InlineConstant { def, .. } => {
|
PatKind::ExpandedConstant { def_id, is_inline, .. } => {
|
||||||
self.visit_inner_body(*def);
|
if let Some(def) = def_id.as_local()
|
||||||
|
&& *is_inline
|
||||||
|
{
|
||||||
|
self.visit_inner_body(def);
|
||||||
|
}
|
||||||
visit::walk_pat(self, pat);
|
visit::walk_pat(self, pat);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -670,11 +670,13 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
|
|||||||
let mut interpreted_as_const = None;
|
let mut interpreted_as_const = None;
|
||||||
let mut interpreted_as_const_sugg = None;
|
let mut interpreted_as_const_sugg = None;
|
||||||
|
|
||||||
if let PatKind::Constant { opt_def: Some(def_id), .. }
|
if let PatKind::ExpandedConstant { def_id, is_inline: false, .. }
|
||||||
| PatKind::AscribeUserType {
|
| PatKind::AscribeUserType {
|
||||||
subpattern: box Pat { kind: PatKind::Constant { opt_def: Some(def_id), .. }, .. },
|
subpattern:
|
||||||
|
box Pat { kind: PatKind::ExpandedConstant { def_id, is_inline: false, .. }, .. },
|
||||||
..
|
..
|
||||||
} = pat.kind
|
} = pat.kind
|
||||||
|
&& let DefKind::Const = self.tcx.def_kind(def_id)
|
||||||
{
|
{
|
||||||
let span = self.tcx.def_span(def_id);
|
let span = self.tcx.def_span(def_id);
|
||||||
let variable = self.tcx.item_name(def_id).to_string();
|
let variable = self.tcx.item_name(def_id).to_string();
|
||||||
@ -1145,7 +1147,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
|
|||||||
|
|
||||||
for &arm in arms {
|
for &arm in arms {
|
||||||
let arm = &thir.arms[arm];
|
let arm = &thir.arms[arm];
|
||||||
if let PatKind::Constant { opt_def: Some(def_id), .. } = arm.pattern.kind {
|
if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = arm.pattern.kind {
|
||||||
let const_name = cx.tcx.item_name(def_id);
|
let const_name = cx.tcx.item_name(def_id);
|
||||||
err.span_label(
|
err.span_label(
|
||||||
arm.pattern.span,
|
arm.pattern.span,
|
||||||
|
@ -266,7 +266,6 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
// optimization for now.
|
// optimization for now.
|
||||||
ty::Str => PatKind::Constant {
|
ty::Str => PatKind::Constant {
|
||||||
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
|
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
|
||||||
opt_def: None,
|
|
||||||
},
|
},
|
||||||
// All other references are converted into deref patterns and then recursively
|
// All other references are converted into deref patterns and then recursively
|
||||||
// convert the dereferenced constant to a pattern that is the sub-pattern of the
|
// convert the dereferenced constant to a pattern that is the sub-pattern of the
|
||||||
@ -312,17 +311,13 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
PatKind::Constant {
|
PatKind::Constant {
|
||||||
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
|
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
|
||||||
opt_def: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => {
|
ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => {
|
||||||
// The raw pointers we see here have been "vetted" by valtree construction to be
|
// The raw pointers we see here have been "vetted" by valtree construction to be
|
||||||
// just integers, so we simply allow them.
|
// just integers, so we simply allow them.
|
||||||
PatKind::Constant {
|
PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)) }
|
||||||
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
|
|
||||||
opt_def: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty::FnPtr(..) => {
|
ty::FnPtr(..) => {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
|
@ -149,15 +149,18 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||||||
None => Ok((None, None, None)),
|
None => Ok((None, None, None)),
|
||||||
Some(expr) => {
|
Some(expr) => {
|
||||||
let (kind, ascr, inline_const) = match self.lower_lit(expr) {
|
let (kind, ascr, inline_const) = match self.lower_lit(expr) {
|
||||||
PatKind::InlineConstant { subpattern, def } => {
|
PatKind::ExpandedConstant { subpattern, def_id, is_inline: true } => {
|
||||||
(subpattern.kind, None, Some(def))
|
(subpattern.kind, None, def_id.as_local())
|
||||||
|
}
|
||||||
|
PatKind::ExpandedConstant { subpattern, is_inline: false, .. } => {
|
||||||
|
(subpattern.kind, None, None)
|
||||||
}
|
}
|
||||||
PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
|
PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
|
||||||
(kind, Some(ascription), None)
|
(kind, Some(ascription), None)
|
||||||
}
|
}
|
||||||
kind => (kind, None, None),
|
kind => (kind, None, None),
|
||||||
};
|
};
|
||||||
let value = if let PatKind::Constant { value, opt_def: _ } = kind {
|
let value = if let PatKind::Constant { value } = kind {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
@ -251,7 +254,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||||||
(RangeEnd::Included, Some(Ordering::Less)) => {}
|
(RangeEnd::Included, Some(Ordering::Less)) => {}
|
||||||
// `x..=y` where `x == y` and `x` and `y` are finite.
|
// `x..=y` where `x == y` and `x` and `y` are finite.
|
||||||
(RangeEnd::Included, Some(Ordering::Equal)) if lo.is_finite() && hi.is_finite() => {
|
(RangeEnd::Included, Some(Ordering::Equal)) if lo.is_finite() && hi.is_finite() => {
|
||||||
kind = PatKind::Constant { value: lo.as_finite().unwrap(), opt_def: None };
|
kind = PatKind::Constant { value: lo.as_finite().unwrap() };
|
||||||
}
|
}
|
||||||
// `..=x` where `x == ty::MIN`.
|
// `..=x` where `x == ty::MIN`.
|
||||||
(RangeEnd::Included, Some(Ordering::Equal)) if !lo.is_finite() => {}
|
(RangeEnd::Included, Some(Ordering::Equal)) if !lo.is_finite() => {}
|
||||||
@ -288,7 +291,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
for def in [lo_inline, hi_inline].into_iter().flatten() {
|
for def in [lo_inline, hi_inline].into_iter().flatten() {
|
||||||
kind = PatKind::InlineConstant { def, subpattern: Box::new(Pat { span, ty, kind }) };
|
kind = PatKind::ExpandedConstant {
|
||||||
|
def_id: def.to_def_id(),
|
||||||
|
is_inline: true,
|
||||||
|
subpattern: Box::new(Pat { span, ty, kind }),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Ok(kind)
|
Ok(kind)
|
||||||
}
|
}
|
||||||
@ -562,10 +569,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
let args = self.typeck_results.node_args(id);
|
let args = self.typeck_results.node_args(id);
|
||||||
let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args });
|
let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args });
|
||||||
let mut pattern = self.const_to_pat(c, ty, id, span);
|
let subpattern = self.const_to_pat(c, ty, id, span);
|
||||||
if let PatKind::Constant { value, opt_def: None } = pattern.kind {
|
let pattern = if let hir::QPath::Resolved(None, path) = qpath
|
||||||
pattern.kind = PatKind::Constant { value, opt_def: Some(def_id) };
|
&& path.segments.len() == 1
|
||||||
}
|
{
|
||||||
|
// We only want to mark constants when referenced as bare names that could have been
|
||||||
|
// new bindings if the `const` didn't exist.
|
||||||
|
Box::new(Pat {
|
||||||
|
span,
|
||||||
|
ty,
|
||||||
|
kind: PatKind::ExpandedConstant { subpattern, def_id, is_inline: false },
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
subpattern
|
||||||
|
};
|
||||||
|
|
||||||
if !is_associated_const {
|
if !is_associated_const {
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -640,7 +657,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args };
|
let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args };
|
||||||
let subpattern = self.const_to_pat(ty::Const::new_unevaluated(self.tcx, ct), ty, id, span);
|
let subpattern = self.const_to_pat(ty::Const::new_unevaluated(self.tcx, ct), ty, id, span);
|
||||||
PatKind::InlineConstant { subpattern, def: def_id }
|
PatKind::ExpandedConstant { subpattern, def_id: def_id.to_def_id(), is_inline: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts literals, paths and negation of literals to patterns.
|
/// Converts literals, paths and negation of literals to patterns.
|
||||||
|
@ -702,14 +702,15 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
|||||||
self.print_pat(subpattern, depth_lvl + 2);
|
self.print_pat(subpattern, depth_lvl + 2);
|
||||||
print_indented!(self, "}", depth_lvl + 1);
|
print_indented!(self, "}", depth_lvl + 1);
|
||||||
}
|
}
|
||||||
PatKind::Constant { value, opt_def: _ } => {
|
PatKind::Constant { value } => {
|
||||||
print_indented!(self, "Constant {", depth_lvl + 1);
|
print_indented!(self, "Constant {", depth_lvl + 1);
|
||||||
print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
|
print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
|
||||||
print_indented!(self, "}", depth_lvl + 1);
|
print_indented!(self, "}", depth_lvl + 1);
|
||||||
}
|
}
|
||||||
PatKind::InlineConstant { def, subpattern } => {
|
PatKind::ExpandedConstant { def_id, is_inline, subpattern } => {
|
||||||
print_indented!(self, "InlineConstant {", depth_lvl + 1);
|
print_indented!(self, "ExpandedConstant {", depth_lvl + 1);
|
||||||
print_indented!(self, format!("def: {:?}", def), depth_lvl + 2);
|
print_indented!(self, format!("def_id: {def_id:?}"), depth_lvl + 2);
|
||||||
|
print_indented!(self, format!("is_inline: {is_inline:?}"), depth_lvl + 2);
|
||||||
print_indented!(self, "subpattern:", depth_lvl + 2);
|
print_indented!(self, "subpattern:", depth_lvl + 2);
|
||||||
self.print_pat(subpattern, depth_lvl + 2);
|
self.print_pat(subpattern, depth_lvl + 2);
|
||||||
print_indented!(self, "}", depth_lvl + 1);
|
print_indented!(self, "}", depth_lvl + 1);
|
||||||
|
@ -453,7 +453,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||||||
let fields: Vec<_>;
|
let fields: Vec<_>;
|
||||||
match &pat.kind {
|
match &pat.kind {
|
||||||
PatKind::AscribeUserType { subpattern, .. }
|
PatKind::AscribeUserType { subpattern, .. }
|
||||||
| PatKind::InlineConstant { subpattern, .. } => return self.lower_pat(subpattern),
|
| PatKind::ExpandedConstant { subpattern, .. } => return self.lower_pat(subpattern),
|
||||||
PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
|
PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
|
||||||
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
|
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
|
||||||
ctor = Wildcard;
|
ctor = Wildcard;
|
||||||
@ -536,7 +536,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PatKind::Constant { value, opt_def: _ } => {
|
PatKind::Constant { value } => {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Bool => {
|
ty::Bool => {
|
||||||
ctor = match value.try_eval_bool(cx.tcx, cx.param_env) {
|
ctor = match value.try_eval_bool(cx.tcx, cx.param_env) {
|
||||||
|
@ -370,7 +370,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match pat.kind {
|
match pat.kind {
|
||||||
thir::PatKind::Constant { value, opt_def: _ } => value.has_non_region_param(),
|
thir::PatKind::Constant { value } => value.has_non_region_param(),
|
||||||
thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => {
|
thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => {
|
||||||
lo.has_non_region_param() || hi.has_non_region_param()
|
lo.has_non_region_param() || hi.has_non_region_param()
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
mod foo {
|
mod foo {
|
||||||
pub const b: u8 = 2;
|
pub const b: u8 = 2;
|
||||||
//~^ missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable
|
//~^ missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable
|
||||||
pub const d: u8 = 2;
|
pub const d: (u8, u8) = (2, 1);
|
||||||
//~^ missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
|
//~^ missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11,6 +11,15 @@ use foo::d;
|
|||||||
const a: u8 = 2;
|
const a: u8 = 2;
|
||||||
//~^ missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
|
//~^ missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
struct S {
|
||||||
|
foo: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
const e: S = S {
|
||||||
|
foo: 0,
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = 4;
|
let a = 4;
|
||||||
//~^ ERROR refutable pattern in local binding
|
//~^ ERROR refutable pattern in local binding
|
||||||
@ -20,9 +29,15 @@ fn main() {
|
|||||||
//~^ ERROR refutable pattern in local binding
|
//~^ ERROR refutable pattern in local binding
|
||||||
//~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
|
//~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
|
||||||
//~| HELP introduce a variable instead
|
//~| HELP introduce a variable instead
|
||||||
let d = 4;
|
let d = (4, 4);
|
||||||
//~^ ERROR refutable pattern in local binding
|
//~^ ERROR refutable pattern in local binding
|
||||||
//~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
|
//~| patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered
|
||||||
//~| HELP introduce a variable instead
|
//~| HELP introduce a variable instead
|
||||||
|
let e = S {
|
||||||
|
//~^ ERROR refutable pattern in local binding
|
||||||
|
//~| pattern `S { foo: 1_u8..=u8::MAX }` not covered
|
||||||
|
//~| HELP introduce a variable instead
|
||||||
|
foo: 1,
|
||||||
|
};
|
||||||
fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115).
|
fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115).
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0005]: refutable pattern in local binding
|
error[E0005]: refutable pattern in local binding
|
||||||
--> $DIR/const-pattern-irrefutable.rs:15:9
|
--> $DIR/const-pattern-irrefutable.rs:24:9
|
||||||
|
|
|
|
||||||
LL | const a: u8 = 2;
|
LL | const a: u8 = 2;
|
||||||
| ----------- missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
|
| ----------- missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
|
||||||
@ -15,7 +15,7 @@ LL | let a = 4;
|
|||||||
= note: the matched value is of type `u8`
|
= note: the matched value is of type `u8`
|
||||||
|
|
||||||
error[E0005]: refutable pattern in local binding
|
error[E0005]: refutable pattern in local binding
|
||||||
--> $DIR/const-pattern-irrefutable.rs:19:9
|
--> $DIR/const-pattern-irrefutable.rs:28:9
|
||||||
|
|
|
|
||||||
LL | pub const b: u8 = 2;
|
LL | pub const b: u8 = 2;
|
||||||
| --------------- missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable
|
| --------------- missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable
|
||||||
@ -31,21 +31,42 @@ LL | let c = 4;
|
|||||||
= note: the matched value is of type `u8`
|
= note: the matched value is of type `u8`
|
||||||
|
|
||||||
error[E0005]: refutable pattern in local binding
|
error[E0005]: refutable pattern in local binding
|
||||||
--> $DIR/const-pattern-irrefutable.rs:23:9
|
--> $DIR/const-pattern-irrefutable.rs:32:9
|
||||||
|
|
|
|
||||||
LL | pub const d: u8 = 2;
|
LL | pub const d: (u8, u8) = (2, 1);
|
||||||
| --------------- missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
|
| --------------------- missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
|
||||||
...
|
...
|
||||||
LL | let d = 4;
|
LL | let d = (4, 4);
|
||||||
| ^
|
| ^
|
||||||
| |
|
| |
|
||||||
| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
|
| patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered
|
||||||
| help: introduce a variable instead: `d_var`
|
| help: introduce a variable instead: `d_var`
|
||||||
|
|
|
|
||||||
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||||
= note: the matched value is of type `u8`
|
= note: the matched value is of type `(u8, u8)`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0005]: refutable pattern in local binding
|
||||||
|
--> $DIR/const-pattern-irrefutable.rs:36:9
|
||||||
|
|
|
||||||
|
LL | const e: S = S {
|
||||||
|
| ---------- missing patterns are not covered because `e` is interpreted as a constant pattern, not a new variable
|
||||||
|
...
|
||||||
|
LL | let e = S {
|
||||||
|
| ^
|
||||||
|
| |
|
||||||
|
| pattern `S { foo: 1_u8..=u8::MAX }` not covered
|
||||||
|
| help: introduce a variable instead: `e_var`
|
||||||
|
|
|
||||||
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||||
|
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||||
|
note: `S` defined here
|
||||||
|
--> $DIR/const-pattern-irrefutable.rs:15:8
|
||||||
|
|
|
||||||
|
LL | struct S {
|
||||||
|
| ^
|
||||||
|
= note: the matched value is of type `S`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0005`.
|
For more information about this error, try `rustc --explain E0005`.
|
||||||
|
@ -3,8 +3,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
|
|||||||
|
|
|
|
||||||
LL | match &[][..] {
|
LL | match &[][..] {
|
||||||
| ^^^^^^^ patterns `&[]` and `&[_, _, ..]` not covered
|
| ^^^^^^^ patterns `&[]` and `&[_, _, ..]` not covered
|
||||||
|
LL |
|
||||||
|
LL | E_SL => {}
|
||||||
|
| ---- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `E_SL`
|
||||||
|
|
|
|
||||||
= note: the matched value is of type `&[E]`
|
= note: the matched value is of type `&[E]`
|
||||||
|
note: constant `E_SL` defined here
|
||||||
|
--> $DIR/incomplete-slice.rs:6:1
|
||||||
|
|
|
||||||
|
LL | const E_SL: &[E] = &[E::A];
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
help: if you meant to introduce a binding, use a different name
|
||||||
|
|
|
||||||
|
LL | E_SL_var => {}
|
||||||
|
| ++++
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||||
|
|
|
|
||||||
LL ~ E_SL => {},
|
LL ~ E_SL => {},
|
||||||
|
@ -3,8 +3,20 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered
|
|||||||
|
|
|
|
||||||
LL | match (true, false) {
|
LL | match (true, false) {
|
||||||
| ^^^^^^^^^^^^^ pattern `(true, false)` not covered
|
| ^^^^^^^^^^^^^ pattern `(true, false)` not covered
|
||||||
|
LL |
|
||||||
|
LL | TRUE_TRUE => (),
|
||||||
|
| --------- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `TRUE_TRUE`
|
||||||
|
|
|
|
||||||
= note: the matched value is of type `(bool, bool)`
|
= note: the matched value is of type `(bool, bool)`
|
||||||
|
note: constant `TRUE_TRUE` defined here
|
||||||
|
--> $DIR/match-arm-statics-2.rs:14:1
|
||||||
|
|
|
||||||
|
LL | const TRUE_TRUE: (bool, bool) = (true, true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: if you meant to introduce a binding, use a different name
|
||||||
|
|
|
||||||
|
LL | TRUE_TRUE_var => (),
|
||||||
|
| ++++
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||||
|
|
|
|
||||||
LL ~ (false, true) => (),
|
LL ~ (false, true) => (),
|
||||||
|
@ -199,8 +199,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
|
|||||||
|
|
|
|
||||||
LL | match s {
|
LL | match s {
|
||||||
| ^ patterns `&[]` and `&[_, _, ..]` not covered
|
| ^ patterns `&[]` and `&[_, _, ..]` not covered
|
||||||
|
LL |
|
||||||
|
LL | CONST => {}
|
||||||
|
| ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
|
||||||
|
|
|
|
||||||
= note: the matched value is of type `&[bool]`
|
= note: the matched value is of type `&[bool]`
|
||||||
|
note: constant `CONST` defined here
|
||||||
|
--> $DIR/slice-patterns-exhaustiveness.rs:88:5
|
||||||
|
|
|
||||||
|
LL | const CONST: &[bool] = &[true];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: if you meant to introduce a binding, use a different name
|
||||||
|
|
|
||||||
|
LL | CONST_var => {}
|
||||||
|
| ++++
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||||
|
|
|
|
||||||
LL ~ CONST => {},
|
LL ~ CONST => {},
|
||||||
@ -212,8 +224,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
|
|||||||
|
|
|
|
||||||
LL | match s {
|
LL | match s {
|
||||||
| ^ patterns `&[]` and `&[_, _, ..]` not covered
|
| ^ patterns `&[]` and `&[_, _, ..]` not covered
|
||||||
|
LL |
|
||||||
|
LL | CONST => {}
|
||||||
|
| ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
|
||||||
|
|
|
|
||||||
= note: the matched value is of type `&[bool]`
|
= note: the matched value is of type `&[bool]`
|
||||||
|
note: constant `CONST` defined here
|
||||||
|
--> $DIR/slice-patterns-exhaustiveness.rs:88:5
|
||||||
|
|
|
||||||
|
LL | const CONST: &[bool] = &[true];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: if you meant to introduce a binding, use a different name
|
||||||
|
|
|
||||||
|
LL | CONST_var => {}
|
||||||
|
| ++++
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||||
|
|
|
|
||||||
LL ~ &[false] => {},
|
LL ~ &[false] => {},
|
||||||
@ -225,8 +249,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
|
|||||||
|
|
|
|
||||||
LL | match s {
|
LL | match s {
|
||||||
| ^ patterns `&[]` and `&[_, _, ..]` not covered
|
| ^ patterns `&[]` and `&[_, _, ..]` not covered
|
||||||
|
...
|
||||||
|
LL | CONST => {}
|
||||||
|
| ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
|
||||||
|
|
|
|
||||||
= note: the matched value is of type `&[bool]`
|
= note: the matched value is of type `&[bool]`
|
||||||
|
note: constant `CONST` defined here
|
||||||
|
--> $DIR/slice-patterns-exhaustiveness.rs:88:5
|
||||||
|
|
|
||||||
|
LL | const CONST: &[bool] = &[true];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: if you meant to introduce a binding, use a different name
|
||||||
|
|
|
||||||
|
LL | CONST_var => {}
|
||||||
|
| ++++
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||||
|
|
|
|
||||||
LL ~ CONST => {},
|
LL ~ CONST => {},
|
||||||
@ -238,8 +274,20 @@ error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
|
|||||||
|
|
|
|
||||||
LL | match s {
|
LL | match s {
|
||||||
| ^ pattern `&[_, _, ..]` not covered
|
| ^ pattern `&[_, _, ..]` not covered
|
||||||
|
...
|
||||||
|
LL | CONST => {}
|
||||||
|
| ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
|
||||||
|
|
|
|
||||||
= note: the matched value is of type `&[bool]`
|
= note: the matched value is of type `&[bool]`
|
||||||
|
note: constant `CONST` defined here
|
||||||
|
--> $DIR/slice-patterns-exhaustiveness.rs:88:5
|
||||||
|
|
|
||||||
|
LL | const CONST: &[bool] = &[true];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: if you meant to introduce a binding, use a different name
|
||||||
|
|
|
||||||
|
LL | CONST_var => {}
|
||||||
|
| ++++
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||||
|
|
|
|
||||||
LL ~ CONST => {},
|
LL ~ CONST => {},
|
||||||
@ -251,8 +299,20 @@ error[E0004]: non-exhaustive patterns: `&[false]` not covered
|
|||||||
|
|
|
|
||||||
LL | match s {
|
LL | match s {
|
||||||
| ^ pattern `&[false]` not covered
|
| ^ pattern `&[false]` not covered
|
||||||
|
...
|
||||||
|
LL | CONST => {}
|
||||||
|
| ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
|
||||||
|
|
|
|
||||||
= note: the matched value is of type `&[bool]`
|
= note: the matched value is of type `&[bool]`
|
||||||
|
note: constant `CONST` defined here
|
||||||
|
--> $DIR/slice-patterns-exhaustiveness.rs:88:5
|
||||||
|
|
|
||||||
|
LL | const CONST: &[bool] = &[true];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: if you meant to introduce a binding, use a different name
|
||||||
|
|
|
||||||
|
LL | CONST_var => {}
|
||||||
|
| ++++
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||||
|
|
|
|
||||||
LL ~ &[_, _, ..] => {},
|
LL ~ &[_, _, ..] => {},
|
||||||
@ -264,8 +324,20 @@ error[E0004]: non-exhaustive patterns: `&[false]` not covered
|
|||||||
|
|
|
|
||||||
LL | match s1 {
|
LL | match s1 {
|
||||||
| ^^ pattern `&[false]` not covered
|
| ^^ pattern `&[false]` not covered
|
||||||
|
LL |
|
||||||
|
LL | CONST1 => {}
|
||||||
|
| ------ this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST1`
|
||||||
|
|
|
|
||||||
= note: the matched value is of type `&[bool; 1]`
|
= note: the matched value is of type `&[bool; 1]`
|
||||||
|
note: constant `CONST1` defined here
|
||||||
|
--> $DIR/slice-patterns-exhaustiveness.rs:124:5
|
||||||
|
|
|
||||||
|
LL | const CONST1: &[bool; 1] = &[true];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: if you meant to introduce a binding, use a different name
|
||||||
|
|
|
||||||
|
LL | CONST1_var => {}
|
||||||
|
| ++++
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||||
|
|
|
|
||||||
LL ~ CONST1 => {},
|
LL ~ CONST1 => {},
|
||||||
|
Loading…
Reference in New Issue
Block a user