Change:
This (probably incorrect) program causes nightly rustc to panic: On the beta, instead you get:

Discussion:
for (i, &expr) in exprs.iter().rev().enumerate() { debug!("convert_lvalue_derefs_to_mutable: i={} expr={:?}", i, expr); <del> // Fix up the adjustment. let autoderefs = match self.tables.borrow_mut().adjustments.get_mut(&expr.id) { Some(&mut Adjustment { kind: Adjust::DerefRef { autoderefs, ref mut autoref, .. }, ref mut target }) => { if let &mut Some(AutoBorrow::Ref(_, ref mut mutbl)) = autoref { *mutbl = hir::Mutability::MutMutable; *target = match target.sty { ty::TyRef(r, ty::TypeAndMut { ty, .. }) => self.tcx.mk_ref(r, ty::TypeAndMut { ty, mutbl: *mutbl }), _ => span_bug!(expr.span, "AutoBorrow::Ref resulted in non-ref {:?}", target) }; } autoderefs } </del> <ins> // Fix up the autoderefs. Autorefs can only occur immediately preceding // overloaded lvalue ops, and will be fixed by them in order to get // the correct region. let autoderefs = match self.tables.borrow().adjustments.get(&expr.id) { Some(&Adjustment { kind: Adjust::DerefRef { autoderefs, .. }, .. }) => autoderefs, </ins> Some(_) | None => 0 };

let method = self.try_overloaded_lvalue_op( expr.span, None, base_ty, arg_tys, PreferMutLvalue, op); <del> let ok = method.expect("re-trying op failed"); </del> <ins> let ok = match method { Some(method) => method, None => return self.tcx.sess.delay_span_bug(expr.span, "re-trying op failed") }; </ins> let method = self.register_infer_ok_obligations(ok); debug!("convert_lvalue_op_to_mutable: method={:?}", method); self.tables.borrow_mut().method_map.insert(method_call, method); <ins> // Convert the autoref in the base expr to mutable with the correct // region and mutability. if let Some(&mut Adjustment { ref mut target, kind: Adjust::DerefRef { autoref: Some(AutoBorrow::Ref(ref mut r, ref mut mutbl)), .. } }) = self.tables.borrow_mut().adjustments.get_mut(&base_expr.id) { debug!("convert_lvalue_op_to_mutable: converting autoref of {:?}", target); // extract method return type, which will be &mut T; // all LB regions should have been instantiated during method lookup let method_sig = self.tcx.no_late_bound_regions(&method.ty.fn_sig()).unwrap(); *target = method_sig.inputs()[0]; if let ty::TyRef(r_, mt) = target.sty { *r = r_; *mutbl = mt.mutbl; } else { span_bug!(expr.span, "input to lvalue op is not a ref?"); } } </ins> } ///////////////////////////////////////////////////////////////////////////

<ins> // Copyright 2017 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 std::collections::HashMap; fn main() { let things: HashMap<String, Vec<String>> = HashMap::new(); for src in things.keys() { things[src.as_str()].sort(); //~ ERROR cannot borrow immutable } } </ins>

<ins> // Copyright 2017 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 std::ops::{Index, IndexMut}; struct S; struct H; impl S { fn f(&mut self) {} } impl Index<u32> for H { type Output = S; fn index(&self, index: u32) -> &S { unimplemented!() } } impl IndexMut<u32> for H { fn index_mut(&mut self, index: u32) -> &mut S { unimplemented!() } } fn main() { H["?"].f(); //~ ERROR mismatched types } </ins>

<ins> // Copyright 2017 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. // check that we link regions in mutable lvalue ops correctly - issue #41774 struct Data(i32); trait OhNo { fn oh_no(&mut self, other: &Vec<Data>) { loop {} } } impl OhNo for Data {} impl OhNo for [Data] {} fn main() { let mut v = vec![Data(0)]; v[0].oh_no(&v); //~ ERROR cannot borrow `v` as immutable because (*v).oh_no(&v); //~ ERROR cannot borrow `v` as immutable because } </ins>