-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Modify compile-fail/E0389 error message WIP #48914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
7d590b5
308e30e
f60788b
3f0ce08
bfc9b76
7a266a6
0c7fc04
fdb2f7f
55bd914
50299c6
7745b52
311a8be
6c649fb
1b06fe1
c119206
12d1415
1fb25fb
e6938ee
6686d10
e18a83b
e5a96a4
cbde62c
2ad20e8
c792d1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,7 @@ use dataflow::indexes::BorrowIndex; | |
use dataflow::move_paths::{IllegalMoveOriginKind, MoveError}; | ||
use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex}; | ||
use util::borrowck_errors::{BorrowckErrors, Origin}; | ||
use util::collect_writes::FindAssignments; | ||
|
||
use std::iter; | ||
|
||
|
@@ -1421,6 +1422,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { | |
} | ||
} | ||
|
||
fn get_main_error_message(&self, place:&Place<'tcx>) -> String{ | ||
match self.describe_place(place) { | ||
Some(name) => format!("immutable item `{}`", name), | ||
None => "immutable item".to_owned(), | ||
} | ||
} | ||
|
||
/// Currently MoveData does not store entries for all places in | ||
/// the input MIR. For example it will currently filter out | ||
/// places that are Copy; thus we do not track places of shared | ||
|
@@ -1551,19 +1559,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { | |
self.is_mutable(place, is_local_mutation_allowed) | ||
{ | ||
error_reported = true; | ||
|
||
let item_msg = match self.describe_place(place) { | ||
Some(name) => format!("immutable item `{}`", name), | ||
None => "immutable item".to_owned(), | ||
}; | ||
|
||
let item_msg = self.get_main_error_message(place); | ||
let mut err = self.tcx | ||
.cannot_borrow_path_as_mutable(span, &item_msg, Origin::Mir); | ||
err.span_label(span, "cannot borrow as mutable"); | ||
|
||
if place != place_err { | ||
if let Some(name) = self.describe_place(place_err) { | ||
err.note(&format!("Value not mutable causing this error: `{}`", name)); | ||
err.note(&format!("value not mutable causing this error: `{}`", name)); | ||
} | ||
} | ||
|
||
|
@@ -1573,21 +1576,61 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { | |
if let Err(place_err) = self.is_mutable(place, is_local_mutation_allowed) { | ||
error_reported = true; | ||
|
||
let item_msg = match self.describe_place(place) { | ||
Some(name) => format!("immutable item `{}`", name), | ||
None => "immutable item".to_owned(), | ||
let err_info = match *place_err { | ||
|
||
Place::Projection(ref proj) => { | ||
|
||
match proj.elem { | ||
ProjectionElem::Deref => { | ||
match proj.base { | ||
Place::Local(local) => { | ||
let locations = self.mir.find_assignments(local); | ||
if locations.len() > 0 { | ||
let item_msg = if error_reported { | ||
if let Some(name) = | ||
self.describe_place(place_err) { | ||
let var = str::replace(&name, "*", ""); | ||
|
||
format!("`&`-reference `{}`", var) | ||
} else { | ||
self.get_main_error_message(place) | ||
|
||
} | ||
} else { | ||
self.get_main_error_message(place) | ||
}; | ||
Some((self.mir.source_info(locations[0]).span, | ||
"consider changing this to be a \ | ||
mutable reference: `&mut`", item_msg, | ||
"cannot assign through `&`-reference")) | ||
} else { | ||
None | ||
} | ||
} | ||
_ => None, | ||
} | ||
} | ||
_ => None, | ||
} | ||
} | ||
_ => None, | ||
|
||
}; | ||
|
||
let mut err = self.tcx.cannot_assign(span, &item_msg, Origin::Mir); | ||
err.span_label(span, "cannot mutate"); | ||
|
||
if place != place_err { | ||
if let Some(name) = self.describe_place(place_err) { | ||
err.note(&format!("Value not mutable causing this error: `{}`", name)); | ||
if let Some((err_help_span, err_help_stmt, item_msg, sec_span)) = err_info { | ||
let mut err = self.tcx.cannot_assign(span, &item_msg, Origin::Mir, true); | ||
err.span_suggestion(err_help_span, err_help_stmt, format!("")); | ||
if place != place_err { | ||
err.span_label(span, sec_span); | ||
} | ||
err.emit() | ||
} else { | ||
let item_msg_ = self.get_main_error_message(place); | ||
let mut err = self.tcx.cannot_assign(span, &item_msg_, Origin::Mir, false); | ||
err.span_label(span, "cannot mutate"); | ||
if place != place_err { | ||
if let Some(name) = self.describe_place(place_err) { | ||
err.note(&format!("value not mutable causing this error: `{}`", | ||
name)); | ||
} | ||
} | ||
err.emit(); | ||
} | ||
|
||
err.emit(); | ||
} | ||
} | ||
Reservation(WriteKind::Move) | ||
|
@@ -2230,3 +2273,4 @@ impl ContextKind { | |
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! | |
#![feature(collection_placement)] | ||
#![feature(nonzero)] | ||
#![feature(underscore_lifetimes)] | ||
#![feature(crate_visibility_modifier)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, due to the usage here |
||
|
||
extern crate arena; | ||
#[macro_use] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright 2018 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. | ||
|
||
use rustc::mir::{Local, Location}; | ||
use rustc::mir::Mir; | ||
use rustc::mir::visit::PlaceContext; | ||
use rustc::mir::visit::Visitor; | ||
|
||
// The Visitor walks the MIR to return the assignment statements corresponding | ||
// to a Local. | ||
pub struct FindLocalAssignmentVisitor { | ||
|
||
needle: Local, | ||
locations: Vec<Location>, | ||
} | ||
|
||
impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor { | ||
fn visit_local(&mut self, | ||
local: &Local, | ||
place_context: PlaceContext<'tcx>, | ||
location: Location) { | ||
if self.needle != *local { | ||
return; | ||
} | ||
|
||
match place_context { | ||
PlaceContext::Store | PlaceContext::Call => { | ||
self.locations.push(location); | ||
} | ||
PlaceContext::AsmOutput | | ||
PlaceContext::Drop | | ||
PlaceContext::Inspect | | ||
PlaceContext::Borrow { .. } | | ||
PlaceContext::Projection(..) | | ||
PlaceContext::Copy | | ||
PlaceContext::Move | | ||
PlaceContext::StorageLive | | ||
PlaceContext::StorageDead | | ||
PlaceContext::Validate => { | ||
// TO-DO | ||
// self.super_local(local) | ||
} | ||
} | ||
} | ||
// TO-DO | ||
// fn super_local() | ||
} | ||
|
||
crate trait FindAssignments { | ||
|
||
fn find_assignments(&self, local: Local) -> Vec<Location>; | ||
} | ||
|
||
|
||
impl<'tcx> FindAssignments for Mir<'tcx>{ | ||
fn find_assignments(&self, local: Local) -> Vec<Location>{ | ||
let mut visitor = FindLocalAssignmentVisitor{ needle: local, locations: vec![]}; | ||
visitor.visit_mir(self); | ||
visitor.locations | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,7 @@ fn indirect_write_to_imm_box() { | |
let y: Box<_> = box &mut x; | ||
let p = &y; | ||
***p = 2; //[ast]~ ERROR cannot assign to data in a `&` reference | ||
//[mir]~^ ERROR cannot assign to immutable item `***p` | ||
//[mir]~^ ERROR cannot assign through `&`-reference `p` | ||
|
||
drop(p); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,5 +70,5 @@ fn main() { | |
}; | ||
s[2] = 20; | ||
//[ast]~^ ERROR cannot assign to immutable indexed content | ||
//[mir]~^^ ERROR cannot assign to immutable item | ||
//[mir]~^^ ERROR cannot assign through immutable item | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright 2018 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. | ||
#![feature(nll)] | ||
struct FancyNum { | ||
num: u8, | ||
} | ||
|
||
fn main() { | ||
let mut fancy = FancyNum{ num: 5 }; | ||
let fancy_ref = &(&mut fancy); | ||
fancy_ref.num = 6; //~^ ERROR E0594 | ||
println!("{}", fancy_ref.num); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error[E0594]: cannot assign through `&`-reference `fancy_ref` | ||
--> $DIR/issue-47388.rs:18:5 | ||
| | ||
LL | let fancy_ref = &(&mut fancy); | ||
| ------------- help: consider changing this to be a mutable reference: `&mut` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe either the span or the suggestion text might be incorrect. It should either suggest There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Filed #49859 |
||
LL | fancy_ref.num = 6; //~^ ERROR E0594 | ||
| ^^^^^^^^^^^^^^^^^ cannot assign through `&`-reference | ||
|
||
error: aborting due to previous error | ||
|
||
If you want more information on this error, try using "rustc --explain E0594" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pre-existing, but this message is not particularly grammatical. In fact, I have a hard time even understanding it -- I guess it is saying that "the value which is causing this path not to be mutable is..."?