Remove refs from pat slices
This commit is contained in:
parent
26366828a4
commit
1537cd4fb1
12 changed files with 85 additions and 68 deletions
|
@ -1067,6 +1067,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
eq_sign_span: Span,
|
eq_sign_span: Span,
|
||||||
assignments: &mut Vec<hir::Stmt<'hir>>,
|
assignments: &mut Vec<hir::Stmt<'hir>>,
|
||||||
) -> &'hir hir::Pat<'hir> {
|
) -> &'hir hir::Pat<'hir> {
|
||||||
|
self.arena.alloc(self.destructure_assign_mut(lhs, eq_sign_span, assignments))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destructure_assign_mut(
|
||||||
|
&mut self,
|
||||||
|
lhs: &Expr,
|
||||||
|
eq_sign_span: Span,
|
||||||
|
assignments: &mut Vec<hir::Stmt<'hir>>,
|
||||||
|
) -> hir::Pat<'hir> {
|
||||||
match &lhs.kind {
|
match &lhs.kind {
|
||||||
// Underscore pattern.
|
// Underscore pattern.
|
||||||
ExprKind::Underscore => {
|
ExprKind::Underscore => {
|
||||||
|
@ -1080,7 +1089,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let (before, after) = pats.split_at(i);
|
let (before, after) = pats.split_at(i);
|
||||||
hir::PatKind::Slice(
|
hir::PatKind::Slice(
|
||||||
before,
|
before,
|
||||||
Some(self.pat_without_dbm(span, hir::PatKind::Wild)),
|
Some(self.arena.alloc(self.pat_without_dbm(span, hir::PatKind::Wild))),
|
||||||
after,
|
after,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1165,14 +1174,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let tuple_pat = hir::PatKind::Tuple(&[], Some(0));
|
let tuple_pat = hir::PatKind::Tuple(&[], Some(0));
|
||||||
return self.pat_without_dbm(lhs.span, tuple_pat);
|
return self.pat_without_dbm(lhs.span, tuple_pat);
|
||||||
} else {
|
} else {
|
||||||
return self.destructure_assign(e, eq_sign_span, assignments);
|
return self.destructure_assign_mut(e, eq_sign_span, assignments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
// Treat all other cases as normal lvalue.
|
// Treat all other cases as normal lvalue.
|
||||||
let ident = Ident::new(sym::lhs, lhs.span);
|
let ident = Ident::new(sym::lhs, lhs.span);
|
||||||
let (pat, binding) = self.pat_ident(lhs.span, ident);
|
let (pat, binding) = self.pat_ident_mut(lhs.span, ident);
|
||||||
let ident = self.expr_ident(lhs.span, ident, binding);
|
let ident = self.expr_ident(lhs.span, ident, binding);
|
||||||
let assign = hir::ExprKind::Assign(self.lower_expr(lhs), ident, eq_sign_span);
|
let assign = hir::ExprKind::Assign(self.lower_expr(lhs), ident, eq_sign_span);
|
||||||
let expr = self.expr(lhs.span, assign, ThinVec::new());
|
let expr = self.expr(lhs.span, assign, ThinVec::new());
|
||||||
|
@ -1191,7 +1200,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
ctx: &str,
|
ctx: &str,
|
||||||
eq_sign_span: Span,
|
eq_sign_span: Span,
|
||||||
assignments: &mut Vec<hir::Stmt<'hir>>,
|
assignments: &mut Vec<hir::Stmt<'hir>>,
|
||||||
) -> (&'hir [&'hir hir::Pat<'hir>], Option<(usize, Span)>) {
|
) -> (&'hir [hir::Pat<'hir>], Option<(usize, Span)>) {
|
||||||
let mut rest = None;
|
let mut rest = None;
|
||||||
let elements =
|
let elements =
|
||||||
self.arena.alloc_from_iter(elements.iter().enumerate().filter_map(|(i, e)| {
|
self.arena.alloc_from_iter(elements.iter().enumerate().filter_map(|(i, e)| {
|
||||||
|
@ -1204,7 +1213,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(self.destructure_assign(e, eq_sign_span, assignments))
|
Some(self.destructure_assign_mut(e, eq_sign_span, assignments))
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
(elements, rest)
|
(elements, rest)
|
||||||
|
|
|
@ -2577,21 +2577,35 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
|
self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) {
|
||||||
|
self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::Unannotated)
|
||||||
|
}
|
||||||
|
|
||||||
fn pat_ident_binding_mode(
|
fn pat_ident_binding_mode(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
bm: hir::BindingAnnotation,
|
bm: hir::BindingAnnotation,
|
||||||
) -> (&'hir hir::Pat<'hir>, hir::HirId) {
|
) -> (&'hir hir::Pat<'hir>, hir::HirId) {
|
||||||
|
let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
|
||||||
|
(self.arena.alloc(pat), hir_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pat_ident_binding_mode_mut(
|
||||||
|
&mut self,
|
||||||
|
span: Span,
|
||||||
|
ident: Ident,
|
||||||
|
bm: hir::BindingAnnotation,
|
||||||
|
) -> (hir::Pat<'hir>, hir::HirId) {
|
||||||
let hir_id = self.next_id();
|
let hir_id = self.next_id();
|
||||||
|
|
||||||
(
|
(
|
||||||
self.arena.alloc(hir::Pat {
|
hir::Pat {
|
||||||
hir_id,
|
hir_id,
|
||||||
kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None),
|
kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None),
|
||||||
span,
|
span,
|
||||||
default_binding_modes: true,
|
default_binding_modes: true,
|
||||||
}),
|
},
|
||||||
hir_id,
|
hir_id,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2609,13 +2623,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
|
fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
|
||||||
self.arena.alloc(hir::Pat {
|
hir::Pat { hir_id: self.next_id(), kind, span, default_binding_modes: false }
|
||||||
hir_id: self.next_id(),
|
|
||||||
kind,
|
|
||||||
span,
|
|
||||||
default_binding_modes: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_path(
|
fn ty_path(
|
||||||
|
|
|
@ -10,7 +10,11 @@ use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{source_map::Spanned, Span};
|
use rustc_span::{source_map::Spanned, Span};
|
||||||
|
|
||||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
crate fn lower_pat(&mut self, mut pattern: &Pat) -> &'hir hir::Pat<'hir> {
|
crate fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> {
|
||||||
|
self.arena.alloc(self.lower_pat_mut(pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
|
||||||
ensure_sufficient_stack(|| {
|
ensure_sufficient_stack(|| {
|
||||||
// loop here to avoid recursion
|
// loop here to avoid recursion
|
||||||
let node = loop {
|
let node = loop {
|
||||||
|
@ -34,7 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
PatKind::Or(ref pats) => {
|
PatKind::Or(ref pats) => {
|
||||||
break hir::PatKind::Or(
|
break hir::PatKind::Or(
|
||||||
self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))),
|
self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat_mut(x))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
PatKind::Path(ref qself, ref path) => {
|
PatKind::Path(ref qself, ref path) => {
|
||||||
|
@ -101,7 +105,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
&mut self,
|
&mut self,
|
||||||
pats: &[P<Pat>],
|
pats: &[P<Pat>],
|
||||||
ctx: &str,
|
ctx: &str,
|
||||||
) -> (&'hir [&'hir hir::Pat<'hir>], Option<usize>) {
|
) -> (&'hir [hir::Pat<'hir>], Option<usize>) {
|
||||||
let mut elems = Vec::with_capacity(pats.len());
|
let mut elems = Vec::with_capacity(pats.len());
|
||||||
let mut rest = None;
|
let mut rest = None;
|
||||||
|
|
||||||
|
@ -140,7 +144,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// It was not a sub-tuple pattern so lower it normally.
|
// It was not a sub-tuple pattern so lower it normally.
|
||||||
elems.push(self.lower_pat(pat));
|
elems.push(self.lower_pat_mut(pat));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, pat) in iter {
|
for (_, pat) in iter {
|
||||||
|
@ -149,7 +153,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// ...but there was one again, so error.
|
// ...but there was one again, so error.
|
||||||
self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx);
|
self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx);
|
||||||
} else {
|
} else {
|
||||||
elems.push(self.lower_pat(pat));
|
elems.push(self.lower_pat_mut(pat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,11 +193,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
|
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
|
||||||
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
|
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
|
||||||
prev_rest_span = Some(sub.span);
|
prev_rest_span = Some(sub.span);
|
||||||
slice = Some(lower_rest_sub(self, pat, bm, ident, sub));
|
slice = Some(self.arena.alloc(lower_rest_sub(self, pat, bm, ident, sub)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// It was not a subslice pattern so lower it normally.
|
// It was not a subslice pattern so lower it normally.
|
||||||
_ => before.push(self.lower_pat(pat)),
|
_ => before.push(self.lower_pat_mut(pat)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +218,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice");
|
self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice");
|
||||||
} else {
|
} else {
|
||||||
// Lower the pattern normally.
|
// Lower the pattern normally.
|
||||||
after.push(self.lower_pat(pat));
|
after.push(self.lower_pat_mut(pat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,17 +272,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
|
fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
|
||||||
self.pat_with_node_id_of(p, hir::PatKind::Wild)
|
self.arena.alloc(self.pat_with_node_id_of(p, hir::PatKind::Wild))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a `Pat` with the `HirId` of `p.id` lowered.
|
/// Construct a `Pat` with the `HirId` of `p.id` lowered.
|
||||||
fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
|
fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
|
||||||
self.arena.alloc(hir::Pat {
|
hir::Pat {
|
||||||
hir_id: self.lower_node_id(p.id),
|
hir_id: self.lower_node_id(p.id),
|
||||||
kind,
|
kind,
|
||||||
span: p.span,
|
span: p.span,
|
||||||
default_binding_modes: true,
|
default_binding_modes: true,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
|
/// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
|
||||||
|
|
|
@ -808,13 +808,13 @@ impl<'hir> Pat<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
use PatKind::*;
|
use PatKind::*;
|
||||||
match &self.kind {
|
match self.kind {
|
||||||
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
|
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
|
||||||
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
|
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
|
||||||
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
|
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
|
||||||
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
|
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
|
||||||
Slice(before, slice, after) => {
|
Slice(before, slice, after) => {
|
||||||
before.iter().chain(slice.iter()).chain(after.iter()).all(|p| p.walk_short_(it))
|
before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -836,13 +836,13 @@ impl<'hir> Pat<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
use PatKind::*;
|
use PatKind::*;
|
||||||
match &self.kind {
|
match self.kind {
|
||||||
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
|
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
|
||||||
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
|
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
|
||||||
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
|
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
|
||||||
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
|
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
|
||||||
Slice(before, slice, after) => {
|
Slice(before, slice, after) => {
|
||||||
before.iter().chain(slice.iter()).chain(after.iter()).for_each(|p| p.walk_(it))
|
before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -940,11 +940,11 @@ pub enum PatKind<'hir> {
|
||||||
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
|
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
|
||||||
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
|
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
|
||||||
/// `0 <= position <= subpats.len()`
|
/// `0 <= position <= subpats.len()`
|
||||||
TupleStruct(QPath<'hir>, &'hir [&'hir Pat<'hir>], Option<usize>),
|
TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], Option<usize>),
|
||||||
|
|
||||||
/// An or-pattern `A | B | C`.
|
/// An or-pattern `A | B | C`.
|
||||||
/// Invariant: `pats.len() >= 2`.
|
/// Invariant: `pats.len() >= 2`.
|
||||||
Or(&'hir [&'hir Pat<'hir>]),
|
Or(&'hir [Pat<'hir>]),
|
||||||
|
|
||||||
/// A path pattern for an unit struct/variant or a (maybe-associated) constant.
|
/// A path pattern for an unit struct/variant or a (maybe-associated) constant.
|
||||||
Path(QPath<'hir>),
|
Path(QPath<'hir>),
|
||||||
|
@ -952,7 +952,7 @@ pub enum PatKind<'hir> {
|
||||||
/// A tuple pattern (e.g., `(a, b)`).
|
/// A tuple pattern (e.g., `(a, b)`).
|
||||||
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
|
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
|
||||||
/// `0 <= position <= subpats.len()`
|
/// `0 <= position <= subpats.len()`
|
||||||
Tuple(&'hir [&'hir Pat<'hir>], Option<usize>),
|
Tuple(&'hir [Pat<'hir>], Option<usize>),
|
||||||
|
|
||||||
/// A `box` pattern.
|
/// A `box` pattern.
|
||||||
Box(&'hir Pat<'hir>),
|
Box(&'hir Pat<'hir>),
|
||||||
|
@ -975,7 +975,7 @@ pub enum PatKind<'hir> {
|
||||||
/// ```
|
/// ```
|
||||||
/// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
|
/// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
|
||||||
/// ```
|
/// ```
|
||||||
Slice(&'hir [&'hir Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [&'hir Pat<'hir>]),
|
Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
||||||
|
|
|
@ -325,7 +325,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
fn lower_tuple_subpats(
|
fn lower_tuple_subpats(
|
||||||
&mut self,
|
&mut self,
|
||||||
pats: &'tcx [&'tcx hir::Pat<'tcx>],
|
pats: &'tcx [hir::Pat<'tcx>],
|
||||||
expected_len: usize,
|
expected_len: usize,
|
||||||
gap_pos: Option<usize>,
|
gap_pos: Option<usize>,
|
||||||
) -> Vec<FieldPat<'tcx>> {
|
) -> Vec<FieldPat<'tcx>> {
|
||||||
|
@ -338,7 +338,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_patterns(&mut self, pats: &'tcx [&'tcx hir::Pat<'tcx>]) -> Vec<Pat<'tcx>> {
|
fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Vec<Pat<'tcx>> {
|
||||||
pats.iter().map(|p| self.lower_pattern(p)).collect()
|
pats.iter().map(|p| self.lower_pattern(p)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,9 +350,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
prefix: &'tcx [&'tcx hir::Pat<'tcx>],
|
prefix: &'tcx [hir::Pat<'tcx>],
|
||||||
slice: &'tcx Option<&'tcx hir::Pat<'tcx>>,
|
slice: &'tcx Option<&'tcx hir::Pat<'tcx>>,
|
||||||
suffix: &'tcx [&'tcx hir::Pat<'tcx>],
|
suffix: &'tcx [hir::Pat<'tcx>],
|
||||||
) -> PatKind<'tcx> {
|
) -> PatKind<'tcx> {
|
||||||
let prefix = self.lower_patterns(prefix);
|
let prefix = self.lower_patterns(prefix);
|
||||||
let slice = self.lower_opt_pattern(slice);
|
let slice = self.lower_opt_pattern(slice);
|
||||||
|
|
|
@ -864,7 +864,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
pat: &'tcx Pat<'tcx>,
|
pat: &'tcx Pat<'tcx>,
|
||||||
qpath: &'tcx hir::QPath<'tcx>,
|
qpath: &'tcx hir::QPath<'tcx>,
|
||||||
subpats: &'tcx [&'tcx Pat<'tcx>],
|
subpats: &'tcx [Pat<'tcx>],
|
||||||
ddpos: Option<usize>,
|
ddpos: Option<usize>,
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
def_bm: BindingMode,
|
def_bm: BindingMode,
|
||||||
|
@ -982,7 +982,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
pat_span: Span,
|
pat_span: Span,
|
||||||
res: Res,
|
res: Res,
|
||||||
qpath: &hir::QPath<'_>,
|
qpath: &hir::QPath<'_>,
|
||||||
subpats: &'tcx [&'tcx Pat<'tcx>],
|
subpats: &'tcx [Pat<'tcx>],
|
||||||
fields: &'tcx [ty::FieldDef],
|
fields: &'tcx [ty::FieldDef],
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
had_err: bool,
|
had_err: bool,
|
||||||
|
@ -1112,7 +1112,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fn check_pat_tuple(
|
fn check_pat_tuple(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
elements: &'tcx [&'tcx Pat<'tcx>],
|
elements: &'tcx [Pat<'tcx>],
|
||||||
ddpos: Option<usize>,
|
ddpos: Option<usize>,
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
def_bm: BindingMode,
|
def_bm: BindingMode,
|
||||||
|
@ -1746,9 +1746,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fn check_pat_slice(
|
fn check_pat_slice(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
before: &'tcx [&'tcx Pat<'tcx>],
|
before: &'tcx [Pat<'tcx>],
|
||||||
slice: Option<&'tcx Pat<'tcx>>,
|
slice: Option<&'tcx Pat<'tcx>>,
|
||||||
after: &'tcx [&'tcx Pat<'tcx>],
|
after: &'tcx [Pat<'tcx>],
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
def_bm: BindingMode,
|
def_bm: BindingMode,
|
||||||
ti: TopInfo<'tcx>,
|
ti: TopInfo<'tcx>,
|
||||||
|
|
|
@ -260,17 +260,12 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
|
||||||
PatKind::Wild | PatKind::Struct(..) => return kw::Underscore,
|
PatKind::Wild | PatKind::Struct(..) => return kw::Underscore,
|
||||||
PatKind::Binding(_, _, ident, _) => return ident.name,
|
PatKind::Binding(_, _, ident, _) => return ident.name,
|
||||||
PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
|
PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
|
||||||
PatKind::Or(ref pats) => pats
|
PatKind::Or(ref pats) => {
|
||||||
.iter()
|
pats.iter().map(|p| name_from_pat(p).to_string()).collect::<Vec<String>>().join(" | ")
|
||||||
.map(|p| name_from_pat(&**p).to_string())
|
}
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(" | "),
|
|
||||||
PatKind::Tuple(ref elts, _) => format!(
|
PatKind::Tuple(ref elts, _) => format!(
|
||||||
"({})",
|
"({})",
|
||||||
elts.iter()
|
elts.iter().map(|p| name_from_pat(p).to_string()).collect::<Vec<String>>().join(", ")
|
||||||
.map(|p| name_from_pat(&**p).to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(", ")
|
|
||||||
),
|
),
|
||||||
PatKind::Box(ref p) => return name_from_pat(&**p),
|
PatKind::Box(ref p) => return name_from_pat(&**p),
|
||||||
PatKind::Ref(ref p, _) => return name_from_pat(&**p),
|
PatKind::Ref(ref p, _) => return name_from_pat(&**p),
|
||||||
|
@ -282,9 +277,9 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
|
||||||
}
|
}
|
||||||
PatKind::Range(..) => return kw::Underscore,
|
PatKind::Range(..) => return kw::Underscore,
|
||||||
PatKind::Slice(ref begin, ref mid, ref end) => {
|
PatKind::Slice(ref begin, ref mid, ref end) => {
|
||||||
let begin = begin.iter().map(|p| name_from_pat(&**p).to_string());
|
let begin = begin.iter().map(|p| name_from_pat(p).to_string());
|
||||||
let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter();
|
let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter();
|
||||||
let end = end.iter().map(|p| name_from_pat(&**p).to_string());
|
let end = end.iter().map(|p| name_from_pat(p).to_string());
|
||||||
format!("[{}]", begin.chain(mid).chain(end).collect::<Vec<_>>().join(", "))
|
format!("[{}]", begin.chain(mid).chain(end).collect::<Vec<_>>().join(", "))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -61,13 +61,13 @@ fn lint_manual_unwrap_or<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||||
if let Some((idx, or_arm)) = arms.iter().enumerate().find(|(_, arm)| {
|
if let Some((idx, or_arm)) = arms.iter().enumerate().find(|(_, arm)| {
|
||||||
match arm.pat.kind {
|
match arm.pat.kind {
|
||||||
PatKind::Path(ref qpath) => is_lang_ctor(cx, qpath, OptionNone),
|
PatKind::Path(ref qpath) => is_lang_ctor(cx, qpath, OptionNone),
|
||||||
PatKind::TupleStruct(ref qpath, &[pat], _) =>
|
PatKind::TupleStruct(ref qpath, [pat], _) =>
|
||||||
matches!(pat.kind, PatKind::Wild) && is_lang_ctor(cx, qpath, ResultErr),
|
matches!(pat.kind, PatKind::Wild) && is_lang_ctor(cx, qpath, ResultErr),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let unwrap_arm = &arms[1 - idx];
|
let unwrap_arm = &arms[1 - idx];
|
||||||
if let PatKind::TupleStruct(ref qpath, &[unwrap_pat], _) = unwrap_arm.pat.kind;
|
if let PatKind::TupleStruct(ref qpath, [unwrap_pat], _) = unwrap_arm.pat.kind;
|
||||||
if is_lang_ctor(cx, qpath, OptionSome) || is_lang_ctor(cx, qpath, ResultOk);
|
if is_lang_ctor(cx, qpath, OptionSome) || is_lang_ctor(cx, qpath, ResultOk);
|
||||||
if let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind;
|
if let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind;
|
||||||
if path_to_local_id(unwrap_arm.body, binding_hir_id);
|
if path_to_local_id(unwrap_arm.body, binding_hir_id);
|
||||||
|
|
|
@ -625,7 +625,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
|
||||||
if let PatKind::TupleStruct(
|
if let PatKind::TupleStruct(
|
||||||
QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind;
|
QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind;
|
||||||
if args.len() == 1;
|
if args.len() == 1;
|
||||||
if let PatKind::Binding(_, arg, ..) = strip_pat_refs(args[0]).kind;
|
if let PatKind::Binding(_, arg, ..) = strip_pat_refs(&args[0]).kind;
|
||||||
let body = remove_blocks(arms[0].body);
|
let body = remove_blocks(arms[0].body);
|
||||||
if path_to_local_id(body, arg);
|
if path_to_local_id(body, arg);
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ fn detect_option_if_let_else<'tcx>(
|
||||||
if !is_else_clause(cx.tcx, expr);
|
if !is_else_clause(cx.tcx, expr);
|
||||||
if arms.len() == 2;
|
if arms.len() == 2;
|
||||||
if !is_result_ok(cx, cond_expr); // Don't lint on Result::ok because a different lint does it already
|
if !is_result_ok(cx, cond_expr); // Don't lint on Result::ok because a different lint does it already
|
||||||
if let PatKind::TupleStruct(struct_qpath, &[inner_pat], _) = &arms[0].pat.kind;
|
if let PatKind::TupleStruct(struct_qpath, [inner_pat], _) = &arms[0].pat.kind;
|
||||||
if is_lang_ctor(cx, struct_qpath, OptionSome);
|
if is_lang_ctor(cx, struct_qpath, OptionSome);
|
||||||
if let PatKind::Binding(bind_annotation, _, id, _) = &inner_pat.kind;
|
if let PatKind::Binding(bind_annotation, _, id, _) = &inner_pat.kind;
|
||||||
if !contains_return_break_continue_macro(arms[0].body);
|
if !contains_return_break_continue_macro(arms[0].body);
|
||||||
|
|
|
@ -258,7 +258,7 @@ fn get_variant<'a>(adt_def: &'a AdtDef, qpath: &QPath<'_>) -> Option<&'a Variant
|
||||||
|
|
||||||
fn find_first_mismatch_in_tuple<'tcx, I>(
|
fn find_first_mismatch_in_tuple<'tcx, I>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
pats: &[&Pat<'_>],
|
pats: &[Pat<'_>],
|
||||||
ty_iter_src: I,
|
ty_iter_src: I,
|
||||||
) -> Option<(Span, Mutability, Level)>
|
) -> Option<(Span, Mutability, Level)>
|
||||||
where
|
where
|
||||||
|
|
|
@ -255,7 +255,7 @@ pub fn in_macro(span: Span) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if given pattern is a wildcard (`_`)
|
/// Checks if given pattern is a wildcard (`_`)
|
||||||
pub fn is_wild<'tcx>(pat: &impl std::ops::Deref<Target = Pat<'tcx>>) -> bool {
|
pub fn is_wild(pat: &Pat<'_>) -> bool {
|
||||||
matches!(pat.kind, PatKind::Wild)
|
matches!(pat.kind, PatKind::Wild)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,8 +1023,8 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn are_refutable<'a, I: Iterator<Item = &'a Pat<'a>>>(cx: &LateContext<'_>, mut i: I) -> bool {
|
fn are_refutable<'a, I: IntoIterator<Item = &'a Pat<'a>>>(cx: &LateContext<'_>, i: I) -> bool {
|
||||||
i.any(|pat| is_refutable(cx, pat))
|
i.into_iter().any(|pat| is_refutable(cx, pat))
|
||||||
}
|
}
|
||||||
|
|
||||||
match pat.kind {
|
match pat.kind {
|
||||||
|
@ -1035,23 +1035,23 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
|
||||||
PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
|
PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
|
||||||
PatKind::Or(pats) => {
|
PatKind::Or(pats) => {
|
||||||
// TODO: should be the honest check, that pats is exhaustive set
|
// TODO: should be the honest check, that pats is exhaustive set
|
||||||
are_refutable(cx, pats.iter().map(|pat| &**pat))
|
are_refutable(cx, pats)
|
||||||
},
|
},
|
||||||
PatKind::Tuple(pats, _) => are_refutable(cx, pats.iter().map(|pat| &**pat)),
|
PatKind::Tuple(pats, _) => are_refutable(cx, pats),
|
||||||
PatKind::Struct(ref qpath, fields, _) => {
|
PatKind::Struct(ref qpath, fields, _) => {
|
||||||
is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| &*field.pat))
|
is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| &*field.pat))
|
||||||
},
|
},
|
||||||
PatKind::TupleStruct(ref qpath, pats, _) => {
|
PatKind::TupleStruct(ref qpath, pats, _) => {
|
||||||
is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats.iter().map(|pat| &**pat))
|
is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats)
|
||||||
},
|
},
|
||||||
PatKind::Slice(head, ref middle, tail) => {
|
PatKind::Slice(head, middle, tail) => {
|
||||||
match &cx.typeck_results().node_type(pat.hir_id).kind() {
|
match &cx.typeck_results().node_type(pat.hir_id).kind() {
|
||||||
rustc_ty::Slice(..) => {
|
rustc_ty::Slice(..) => {
|
||||||
// [..] is the only irrefutable slice pattern.
|
// [..] is the only irrefutable slice pattern.
|
||||||
!head.is_empty() || middle.is_none() || !tail.is_empty()
|
!head.is_empty() || middle.is_none() || !tail.is_empty()
|
||||||
},
|
},
|
||||||
rustc_ty::Array(..) => {
|
rustc_ty::Array(..) => {
|
||||||
are_refutable(cx, head.iter().chain(middle).chain(tail.iter()).map(|pat| &**pat))
|
are_refutable(cx, head.iter().chain(middle).chain(tail.iter()))
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
// unreachable!()
|
// unreachable!()
|
||||||
|
@ -1066,7 +1066,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
|
||||||
/// the function once on the given pattern.
|
/// the function once on the given pattern.
|
||||||
pub fn recurse_or_patterns<'tcx, F: FnMut(&'tcx Pat<'tcx>)>(pat: &'tcx Pat<'tcx>, mut f: F) {
|
pub fn recurse_or_patterns<'tcx, F: FnMut(&'tcx Pat<'tcx>)>(pat: &'tcx Pat<'tcx>, mut f: F) {
|
||||||
if let PatKind::Or(pats) = pat.kind {
|
if let PatKind::Or(pats) = pat.kind {
|
||||||
pats.iter().copied().for_each(f);
|
pats.iter().for_each(f);
|
||||||
} else {
|
} else {
|
||||||
f(pat);
|
f(pat);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue