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
This commit is contained in:
Dylan DPC 2022-08-19 12:26:45 +05:30 committed by GitHub
commit 490d04bfbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 229 additions and 2 deletions

View File

@ -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::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 @@ fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr<'_>) {
}
}
// (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 @@ fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
)
});
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);

View File

@ -0,0 +1,31 @@
// compile-flags: -Z mir-opt-level=0
// EMIT_MIR issue_91633.hey.mir_map.0.mir
fn hey<T> (it: &[T])
where
[T] : std::ops::Index<usize>,
{
let _ = &it[0];
}
// EMIT_MIR issue_91633.bar.mir_map.0.mir
fn bar<T> (it: Box<[T]>)
where
[T] : std::ops::Index<usize>,
{
let _ = it[0];
}
// EMIT_MIR issue_91633.fun.mir_map.0.mir
fn fun<T> (it: &[T]) -> &T
{
let f = &it[0];
f
}
// EMIT_MIR issue_91633.foo.mir_map.0.mir
fn foo<T: Clone> (it: Box<[T]>) -> T
{
let f = it[0].clone();
f
}
fn main(){}

View File

@ -0,0 +1,39 @@
// MIR for `bar` 0 mir_map
fn bar(_1: Box<[T]>) -> () {
debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
let mut _0: (); // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2
let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
let mut _3: &[T]; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
scope 1 {
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
_3 = &(*_1); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
_2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
// mir::Constant
// + span: $DIR/issue-91633.rs:15:14: 15:19
// + literal: Const { ty: for<'r> fn(&'r [T], usize) -> &'r <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+4:18: +4:19
StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20
_0 = const (); // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3
drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
}
bb2: {
return; // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3
}
bb3 (cleanup): {
drop(_1) -> bb4; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3
}
}

View File

@ -0,0 +1,57 @@
// MIR for `foo` 0 mir_map
fn foo(_1: Box<[T]>) -> T {
debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:19: +0:21
let mut _0: T; // return place in scope 0 at $DIR/issue-91633.rs:+0:36: +0:37
let _2: T; // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
let mut _3: &T; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
let _4: usize; // in scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
let mut _5: usize; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
let mut _6: bool; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
scope 1 {
debug f => _2; // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
StorageLive(_4); // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
_4 = const 0_usize; // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
_5 = Len((*_1)); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
_6 = Lt(_4, _5); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
}
bb1: {
_3 = &(*_1)[_4]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
_2 = <T as Clone>::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
// mir::Constant
// + span: $DIR/issue-91633.rs:28:20: 28:25
// + literal: Const { ty: for<'r> fn(&'r T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
}
bb2: {
StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+2:26: +2:27
FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
StorageDead(_4); // scope 0 at $DIR/issue-91633.rs:+2:27: +2:28
_0 = move _2; // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7
drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
}
bb3: {
StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
}
bb4: {
return; // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3
}
bb5 (cleanup): {
drop(_1) -> bb6; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
}
bb6 (cleanup): {
resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3
}
}

View File

@ -0,0 +1,35 @@
// MIR for `fun` 0 mir_map
fn fun(_1: &[T]) -> &T {
debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
let mut _0: &T; // return place in scope 0 at $DIR/issue-91633.rs:+0:25: +0:27
let _2: &T; // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
let _3: usize; // in scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
let mut _4: usize; // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
let mut _5: bool; // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
scope 1 {
debug f => _2; // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
_3 = const 0_usize; // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
_4 = Len((*_1)); // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
_5 = Lt(_3, _4); // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
}
bb1: {
_2 = &(*_1)[_3]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:20
FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
_0 = &(*_2); // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7
StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
return; // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3
}
bb2 (cleanup): {
resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3
}
}

View File

@ -0,0 +1,35 @@
// MIR for `hey` 0 mir_map
fn hey(_1: &[T]) -> () {
debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
let mut _0: (); // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2
let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
let _3: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
let mut _4: &[T]; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
scope 1 {
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
StorageLive(_4); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
_4 = &(*_1); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
_3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
// mir::Constant
// + span: $DIR/issue-91633.rs:7:15: 7:20
// + literal: Const { ty: for<'r> fn(&'r [T], usize) -> &'r <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_4); // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20
_2 = &(*_3); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:20: +4:21
_0 = const (); // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3
StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
return; // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3
}
bb2 (cleanup): {
resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3
}
}

View File

@ -0,0 +1,8 @@
// check-pass
fn f<T> (it: &[T])
where
[T] : std::ops::Index<usize>,
{
let _ = &it[0];
}
fn main(){}