Skip to content

Commit 8efcb28

Browse files
Do fix_*_builtin_expr hacks on the writeback results
1 parent f383703 commit 8efcb28

File tree

2 files changed

+46
-48
lines changed

2 files changed

+46
-48
lines changed

compiler/rustc_hir_typeck/src/writeback.rs

+35-48
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_middle::mir::FakeReadCause;
1414
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
1515
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
1616
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
17-
use rustc_middle::ty::TypeckResults;
1817
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
1918
use rustc_span::symbol::sym;
2019
use rustc_span::Span;
@@ -148,31 +147,25 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
148147
fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr<'_>) {
149148
match e.kind {
150149
hir::ExprKind::Unary(hir::UnOp::Neg | hir::UnOp::Not, inner) => {
151-
let inner_ty = self.fcx.node_ty(inner.hir_id);
152-
let inner_ty = self.fcx.resolve_vars_if_possible(inner_ty);
150+
let inner_ty = self.typeck_results.node_type(inner.hir_id);
153151

154152
if inner_ty.is_scalar() {
155-
let mut typeck_results = self.fcx.typeck_results.borrow_mut();
156-
typeck_results.type_dependent_defs_mut().remove(e.hir_id);
157-
typeck_results.node_substs_mut().remove(e.hir_id);
153+
self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
154+
self.typeck_results.node_substs_mut().remove(e.hir_id);
158155
}
159156
}
160157
hir::ExprKind::Binary(ref op, lhs, rhs) | hir::ExprKind::AssignOp(ref op, lhs, rhs) => {
161-
let lhs_ty = self.fcx.node_ty(lhs.hir_id);
162-
let lhs_ty = self.fcx.resolve_vars_if_possible(lhs_ty);
163-
164-
let rhs_ty = self.fcx.node_ty(rhs.hir_id);
165-
let rhs_ty = self.fcx.resolve_vars_if_possible(rhs_ty);
158+
let lhs_ty = self.typeck_results.node_type(lhs.hir_id);
159+
let rhs_ty = self.typeck_results.node_type(rhs.hir_id);
166160

167161
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
168-
let mut typeck_results = self.fcx.typeck_results.borrow_mut();
169-
typeck_results.type_dependent_defs_mut().remove(e.hir_id);
170-
typeck_results.node_substs_mut().remove(e.hir_id);
162+
self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
163+
self.typeck_results.node_substs_mut().remove(e.hir_id);
171164

172165
match e.kind {
173166
hir::ExprKind::Binary(..) => {
174167
if !op.node.is_by_value() {
175-
let mut adjustments = typeck_results.adjustments_mut();
168+
let mut adjustments = self.typeck_results.adjustments_mut();
176169
if let Some(a) = adjustments.get_mut(lhs.hir_id) {
177170
a.pop();
178171
}
@@ -182,7 +175,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
182175
}
183176
}
184177
hir::ExprKind::AssignOp(..)
185-
if let Some(a) = typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
178+
if let Some(a) = self.typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
186179
{
187180
a.pop();
188181
}
@@ -200,16 +193,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
200193
// if they are not we don't modify the expr, hence we bypass the ICE
201194
fn is_builtin_index(
202195
&mut self,
203-
typeck_results: &TypeckResults<'tcx>,
204196
e: &hir::Expr<'_>,
205197
base_ty: Ty<'tcx>,
206198
index_ty: Ty<'tcx>,
207199
) -> bool {
208-
if let Some(elem_ty) = base_ty.builtin_index() {
209-
let Some(exp_ty) = typeck_results.expr_ty_opt(e) else {return false;};
210-
let resolved_exp_ty = self.resolve(exp_ty, &e.span);
211-
212-
elem_ty == resolved_exp_ty && index_ty == self.fcx.tcx.types.usize
200+
if let Some(elem_ty) = base_ty.builtin_index()
201+
&& let Some(exp_ty) = self.typeck_results.expr_ty_opt(e)
202+
{
203+
elem_ty == exp_ty && index_ty == self.fcx.tcx.types.usize
213204
} else {
214205
false
215206
}
@@ -221,38 +212,34 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
221212
// usize-ish
222213
fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
223214
if let hir::ExprKind::Index(ref base, ref index) = e.kind {
224-
let mut typeck_results = self.fcx.typeck_results.borrow_mut();
225-
226215
// All valid indexing looks like this; might encounter non-valid indexes at this point.
227-
let base_ty = typeck_results
228-
.expr_ty_adjusted_opt(base)
229-
.map(|t| self.fcx.resolve_vars_if_possible(t).kind());
216+
let base_ty = self.typeck_results.expr_ty_adjusted_opt(base);
230217
if base_ty.is_none() {
231218
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base
232219
// that isn't in the type table. We assume more relevant errors have already been
233220
// emitted, so we delay an ICE if none have. (#64638)
234221
self.tcx().sess.delay_span_bug(e.span, format!("bad base: `{:?}`", base));
235222
}
236-
if let Some(ty::Ref(_, base_ty, _)) = base_ty {
237-
let index_ty = typeck_results.expr_ty_adjusted_opt(index).unwrap_or_else(|| {
238-
// When encountering `return [0][0]` outside of a `fn` body we would attempt
239-
// to access an nonexistent index. We assume that more relevant errors will
240-
// already have been emitted, so we only gate on this with an ICE if no
241-
// error has been emitted. (#64638)
242-
self.fcx.tcx.ty_error_with_message(
243-
e.span,
244-
format!("bad index {:?} for base: `{:?}`", index, base),
245-
)
246-
});
247-
let index_ty = self.fcx.resolve_vars_if_possible(index_ty);
248-
let resolved_base_ty = self.resolve(*base_ty, &base.span);
249-
250-
if self.is_builtin_index(&typeck_results, e, resolved_base_ty, index_ty) {
223+
if let Some(base_ty) = base_ty
224+
&& let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()
225+
{
226+
let index_ty =
227+
self.typeck_results.expr_ty_adjusted_opt(index).unwrap_or_else(|| {
228+
// When encountering `return [0][0]` outside of a `fn` body we would attempt
229+
// to access an nonexistent index. We assume that more relevant errors will
230+
// already have been emitted, so we only gate on this with an ICE if no
231+
// error has been emitted. (#64638)
232+
self.fcx.tcx.ty_error_with_message(
233+
e.span,
234+
format!("bad index {:?} for base: `{:?}`", index, base),
235+
)
236+
});
237+
if self.is_builtin_index(e, base_ty_inner, index_ty) {
251238
// Remove the method call record
252-
typeck_results.type_dependent_defs_mut().remove(e.hir_id);
253-
typeck_results.node_substs_mut().remove(e.hir_id);
239+
self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
240+
self.typeck_results.node_substs_mut().remove(e.hir_id);
254241

255-
if let Some(a) = typeck_results.adjustments_mut().get_mut(base.hir_id) {
242+
if let Some(a) = self.typeck_results.adjustments_mut().get_mut(base.hir_id) {
256243
// Discard the need for a mutable borrow
257244

258245
// Extra adjustment made when indexing causes a drop
@@ -283,9 +270,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
283270

284271
impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
285272
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
286-
self.fix_scalar_builtin_expr(e);
287-
self.fix_index_builtin_expr(e);
288-
289273
match e.kind {
290274
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
291275
let body = self.fcx.tcx.hir().body(body);
@@ -314,6 +298,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
314298

315299
self.visit_node_id(e.span, e.hir_id);
316300
intravisit::walk_expr(self, e);
301+
302+
self.fix_scalar_builtin_expr(e);
303+
self.fix_index_builtin_expr(e);
317304
}
318305

319306
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
4+
const fn foo() {
5+
let mut x = [1, 2, 3];
6+
// We need to fix up `<<[i32; 3] as Index<usize>>::Output as AddAssign>`
7+
// to be treated like a built-in operation.
8+
x[1] += 5;
9+
}
10+
11+
fn main() {}

0 commit comments

Comments
 (0)