Improve diagnostics that result from the fix for #18335

This commit is contained in:
Brian Koropoff 2014-10-25 21:46:24 -07:00
parent 1062955b46
commit 7129f172ae
2 changed files with 37 additions and 13 deletions

View File

@ -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) => {

View File

@ -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");
}
}
_ => {}
}