Skip to content

Commit 95bd41e

Browse files
committed
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 rust-lang#41104.
1 parent 5309a3e commit 95bd41e

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

src/librustc/middle/mem_categorization.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,14 @@ pub enum ImmutabilityBlame<'tcx> {
202202
}
203203

204204
impl<'tcx> cmt_<'tcx> {
205-
fn resolve_field(&self, field_name: FieldName) -> (&'tcx ty::AdtDef, &'tcx ty::FieldDef)
205+
fn resolve_field(&self, field_name: FieldName) -> Option<(&'tcx ty::AdtDef, &'tcx ty::FieldDef)>
206206
{
207-
let adt_def = self.ty.ty_adt_def().unwrap_or_else(|| {
208-
bug!("interior cmt {:?} is not an ADT", self)
209-
});
207+
let adt_def = match self.ty.sty {
208+
ty::TyAdt(def, _) => def,
209+
ty::TyTuple(..) => return None,
210+
// closures get `Categorization::Upvar` rather than `Categorization::Interior`
211+
_ => bug!("interior cmt {:?} is not an ADT", self)
212+
};
210213
let variant_def = match self.cat {
211214
Categorization::Downcast(_, variant_did) => {
212215
adt_def.variant_with_id(variant_did)
@@ -220,7 +223,7 @@ impl<'tcx> cmt_<'tcx> {
220223
NamedField(name) => variant_def.field_named(name),
221224
PositionalField(idx) => &variant_def.fields[idx]
222225
};
223-
(adt_def, field_def)
226+
Some((adt_def, field_def))
224227
}
225228

226229
pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
@@ -232,8 +235,9 @@ impl<'tcx> cmt_<'tcx> {
232235
Categorization::Local(node_id) =>
233236
Some(ImmutabilityBlame::LocalDeref(node_id)),
234237
Categorization::Interior(ref base_cmt, InteriorField(field_name)) => {
235-
let (adt_def, field_def) = base_cmt.resolve_field(field_name);
236-
Some(ImmutabilityBlame::AdtFieldDeref(adt_def, field_def))
238+
base_cmt.resolve_field(field_name).map(|(adt_def, field_def)| {
239+
ImmutabilityBlame::AdtFieldDeref(adt_def, field_def)
240+
})
237241
}
238242
Categorization::Upvar(Upvar { id, .. }) => {
239243
if let NoteClosureEnv(..) = self.note {

src/test/ui/did_you_mean/issue-39544.rs

+6
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,9 @@ pub fn with_arg(z: Z, w: &Z) {
5151
let _ = &mut z.x;
5252
let _ = &mut w.x;
5353
}
54+
55+
pub fn with_tuple() {
56+
let mut y = 0;
57+
let x = (&y,);
58+
*x.0 = 1;
59+
}

src/test/ui/did_you_mean/issue-39544.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,11 @@ error: cannot borrow immutable field `w.x` as mutable
9090
52 | let _ = &mut w.x;
9191
| ^^^ cannot mutably borrow immutable field
9292

93-
error: aborting due to 11 previous errors
93+
error: cannot assign to immutable borrowed content `*x.0`
94+
--> $DIR/issue-39544.rs:58:5
95+
|
96+
58 | *x.0 = 1;
97+
| ^^^^^^^^ cannot borrow as mutable
98+
99+
error: aborting due to 12 previous errors
94100

0 commit comments

Comments
 (0)