Skip to content

Commit df80193

Browse files
committed
Auto merge of #4628 - flip1995:rustup, r=phansch
Rustup to rust-lang/rust#64874 TODO: - [x] replace `rvalue_promotable_map` in [1] - [ ] ~~fix [2] according to this comment rust-lang/rust#64874 (comment) this should be merged with `consume`, but I didn't figure out how to merge them, yet.~~ - [ ] ~~fix [3]; What to do with `LoanCause`?~~ [2]+[3] probably have to be resolved by a rewrite of the lint. #4628 (comment) [1] https://github.com/rust-lang/rust-clippy/blob/54bf4ffd626970e831bb80c037f804a3b3450835/clippy_lints/src/methods/mod.rs#L1292-L1299 [2] https://github.com/rust-lang/rust-clippy/blob/54bf4ffd626970e831bb80c037f804a3b3450835/clippy_lints/src/escape.rs#L126 [3] https://github.com/rust-lang/rust-clippy/blob/54bf4ffd626970e831bb80c037f804a3b3450835/clippy_lints/src/escape.rs#L166-L176 I could need some help with [1]. The purpose of this is to "don't lint for constant values". cc @matthewjasper For now I see what I can do with [2]. changelog: Temporary break `boxed_local` lint.
2 parents 54bf4ff + 3d39379 commit df80193

File tree

9 files changed

+71
-260
lines changed

9 files changed

+71
-260
lines changed

clippy_lints/src/escape.rs

