提交 96e9cee7 编写于 作者: B bors

Auto merge of #46040 - zilbuz:mir-misc, r=nikomatsakis

MIR-borrowck: Some minor fixes

- Remove parens when printing dereference (fix #45185)
- Change argument type of `autoderef` to `bool`
- Change argument type of `field_index` to `Field`
......@@ -15,7 +15,7 @@
use rustc::infer::{InferCtxt};
use rustc::ty::{self, TyCtxt, ParamEnv};
use rustc::ty::maps::Providers;
use rustc::mir::{AssertMessage, BasicBlock, BorrowKind, Location, Lvalue, Local};
use rustc::mir::{AssertMessage, BasicBlock, BorrowKind, Field, Location, Lvalue, Local};
use rustc::mir::{Mir, Mutability, Operand, Projection, ProjectionElem, Rvalue};
use rustc::mir::{Statement, StatementKind, Terminator, TerminatorKind};
use transform::nll;
......@@ -1577,7 +1577,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// End-user visible description of `lvalue`
fn describe_lvalue(&self, lvalue: &Lvalue<'tcx>) -> String {
let mut buf = String::new();
self.append_lvalue_to_string(lvalue, &mut buf, None);
self.append_lvalue_to_string(lvalue, &mut buf, false);
buf
}
......@@ -1585,7 +1585,7 @@ fn describe_lvalue(&self, lvalue: &Lvalue<'tcx>) -> String {
fn append_lvalue_to_string(&self,
lvalue: &Lvalue<'tcx>,
buf: &mut String,
autoderef: Option<bool>) {
mut autoderef: bool) {
match *lvalue {
Lvalue::Local(local) => {
self.append_local_to_string(local, buf, "_");
......@@ -1594,38 +1594,35 @@ fn append_lvalue_to_string(&self,
buf.push_str(&format!("{}", &self.tcx.item_name(static_.def_id)));
}
Lvalue::Projection(ref proj) => {
let mut autoderef = autoderef.unwrap_or(false);
match proj.elem {
ProjectionElem::Deref => {
if autoderef {
self.append_lvalue_to_string(&proj.base, buf, Some(autoderef));
self.append_lvalue_to_string(&proj.base, buf, autoderef);
} else {
buf.push_str(&"(*");
self.append_lvalue_to_string(&proj.base, buf, Some(autoderef));
buf.push_str(&")");
buf.push_str(&"*");
self.append_lvalue_to_string(&proj.base, buf, autoderef);
}
},
ProjectionElem::Downcast(..) => {
self.append_lvalue_to_string(&proj.base, buf, Some(autoderef));
self.append_lvalue_to_string(&proj.base, buf, autoderef);
},
ProjectionElem::Field(field, _ty) => {
autoderef = true;
let is_projection_from_ty_closure = proj.base.ty(self.mir, self.tcx)
.to_ty(self.tcx).is_closure();
let field_name = self.describe_field(&proj.base, field.index());
let field_name = self.describe_field(&proj.base, field);
if is_projection_from_ty_closure {
buf.push_str(&format!("{}", field_name));
} else {
self.append_lvalue_to_string(&proj.base, buf, Some(autoderef));
self.append_lvalue_to_string(&proj.base, buf, autoderef);
buf.push_str(&format!(".{}", field_name));
}
},
ProjectionElem::Index(index) => {
autoderef = true;
self.append_lvalue_to_string(&proj.base, buf, Some(autoderef));
self.append_lvalue_to_string(&proj.base, buf, autoderef);
buf.push_str("[");
self.append_local_to_string(index, buf, "..");
buf.push_str("]");
......@@ -1635,7 +1632,7 @@ fn append_lvalue_to_string(&self,
// Since it isn't possible to borrow an element on a particular index and
// then use another while the borrow is held, don't output indices details
// to avoid confusing the end-user
self.append_lvalue_to_string(&proj.base, buf, Some(autoderef));
self.append_lvalue_to_string(&proj.base, buf, autoderef);
buf.push_str(&"[..]");
},
};
......@@ -1653,58 +1650,57 @@ fn append_local_to_string(&self, local_index: Local, buf: &mut String, none_stri
}
}
// FIXME Instead of passing usize, Field should be passed
// End-user visible description of the `field_index`nth field of `base`
fn describe_field(&self, base: &Lvalue, field_index: usize) -> String {
// End-user visible description of the `field`nth field of `base`
fn describe_field(&self, base: &Lvalue, field: Field) -> String {
match *base {
Lvalue::Local(local) => {
let local = &self.mir.local_decls[local];
self.describe_field_from_ty(&local.ty, field_index)
self.describe_field_from_ty(&local.ty, field)
},
Lvalue::Static(ref static_) => {
self.describe_field_from_ty(&static_.ty, field_index)
self.describe_field_from_ty(&static_.ty, field)
},
Lvalue::Projection(ref proj) => {
match proj.elem {
ProjectionElem::Deref =>
self.describe_field(&proj.base, field_index),
self.describe_field(&proj.base, field),
ProjectionElem::Downcast(def, variant_index) =>
format!("{}", def.variants[variant_index].fields[field_index].name),
format!("{}", def.variants[variant_index].fields[field.index()].name),
ProjectionElem::Field(_, field_type) =>
self.describe_field_from_ty(&field_type, field_index),
self.describe_field_from_ty(&field_type, field),
ProjectionElem::Index(..)
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. } =>
format!("{}", self.describe_field(&proj.base, field_index)),
format!("{}", self.describe_field(&proj.base, field)),
}
}
}
}
// End-user visible description of the `field_index`nth field of `ty`
fn describe_field_from_ty(&self, ty: &ty::Ty, field_index: usize) -> String {
fn describe_field_from_ty(&self, ty: &ty::Ty, field: Field) -> String {
if ty.is_box() {
// If the type is a box, the field is described from the boxed type
self.describe_field_from_ty(&ty.boxed_ty(), field_index)
self.describe_field_from_ty(&ty.boxed_ty(), field)
}
else {
match ty.sty {
ty::TyAdt(def, _) => {
if def.is_enum() {
format!("{}", field_index)
format!("{}", field.index())
}
else {
format!("{}", def.struct_variant().fields[field_index].name)
format!("{}", def.struct_variant().fields[field.index()].name)
}
},
ty::TyTuple(_, _) => {
format!("{}", field_index)
format!("{}", field.index())
},
ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => {
self.describe_field_from_ty(&tnm.ty, field_index)
self.describe_field_from_ty(&tnm.ty, field)
},
ty::TyArray(ty, _) | ty::TySlice(ty) => {
self.describe_field_from_ty(&ty, field_index)
self.describe_field_from_ty(&ty, field)
},
ty::TyClosure(closure_def_id, _) => {
// Convert the def-id into a node-id. node-ids are only valid for
......@@ -1712,7 +1708,7 @@ fn describe_field_from_ty(&self, ty: &ty::Ty, field_index: usize) -> String {
// the closure comes from another crate. But in that case we wouldn't
// be borrowck'ing it, so we can just unwrap:
let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap();
let freevar = self.tcx.with_freevars(node_id, |fv| fv[field_index]);
let freevar = self.tcx.with_freevars(node_id, |fv| fv[field.index()]);
self.tcx.hir.name(freevar.var_id()).to_string()
}
......
......@@ -70,7 +70,7 @@ fn f() {
let c1 = || get(&*x);
*x = 5; //[ast]~ ERROR cannot assign
//[mir]~^ ERROR cannot assign to `*x` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `(*x)` because it is borrowed (Mir)
//[mir]~| ERROR cannot assign to `*x` because it is borrowed (Mir)
}
fn g() {
......@@ -82,7 +82,7 @@ struct Foo {
let c1 = || get(&*x.f);
*x.f = 5; //[ast]~ ERROR cannot assign to `*x.f`
//[mir]~^ ERROR cannot assign to `*x.f` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `(*x.f)` because it is borrowed (Mir)
//[mir]~| ERROR cannot assign to `*x.f` because it is borrowed (Mir)
}
fn h() {
......
......@@ -252,7 +252,7 @@ struct Block<'a> {
fn bump<'a>(mut block: &mut Block<'a>) {
let x = &mut block;
let p: &'a u8 = &*block.current;
//[mir]~^ ERROR cannot borrow `(*block.current)` as immutable because it is also borrowed as mutable (Mir)
//[mir]~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable (Mir)
// No errors in AST because of issue rust#38899
}
}
......@@ -266,7 +266,7 @@ struct Block2 {
unsafe fn bump2(mut block: *mut Block2) {
let x = &mut block;
let p : *const u8 = &*(*block).current;
//[mir]~^ ERROR cannot borrow `(*block.current)` as immutable because it is also borrowed as mutable (Mir)
//[mir]~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable (Mir)
// No errors in AST because of issue rust#38899
}
}
......@@ -279,7 +279,7 @@ unsafe fn bump2(mut block: *mut Block2) {
//[ast]~^ ERROR cannot use `v[..].y` because it was mutably borrowed
//[mir]~^^ ERROR cannot use `v[..].y` because it was mutably borrowed (Ast)
//[mir]~| ERROR cannot use `v[..].y` because it was mutably borrowed (Mir)
//[mir]~| ERROR cannot use `(*v)` because it was mutably borrowed (Mir)
//[mir]~| ERROR cannot use `*v` because it was mutably borrowed (Mir)
}
// Field of constant index
{
......@@ -300,7 +300,7 @@ unsafe fn bump2(mut block: *mut Block2) {
let y = &mut x;
&mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
//[mir]~^ ERROR cannot borrow `**x` as mutable more than once at a time (Ast)
//[mir]~| ERROR cannot borrow `(*x)` as mutable more than once at a time (Mir)
//[mir]~| ERROR cannot borrow `*x` as mutable more than once at a time (Mir)
*y = 1;
};
}
......@@ -312,7 +312,7 @@ unsafe fn bump2(mut block: *mut Block2) {
let y = &mut x;
&mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
//[mir]~^ ERROR cannot borrow `**x` as mutable more than once at a time (Ast)
//[mir]~| ERROR cannot borrow `(*x)` as mutable more than once at a time (Mir)
//[mir]~| ERROR cannot borrow `*x` as mutable more than once at a time (Mir)
*y = 1;
}
};
......
......@@ -22,7 +22,7 @@ fn double_mut_borrow<T>(x: &mut Box<T>) {
let z = borrow_mut(x);
//[ast]~^ ERROR cannot borrow `*x` as mutable more than once at a time
//[mir]~^^ ERROR cannot borrow `*x` as mutable more than once at a time (Ast)
//[mir]~| ERROR cannot borrow `(*x)` as mutable more than once at a time (Mir)
//[mir]~| ERROR cannot borrow `*x` as mutable more than once at a time (Mir)
}
fn double_imm_borrow(x: &mut Box<i32>) {
......@@ -31,21 +31,21 @@ fn double_imm_borrow(x: &mut Box<i32>) {
**x += 1;
//[ast]~^ ERROR cannot assign to `**x` because it is borrowed
//[mir]~^^ ERROR cannot assign to `**x` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `(*(*x))` because it is borrowed (Mir)
//[mir]~| ERROR cannot assign to `**x` because it is borrowed (Mir)
}
fn double_mut_borrow2<T>(x: &mut Box<T>) {
borrow_mut2(x, x);
//[ast]~^ ERROR cannot borrow `*x` as mutable more than once at a time
//[mir]~^^ ERROR cannot borrow `*x` as mutable more than once at a time (Ast)
//[mir]~| ERROR cannot borrow `(*x)` as mutable more than once at a time (Mir)
//[mir]~| ERROR cannot borrow `*x` as mutable more than once at a time (Mir)
}
fn double_borrow2<T>(x: &mut Box<T>) {
borrow2(x, x);
//[ast]~^ ERROR cannot borrow `*x` as immutable because it is also borrowed as mutable
//[mir]~^^ ERROR cannot borrow `*x` as immutable because it is also borrowed as mutable (Ast)
//[mir]~| ERROR cannot borrow `(*x)` as immutable because it is also borrowed as mutable (Mir)
//[mir]~| ERROR cannot borrow `*x` as immutable because it is also borrowed as mutable (Mir)
}
pub fn main() {}
......@@ -27,5 +27,5 @@ fn main() {
let &mut ref x = foo;
*foo += 1; //[ast]~ ERROR cannot assign to `*foo` because it is borrowed
//[mir]~^ ERROR cannot assign to `*foo` because it is borrowed (Ast)
//[mir]~| ERROR cannot assign to `(*foo)` because it is borrowed (Mir)
//[mir]~| ERROR cannot assign to `*foo` because it is borrowed (Mir)
}
......@@ -34,7 +34,7 @@ error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as imm
51 | }
| - immutable borrow ends here
error[E0502]: cannot borrow `(*map)` as mutable because it is also borrowed as immutable (Mir)
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
--> $DIR/get_default.rs:43:17
|
41 | match map.get() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册