Skip to content

Commit d123188

Browse files
author
Cameron Zwarich
committed
Clean up check_loans.
Refactor a number of functions in check_loans to take node IDs and spans rather than taking expressions directly. Also rename some variables to make them less ambiguous. This is the first step towards using ExprUseVisitor in check_loans, as now some of the interfaces more closely match those used in ExprUseVisitor.
1 parent 071e22e commit d123188

File tree

1 file changed

+48
-37
lines changed

1 file changed

+48
-37
lines changed

src/librustc/middle/borrowck/check_loans.rs

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -385,37 +385,47 @@ impl<'a> CheckLoanCtxt<'a> {
385385
});
386386
}
387387

388-
pub fn check_assignment(&self, expr: &ast::Expr) {
388+
pub fn check_assignment_expr(&self, expr: &ast::Expr) {
389+
let assignment_id = expr.id;
390+
let assignment_span = expr.span;
391+
389392
// We don't use cat_expr() here because we don't want to treat
390393
// auto-ref'd parameters in overloaded operators as rvalues.
391-
let cmt = match self.bccx.tcx.adjustments.borrow().find(&expr.id) {
394+
let assignee_cmt = match self.bccx.tcx.adjustments.borrow().find(&assignment_id) {
392395
None => self.bccx.cat_expr_unadjusted(expr),
393396
Some(adj) => self.bccx.cat_expr_autoderefd(expr, adj)
394397
};
395398

396-
debug!("check_assignment(cmt={})", cmt.repr(self.tcx()));
399+
self.check_assignment(assignment_id, assignment_span, assignee_cmt);
400+
}
401+
402+
fn check_assignment(&self,
403+
assignment_id: ast::NodeId,
404+
assignment_span: Span,
405+
assignee_cmt: mc::cmt) {
406+
debug!("check_assignment(assignee_cmt={})", assignee_cmt.repr(self.tcx()));
397407

398408
// Mutable values can be assigned, as long as they obey loans
399409
// and aliasing restrictions:
400-
if cmt.mutbl.is_mutable() {
401-
if check_for_aliasable_mutable_writes(self, expr, cmt.clone()) {
410+
if assignee_cmt.mutbl.is_mutable() {
411+
if check_for_aliasable_mutable_writes(self, assignment_span, assignee_cmt.clone()) {
402412
if check_for_assignment_to_restricted_or_frozen_location(
403-
self, expr, cmt.clone()) {
413+
self, assignment_id, assignment_span, assignee_cmt.clone()) {
404414
// Safe, but record for lint pass later:
405-
mark_variable_as_used_mut(self, cmt);
415+
mark_variable_as_used_mut(self, assignee_cmt);
406416
}
407417
}
408418
return;
409419
}
410420

411421
// For immutable local variables, assignments are legal
412422
// if they cannot already have been assigned
413-
if self.is_local_variable(cmt.clone()) {
414-
assert!(cmt.mutbl.is_immutable()); // no "const" locals
415-
let lp = opt_loan_path(&cmt).unwrap();
416-
self.move_data.each_assignment_of(expr.id, &lp, |assign| {
423+
if self.is_local_variable(assignee_cmt.clone()) {
424+
assert!(assignee_cmt.mutbl.is_immutable()); // no "const" locals
425+
let lp = opt_loan_path(&assignee_cmt).unwrap();
426+
self.move_data.each_assignment_of(assignment_id, &lp, |assign| {
417427
self.bccx.report_reassigned_immutable_variable(
418-
expr.span,
428+
assignment_span,
419429
&*lp,
420430
assign);
421431
false
@@ -424,21 +434,21 @@ impl<'a> CheckLoanCtxt<'a> {
424434
}
425435

426436
// Otherwise, just a plain error.
427-
match opt_loan_path(&cmt) {
437+
match opt_loan_path(&assignee_cmt) {
428438
Some(lp) => {
429439
self.bccx.span_err(
430-
expr.span,
440+
assignment_span,
431441
format!("cannot assign to {} {} `{}`",
432-
cmt.mutbl.to_user_str(),
433-
self.bccx.cmt_to_str(&*cmt),
442+
assignee_cmt.mutbl.to_user_str(),
443+
self.bccx.cmt_to_str(&*assignee_cmt),
434444
self.bccx.loan_path_to_str(&*lp)).as_slice());
435445
}
436446
None => {
437447
self.bccx.span_err(
438-
expr.span,
448+
assignment_span,
439449
format!("cannot assign to {} {}",
440-
cmt.mutbl.to_user_str(),
441-
self.bccx.cmt_to_str(&*cmt)).as_slice());
450+
assignee_cmt.mutbl.to_user_str(),
451+
self.bccx.cmt_to_str(&*assignee_cmt)).as_slice());
442452
}
443453
}
444454
return;
@@ -495,7 +505,7 @@ impl<'a> CheckLoanCtxt<'a> {
495505
}
496506

497507
fn check_for_aliasable_mutable_writes(this: &CheckLoanCtxt,
498-
expr: &ast::Expr,
508+
span: Span,
499509
cmt: mc::cmt) -> bool {
500510
//! Safety checks related to writes to aliasable, mutable locations
501511
@@ -506,7 +516,7 @@ impl<'a> CheckLoanCtxt<'a> {
506516
mc::cat_deref(ref b, _, mc::BorrowedPtr(ty::MutBorrow, _)) => {
507517
// Statically prohibit writes to `&mut` when aliasable
508518

509-
check_for_aliasability_violation(this, expr, b.clone());
519+
check_for_aliasability_violation(this, span, b.clone());
510520
}
511521

512522
_ => {}
@@ -516,7 +526,7 @@ impl<'a> CheckLoanCtxt<'a> {
516526
}
517527

518528
fn check_for_aliasability_violation(this: &CheckLoanCtxt,
519-
expr: &ast::Expr,
529+
span: Span,
520530
cmt: mc::cmt)
521531
-> bool {
522532
match cmt.freely_aliasable(this.tcx()) {
@@ -528,7 +538,7 @@ impl<'a> CheckLoanCtxt<'a> {
528538
}
529539
Some(cause) => {
530540
this.bccx.report_aliasability_violation(
531-
expr.span,
541+
span,
532542
MutabilityViolation,
533543
cause);
534544
return false;
@@ -538,13 +548,14 @@ impl<'a> CheckLoanCtxt<'a> {
538548

539549
fn check_for_assignment_to_restricted_or_frozen_location(
540550
this: &CheckLoanCtxt,
541-
expr: &ast::Expr,
542-
cmt: mc::cmt) -> bool
551+
assignment_id: ast::NodeId,
552+
assignment_span: Span,
553+
assignee_cmt: mc::cmt) -> bool
543554
{
544555
//! Check for assignments that violate the terms of an
545556
//! outstanding loan.
546557
547-
let loan_path = match opt_loan_path(&cmt) {
558+
let loan_path = match opt_loan_path(&assignee_cmt) {
548559
Some(lp) => lp,
549560
None => { return true; /* no loan path, can't be any loans */ }
550561
};
@@ -579,11 +590,11 @@ impl<'a> CheckLoanCtxt<'a> {
579590
// `RESTR_MUTATE` restriction whenever the contents of an
580591
// owned pointer are borrowed, and hence while `v[*]` is not
581592
// restricted from being written, `v` is.
582-
let cont = this.each_in_scope_restriction(expr.id,
593+
let cont = this.each_in_scope_restriction(assignment_id,
583594
&*loan_path,
584595
|loan, restr| {
585596
if restr.set.intersects(RESTR_MUTATE) {
586-
this.report_illegal_mutation(expr, &*loan_path, loan);
597+
this.report_illegal_mutation(assignment_span, &*loan_path, loan);
587598
false
588599
} else {
589600
true
@@ -656,9 +667,9 @@ impl<'a> CheckLoanCtxt<'a> {
656667
};
657668

658669
// Check for a non-const loan of `loan_path`
659-
let cont = this.each_in_scope_loan(expr.id, |loan| {
670+
let cont = this.each_in_scope_loan(assignment_id, |loan| {
660671
if loan.loan_path == loan_path {
661-
this.report_illegal_mutation(expr, &*full_loan_path, loan);
672+
this.report_illegal_mutation(assignment_span, &*full_loan_path, loan);
662673
false
663674
} else {
664675
true
@@ -671,11 +682,11 @@ impl<'a> CheckLoanCtxt<'a> {
671682
}
672683

673684
pub fn report_illegal_mutation(&self,
674-
expr: &ast::Expr,
685+
span: Span,
675686
loan_path: &LoanPath,
676687
loan: &Loan) {
677688
self.bccx.span_err(
678-
expr.span,
689+
span,
679690
format!("cannot assign to `{}` because it is borrowed",
680691
self.bccx.loan_path_to_str(loan_path)).as_slice());
681692
self.bccx.span_note(
@@ -733,7 +744,7 @@ impl<'a> CheckLoanCtxt<'a> {
733744
match freevar_mode {
734745
freevars::CaptureByRef => { }
735746
freevars::CaptureByValue => {
736-
check_by_move_capture(self, closure_id, freevar, &*var_path);
747+
check_by_move_capture(self, closure_id, freevar.span, &*var_path);
737748
}
738749
}
739750
}
@@ -742,14 +753,14 @@ impl<'a> CheckLoanCtxt<'a> {
742753

743754
fn check_by_move_capture(this: &CheckLoanCtxt,
744755
closure_id: ast::NodeId,
745-
freevar: &freevars::freevar_entry,
756+
freevar_span: Span,
746757
move_path: &LoanPath) {
747758
let move_err = this.analyze_move_out_from(closure_id, move_path);
748759
match move_err {
749760
MoveOk => {}
750761
MoveWhileBorrowed(loan_path, loan_span) => {
751762
this.bccx.span_err(
752-
freevar.span,
763+
freevar_span,
753764
format!("cannot move `{}` into closure \
754765
because it is borrowed",
755766
this.bccx.loan_path_to_str(
@@ -841,7 +852,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
841852
}
842853
ast::ExprAssign(dest, _) |
843854
ast::ExprAssignOp(_, dest, _) => {
844-
this.check_assignment(dest);
855+
this.check_assignment_expr(dest);
845856
}
846857
ast::ExprCall(f, ref args) => {
847858
this.check_call(expr, Some(f), f.span, args.as_slice());
@@ -859,7 +870,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
859870
}
860871
ast::ExprInlineAsm(ref ia) => {
861872
for &(_, out) in ia.outputs.iter() {
862-
this.check_assignment(out);
873+
this.check_assignment_expr(out);
863874
}
864875
}
865876
_ => {}

0 commit comments

Comments
 (0)