+25-73
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxedLocal {
7878

7979
let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
8080
let region_scope_tree = &cx.tcx.region_scope_tree(fn_def_id);
81-
ExprUseVisitor::new(
82-
&mut v,
83-
cx.tcx,
84-
fn_def_id,
85-
cx.param_env,
86-
region_scope_tree,
87-
cx.tables,
88-
None,
89-
)
90-
.consume_body(body);
81+
ExprUseVisitor::new(&mut v, cx.tcx, fn_def_id, cx.param_env, region_scope_tree, cx.tables).consume_body(body);
9182

9283
for node in v.set {
9384
span_lint(
@@ -114,86 +105,47 @@ fn is_argument(map: &hir::map::Map<'_>, id: HirId) -> bool {
114105
}
115106

116107
impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
117-
fn consume(&mut self, _: HirId, _: Span, cmt: &cmt_<'tcx>, mode: ConsumeMode) {
108+
fn consume(&mut self, cmt: &cmt_<'tcx>, mode: ConsumeMode) {
118109
if let Categorization::Local(lid) = cmt.cat {
119-
if let Move(DirectRefMove) | Move(CaptureMove) = mode {
110+
if let ConsumeMode::Move = mode {
120111
// moved out or in. clearly can't be localized
121112
self.set.remove(&lid);
122113
}
123114
}
124-
}
125-
fn matched_pat(&mut self, _: &Pat, _: &cmt_<'tcx>, _: MatchMode) {}
126-
fn consume_pat(&mut self, consume_pat: &Pat, cmt: &cmt_<'tcx>, _: ConsumeMode) {
127115
let map = &self.cx.tcx.hir();
128-
if is_argument(map, consume_pat.hir_id) {
129-
// Skip closure arguments
130-
let parent_id = map.get_parent_node(consume_pat.hir_id);
131-
if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) {
132-
return;
133-
}
134-
135-
if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
136-
self.set.insert(consume_pat.hir_id);
137-
}
138-
return;
139-
}
140-
if let Categorization::Rvalue(..) = cmt.cat {
141-
if let Some(Node::Stmt(st)) = map.find(map.get_parent_node(cmt.hir_id)) {
142-
if let StmtKind::Local(ref loc) = st.kind {
143-
if let Some(ref ex) = loc.init {
144-
if let ExprKind::Box(..) = ex.kind {
145-
if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
146-
// let x = box (...)
147-
self.set.insert(consume_pat.hir_id);
148-
}
149-
// TODO Box::new
150-
// TODO vec![]
151-
// TODO "foo".to_owned() and friends
152-
}
153-
}
116+
if let Categorization::Local(lid) = cmt.cat {
117+
if let Some(Node::Binding(_)) = map.find(cmt.hir_id) {
118+
if self.set.contains(&lid) {
119+
// let y = x where x is known
120+
// remove x, insert y
121+
self.set.insert(cmt.hir_id);
122+
self.set.remove(&lid);
154123
}
155124
}
156125
}
126+
}
127+
128+
fn borrow(&mut self, cmt: &cmt_<'tcx>, _: ty::BorrowKind) {
157129
if let Categorization::Local(lid) = cmt.cat {
158-
if self.set.contains(&lid) {
159-
// let y = x where x is known
160-
// remove x, insert y
161-
self.set.insert(consume_pat.hir_id);
162-
self.set.remove(&lid);
163-
}
130+
self.set.remove(&lid);
164131
}
165132
}
166-
fn borrow(
167-
&mut self,
168-
_: HirId,
169-
_: Span,
170-
cmt: &cmt_<'tcx>,
171-
_: ty::Region<'_>,
172-
_: ty::BorrowKind,
173-
loan_cause: LoanCause,
174-
) {
175-
if let Categorization::Local(lid) = cmt.cat {
176-
match loan_cause {
177-
// `x.foo()`
178-
// Used without autoderef-ing (i.e., `x.clone()`).
179-
LoanCause::AutoRef |
180-
181-
// `&x`
182-
// `foo(&x)` where no extra autoref-ing is happening.
183-
LoanCause::AddrOf |
184133

185-
// `match x` can move.
186-
LoanCause::MatchDiscriminant => {
187-
self.set.remove(&lid);
188-
}
134+
fn mutate(&mut self, cmt: &cmt_<'tcx>) {
135+
let map = &self.cx.tcx.hir();
136+
if is_argument(map, cmt.hir_id) {
137+
// Skip closure arguments
138+
let parent_id = map.get_parent_node(cmt.hir_id);
139+
if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) {
140+
return;
141+
}
189142

190-
// Do nothing for matches, etc. These can't escape.
191-
_ => {}
143+
if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
144+
self.set.insert(cmt.hir_id);
192145
}
146+
return;
193147
}
194148
}
195-
fn decl_without_init(&mut self, _: HirId, _: Span) {}
196-
fn mutate(&mut self, _: HirId, _: Span, _: &cmt_<'tcx>, _: MutateMode) {}
197149
}
198150

199151
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {

clippy_lints/src/loops.rs

+7-14
Original file line numberDiff line numberDiff line change
@@ -1547,37 +1547,31 @@ struct MutatePairDelegate {
15471547
}
15481548

15491549
impl<'tcx> Delegate<'tcx> for MutatePairDelegate {
1550-
fn consume(&mut self, _: HirId, _: Span, _: &cmt_<'tcx>, _: ConsumeMode) {}
1550+
fn consume(&mut self, _: &cmt_<'tcx>, _: ConsumeMode) {}
15511551

1552-
fn matched_pat(&mut self, _: &Pat, _: &cmt_<'tcx>, _: MatchMode) {}
1553-
1554-
fn consume_pat(&mut self, _: &Pat, _: &cmt_<'tcx>, _: ConsumeMode) {}
1555-
1556-
fn borrow(&mut self, _: HirId, sp: Span, cmt: &cmt_<'tcx>, _: ty::Region<'_>, bk: ty::BorrowKind, _: LoanCause) {
1552+
fn borrow(&mut self, cmt: &cmt_<'tcx>, bk: ty::BorrowKind) {
15571553
if let ty::BorrowKind::MutBorrow = bk {
15581554
if let Categorization::Local(id) = cmt.cat {
15591555
if Some(id) == self.hir_id_low {
1560-
self.span_low = Some(sp)
1556+
self.span_low = Some(cmt.span)
15611557
}
15621558
if Some(id) == self.hir_id_high {
1563-
self.span_high = Some(sp)
1559+
self.span_high = Some(cmt.span)
15641560
}
15651561
}
15661562
}
15671563
}
15681564

1569-
fn mutate(&mut self, _: HirId, sp: Span, cmt: &cmt_<'tcx>, _: MutateMode) {
1565+
fn mutate(&mut self, cmt: &cmt_<'tcx>) {
15701566
if let Categorization::Local(id) = cmt.cat {
15711567
if Some(id) == self.hir_id_low {
1572-
self.span_low = Some(sp)
1568+
self.span_low = Some(cmt.span)
15731569
}
15741570
if Some(id) == self.hir_id_high {
1575-
self.span_high = Some(sp)
1571+
self.span_high = Some(cmt.span)
15761572
}
15771573
}
15781574
}
1579-
1580-
fn decl_without_init(&mut self, _: HirId, _: Span) {}
15811575
}
15821576

15831577
impl<'tcx> MutatePairDelegate {
@@ -1655,7 +1649,6 @@ fn check_for_mutation(
16551649
cx.param_env,
16561650
region_scope_tree,
16571651
cx.tables,
1658-
None,
16591652
)
16601653
.walk_expr(body);
16611654
delegate.mutation_span()

clippy_lints/src/methods/mod.rs

+7-16
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ use syntax::symbol::{sym, LocalInternedString, Symbol};
2121
use crate::utils::usage::mutated_variables;
2222
use crate::utils::{
2323
get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, in_macro, is_copy,
24-
is_ctor_function, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path,
25-
match_qpath, match_trait_method, match_type, match_var, method_calls, method_chain_args, paths, remove_blocks,
26-
return_ty, same_tys, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite,
27-
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, sugg, walk_ptrs_ty,
28-
walk_ptrs_ty_depth, SpanlessEq,
24+
is_ctor_or_promotable_const_function, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment,
25+
match_def_path, match_qpath, match_trait_method, match_type, match_var, method_calls, method_chain_args, paths,
26+
remove_blocks, return_ty, same_tys, single_segment_path, snippet, snippet_with_applicability,
27+
snippet_with_macro_callsite, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then,
28+
span_note_and_lint, sugg, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
2929
};
3030

3131
declare_clippy_lint! {
@@ -1281,22 +1281,13 @@ fn lint_or_fun_call<'a, 'tcx>(
12811281
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
12821282
let call_found = match &expr.kind {
12831283
// ignore enum and struct constructors
1284-
hir::ExprKind::Call(..) => !is_ctor_function(self.cx, expr),
1284+
hir::ExprKind::Call(..) => !is_ctor_or_promotable_const_function(self.cx, expr),
12851285
hir::ExprKind::MethodCall(..) => true,
12861286
_ => false,
12871287
};
12881288

12891289
if call_found {
1290-
// don't lint for constant values
1291-
let owner_def = self.cx.tcx.hir().get_parent_did(expr.hir_id);
1292-
let promotable = self
1293-
.cx
1294-
.tcx
1295-
.rvalue_promotable_map(owner_def)
1296-
.contains(&expr.hir_id.local_id);
1297-
if !promotable {
1298-
self.found |= true;
1299-
}
1290+
self.found |= true;
13001291
}
13011292

13021293
if !self.found {

clippy_lints/src/needless_pass_by_value.rs

+13-102
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
134134
spans_need_deref,
135135
..
136136
} = {
137-
let mut ctx = MovedVariablesCtxt::new(cx);
137+
let mut ctx = MovedVariablesCtxt::default();
138138
let region_scope_tree = &cx.tcx.region_scope_tree(fn_def_id);
139-
euv::ExprUseVisitor::new(
140-
&mut ctx,
141-
cx.tcx,
142-
fn_def_id,
143-
cx.param_env,
144-
region_scope_tree,
145-
cx.tables,
146-
None,
147-
)
148-
.consume_body(body);
139+
euv::ExprUseVisitor::new(&mut ctx, cx.tcx, fn_def_id, cx.param_env, region_scope_tree, cx.tables)
140+
.consume_body(body);
149141
ctx
150142
};
151143

@@ -325,115 +317,34 @@ fn requires_exact_signature(attrs: &[Attribute]) -> bool {
325317
})
326318
}
327319

328-
struct MovedVariablesCtxt<'a, 'tcx> {
329-
cx: &'a LateContext<'a, 'tcx>,
320+
#[derive(Default)]
321+
struct MovedVariablesCtxt {
330322
moved_vars: FxHashSet<HirId>,
331323
/// Spans which need to be prefixed with `*` for dereferencing the
332324
/// suggested additional reference.
333325
spans_need_deref: FxHashMap<HirId, FxHashSet<Span>>,
334326
}
335327

336-
impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
337-
fn new(cx: &'a LateContext<'a, 'tcx>) -> Self {
338-
Self {
339-
cx,
340-
moved_vars: FxHashSet::default(),
341-
spans_need_deref: FxHashMap::default(),
342-
}
343-
}
344-
345-
fn move_common(&mut self, _consume_id: HirId, _span: Span, cmt: &mc::cmt_<'tcx>) {
328+
impl MovedVariablesCtxt {
329+
fn move_common(&mut self, cmt: &mc::cmt_<'_>) {
346330
let cmt = unwrap_downcast_or_interior(cmt);
347331

348332
if let mc::Categorization::Local(vid) = cmt.cat {
349333
self.moved_vars.insert(vid);
350334
}
351335
}
352-
353-
fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: &mc::cmt_<'tcx>) {
354-
let cmt = unwrap_downcast_or_interior(cmt);
355-
356-
if let mc::Categorization::Local(vid) = cmt.cat {
357-
let mut id = matched_pat.hir_id;
358-
loop {
359-
let parent = self.cx.tcx.hir().get_parent_node(id);
360-
if id == parent {
361-
// no parent
362-
return;
363-
}
364-
id = parent;
365-
366-
if let Some(node) = self.cx.tcx.hir().find(id) {
367-
match node {
368-
Node::Expr(e) => {
369-
// `match` and `if let`
370-
if let ExprKind::Match(ref c, ..) = e.kind {
371-
self.spans_need_deref
372-
.entry(vid)
373-
.or_insert_with(FxHashSet::default)
374-
.insert(c.span);
375-
}
376-
},
377-
378-
Node::Stmt(s) => {
379-
// `let <pat> = x;`
380-
if_chain! {
381-
if let StmtKind::Local(ref local) = s.kind;
382-
then {
383-
self.spans_need_deref
384-
.entry(vid)
385-
.or_insert_with(FxHashSet::default)
386-
.insert(local.init
387-
.as_ref()
388-
.map(|e| e.span)
389-
.expect("`let` stmt without init aren't caught by match_pat"));
390-
}
391-
}
392-
},
393-
394-
_ => {},
395-
}
396-
}
397-
}
398-
}
399-
}
400336
}
401337

402-
impl<'a, 'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt<'a, 'tcx> {
403-
fn consume(&mut self, consume_id: HirId, consume_span: Span, cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) {
404-
if let euv::ConsumeMode::Move(_) = mode {
405-
self.move_common(consume_id, consume_span, cmt);
406-
}
407-
}
408-
409-
fn matched_pat(&mut self, matched_pat: &Pat, cmt: &mc::cmt_<'tcx>, mode: euv::MatchMode) {
410-
if let euv::MatchMode::MovingMatch = mode {
411-
self.move_common(matched_pat.hir_id, matched_pat.span, cmt);
412-
} else {
413-
self.non_moving_pat(matched_pat, cmt);
414-
}
415-
}
416-
417-
fn consume_pat(&mut self, consume_pat: &Pat, cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) {
418-
if let euv::ConsumeMode::Move(_) = mode {
419-
self.move_common(consume_pat.hir_id, consume_pat.span, cmt);
338+
impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
339+
fn consume(&mut self, cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) {
340+
if let euv::ConsumeMode::Move = mode {
341+
self.move_common(cmt);
420342
}
421343
}
422344

423-
fn borrow(
424-
&mut self,
425-
_: HirId,
426-
_: Span,
427-
_: &mc::cmt_<'tcx>,
428-
_: ty::Region<'_>,
429-
_: ty::BorrowKind,
430-
_: euv::LoanCause,
431-
) {
432-
}
433-
434-
fn mutate(&mut self, _: HirId, _: Span, _: &mc::cmt_<'tcx>, _: euv::MutateMode) {}
345+
fn borrow(&mut self, _: &mc::cmt_<'tcx>, _: ty::BorrowKind) {}
435346

436-
fn decl_without_init(&mut self, _: HirId, _: Span) {}
347+
fn mutate(&mut self, _: &mc::cmt_<'tcx>) {}
437348
}
438349

439350
fn unwrap_downcast_or_interior<'a, 'tcx>(mut cmt: &'a mc::cmt_<'tcx>) -> mc::cmt_<'tcx> {

clippy_lints/src/utils/mod.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -803,13 +803,15 @@ pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
803803
}
804804

805805
/// Checks if an expression is constructing a tuple-like enum variant or struct
806-
pub fn is_ctor_function(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
806+
pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
807807
if let ExprKind::Call(ref fun, _) = expr.kind {
808808
if let ExprKind::Path(ref qp) = fun.kind {
809-
return matches!(
810-
cx.tables.qpath_res(qp, fun.hir_id),
811-
def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(..), _)
812-
);
809+
let res = cx.tables.qpath_res(qp, fun.hir_id);
810+
return match res {
811+
def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(..), _) => true,
812+
def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
813+
_ => false,
814+
};
813815
}
814816
}
815817
false

0 commit comments

Comments
 (0)