@@ -9,6 +9,7 @@ use rustc_middle::ty::{self, Ty};
99use rustc_span:: symbol:: { sym, Ident } ;
1010use rustc_span:: Span ;
1111use rustc_trait_selection:: autoderef:: Autoderef ;
12+ use std:: slice;
1213
1314impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
1415 /// Type-check `*oprnd_expr` with `oprnd_expr` type-checked already.
@@ -245,19 +246,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
245246 }
246247
247248 match expr. kind {
248- hir:: ExprKind :: Index ( ref base_expr, ref index_expr) => {
249- // We need to get the final type in case dereferences were needed for the trait
250- // to apply (#72002).
251- let index_expr_ty = self . tables . borrow ( ) . expr_ty_adjusted ( index_expr) ;
252- self . convert_place_op_to_mutable (
253- PlaceOp :: Index ,
254- expr,
255- base_expr,
256- & [ index_expr_ty] ,
257- ) ;
249+ hir:: ExprKind :: Index ( ref base_expr, ..) => {
250+ self . convert_place_op_to_mutable ( PlaceOp :: Index , expr, base_expr) ;
258251 }
259252 hir:: ExprKind :: Unary ( hir:: UnOp :: UnDeref , ref base_expr) => {
260- self . convert_place_op_to_mutable ( PlaceOp :: Deref , expr, base_expr, & [ ] ) ;
253+ self . convert_place_op_to_mutable ( PlaceOp :: Deref , expr, base_expr) ;
261254 }
262255 _ => { }
263256 }
@@ -269,9 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
269262 op : PlaceOp ,
270263 expr : & hir:: Expr < ' _ > ,
271264 base_expr : & hir:: Expr < ' _ > ,
272- arg_tys : & [ Ty < ' tcx > ] ,
273265 ) {
274- debug ! ( "convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?} )" , op, expr, base_expr, arg_tys ) ;
266+ debug ! ( "convert_place_op_to_mutable({:?}, {:?}, {:?})" , op, expr, base_expr) ;
275267 if !self . tables . borrow ( ) . is_method_call ( expr) {
276268 debug ! ( "convert_place_op_to_mutable - builtin, nothing to do" ) ;
277269 return ;
@@ -286,6 +278,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
286278 . expect ( "place op takes something that is not a ref" )
287279 . ty ;
288280
281+ let arg_ty = match op {
282+ PlaceOp :: Deref => None ,
283+ PlaceOp :: Index => {
284+ // We would need to recover the `T` used when we resolve `<_ as Index<T>>::index`
285+ // in try_index_step. This is the subst at index 1.
286+ //
287+ // Note: we should *not* use `expr_ty` of index_expr here because autoderef
288+ // during coercions can cause type of index_expr to differ from `T` (#72002).
289+ // We also could not use `expr_ty_adjusted` of index_expr because reborrowing
290+ // during coercions can also cause type of index_expr to differ from `T`,
291+ // which can potentially cause regionck failure (#74933).
292+ Some ( self . tables . borrow ( ) . node_substs ( expr. hir_id ) . type_at ( 1 ) )
293+ }
294+ } ;
295+ let arg_tys = match arg_ty {
296+ None => & [ ] ,
297+ Some ( ref ty) => slice:: from_ref ( ty) ,
298+ } ;
299+
289300 let method = self . try_mutable_overloaded_place_op ( expr. span , base_ty, arg_tys, op) ;
290301 let method = match method {
291302 Some ( ok) => self . register_infer_ok_obligations ( ok) ,
0 commit comments