From cb301751b3ade3cf65f1d3eeb0c94ffce1a45561 Mon Sep 17 00:00:00 2001 From: delta17920 Date: Sat, 13 Dec 2025 15:18:34 +0000 Subject: [PATCH 1/3] Suggest struct pattern when destructuring Range with .. syntax --- .../rustc_resolve/src/late/diagnostics.rs | 36 ++++++++++ .../suggest-range-struct-destructuring.rs | 15 +++++ .../suggest-range-struct-destructuring.stderr | 66 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 tests/ui/resolve/suggest-range-struct-destructuring.rs create mode 100644 tests/ui/resolve/suggest-range-struct-destructuring.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 233a4c48862ac..0348764009b28 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -440,6 +440,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg); self.suggest_at_operator_in_slice_pat_with_range(&mut err, path); + self.suggest_range_struct_destructuring(&mut err, path, source); self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); if let Some((span, label)) = base_error.span_label { @@ -1383,6 +1384,41 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } + fn suggest_range_struct_destructuring( + &self, + err: &mut Diag<'_>, + path: &[Segment], + source: PathSource<'_, '_, '_>, + ) { + // We accept Expr here because range bounds (start..end) are parsed as expressions + if !matches!(source, PathSource::Pat | PathSource::TupleStruct(..) | PathSource::Expr(..)) { + return; + } + + if let Some(pat) = self.diag_metadata.current_pat + && let ast::PatKind::Range(Some(start_expr), Some(end_expr), _) = &pat.kind + && let (ast::ExprKind::Path(None, start_path), ast::ExprKind::Path(None, end_path)) = + (&start_expr.kind, &end_expr.kind) + && path.len() == 1 + { + let ident = path[0].ident; + + if (start_path.segments.len() == 1 && start_path.segments[0].ident == ident) + || (end_path.segments.len() == 1 && end_path.segments[0].ident == ident) + { + let start_name = start_path.segments[0].ident; + let end_name = end_path.segments[0].ident; + + err.span_suggestion_verbose( + pat.span, + "if you meant to destructure a `Range`, use the struct pattern", + format!("std::ops::Range {{ start: {}, end: {} }}", start_name, end_name), + Applicability::MaybeIncorrect, + ); + } + } + } + fn suggest_swapping_misplaced_self_ty_and_trait( &mut self, err: &mut Diag<'_>, diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.rs b/tests/ui/resolve/suggest-range-struct-destructuring.rs new file mode 100644 index 0000000000000..f690a7cad23f2 --- /dev/null +++ b/tests/ui/resolve/suggest-range-struct-destructuring.rs @@ -0,0 +1,15 @@ +use std::ops::Range; + +fn test_basic_range(r: Range) { + let start..end = r; + //~^ ERROR cannot find value `start` in this scope + //~| ERROR cannot find value `end` in this scope +} + +fn test_different_names(r: Range) { + let min..max = r; + //~^ ERROR cannot find value `min` in this scope + //~| ERROR cannot find value `max` in this scope +} + +fn main() {} diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.stderr b/tests/ui/resolve/suggest-range-struct-destructuring.stderr new file mode 100644 index 0000000000000..291abf0d01d3f --- /dev/null +++ b/tests/ui/resolve/suggest-range-struct-destructuring.stderr @@ -0,0 +1,66 @@ +error[E0425]: cannot find value `start` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:4:9 + | +LL | let start..end = r; + | ^^^^^ not found in this scope + | +help: if you meant to destructure a `Range`, use the struct pattern + | +LL - let start..end = r; +LL + let std::ops::Range { start: start, end: end } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:4:16 + | +LL | let start..end = r; + | ^^^ not found in this scope + | +help: if you meant to destructure a `Range`, use the struct pattern + | +LL - let start..end = r; +LL + let std::ops::Range { start: start, end: end } = r; + | + +error[E0425]: cannot find value `min` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:10:9 + | +LL | let min..max = r; + | ^^^ +... +LL | fn main() {} + | --------- similarly named function `main` defined here + | +help: if you meant to destructure a `Range`, use the struct pattern + | +LL - let min..max = r; +LL + let std::ops::Range { start: min, end: max } = r; + | +help: a function with a similar name exists + | +LL | let main..max = r; + | + +help: consider importing this function + | +LL + use std::cmp::min; + | + +error[E0425]: cannot find value `max` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:10:14 + | +LL | let min..max = r; + | ^^^ not found in this scope + | +help: if you meant to destructure a `Range`, use the struct pattern + | +LL - let min..max = r; +LL + let std::ops::Range { start: min, end: max } = r; + | +help: consider importing this function + | +LL + use std::cmp::max; + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`. From 3e78653ec32342708b70268e179dfcaad02f4d4e Mon Sep 17 00:00:00 2001 From: delta17920 Date: Sun, 14 Dec 2025 04:04:53 +0000 Subject: [PATCH 2/3] Fix grammar in suggestion message --- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- .../ui/resolve/suggest-range-struct-destructuring.stderr | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0348764009b28..85e8917ae32e8 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1411,7 +1411,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.span_suggestion_verbose( pat.span, - "if you meant to destructure a `Range`, use the struct pattern", + "if you meant to destructure a `Range`, use a struct pattern", format!("std::ops::Range {{ start: {}, end: {} }}", start_name, end_name), Applicability::MaybeIncorrect, ); diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.stderr b/tests/ui/resolve/suggest-range-struct-destructuring.stderr index 291abf0d01d3f..1a11e6ac84219 100644 --- a/tests/ui/resolve/suggest-range-struct-destructuring.stderr +++ b/tests/ui/resolve/suggest-range-struct-destructuring.stderr @@ -4,7 +4,7 @@ error[E0425]: cannot find value `start` in this scope LL | let start..end = r; | ^^^^^ not found in this scope | -help: if you meant to destructure a `Range`, use the struct pattern +help: if you meant to destructure a `Range`, use a struct pattern | LL - let start..end = r; LL + let std::ops::Range { start: start, end: end } = r; @@ -16,7 +16,7 @@ error[E0425]: cannot find value `end` in this scope LL | let start..end = r; | ^^^ not found in this scope | -help: if you meant to destructure a `Range`, use the struct pattern +help: if you meant to destructure a `Range`, use a struct pattern | LL - let start..end = r; LL + let std::ops::Range { start: start, end: end } = r; @@ -31,7 +31,7 @@ LL | let min..max = r; LL | fn main() {} | --------- similarly named function `main` defined here | -help: if you meant to destructure a `Range`, use the struct pattern +help: if you meant to destructure a `Range`, use a struct pattern | LL - let min..max = r; LL + let std::ops::Range { start: min, end: max } = r; @@ -51,7 +51,7 @@ error[E0425]: cannot find value `max` in this scope LL | let min..max = r; | ^^^ not found in this scope | -help: if you meant to destructure a `Range`, use the struct pattern +help: if you meant to destructure a `Range`, use a struct pattern | LL - let min..max = r; LL + let std::ops::Range { start: min, end: max } = r; From 6fac0fac9962962f77f46fe148bbca2ed6b60f59 Mon Sep 17 00:00:00 2001 From: delta17920 Date: Sun, 14 Dec 2025 15:08:01 +0000 Subject: [PATCH 3/3] Apply review suggestions --- .../rustc_resolve/src/late/diagnostics.rs | 85 +++++++++---- tests/ui/match/issue-92100.stderr | 6 + ...tern-meant-to-be-slice-rest-pattern.stderr | 18 +++ .../suggest-range-struct-destructuring.rs | 41 ++++-- .../suggest-range-struct-destructuring.stderr | 117 +++++++++++++----- tests/ui/typeck/issue-105946.stderr | 6 + 6 files changed, 216 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 85e8917ae32e8..f75ac400dc0ba 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1385,38 +1385,81 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } fn suggest_range_struct_destructuring( - &self, + &mut self, err: &mut Diag<'_>, path: &[Segment], source: PathSource<'_, '_, '_>, ) { - // We accept Expr here because range bounds (start..end) are parsed as expressions if !matches!(source, PathSource::Pat | PathSource::TupleStruct(..) | PathSource::Expr(..)) { return; } - if let Some(pat) = self.diag_metadata.current_pat - && let ast::PatKind::Range(Some(start_expr), Some(end_expr), _) = &pat.kind - && let (ast::ExprKind::Path(None, start_path), ast::ExprKind::Path(None, end_path)) = - (&start_expr.kind, &end_expr.kind) - && path.len() == 1 - { - let ident = path[0].ident; + let Some(pat) = self.diag_metadata.current_pat else { return }; + let ast::PatKind::Range(start, end, end_kind) = &pat.kind else { return }; - if (start_path.segments.len() == 1 && start_path.segments[0].ident == ident) - || (end_path.segments.len() == 1 && end_path.segments[0].ident == ident) - { - let start_name = start_path.segments[0].ident; - let end_name = end_path.segments[0].ident; + let [segment] = path else { return }; + let failing_span = segment.ident.span; - err.span_suggestion_verbose( - pat.span, - "if you meant to destructure a `Range`, use a struct pattern", - format!("std::ops::Range {{ start: {}, end: {} }}", start_name, end_name), - Applicability::MaybeIncorrect, - ); - } + let in_start = start.as_ref().is_some_and(|e| e.span.contains(failing_span)); + let in_end = end.as_ref().is_some_and(|e| e.span.contains(failing_span)); + + if !in_start && !in_end { + return; } + + let start_snippet = + start.as_ref().and_then(|e| self.r.tcx.sess.source_map().span_to_snippet(e.span).ok()); + let end_snippet = + end.as_ref().and_then(|e| self.r.tcx.sess.source_map().span_to_snippet(e.span).ok()); + + let field = |name: &str, val: String| { + if val == name { val } else { format!("{name}: {val}") } + }; + + let mut resolve_short_name = |short: Symbol, full: &str| -> String { + let ident = Ident::with_dummy_span(short); + let path = Segment::from_path(&Path::from_ident(ident)); + + match self.resolve_path(&path, Some(TypeNS), None, PathSource::Type) { + PathResult::NonModule(..) => short.to_string(), + _ => full.to_string(), + } + }; + // FIXME(new_range): Also account for new range types + let (struct_path, fields) = match (start_snippet, end_snippet, &end_kind.node) { + (Some(start), Some(end), ast::RangeEnd::Excluded) => ( + resolve_short_name(sym::Range, "std::ops::Range"), + vec![field("start", start), field("end", end)], + ), + (Some(start), Some(end), ast::RangeEnd::Included(_)) => ( + resolve_short_name(sym::RangeInclusive, "std::ops::RangeInclusive"), + vec![field("start", start), field("end", end)], + ), + (Some(start), None, _) => ( + resolve_short_name(sym::RangeFrom, "std::ops::RangeFrom"), + vec![field("start", start)], + ), + (None, Some(end), ast::RangeEnd::Excluded) => { + (resolve_short_name(sym::RangeTo, "std::ops::RangeTo"), vec![field("end", end)]) + } + (None, Some(end), ast::RangeEnd::Included(_)) => ( + resolve_short_name(sym::RangeToInclusive, "std::ops::RangeToInclusive"), + vec![field("end", end)], + ), + _ => return, + }; + + err.span_suggestion_verbose( + pat.span, + format!("if you meant to destructure a range use a struct pattern"), + format!("{} {{ {} }}", struct_path, fields.join(", ")), + Applicability::MaybeIncorrect, + ); + + err.note( + "range patterns match against the start and end of a range; \ + to bind the components, use a struct pattern", + ); } fn suggest_swapping_misplaced_self_ty_and_trait( diff --git a/tests/ui/match/issue-92100.stderr b/tests/ui/match/issue-92100.stderr index eb9f4ba1ad698..13aacc4782af2 100644 --- a/tests/ui/match/issue-92100.stderr +++ b/tests/ui/match/issue-92100.stderr @@ -4,10 +4,16 @@ error[E0425]: cannot find value `a` in this scope LL | [a.., a] => {} | ^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `a`, use the at operator | LL | [a @ .., a] => {} | + +help: if you meant to destructure a range use a struct pattern + | +LL - [a.., a] => {} +LL + [std::ops::RangeFrom { start: a }, a] => {} + | error: aborting due to 1 previous error diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr index 37b2d96bb0194..378ff04d3a1af 100644 --- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr +++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr @@ -16,10 +16,16 @@ error[E0425]: cannot find value `rest` in this scope LL | [1, rest..] => println!("{rest}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `rest`, use the at operator | LL | [1, rest @ ..] => println!("{rest}"), | + +help: if you meant to destructure a range use a struct pattern + | +LL - [1, rest..] => println!("{rest}"), +LL + [1, std::ops::RangeFrom { start: rest }] => println!("{rest}"), + | error[E0425]: cannot find value `rest` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:35 @@ -33,11 +39,17 @@ error[E0425]: cannot find value `tail` in this scope LL | [_, ..tail] => println!("{tail}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `tail`, use the at operator | LL - [_, ..tail] => println!("{tail}"), LL + [_, tail @ ..] => println!("{tail}"), | +help: if you meant to destructure a range use a struct pattern + | +LL - [_, ..tail] => println!("{tail}"), +LL + [_, std::ops::RangeTo { end: tail }] => println!("{tail}"), + | error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:35 @@ -51,11 +63,17 @@ error[E0425]: cannot find value `tail` in this scope LL | [_, ...tail] => println!("{tail}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `tail`, use the at operator | LL - [_, ...tail] => println!("{tail}"), LL + [_, tail @ ..] => println!("{tail}"), | +help: if you meant to destructure a range use a struct pattern + | +LL - [_, ...tail] => println!("{tail}"), +LL + [_, std::ops::RangeToInclusive { end: tail }] => println!("{tail}"), + | error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:36 diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.rs b/tests/ui/resolve/suggest-range-struct-destructuring.rs index f690a7cad23f2..ee8a99ceaa1a3 100644 --- a/tests/ui/resolve/suggest-range-struct-destructuring.rs +++ b/tests/ui/resolve/suggest-range-struct-destructuring.rs @@ -1,15 +1,40 @@ -use std::ops::Range; +use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive}; -fn test_basic_range(r: Range) { +fn test_range(r: Range) { let start..end = r; - //~^ ERROR cannot find value `start` in this scope - //~| ERROR cannot find value `end` in this scope + //~^ ERROR cannot find value `start` + //~| ERROR cannot find value `end` } -fn test_different_names(r: Range) { - let min..max = r; - //~^ ERROR cannot find value `min` in this scope - //~| ERROR cannot find value `max` in this scope +fn test_inclusive(r: RangeInclusive) { + let start..=end = r; + //~^ ERROR cannot find value `start` + //~| ERROR cannot find value `end` +} + +fn test_from(r: RangeFrom) { + let start.. = r; + //~^ ERROR cannot find value `start` +} + +fn test_to(r: RangeTo) { + let ..end = r; + //~^ ERROR cannot find value `end` +} + +fn test_to_inclusive(r: RangeToInclusive) { + let ..=end = r; + //~^ ERROR cannot find value `end` +} + +// Case 6: Complex Path (Keep this! It works!) +mod my { + // We don't define MISSING here to trigger the error +} +fn test_path(r: Range) { + let my::MISSING..end = r; + //~^ ERROR cannot find value `MISSING` + //~| ERROR cannot find value `end` } fn main() {} diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.stderr b/tests/ui/resolve/suggest-range-struct-destructuring.stderr index 1a11e6ac84219..78a248ed777d1 100644 --- a/tests/ui/resolve/suggest-range-struct-destructuring.stderr +++ b/tests/ui/resolve/suggest-range-struct-destructuring.stderr @@ -4,10 +4,11 @@ error[E0425]: cannot find value `start` in this scope LL | let start..end = r; | ^^^^^ not found in this scope | -help: if you meant to destructure a `Range`, use a struct pattern + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern | LL - let start..end = r; -LL + let std::ops::Range { start: start, end: end } = r; +LL + let Range { start, end } = r; | error[E0425]: cannot find value `end` in this scope @@ -16,51 +17,111 @@ error[E0425]: cannot find value `end` in this scope LL | let start..end = r; | ^^^ not found in this scope | -help: if you meant to destructure a `Range`, use a struct pattern + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern | LL - let start..end = r; -LL + let std::ops::Range { start: start, end: end } = r; +LL + let Range { start, end } = r; | -error[E0425]: cannot find value `min` in this scope +error[E0425]: cannot find value `start` in this scope --> $DIR/suggest-range-struct-destructuring.rs:10:9 | -LL | let min..max = r; - | ^^^ -... -LL | fn main() {} - | --------- similarly named function `main` defined here +LL | let start..=end = r; + | ^^^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern + | +LL - let start..=end = r; +LL + let RangeInclusive { start, end } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:10:17 + | +LL | let start..=end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern + | +LL - let start..=end = r; +LL + let RangeInclusive { start, end } = r; + | + +error[E0425]: cannot find value `start` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:16:9 + | +LL | let start.. = r; + | ^^^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `start`, use the at operator + | +LL | let start @ .. = r; + | + +help: if you meant to destructure a range use a struct pattern + | +LL - let start.. = r; +LL + let RangeFrom { start } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:21:11 | -help: if you meant to destructure a `Range`, use a struct pattern +LL | let ..end = r; + | ^^^ not found in this scope | -LL - let min..max = r; -LL + let std::ops::Range { start: min, end: max } = r; + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `end`, use the at operator | -help: a function with a similar name exists +LL - let ..end = r; +LL + let end @ .. = r; | -LL | let main..max = r; - | + -help: consider importing this function +help: if you meant to destructure a range use a struct pattern | -LL + use std::cmp::min; +LL - let ..end = r; +LL + let RangeTo { end } = r; | -error[E0425]: cannot find value `max` in this scope - --> $DIR/suggest-range-struct-destructuring.rs:10:14 +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:26:12 + | +LL | let ..=end = r; + | ^^^ not found in this scope | -LL | let min..max = r; - | ^^^ not found in this scope + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `end`, use the at operator | -help: if you meant to destructure a `Range`, use a struct pattern +LL - let ..=end = r; +LL + let end @ .. = r; + | +help: if you meant to destructure a range use a struct pattern + | +LL - let ..=end = r; +LL + let RangeToInclusive { end } = r; + | + +error[E0425]: cannot find value `MISSING` in module `my` + --> $DIR/suggest-range-struct-destructuring.rs:35:13 + | +LL | let my::MISSING..end = r; + | ^^^^^^^ not found in `my` + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:35:22 | -LL - let min..max = r; -LL + let std::ops::Range { start: min, end: max } = r; +LL | let my::MISSING..end = r; + | ^^^ not found in this scope | -help: consider importing this function + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern | -LL + use std::cmp::max; +LL - let my::MISSING..end = r; +LL + let Range { start: my::MISSING, end } = r; | -error: aborting due to 4 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/typeck/issue-105946.stderr b/tests/ui/typeck/issue-105946.stderr index 30fe2000a4619..3f8733bda7631 100644 --- a/tests/ui/typeck/issue-105946.stderr +++ b/tests/ui/typeck/issue-105946.stderr @@ -4,10 +4,16 @@ error[E0425]: cannot find value `_y` in this scope LL | let [_y..] = [Box::new(1), Box::new(2)]; | ^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `_y`, use the at operator | LL | let [_y @ ..] = [Box::new(1), Box::new(2)]; | + +help: if you meant to destructure a range use a struct pattern + | +LL - let [_y..] = [Box::new(1), Box::new(2)]; +LL + let [std::ops::RangeFrom { start: _y }] = [Box::new(1), Box::new(2)]; + | error[E0658]: `X..` patterns in slices are experimental --> $DIR/issue-105946.rs:7:10