@@ -9,6 +9,7 @@ use rustc_middle::ty::{self, Ty};
9
9
use rustc_span:: symbol:: { sym, Ident } ;
10
10
use rustc_span:: Span ;
11
11
use rustc_trait_selection:: autoderef:: Autoderef ;
12
+ use std:: slice;
12
13
13
14
impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
14
15
/// Type-check `*oprnd_expr` with `oprnd_expr` type-checked already.
@@ -245,19 +246,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
245
246
}
246
247
247
248
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 . typeck_results . 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) ;
258
251
}
259
252
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) ;
261
254
}
262
255
_ => { }
263
256
}
@@ -269,9 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
269
262
op : PlaceOp ,
270
263
expr : & hir:: Expr < ' _ > ,
271
264
base_expr : & hir:: Expr < ' _ > ,
272
- arg_tys : & [ Ty < ' tcx > ] ,
273
265
) {
274
- debug ! ( "convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?} )" , op, expr, base_expr, arg_tys ) ;
266
+ debug ! ( "convert_place_op_to_mutable({:?}, {:?}, {:?})" , op, expr, base_expr) ;
275
267
if !self . typeck_results . borrow ( ) . is_method_call ( expr) {
276
268
debug ! ( "convert_place_op_to_mutable - builtin, nothing to do" ) ;
277
269
return ;
@@ -286,6 +278,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
286
278
. expect ( "place op takes something that is not a ref" )
287
279
. ty ;
288
280
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 . typeck_results . 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
+
289
300
let method = self . try_mutable_overloaded_place_op ( expr. span , base_ty, arg_tys, op) ;
290
301
let method = match method {
291
302
Some ( ok) => self . register_infer_ok_obligations ( ok) ,
0 commit comments