Skip to content

Commit

Permalink
Remove refs from pat slices
Browse files Browse the repository at this point in the history
  • Loading branch information
camsteffen committed Jul 15, 2021
1 parent 2636682 commit 1537cd4
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 68 deletions.
19 changes: 14 additions & 5 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
eq_sign_span: Span,
assignments: &mut Vec<hir::Stmt<'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 {
// Underscore pattern.
ExprKind::Underscore => {
Expand All @@ -1080,7 +1089,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (before, after) = pats.split_at(i);
hir::PatKind::Slice(
before,
Some(self.pat_without_dbm(span, hir::PatKind::Wild)),
Some(self.arena.alloc(self.pat_without_dbm(span, hir::PatKind::Wild))),
after,
)
} else {
Expand Down Expand Up @@ -1165,14 +1174,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
let tuple_pat = hir::PatKind::Tuple(&[], Some(0));
return self.pat_without_dbm(lhs.span, tuple_pat);
} 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.
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 assign = hir::ExprKind::Assign(self.lower_expr(lhs), ident, eq_sign_span);
let expr = self.expr(lhs.span, assign, ThinVec::new());
Expand All @@ -1191,7 +1200,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ctx: &str,
eq_sign_span: Span,
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 elements =
self.arena.alloc_from_iter(elements.iter().enumerate().filter_map(|(i, e)| {
Expand All @@ -1204,7 +1213,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
None
} else {
Some(self.destructure_assign(e, eq_sign_span, assignments))
Some(self.destructure_assign_mut(e, eq_sign_span, assignments))
}
}));
(elements, rest)
Expand Down
27 changes: 18 additions & 9 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2577,21 +2577,35 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
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(
&mut self,
span: Span,
ident: Ident,
bm: hir::BindingAnnotation,
) -> (&'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();

(
self.arena.alloc(hir::Pat {
hir::Pat {
hir_id,
kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None),
span,
default_binding_modes: true,
}),
},
hir_id,
)
}
Expand All @@ -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> {
self.arena.alloc(hir::Pat {
hir_id: self.next_id(),
kind,
span,
default_binding_modes: false,
})
fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
hir::Pat { hir_id: self.next_id(), kind, span, default_binding_modes: false }
}

fn ty_path(
Expand Down
28 changes: 16 additions & 12 deletions compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ use rustc_span::symbol::Ident;
use rustc_span::{source_map::Spanned, Span};

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(|| {
// loop here to avoid recursion
let node = loop {
Expand All @@ -34,7 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
PatKind::Or(ref pats) => {
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) => {
Expand Down Expand Up @@ -101,7 +105,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
pats: &[P<Pat>],
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 rest = None;

Expand Down Expand Up @@ -140,7 +144,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}

// 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 {
Expand All @@ -149,7 +153,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// ...but there was one again, so error.
self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx);
} else {
elems.push(self.lower_pat(pat));
elems.push(self.lower_pat_mut(pat));
}
}

Expand Down Expand Up @@ -189,11 +193,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
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;
}
// It was not a subslice pattern so lower it normally.
_ => before.push(self.lower_pat(pat)),
_ => before.push(self.lower_pat_mut(pat)),
}
}

Expand All @@ -214,7 +218,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice");
} else {
// Lower the pattern normally.
after.push(self.lower_pat(pat));
after.push(self.lower_pat_mut(pat));
}
}

Expand Down Expand Up @@ -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> {
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.
fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
self.arena.alloc(hir::Pat {
fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
hir::Pat {
hir_id: self.lower_node_id(p.id),
kind,
span: p.span,
default_binding_modes: true,
})
}
}

/// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,13 +808,13 @@ impl<'hir> Pat<'hir> {
}

use PatKind::*;
match &self.kind {
match self.kind {
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.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)),
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))
}
}
}
Expand All @@ -836,13 +836,13 @@ impl<'hir> Pat<'hir> {
}

use PatKind::*;
match &self.kind {
match self.kind {
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.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)),
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))
}
}
}
Expand Down Expand Up @@ -940,19 +940,19 @@ pub enum PatKind<'hir> {
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
/// `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`.
/// 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.
Path(QPath<'hir>),

/// A tuple pattern (e.g., `(a, b)`).
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
/// `0 <= position <= subpats.len()`
Tuple(&'hir [&'hir Pat<'hir>], Option<usize>),
Tuple(&'hir [Pat<'hir>], Option<usize>),

/// A `box` pattern.
Box(&'hir Pat<'hir>),
Expand All @@ -975,7 +975,7 @@ pub enum PatKind<'hir> {
/// ```
/// 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)]
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {

fn lower_tuple_subpats(
&mut self,
pats: &'tcx [&'tcx hir::Pat<'tcx>],
pats: &'tcx [hir::Pat<'tcx>],
expected_len: usize,
gap_pos: Option<usize>,
) -> Vec<FieldPat<'tcx>> {
Expand All @@ -338,7 +338,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
.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()
}

Expand All @@ -350,9 +350,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
&mut self,
span: Span,
ty: Ty<'tcx>,
prefix: &'tcx [&'tcx hir::Pat<'tcx>],
prefix: &'tcx [hir::Pat<'tcx>],
slice: &'tcx Option<&'tcx hir::Pat<'tcx>>,
suffix: &'tcx [&'tcx hir::Pat<'tcx>],
suffix: &'tcx [hir::Pat<'tcx>],
) -> PatKind<'tcx> {
let prefix = self.lower_patterns(prefix);
let slice = self.lower_opt_pattern(slice);
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_typeck/src/check/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
pat: &'tcx Pat<'tcx>,
qpath: &'tcx hir::QPath<'tcx>,
subpats: &'tcx [&'tcx Pat<'tcx>],
subpats: &'tcx [Pat<'tcx>],
ddpos: Option<usize>,
expected: Ty<'tcx>,
def_bm: BindingMode,
Expand Down Expand Up @@ -982,7 +982,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat_span: Span,
res: Res,
qpath: &hir::QPath<'_>,
subpats: &'tcx [&'tcx Pat<'tcx>],
subpats: &'tcx [Pat<'tcx>],
fields: &'tcx [ty::FieldDef],
expected: Ty<'tcx>,
had_err: bool,
Expand Down Expand Up @@ -1112,7 +1112,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn check_pat_tuple(
&self,
span: Span,
elements: &'tcx [&'tcx Pat<'tcx>],
elements: &'tcx [Pat<'tcx>],
ddpos: Option<usize>,
expected: Ty<'tcx>,
def_bm: BindingMode,
Expand Down Expand Up @@ -1746,9 +1746,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn check_pat_slice(
&self,
span: Span,
before: &'tcx [&'tcx Pat<'tcx>],
before: &'tcx [Pat<'tcx>],
slice: Option<&'tcx Pat<'tcx>>,
after: &'tcx [&'tcx Pat<'tcx>],
after: &'tcx [Pat<'tcx>],
expected: Ty<'tcx>,
def_bm: BindingMode,
ti: TopInfo<'tcx>,
Expand Down
17 changes: 6 additions & 11 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,17 +260,12 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
PatKind::Wild | PatKind::Struct(..) => return kw::Underscore,
PatKind::Binding(_, _, ident, _) => return ident.name,
PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
PatKind::Or(ref pats) => pats
.iter()
.map(|p| name_from_pat(&**p).to_string())
.collect::<Vec<String>>()
.join(" | "),
PatKind::Or(ref pats) => {
pats.iter().map(|p| name_from_pat(p).to_string()).collect::<Vec<String>>().join(" | ")
}
PatKind::Tuple(ref elts, _) => format!(
"({})",
elts.iter()
.map(|p| name_from_pat(&**p).to_string())
.collect::<Vec<String>>()
.join(", ")
elts.iter().map(|p| name_from_pat(p).to_string()).collect::<Vec<String>>().join(", ")
),
PatKind::Box(ref p) => return name_from_pat(&**p),
PatKind::Ref(ref p, _) => return name_from_pat(&**p),
Expand All @@ -282,9 +277,9 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
}
PatKind::Range(..) => return kw::Underscore,
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 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(", "))
}
})
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_lints/src/manual_unwrap_or.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)| {
match arm.pat.kind {
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),
_ => false,
}
});
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 let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind;
if path_to_local_id(unwrap_arm.body, binding_hir_id);
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
if let PatKind::TupleStruct(
QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind;
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);
if path_to_local_id(body, arg);

Expand Down
Loading

0 comments on commit 1537cd4

Please sign in to comment.