Fix regionck failure when converting Index to IndexMut
This commit is contained in:
parent
32c481e156
commit
b4e552b1c8
1 changed files with 24 additions and 13 deletions
|
|
@ -9,6 +9,7 @@ use rustc_middle::ty::{self, Ty};
|
|||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::autoderef::Autoderef;
|
||||
use std::slice;
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// Type-check `*oprnd_expr` with `oprnd_expr` type-checked already.
|
||||
|
|
@ -245,19 +246,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
match expr.kind {
|
||||
hir::ExprKind::Index(ref base_expr, ref index_expr) => {
|
||||
// We need to get the final type in case dereferences were needed for the trait
|
||||
// to apply (#72002).
|
||||
let index_expr_ty = self.tables.borrow().expr_ty_adjusted(index_expr);
|
||||
self.convert_place_op_to_mutable(
|
||||
PlaceOp::Index,
|
||||
expr,
|
||||
base_expr,
|
||||
&[index_expr_ty],
|
||||
);
|
||||
hir::ExprKind::Index(ref base_expr, ..) => {
|
||||
self.convert_place_op_to_mutable(PlaceOp::Index, expr, base_expr);
|
||||
}
|
||||
hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base_expr) => {
|
||||
self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr, &[]);
|
||||
self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -269,9 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
op: PlaceOp,
|
||||
expr: &hir::Expr<'_>,
|
||||
base_expr: &hir::Expr<'_>,
|
||||
arg_tys: &[Ty<'tcx>],
|
||||
) {
|
||||
debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys);
|
||||
debug!("convert_place_op_to_mutable({:?}, {:?}, {:?})", op, expr, base_expr);
|
||||
if !self.tables.borrow().is_method_call(expr) {
|
||||
debug!("convert_place_op_to_mutable - builtin, nothing to do");
|
||||
return;
|
||||
|
|
@ -286,6 +278,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.expect("place op takes something that is not a ref")
|
||||
.ty;
|
||||
|
||||
let arg_ty = match op {
|
||||
PlaceOp::Deref => None,
|
||||
PlaceOp::Index => {
|
||||
// We would need to recover the `T` used when we resolve `<_ as Index<T>>::index`
|
||||
// in try_index_step. This is the subst at index 1.
|
||||
//
|
||||
// Note: we should *not* use `expr_ty` of index_expr here because autoderef
|
||||
// during coercions can cause type of index_expr to differ from `T` (#72002).
|
||||
// We also could not use `expr_ty_adjusted` of index_expr because reborrowing
|
||||
// during coercions can also cause type of index_expr to differ from `T`,
|
||||
// which can potentially cause regionck failure (#74933).
|
||||
Some(self.tables.borrow().node_substs(expr.hir_id).type_at(1))
|
||||
}
|
||||
};
|
||||
let arg_tys = match arg_ty {
|
||||
None => &[],
|
||||
Some(ref ty) => slice::from_ref(ty),
|
||||
};
|
||||
|
||||
let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_tys, op);
|
||||
let method = match method {
|
||||
Some(ok) => self.register_infer_ok_obligations(ok),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue