diff options
| author | bors <bors@rust-lang.org> | 2023-12-07 21:26:18 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-07 21:26:18 +0000 |
| commit | 4196675f44dd98596d638860d6707dcce52a37fd (patch) | |
| tree | b0a0100d37c4e360a309dd45fd01b3596b0094fe | |
| parent | 49dd3804c0f61cee06abbca3dfb2df7b3a78bee6 (diff) | |
| parent | c11a002bca3c7b465ce21dcdbfffe18fd2a8c58c (diff) | |
| download | rust-4196675f44dd98596d638860d6707dcce52a37fd.tar.gz rust-4196675f44dd98596d638860d6707dcce52a37fd.zip | |
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.
| -rw-r--r-- | crates/hir-ty/src/consteval.rs | 18 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/regression.rs | 12 |
2 files changed, 27 insertions, 3 deletions
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index 576a07d4fb6..ddeb9f14b5d 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -3,7 +3,8 @@ use base_db::{salsa::Cycle, CrateId}; use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex}; use hir_def::{ - hir::Expr, + body::Body, + hir::{Expr, ExprId}, path::Path, resolver::{Resolver, ValueNs}, 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 // and make this function private. See the fixme comment on `InferenceContext::resolve_all`. pub(crate) fn eval_to_const( - expr: Idx<Expr>, + expr: ExprId, mode: ParamLoweringMode, ctx: &mut InferenceContext<'_>, args: impl FnOnce() -> Generics, @@ -288,13 +289,24 @@ pub(crate) fn eval_to_const( ) -> Const { let db = ctx.db; 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] { let resolver = &ctx.resolver; if let Some(c) = path_to_const(db, resolver, p, mode, args, debruijn, infer[expr].clone()) { 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(result) = interpret_mir(db, Arc::new(mir_body), true, None).0 { return result; diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs index 6ea059065e9..35079e70946 100644 --- a/crates/hir-ty/src/tests/regression.rs +++ b/crates/hir-ty/src/tests/regression.rs @@ -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] + //^ [(); _] + } + "#, + ); +} |
