This commit is contained in:
Yuki Okushi 2020-01-12 03:41:54 +09:00
parent 11fb749a96
commit 8a3a0ea2ea
2 changed files with 29 additions and 62 deletions

View File

@ -334,7 +334,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
let result = self let result = self
.lcx .lcx
.tcx .tcx
.const_eval_resolve(self.param_env, def_id, substs, None) .const_eval_resolve(self.param_env, def_id, substs, None, None)
.ok()?; .ok()?;
let result = miri_to_const(&result); let result = miri_to_const(&result);
if result.is_some() { if result.is_some() {

View File

@ -157,7 +157,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
let pred_arg = if_chain! { let pred_arg = if_chain! {
if let Some((pred_fn_def_id, pred_arg, pred_arg_ty, Some(res))) = if let Some((pred_fn_def_id, pred_arg, pred_arg_ty, Some(res))) =
is_call_with_ref_arg(cx, mir, &pred_terminator.kind); is_call_with_ref_arg(cx, mir, &pred_terminator.kind);
if res.base == mir::PlaceBase::Local(cloned); if res.local == cloned;
if match_def_path(cx, pred_fn_def_id, &paths::DEREF_TRAIT_METHOD); if match_def_path(cx, pred_fn_def_id, &paths::DEREF_TRAIT_METHOD);
if match_type(cx, pred_arg_ty, &paths::PATH_BUF) if match_type(cx, pred_arg_ty, &paths::PATH_BUF)
|| match_type(cx, pred_arg_ty, &paths::OS_STRING); || match_type(cx, pred_arg_ty, &paths::OS_STRING);
@ -264,7 +264,7 @@ fn is_call_with_ref_arg<'tcx>(
if_chain! { if_chain! {
if let mir::TerminatorKind::Call { func, args, destination, .. } = kind; if let mir::TerminatorKind::Call { func, args, destination, .. } = kind;
if args.len() == 1; if args.len() == 1;
if let mir::Operand::Move(mir::Place { base: mir::PlaceBase::Local(local), .. }) = &args[0]; if let mir::Operand::Move(mir::Place { local, .. }) = &args[0];
if let ty::FnDef(def_id, _) = func.ty(&*mir, cx.tcx).kind; if let ty::FnDef(def_id, _) = func.ty(&*mir, cx.tcx).kind;
if let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].ty(&*mir, cx.tcx)); if let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].ty(&*mir, cx.tcx));
if !is_copy(cx, inner_ty); if !is_copy(cx, inner_ty);
@ -288,14 +288,7 @@ fn find_stmt_assigns_to<'tcx>(
bb: mir::BasicBlock, bb: mir::BasicBlock,
) -> Option<(mir::Local, CannotMoveOut)> { ) -> Option<(mir::Local, CannotMoveOut)> {
let rvalue = mir.basic_blocks()[bb].statements.iter().rev().find_map(|stmt| { let rvalue = mir.basic_blocks()[bb].statements.iter().rev().find_map(|stmt| {
if let mir::StatementKind::Assign(box ( if let mir::StatementKind::Assign(box (mir::Place { local, .. }, v)) = &stmt.kind {
mir::Place {
base: mir::PlaceBase::Local(local),
..
},
v,
)) = &stmt.kind
{
return if *local == to_local { Some(v) } else { None }; return if *local == to_local { Some(v) } else { None };
} }
@ -333,25 +326,15 @@ fn base_local_and_movability<'tcx>(
// Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509. // Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.
let mut field = false; let mut field = false;
let PlaceRef { let PlaceRef { local, mut projection } = place.as_ref();
base: place_base, while let [base @ .., elem] = projection {
mut projection, projection = base;
} = place.as_ref(); deref |= matches!(elem, mir::ProjectionElem::Deref);
if let mir::PlaceBase::Local(local) = place_base { field |= matches!(elem, mir::ProjectionElem::Field(..))
while let [base @ .., elem] = projection { && has_drop(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
projection = base;
deref |= matches!(elem, mir::ProjectionElem::Deref);
field |= matches!(elem, mir::ProjectionElem::Field(..))
&& has_drop(
cx,
mir::Place::ty_from(place_base, projection, &mir.local_decls, cx.tcx).ty,
);
}
Some((*local, deref || field))
} else {
None
} }
Some((*local, deref || field))
} }
struct LocalUseVisitor { struct LocalUseVisitor {
@ -502,38 +485,28 @@ impl<'a, 'tcx> PossibleBorrowerVisitor<'a, 'tcx> {
impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> { impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> {
fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) { fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {
if let mir::PlaceBase::Local(lhs) = place.base { let lhs = place.local;
match rvalue { match rvalue {
mir::Rvalue::Ref(_, _, borrowed) => { mir::Rvalue::Ref(_, _, borrowed) => {
if let mir::PlaceBase::Local(borrowed_local) = borrowed.base { self.possible_borrower.add(borrowed.local, lhs);
self.possible_borrower.add(borrowed_local, lhs); },
other => {
if !ContainsRegion.visit_ty(place.ty(&self.body.local_decls, self.cx.tcx).ty) {
return;
}
rvalue_locals(other, |rhs| {
if lhs != rhs {
self.possible_borrower.add(rhs, lhs);
} }
}, });
other => { },
if !ContainsRegion.visit_ty(place.ty(&self.body.local_decls, self.cx.tcx).ty) {
return;
}
rvalue_locals(other, |rhs| {
if lhs != rhs {
self.possible_borrower.add(rhs, lhs);
}
});
},
}
} }
} }
fn visit_terminator(&mut self, terminator: &mir::Terminator<'_>, _loc: mir::Location) { fn visit_terminator(&mut self, terminator: &mir::Terminator<'_>, _loc: mir::Location) {
if let mir::TerminatorKind::Call { if let mir::TerminatorKind::Call {
args, args,
destination: destination: Some((mir::Place { local: dest, .. }, _)),
Some((
mir::Place {
base: mir::PlaceBase::Local(dest),
..
},
_,
)),
.. ..
} = &terminator.kind } = &terminator.kind
{ {
@ -547,9 +520,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> {
for op in args { for op in args {
match op { match op {
mir::Operand::Copy(p) | mir::Operand::Move(p) => { mir::Operand::Copy(p) | mir::Operand::Move(p) => {
if let mir::PlaceBase::Local(arg) = p.base { self.possible_borrower.add(p.local, *dest);
self.possible_borrower.add(arg, *dest);
}
}, },
_ => (), _ => (),
} }
@ -570,11 +541,7 @@ fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) {
use rustc::mir::Rvalue::*; use rustc::mir::Rvalue::*;
let mut visit_op = |op: &mir::Operand<'_>| match op { let mut visit_op = |op: &mir::Operand<'_>| match op {
mir::Operand::Copy(p) | mir::Operand::Move(p) => { mir::Operand::Copy(p) | mir::Operand::Move(p) => visit(p.local),
if let mir::PlaceBase::Local(l) = p.base {
visit(l)
}
},
_ => (), _ => (),
}; };