From 932186d9c2046257c0a1fc38c1cecf7bc19736c3 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 29 May 2026 01:16:22 +0300 Subject: [PATCH] Do not assume array destructuring assignments with rest pattern are constant-sized We used to set a `slice: None`. --- crates/hir-def/src/expr_store/lower.rs | 12 ++++++++++-- .../src/handlers/mismatched_array_pat_len.rs | 11 +++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index 21b5b199867f..b33b04e95ae4 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -1844,12 +1844,20 @@ impl<'db> ExprCollector<'db> { } let mut elements = e.exprs(); + let mut rest_ptr = None; let prefix = elements .by_ref() - .map_while(|elem| collect_possibly_rest(self, elem).left()) + .map_while(|elem| match collect_possibly_rest(self, elem.clone()) { + Either::Left(elem) => Some(elem), + Either::Right(()) => { + rest_ptr = Some(AstPtr::new(&elem)); + None + } + }) .collect(); let suffix = elements.map(|elem| self.collect_expr_as_pat(elem)).collect(); - self.alloc_pat_from_expr(Pat::Slice { prefix, slice: None, suffix }, syntax_ptr) + let slice = rest_ptr.map(|ptr| self.alloc_pat_from_expr(Pat::Rest, ptr)); + self.alloc_pat_from_expr(Pat::Slice { prefix, slice, suffix }, syntax_ptr) } ast::Expr::CallExpr(e) => { let path = collect_path(self, e.expr()?)?; diff --git a/crates/ide-diagnostics/src/handlers/mismatched_array_pat_len.rs b/crates/ide-diagnostics/src/handlers/mismatched_array_pat_len.rs index 8cae405c92ee..bd02ce6a02c7 100644 --- a/crates/ide-diagnostics/src/handlers/mismatched_array_pat_len.rs +++ b/crates/ide-diagnostics/src/handlers/mismatched_array_pat_len.rs @@ -111,4 +111,15 @@ fn f(arr: [i32; 3]) { "#, ); } + + #[test] + fn destructuring_assignment_array_rest() { + check_diagnostics( + r#" +fn main() { + [..] = [1, 2, 3]; +} + "#, + ); + } }