about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-04-06 13:20:24 +0300
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-04-06 13:20:24 +0300
commit95bd41e339ad07a2d7fb347de0a71fcdf155f2d5 (patch)
tree0ca258108cdd8d8716e53526812cc4610e2ff4f8 /src
parent5309a3e31d88def1f3ea966162ed4f81f161d500 (diff)
downloadrust-95bd41e339ad07a2d7fb347de0a71fcdf155f2d5.tar.gz
rust-95bd41e339ad07a2d7fb347de0a71fcdf155f2d5.zip
don't try to blame tuple fields for immutability
Tuple fields don't have an `&T` in their declaration that can be changed
to `&mut T` - skip them..

Fixes #41104.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/mem_categorization.rs18
-rw-r--r--src/test/ui/did_you_mean/issue-39544.rs6
-rw-r--r--src/test/ui/did_you_mean/issue-39544.stderr8
3 files changed, 24 insertions, 8 deletions
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 3b52e85e08e..7d3c17a0489 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -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)
@@ -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>> {
@@ -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 {
diff --git a/src/test/ui/did_you_mean/issue-39544.rs b/src/test/ui/did_you_mean/issue-39544.rs
index 6331fc5771f..d7c89355606 100644
--- a/src/test/ui/did_you_mean/issue-39544.rs
+++ b/src/test/ui/did_you_mean/issue-39544.rs
@@ -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;
+}
diff --git a/src/test/ui/did_you_mean/issue-39544.stderr b/src/test/ui/did_you_mean/issue-39544.stderr
index e1e229a8b05..2e98bc65e9e 100644
--- a/src/test/ui/did_you_mean/issue-39544.stderr
+++ b/src/test/ui/did_you_mean/issue-39544.stderr
@@ -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