|
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