|
1 | 1 | use super::{probe, MethodCallee};
|
2 | 2 |
|
3 | 3 | use crate::astconv::AstConv;
|
4 |
| -use crate::check::{callee, FnCtxt, Needs, PlaceOp}; |
| 4 | +use crate::check::{callee, FnCtxt, Needs}; |
5 | 5 | use crate::hir::def_id::DefId;
|
6 | 6 | use crate::hir::GenericArg;
|
7 | 7 | use rustc_hir as hir;
|
8 | 8 | use rustc_infer::infer::{self, InferOk};
|
9 |
| -use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast}; |
| 9 | +use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; |
10 | 10 | use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
11 | 11 | use rustc_middle::ty::fold::TypeFoldable;
|
12 | 12 | use rustc_middle::ty::subst::{Subst, SubstsRef};
|
@@ -121,7 +121,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
121 | 121 | let callee = MethodCallee { def_id: pick.item.def_id, substs: all_substs, sig: method_sig };
|
122 | 122 |
|
123 | 123 | if let Some(hir::Mutability::Mut) = pick.autoref {
|
124 |
| - self.convert_place_derefs_to_mutable(); |
| 124 | + self.convert_place_derefs_to_mutable(self.self_expr); |
125 | 125 | }
|
126 | 126 |
|
127 | 127 | ConfirmResult { callee, illegal_sized_bound }
|
@@ -416,151 +416,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
416 | 416 | self.register_wf_obligation(fty.into(), self.span, traits::MiscObligation);
|
417 | 417 | }
|
418 | 418 |
|
419 |
| - /////////////////////////////////////////////////////////////////////////// |
420 |
| - // RECONCILIATION |
421 |
| - |
422 |
| - /// When we select a method with a mutable autoref, we have to go convert any |
423 |
| - /// auto-derefs, indices, etc from `Deref` and `Index` into `DerefMut` and `IndexMut` |
424 |
| - /// respectively. |
425 |
| - fn convert_place_derefs_to_mutable(&self) { |
426 |
| - // Gather up expressions we want to munge. |
427 |
| - let mut exprs = vec![self.self_expr]; |
428 |
| - |
429 |
| - loop { |
430 |
| - match exprs.last().unwrap().kind { |
431 |
| - hir::ExprKind::Field(ref expr, _) |
432 |
| - | hir::ExprKind::Index(ref expr, _) |
433 |
| - | hir::ExprKind::Unary(hir::UnOp::UnDeref, ref expr) => exprs.push(&expr), |
434 |
| - _ => break, |
435 |
| - } |
436 |
| - } |
437 |
| - |
438 |
| - debug!("convert_place_derefs_to_mutable: exprs={:?}", exprs); |
439 |
| - |
440 |
| - // Fix up autoderefs and derefs. |
441 |
| - for (i, &expr) in exprs.iter().rev().enumerate() { |
442 |
| - debug!("convert_place_derefs_to_mutable: i={} expr={:?}", i, expr); |
443 |
| - |
444 |
| - // Fix up the autoderefs. Autorefs can only occur immediately preceding |
445 |
| - // overloaded place ops, and will be fixed by them in order to get |
446 |
| - // the correct region. |
447 |
| - let mut source = self.node_ty(expr.hir_id); |
448 |
| - // Do not mutate adjustments in place, but rather take them, |
449 |
| - // and replace them after mutating them, to avoid having the |
450 |
| - // tables borrowed during (`deref_mut`) method resolution. |
451 |
| - let previous_adjustments = |
452 |
| - self.tables.borrow_mut().adjustments_mut().remove(expr.hir_id); |
453 |
| - if let Some(mut adjustments) = previous_adjustments { |
454 |
| - let needs = Needs::MutPlace; |
455 |
| - for adjustment in &mut adjustments { |
456 |
| - if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind { |
457 |
| - if let Some(ok) = self.try_overloaded_deref(expr.span, source, needs) { |
458 |
| - let method = self.register_infer_ok_obligations(ok); |
459 |
| - if let ty::Ref(region, _, mutbl) = method.sig.output().kind { |
460 |
| - *deref = OverloadedDeref { region, mutbl }; |
461 |
| - } |
462 |
| - } |
463 |
| - } |
464 |
| - source = adjustment.target; |
465 |
| - } |
466 |
| - self.tables.borrow_mut().adjustments_mut().insert(expr.hir_id, adjustments); |
467 |
| - } |
468 |
| - |
469 |
| - match expr.kind { |
470 |
| - hir::ExprKind::Index(ref base_expr, ref index_expr) => { |
471 |
| - // We need to get the final type in case dereferences were needed for the trait |
472 |
| - // to apply (#72002). |
473 |
| - let index_expr_ty = self.tables.borrow().expr_ty_adjusted(index_expr); |
474 |
| - self.convert_place_op_to_mutable( |
475 |
| - PlaceOp::Index, |
476 |
| - expr, |
477 |
| - base_expr, |
478 |
| - &[index_expr_ty], |
479 |
| - ); |
480 |
| - } |
481 |
| - hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base_expr) => { |
482 |
| - self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr, &[]); |
483 |
| - } |
484 |
| - _ => {} |
485 |
| - } |
486 |
| - } |
487 |
| - } |
488 |
| - |
489 |
| - fn convert_place_op_to_mutable( |
490 |
| - &self, |
491 |
| - op: PlaceOp, |
492 |
| - expr: &hir::Expr<'_>, |
493 |
| - base_expr: &hir::Expr<'_>, |
494 |
| - arg_tys: &[Ty<'tcx>], |
495 |
| - ) { |
496 |
| - debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys); |
497 |
| - if !self.tables.borrow().is_method_call(expr) { |
498 |
| - debug!("convert_place_op_to_mutable - builtin, nothing to do"); |
499 |
| - return; |
500 |
| - } |
501 |
| - |
502 |
| - let base_ty = self |
503 |
| - .tables |
504 |
| - .borrow() |
505 |
| - .expr_adjustments(base_expr) |
506 |
| - .last() |
507 |
| - .map_or_else(|| self.node_ty(expr.hir_id), |adj| adj.target); |
508 |
| - let base_ty = self.resolve_vars_if_possible(&base_ty); |
509 |
| - |
510 |
| - // Need to deref because overloaded place ops take self by-reference. |
511 |
| - let base_ty = |
512 |
| - base_ty.builtin_deref(false).expect("place op takes something that is not a ref").ty; |
513 |
| - |
514 |
| - let method = self.try_overloaded_place_op(expr.span, base_ty, arg_tys, Needs::MutPlace, op); |
515 |
| - let method = match method { |
516 |
| - Some(ok) => self.register_infer_ok_obligations(ok), |
517 |
| - None => return self.tcx.sess.delay_span_bug(expr.span, "re-trying op failed"), |
518 |
| - }; |
519 |
| - debug!("convert_place_op_to_mutable: method={:?}", method); |
520 |
| - self.write_method_call(expr.hir_id, method); |
521 |
| - |
522 |
| - let (region, mutbl) = if let ty::Ref(r, _, mutbl) = method.sig.inputs()[0].kind { |
523 |
| - (r, mutbl) |
524 |
| - } else { |
525 |
| - span_bug!(expr.span, "input to place op is not a ref?"); |
526 |
| - }; |
527 |
| - |
528 |
| - // Convert the autoref in the base expr to mutable with the correct |
529 |
| - // region and mutability. |
530 |
| - let base_expr_ty = self.node_ty(base_expr.hir_id); |
531 |
| - if let Some(adjustments) = |
532 |
| - self.tables.borrow_mut().adjustments_mut().get_mut(base_expr.hir_id) |
533 |
| - { |
534 |
| - let mut source = base_expr_ty; |
535 |
| - for adjustment in &mut adjustments[..] { |
536 |
| - if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind { |
537 |
| - debug!("convert_place_op_to_mutable: converting autoref {:?}", adjustment); |
538 |
| - let mutbl = match mutbl { |
539 |
| - hir::Mutability::Not => AutoBorrowMutability::Not, |
540 |
| - hir::Mutability::Mut => AutoBorrowMutability::Mut { |
541 |
| - // For initial two-phase borrow |
542 |
| - // deployment, conservatively omit |
543 |
| - // overloaded operators. |
544 |
| - allow_two_phase_borrow: AllowTwoPhase::No, |
545 |
| - }, |
546 |
| - }; |
547 |
| - adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(region, mutbl)); |
548 |
| - adjustment.target = |
549 |
| - self.tcx.mk_ref(region, ty::TypeAndMut { ty: source, mutbl: mutbl.into() }); |
550 |
| - } |
551 |
| - source = adjustment.target; |
552 |
| - } |
553 |
| - |
554 |
| - // If we have an autoref followed by unsizing at the end, fix the unsize target. |
555 |
| - |
556 |
| - if let [.., Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. }, Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target }] = |
557 |
| - adjustments[..] |
558 |
| - { |
559 |
| - *target = method.sig.inputs()[0]; |
560 |
| - } |
561 |
| - } |
562 |
| - } |
563 |
| - |
564 | 419 | ///////////////////////////////////////////////////////////////////////////
|
565 | 420 | // MISCELLANY
|
566 | 421 |
|
|
0 commit comments