Skip to content

Commit

Permalink
NLL: Suggest extraction of subcomputation into a new binding
Browse files Browse the repository at this point in the history
  • Loading branch information
KiChjang committed Aug 13, 2018
1 parent 0aa8d03 commit 44f13d9
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
29 changes: 27 additions & 2 deletions src/librustc_mir/borrow_check/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ use rustc::middle::region::ScopeTree;
use rustc::mir::VarBindingForm;
use rustc::mir::{BindingForm, BorrowKind, ClearCrossCrate, Field, Local};
use rustc::mir::{LocalDecl, LocalKind, Location, Operand, Place};
use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind};
use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind};
use rustc::ty;
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::sync::Lrc;
use rustc_errors::DiagnosticBuilder;
use syntax_pos::Span;

use super::borrow_set::BorrowData;
use super::{Context, MirBorrowckCtxt};
use super::{Context, ContextKind, MirBorrowckCtxt};
use super::{InitializationRequiringAction, PrefixSet};

use dataflow::move_paths::MovePathIndex;
Expand Down Expand Up @@ -372,6 +372,31 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {

self.explain_why_borrow_contains_point(context, issued_borrow, None, &mut err);

let bb = &self.mir[context.loc.block];
if let (&TerminatorKind::Call { ref args, .. }, ContextKind::AssignRhs) =
(&bb.terminator().kind, context.kind)
{
let stmt = &bb.statements[context.loc.statement_index];
let assigned_place = match stmt.kind {
StatementKind::Assign(ref place, _) => place,
_ => unreachable!(),
};

for arg in args {
match arg {
Operand::Copy(ref operand) | Operand::Move(ref operand) => {
if assigned_place == operand {
err.span_note(
bb.terminator().source_info.span,
&format!("consider extracting this into a `let`-binding")
);
}
}
Operand::Constant(..) => {}
}
}
}

err.buffer(&mut self.errors_buffer);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0502]: cannot borrow `buckets` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-suggest-extraction-of-subcomputation.rs:25:70
|
LL | buckets.slice_mut()[(key as usize).wrapping_add(22).wrapping_rem(buckets.sweep())] = 22;
| -----------------------------------------------------------------^^^^^^^----------
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| borrow later used here
|
note: consider extracting this into a `let`-binding
--> $DIR/borrowck-suggest-extraction-of-subcomputation.rs:25:70
|
LL | buckets.slice_mut()[(key as usize).wrapping_add(22).wrapping_rem(buckets.sweep())] = 22;
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

trait Sweep {
fn sweep(&self) -> usize;
}

trait SliceWrapper<T> {
fn slice(&self) -> &[T];
}

trait SliceWrapperMut<T> {
fn slice_mut(&mut self) -> &mut [T];
}

fn foo<B: SliceWrapper<u32> + SliceWrapperMut<u32> + Sweep>(mut buckets: B) {
let key = 0u32;
buckets.slice_mut()[(key as usize).wrapping_add(22).wrapping_rem(buckets.sweep())] = 22;
//~^ ERROR cannot borrow `buckets` as immutable
}

fn main() { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0502]: cannot borrow `buckets` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-suggest-extraction-of-subcomputation.rs:25:70
|
LL | buckets.slice_mut()[(key as usize).wrapping_add(22).wrapping_rem(buckets.sweep())] = 22;
| ------- ^^^^^^^ - mutable borrow ends here
| | |
| mutable borrow occurs here immutable borrow occurs here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.

0 comments on commit 44f13d9

Please sign in to comment.