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:
commit
490d04bfbc
@ -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);
|
||||
|
31
src/test/mir-opt/issue-91633.rs
Normal file
31
src/test/mir-opt/issue-91633.rs
Normal 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(){}
|
39
src/test/mir-opt/issue_91633.bar.mir_map.0.mir
Normal file
39
src/test/mir-opt/issue_91633.bar.mir_map.0.mir
Normal 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
|
||||
}
|
||||
}
|
57
src/test/mir-opt/issue_91633.foo.mir_map.0.mir
Normal file
57
src/test/mir-opt/issue_91633.foo.mir_map.0.mir
Normal 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
|
||||
}
|
||||
}
|
35
src/test/mir-opt/issue_91633.fun.mir_map.0.mir
Normal file
35
src/test/mir-opt/issue_91633.fun.mir_map.0.mir
Normal 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
|
||||
}
|
||||
}
|
35
src/test/mir-opt/issue_91633.hey.mir_map.0.mir
Normal file
35
src/test/mir-opt/issue_91633.hey.mir_map.0.mir
Normal 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
|
||||
}
|
||||
}
|
8
src/test/ui/typeck/issue-91633.rs
Normal file
8
src/test/ui/typeck/issue-91633.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// check-pass
|
||||
fn f<T> (it: &[T])
|
||||
where
|
||||
[T] : std::ops::Index<usize>,
|
||||
{
|
||||
let _ = &it[0];
|
||||
}
|
||||
fn main(){}
|
Loading…
Reference in New Issue
Block a user