Skip to content

Rustup #4857

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 29, 2019
Merged

Rustup #4857

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions clippy_lints/src/escape.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use rustc::hir::intravisit as visit;
use rustc::hir::{self, *};
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::middle::expr_use_visitor::*;
use rustc::middle::mem_categorization::{cmt_, Categorization};
use rustc::ty::layout::LayoutOf;
use rustc::ty::{self, Ty};
use rustc::util::nodemap::HirIdSet;
use rustc::{declare_tool_lint, impl_lint_pass};
use rustc_typeck::expr_use_visitor::*;
use syntax::source_map::Span;

use crate::utils::span_lint;
Expand Down Expand Up @@ -77,8 +76,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxedLocal {
};

let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
let region_scope_tree = &cx.tcx.region_scope_tree(fn_def_id);
ExprUseVisitor::new(&mut v, cx.tcx, fn_def_id, cx.param_env, region_scope_tree, cx.tables).consume_body(body);
cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.tables).consume_body(body);
});

for node in v.set {
span_lint(
Expand All @@ -105,45 +105,49 @@ fn is_argument(map: &hir::map::Map<'_>, id: HirId) -> bool {
}

impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
fn consume(&mut self, cmt: &cmt_<'tcx>, mode: ConsumeMode) {
if let Categorization::Local(lid) = cmt.cat {
if let ConsumeMode::Move = mode {
// moved out or in. clearly can't be localized
self.set.remove(&lid);
}
}
let map = &self.cx.tcx.hir();
if let Categorization::Local(lid) = cmt.cat {
if let Some(Node::Binding(_)) = map.find(cmt.hir_id) {
if self.set.contains(&lid) {
// let y = x where x is known
// remove x, insert y
self.set.insert(cmt.hir_id);
fn consume(&mut self, cmt: &Place<'tcx>, mode: ConsumeMode) {
if cmt.projections.is_empty() {
if let PlaceBase::Local(lid) = cmt.base {
if let ConsumeMode::Move = mode {
// moved out or in. clearly can't be localized
self.set.remove(&lid);
}
let map = &self.cx.tcx.hir();
if let Some(Node::Binding(_)) = map.find(cmt.hir_id) {
if self.set.contains(&lid) {
// let y = x where x is known
// remove x, insert y
self.set.insert(cmt.hir_id);
self.set.remove(&lid);
}
}
}
}
}

fn borrow(&mut self, cmt: &cmt_<'tcx>, _: ty::BorrowKind) {
if let Categorization::Local(lid) = cmt.cat {
self.set.remove(&lid);
fn borrow(&mut self, cmt: &Place<'tcx>, _: ty::BorrowKind) {
if cmt.projections.is_empty() {
if let PlaceBase::Local(lid) = cmt.base {
self.set.remove(&lid);
}
}
}

fn mutate(&mut self, cmt: &cmt_<'tcx>) {
let map = &self.cx.tcx.hir();
if is_argument(map, cmt.hir_id) {
// Skip closure arguments
let parent_id = map.get_parent_node(cmt.hir_id);
if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) {
return;
}
fn mutate(&mut self, cmt: &Place<'tcx>) {
if cmt.projections.is_empty() {
let map = &self.cx.tcx.hir();
if is_argument(map, cmt.hir_id) {
// Skip closure arguments
let parent_id = map.get_parent_node(cmt.hir_id);
if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) {
return;
}

if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
self.set.insert(cmt.hir_id);
if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
self.set.insert(cmt.hir_id);
}
return;
}
return;
}
}
}
Expand Down
27 changes: 9 additions & 18 deletions clippy_lints/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ use rustc::{declare_lint_pass, declare_tool_lint};
use crate::consts::{constant, Constant};
use crate::utils::usage::mutated_variables;
use crate::utils::{is_type_diagnostic_item, qpath_res, sext, sugg};
use rustc::middle::expr_use_visitor::*;
use rustc::middle::mem_categorization::cmt_;
use rustc::middle::mem_categorization::Categorization;
use rustc::ty::subst::Subst;
use rustc::ty::{self, Ty};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::Applicability;
use rustc_typeck::expr_use_visitor::*;
use std::iter::{once, Iterator};
use std::mem;
use syntax::ast;
Expand Down Expand Up @@ -1586,11 +1584,11 @@ struct MutatePairDelegate {
}

impl<'tcx> Delegate<'tcx> for MutatePairDelegate {
fn consume(&mut self, _: &cmt_<'tcx>, _: ConsumeMode) {}
fn consume(&mut self, _: &Place<'tcx>, _: ConsumeMode) {}

fn borrow(&mut self, cmt: &cmt_<'tcx>, bk: ty::BorrowKind) {
fn borrow(&mut self, cmt: &Place<'tcx>, bk: ty::BorrowKind) {
if let ty::BorrowKind::MutBorrow = bk {
if let Categorization::Local(id) = cmt.cat {
if let PlaceBase::Local(id) = cmt.base {
if Some(id) == self.hir_id_low {
self.span_low = Some(cmt.span)
}
Expand All @@ -1601,8 +1599,8 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate {
}
}

fn mutate(&mut self, cmt: &cmt_<'tcx>) {
if let Categorization::Local(id) = cmt.cat {
fn mutate(&mut self, cmt: &Place<'tcx>) {
if let PlaceBase::Local(id) = cmt.base {
if Some(id) == self.hir_id_low {
self.span_low = Some(cmt.span)
}
Expand Down Expand Up @@ -1680,16 +1678,9 @@ fn check_for_mutation(
span_high: None,
};
let def_id = def_id::DefId::local(body.hir_id.owner);
let region_scope_tree = &cx.tcx.region_scope_tree(def_id);
ExprUseVisitor::new(
&mut delegate,
cx.tcx,
def_id,
cx.param_env,
region_scope_tree,
cx.tables,
)
.walk_expr(body);
cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(&mut delegate, &infcx, def_id, cx.param_env, cx.tables).walk_expr(body);
});
delegate.mutation_span()
}

Expand Down
32 changes: 9 additions & 23 deletions clippy_lints/src/needless_pass_by_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ use matches::matches;
use rustc::hir::intravisit::FnKind;
use rustc::hir::*;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::traits;
use rustc::ty::{self, RegionKind, TypeFoldable};
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::Applicability;
use rustc_target::spec::abi::Abi;
use rustc_typeck::expr_use_visitor as euv;
use std::borrow::Cow;
use syntax::ast::Attribute;
use syntax::errors::DiagnosticBuilder;
Expand Down Expand Up @@ -135,9 +134,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
..
} = {
let mut ctx = MovedVariablesCtxt::default();
let region_scope_tree = &cx.tcx.region_scope_tree(fn_def_id);
euv::ExprUseVisitor::new(&mut ctx, cx.tcx, fn_def_id, cx.param_env, region_scope_tree, cx.tables)
.consume_body(body);
cx.tcx.infer_ctxt().enter(|infcx| {
euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.tables).consume_body(body);
});
ctx
};

Expand Down Expand Up @@ -326,34 +325,21 @@ struct MovedVariablesCtxt {
}

impl MovedVariablesCtxt {
fn move_common(&mut self, cmt: &mc::cmt_<'_>) {
let cmt = unwrap_downcast_or_interior(cmt);

if let mc::Categorization::Local(vid) = cmt.cat {
fn move_common(&mut self, cmt: &euv::Place<'_>) {
if let euv::PlaceBase::Local(vid) = cmt.base {
self.moved_vars.insert(vid);
}
}
}

impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
fn consume(&mut self, cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) {
fn consume(&mut self, cmt: &euv::Place<'tcx>, mode: euv::ConsumeMode) {
if let euv::ConsumeMode::Move = mode {
self.move_common(cmt);
}
}

fn borrow(&mut self, _: &mc::cmt_<'tcx>, _: ty::BorrowKind) {}

fn mutate(&mut self, _: &mc::cmt_<'tcx>) {}
}
fn borrow(&mut self, _: &euv::Place<'tcx>, _: ty::BorrowKind) {}

fn unwrap_downcast_or_interior<'a, 'tcx>(mut cmt: &'a mc::cmt_<'tcx>) -> mc::cmt_<'tcx> {
loop {
match cmt.cat {
mc::Categorization::Downcast(ref c, _) | mc::Categorization::Interior(ref c, _) => {
cmt = c;
},
_ => return (*cmt).clone(),
}
}
fn mutate(&mut self, _: &euv::Place<'tcx>) {}
}
36 changes: 13 additions & 23 deletions clippy_lints/src/utils/usage.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use rustc::hir::def::Res;
use rustc::hir::*;
use rustc::lint::LateContext;
use rustc::middle::expr_use_visitor::*;
use rustc::middle::mem_categorization::cmt_;
use rustc::middle::mem_categorization::Categorization;
use rustc::ty;
use rustc_data_structures::fx::FxHashSet;
use rustc_typeck::expr_use_visitor::*;

/// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined.
pub fn mutated_variables<'a, 'tcx>(expr: &'tcx Expr, cx: &'a LateContext<'a, 'tcx>) -> Option<FxHashSet<HirId>> {
Expand All @@ -14,16 +12,9 @@ pub fn mutated_variables<'a, 'tcx>(expr: &'tcx Expr, cx: &'a LateContext<'a, 'tc
skip: false,
};
let def_id = def_id::DefId::local(expr.hir_id.owner);
let region_scope_tree = &cx.tcx.region_scope_tree(def_id);
ExprUseVisitor::new(
&mut delegate,
cx.tcx,
def_id,
cx.param_env,
region_scope_tree,
cx.tables,
)
.walk_expr(expr);
cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(&mut delegate, &infcx, def_id, cx.param_env, cx.tables).walk_expr(expr);
});

if delegate.skip {
return None;
Expand All @@ -46,33 +37,32 @@ struct MutVarsDelegate {

impl<'tcx> MutVarsDelegate {
#[allow(clippy::similar_names)]
fn update(&mut self, cat: &'tcx Categorization<'_>) {
match *cat {
Categorization::Local(id) => {
fn update(&mut self, cat: &Place<'tcx>) {
match cat.base {
PlaceBase::Local(id) => {
self.used_mutably.insert(id);
},
Categorization::Upvar(_) => {
PlaceBase::Upvar(_) => {
//FIXME: This causes false negatives. We can't get the `NodeId` from
//`Categorization::Upvar(_)`. So we search for any `Upvar`s in the
//`while`-body, not just the ones in the condition.
self.skip = true
},
Categorization::Deref(ref cmt, _) | Categorization::Interior(ref cmt, _) => self.update(&cmt.cat),
_ => {},
}
}
}

impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
fn consume(&mut self, _: &cmt_<'tcx>, _: ConsumeMode) {}
fn consume(&mut self, _: &Place<'tcx>, _: ConsumeMode) {}

fn borrow(&mut self, cmt: &cmt_<'tcx>, bk: ty::BorrowKind) {
fn borrow(&mut self, cmt: &Place<'tcx>, bk: ty::BorrowKind) {
if let ty::BorrowKind::MutBorrow = bk {
self.update(&cmt.cat)
self.update(&cmt)
}
}

fn mutate(&mut self, cmt: &cmt_<'tcx>) {
self.update(&cmt.cat)
fn mutate(&mut self, cmt: &Place<'tcx>) {
self.update(&cmt)
}
}