diff options
| author | Brian Koropoff <bkoropoff@gmail.com> | 2014-10-25 21:46:24 -0700 |
|---|---|---|
| committer | Brian Koropoff <bkoropoff@gmail.com> | 2014-10-25 21:46:24 -0700 |
| commit | 7129f172aee6d5143ca36d81defd47dd0c113ce3 (patch) | |
| tree | a7771ddda9f63233ee49d77cb29468116bd93cb8 | |
| parent | 1062955b46950114ed3a0a71c043e9644afdce48 (diff) | |
| download | rust-7129f172aee6d5143ca36d81defd47dd0c113ce3.tar.gz rust-7129f172aee6d5143ca36d81defd47dd0c113ce3.zip | |
Improve diagnostics that result from the fix for #18335
| -rw-r--r-- | src/librustc/middle/borrowck/check_loans.rs | 29 | ||||
| -rw-r--r-- | src/librustc/middle/borrowck/mod.rs | 21 |
2 files changed, 37 insertions, 13 deletions
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 5d984168a31..bdcf01b21ab 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -777,13 +777,28 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // Otherwise, just a plain error. match assignee_cmt.note { mc::NoteClosureEnv(upvar_id) => { - self.bccx.span_err( - assignment_span, - format!("cannot assign to {}", - self.bccx.cmt_to_string(&*assignee_cmt)).as_slice()); - self.bccx.span_note( - self.tcx().map.span(upvar_id.closure_expr_id), - "consider changing this closure to take self by mutable reference"); + // If this is an `Fn` closure, it simply can't mutate upvars. + // If it's an `FnMut` closure, the original variable was declared immutable. + // We need to determine which is the case here. + let kind = match assignee_cmt.upvar().unwrap().cat { + mc::cat_upvar(mc::Upvar { kind, .. }) => kind, + _ => unreachable!() + }; + if kind == ty::FnUnboxedClosureKind { + self.bccx.span_err( + assignment_span, + format!("cannot assign to {}", + self.bccx.cmt_to_string(&*assignee_cmt)).as_slice()); + self.bccx.span_note( + self.tcx().map.span(upvar_id.closure_expr_id), + "consider changing this closure to take self by mutable reference"); + } else { + self.bccx.span_err( + assignment_span, + format!("cannot assign to {} {}", + assignee_cmt.mutbl.to_user_str(), + self.bccx.cmt_to_string(&*assignee_cmt)).as_slice()); + } } _ => match opt_loan_path(&assignee_cmt) { Some(lp) => { diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 850c6008706..06249b956b6 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -626,7 +626,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { match err.code { err_mutbl => { let descr = match err.cmt.note { - mc::NoteClosureEnv(_) => { + mc::NoteClosureEnv(_) | mc::NoteUpvarRef(_) => { self.cmt_to_string(&*err.cmt) } _ => match opt_loan_path(&err.cmt) { @@ -762,11 +762,20 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { match code { err_mutbl(..) => { match err.cmt.note { - mc::NoteClosureEnv(upvar_id) => { - self.tcx.sess.span_note( - self.tcx.map.span(upvar_id.closure_expr_id), - "consider changing this closure to take \ - self by mutable reference"); + mc::NoteClosureEnv(upvar_id) | mc::NoteUpvarRef(upvar_id) => { + // If this is an `Fn` closure, it simply can't mutate upvars. + // If it's an `FnMut` closure, the original variable was declared immutable. + // We need to determine which is the case here. + let kind = match err.cmt.upvar().unwrap().cat { + mc::cat_upvar(mc::Upvar { kind, .. }) => kind, + _ => unreachable!() + }; + if kind == ty::FnUnboxedClosureKind { + self.tcx.sess.span_note( + self.tcx.map.span(upvar_id.closure_expr_id), + "consider changing this closure to take \ + self by mutable reference"); + } } _ => {} } |
