Skip to content

Commit

Permalink
don't try to blame tuple fields for immutability
Browse files Browse the repository at this point in the history
Tuple fields don't have an `&T` in their declaration that can be changed
to `&mut T` - skip them..

Fixes #41104.
  • Loading branch information
arielb1 committed Apr 6, 2017
1 parent 5309a3e commit 95bd41e
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 8 deletions.
18 changes: 11 additions & 7 deletions src/librustc/middle/mem_categorization.rs
Expand Up @@ -202,11 +202,14 @@ pub enum ImmutabilityBlame<'tcx> {
}

impl<'tcx> cmt_<'tcx> {
fn resolve_field(&self, field_name: FieldName) -> (&'tcx ty::AdtDef, &'tcx ty::FieldDef)
fn resolve_field(&self, field_name: FieldName) -> Option<(&'tcx ty::AdtDef, &'tcx ty::FieldDef)>
{
let adt_def = self.ty.ty_adt_def().unwrap_or_else(|| {
bug!("interior cmt {:?} is not an ADT", self)
});
let adt_def = match self.ty.sty {
ty::TyAdt(def, _) => def,
ty::TyTuple(..) => return None,
// closures get `Categorization::Upvar` rather than `Categorization::Interior`
_ => bug!("interior cmt {:?} is not an ADT", self)
};
let variant_def = match self.cat {
Categorization::Downcast(_, variant_did) => {
adt_def.variant_with_id(variant_did)
Expand All @@ -220,7 +223,7 @@ impl<'tcx> cmt_<'tcx> {
NamedField(name) => variant_def.field_named(name),
PositionalField(idx) => &variant_def.fields[idx]
};
(adt_def, field_def)
Some((adt_def, field_def))
}

pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
Expand All @@ -232,8 +235,9 @@ impl<'tcx> cmt_<'tcx> {
Categorization::Local(node_id) =>
Some(ImmutabilityBlame::LocalDeref(node_id)),
Categorization::Interior(ref base_cmt, InteriorField(field_name)) => {
let (adt_def, field_def) = base_cmt.resolve_field(field_name);
Some(ImmutabilityBlame::AdtFieldDeref(adt_def, field_def))
base_cmt.resolve_field(field_name).map(|(adt_def, field_def)| {
ImmutabilityBlame::AdtFieldDeref(adt_def, field_def)
})
}
Categorization::Upvar(Upvar { id, .. }) => {
if let NoteClosureEnv(..) = self.note {
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/did_you_mean/issue-39544.rs
Expand Up @@ -51,3 +51,9 @@ pub fn with_arg(z: Z, w: &Z) {
let _ = &mut z.x;
let _ = &mut w.x;
}

pub fn with_tuple() {
let mut y = 0;
let x = (&y,);
*x.0 = 1;
}
8 changes: 7 additions & 1 deletion src/test/ui/did_you_mean/issue-39544.stderr
Expand Up @@ -90,5 +90,11 @@ error: cannot borrow immutable field `w.x` as mutable
52 | let _ = &mut w.x;
| ^^^ cannot mutably borrow immutable field

error: aborting due to 11 previous errors
error: cannot assign to immutable borrowed content `*x.0`
--> $DIR/issue-39544.rs:58:5
|
58 | *x.0 = 1;
| ^^^^^^^^ cannot borrow as mutable

error: aborting due to 12 previous errors

0 comments on commit 95bd41e

Please sign in to comment.