about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-08-19 12:26:45 +0530
committerGitHub <noreply@github.com>2022-08-19 12:26:45 +0530
commit490d04bfbcec365533591a5a5bbcd58fcd3f6517 (patch)
treeeefd28b3ff5e48cdee83a4392b5c9ded992b9de3 /compiler
parent769ad701294401b179e8569625ebeb585cab25ed (diff)
parent7b457184849d343d50a3eb56c28396189c696a42 (diff)
downloadrust-490d04bfbcec365533591a5a5bbcd58fcd3f6517.tar.gz
rust-490d04bfbcec365533591a5a5bbcd58fcd3f6517.zip
Rollup merge of #100598 - ouz-a:91633, r=compiler-errors
Don't fix builtin index when Where clause is found

Where clause shadows blanket impl for `Index` which causes normalization to not occur, which causes ICE to happen when we typeck.

r? `@compiler-errors`

Fixes #91633
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs26
1 files changed, 24 insertions, 2 deletions
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index ebf1f506183..ba687bc4da4 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -3,7 +3,6 @@
 // substitutions.
 
 use crate::check::FnCtxt;
-
 use hir::def_id::LocalDefId;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::ErrorGuaranteed;
@@ -16,6 +15,7 @@ use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable};
+use rustc_middle::ty::TypeckResults;
 use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
@@ -192,6 +192,27 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
+    // (ouz-a 1005988): Normally `[T] : std::ops::Index<usize>` should be normalized
+    // into [T] but currently `Where` clause stops the normalization process for it,
+    // here we compare types of expr and base in a code without `Where` clause they would be equal
+    // if they are not we don't modify the expr, hence we bypass the ICE
+    fn is_builtin_index(
+        &mut self,
+        typeck_results: &TypeckResults<'tcx>,
+        e: &hir::Expr<'_>,
+        base_ty: Ty<'tcx>,
+        index_ty: Ty<'tcx>,
+    ) -> bool {
+        if let Some(elem_ty) = base_ty.builtin_index() {
+            let Some(exp_ty) = typeck_results.expr_ty_opt(e) else {return false;};
+            let resolved_exp_ty = self.resolve(exp_ty, &e.span);
+
+            elem_ty == resolved_exp_ty && index_ty == self.fcx.tcx.types.usize
+        } else {
+            false
+        }
+    }
+
     // Similar to operators, indexing is always assumed to be overloaded
     // Here, correct cases where an indexing expression can be simplified
     // to use builtin indexing because the index type is known to be
@@ -222,8 +243,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                     )
                 });
                 let index_ty = self.fcx.resolve_vars_if_possible(index_ty);
+                let resolved_base_ty = self.resolve(*base_ty, &base.span);
 
-                if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize {
+                if self.is_builtin_index(&typeck_results, e, resolved_base_ty, index_ty) {
                     // Remove the method call record
                     typeck_results.type_dependent_defs_mut().remove(e.hir_id);
                     typeck_results.node_substs_mut().remove(e.hir_id);