From 289772f83dc777bed69e2444d0debd80bc5d0f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 23 Mar 2017 11:22:44 -0700 Subject: [PATCH] Point to definition when modifying field of immutable variable Given a file ```rust struct S { x: i32, } fn foo() { let s = S { x: 42 }; s.x += 1; } fn bar(s: S) { s.x += 1; } ``` Provide the following output: ```rust error: cannot assign to immutable field `s.x` --> $DIR/issue-35937.rs:16:5 | 5 | let s = S { x: 42 }; | - consider changing this to `mut s` 6 | s.x += 1; | ^^^^^^^^ cannot mutably borrow immutable field error: cannot assign to immutable field `s.x` --> $DIR/issue-35937.rs:20:5 | 8 | fn bar(s: S) { | - consider changing this to `mut s` 9 | s.x += 1; | ^^^^^^^^ cannot mutably borrow immutable field ``` Follow up to #40445. Fix #35937. --- src/librustc_borrowck/borrowck/mod.rs | 2 ++ src/test/ui/did_you_mean/issue-35937.rs | 31 +++++++++++++++++++++ src/test/ui/did_you_mean/issue-35937.stderr | 26 +++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 src/test/ui/did_you_mean/issue-35937.rs create mode 100644 src/test/ui/did_you_mean/issue-35937.stderr diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 20d495976b05f..a48f1d2d2709b 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -688,6 +688,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { match err.cause { MutabilityViolation => { + local_def = err.cmt.get_def().map(|nid| self.tcx.hir.span(nid)); format!("cannot assign to {}", descr) } BorrowViolation(euv::ClosureCapture(_)) => { @@ -1132,6 +1133,7 @@ before rustc 1.16, this temporary lived longer - see issue #39283 \ } } } + pub fn append_loan_path_to_string(&self, loan_path: &LoanPath<'tcx>, out: &mut String) { diff --git a/src/test/ui/did_you_mean/issue-35937.rs b/src/test/ui/did_you_mean/issue-35937.rs new file mode 100644 index 0000000000000..9ec8728fd32c1 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-35937.rs @@ -0,0 +1,31 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo { + pub v: Vec +} + +fn main() { + let f = Foo { v: Vec::new() }; + f.v.push("cat".to_string()); +} + + +struct S { + x: i32, +} +fn foo() { + let s = S { x: 42 }; + s.x += 1; +} + +fn bar(s: S) { + s.x += 1; +} diff --git a/src/test/ui/did_you_mean/issue-35937.stderr b/src/test/ui/did_you_mean/issue-35937.stderr new file mode 100644 index 0000000000000..bea3d1291433d --- /dev/null +++ b/src/test/ui/did_you_mean/issue-35937.stderr @@ -0,0 +1,26 @@ +error: cannot borrow immutable field `f.v` as mutable + --> $DIR/issue-35937.rs:17:5 + | +16 | let f = Foo { v: Vec::new() }; + | - consider changing this to `mut f` +17 | f.v.push("cat".to_string()); + | ^^^ cannot mutably borrow immutable field + +error: cannot assign to immutable field `s.x` + --> $DIR/issue-35937.rs:26:5 + | +25 | let s = S { x: 42 }; + | - consider changing this to `mut s` +26 | s.x += 1; + | ^^^^^^^^ cannot mutably borrow immutable field + +error: cannot assign to immutable field `s.x` + --> $DIR/issue-35937.rs:30:5 + | +29 | fn bar(s: S) { + | - consider changing this to `mut s` +30 | s.x += 1; + | ^^^^^^^^ cannot mutably borrow immutable field + +error: aborting due to 3 previous errors +