Auto merge of #16045 - HKalbasi:rustc-tests-fixup, r=HKalbasi

Fix panic with closure inside array len

I was working on #15947 and found out that we panic on this test:
```
fn main() {
    let x = [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
}
```
This PR fixes the panic. Closures in array len are still broken, but closure in const eval is not stable anyway.
This commit is contained in:
bors 2023-12-07 21:26:18 +00:00
commit 4196675f44
2 changed files with 27 additions and 3 deletions

View File

@ -3,7 +3,8 @@
use base_db::{salsa::Cycle, CrateId}; use base_db::{salsa::Cycle, CrateId};
use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex}; use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex};
use hir_def::{ use hir_def::{
hir::Expr, body::Body,
hir::{Expr, ExprId},
path::Path, path::Path,
resolver::{Resolver, ValueNs}, resolver::{Resolver, ValueNs},
type_ref::LiteralConstRef, type_ref::LiteralConstRef,
@ -280,7 +281,7 @@ pub(crate) fn const_eval_discriminant_variant(
// get an `InferenceResult` instead of an `InferenceContext`. And we should remove `ctx.clone().resolve_all()` here // get an `InferenceResult` instead of an `InferenceContext`. And we should remove `ctx.clone().resolve_all()` here
// and make this function private. See the fixme comment on `InferenceContext::resolve_all`. // and make this function private. See the fixme comment on `InferenceContext::resolve_all`.
pub(crate) fn eval_to_const( pub(crate) fn eval_to_const(
expr: Idx<Expr>, expr: ExprId,
mode: ParamLoweringMode, mode: ParamLoweringMode,
ctx: &mut InferenceContext<'_>, ctx: &mut InferenceContext<'_>,
args: impl FnOnce() -> Generics, args: impl FnOnce() -> Generics,
@ -288,13 +289,24 @@ pub(crate) fn eval_to_const(
) -> Const { ) -> Const {
let db = ctx.db; let db = ctx.db;
let infer = ctx.clone().resolve_all(); let infer = ctx.clone().resolve_all();
fn has_closure(body: &Body, expr: ExprId) -> bool {
if matches!(body[expr], Expr::Closure { .. }) {
return true;
}
let mut r = false;
body[expr].walk_child_exprs(|idx| r |= has_closure(body, idx));
r
}
if has_closure(&ctx.body, expr) {
// Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic.
return unknown_const(infer[expr].clone());
}
if let Expr::Path(p) = &ctx.body.exprs[expr] { if let Expr::Path(p) = &ctx.body.exprs[expr] {
let resolver = &ctx.resolver; let resolver = &ctx.resolver;
if let Some(c) = path_to_const(db, resolver, p, mode, args, debruijn, infer[expr].clone()) { if let Some(c) = path_to_const(db, resolver, p, mode, args, debruijn, infer[expr].clone()) {
return c; return c;
} }
} }
let infer = ctx.clone().resolve_all();
if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, &ctx.body, &infer, expr) { if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, &ctx.body, &infer, expr) {
if let Ok(result) = interpret_mir(db, Arc::new(mir_body), true, None).0 { if let Ok(result) = interpret_mir(db, Arc::new(mir_body), true, None).0 {
return result; return result;

View File

@ -2000,3 +2000,15 @@ fn test() {
"#, "#,
); );
} }
#[test]
fn rustc_test_issue_52437() {
check_types(
r#"
fn main() {
let x = [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
//^ [(); _]
}
"#,
);
}