Rollup merge of #120597 - fmease:sugg-on-js-style-spread-op-in-pat, r=estebank
Suggest `[tail @ ..]` on `[..tail]` and `[...tail]` where `tail` is unresolved Fixes #120591. ~~Will conflict with #120570~~ (rebased). r? estebank or compiler
This commit is contained in:
commit
89aa85d805
@ -292,6 +292,9 @@ resolve_underscore_lifetime_name_cannot_be_used_here =
|
|||||||
resolve_unexpected_res_change_ty_to_const_param_sugg =
|
resolve_unexpected_res_change_ty_to_const_param_sugg =
|
||||||
you might have meant to write a const parameter here
|
you might have meant to write a const parameter here
|
||||||
|
|
||||||
|
resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg =
|
||||||
|
if you meant to collect the rest of the slice in `{$ident}`, use the at operator
|
||||||
|
|
||||||
resolve_unreachable_label =
|
resolve_unreachable_label =
|
||||||
use of unreachable label `{$name}`
|
use of unreachable label `{$name}`
|
||||||
.label = unreachable label `{$name}`
|
.label = unreachable label `{$name}`
|
||||||
|
@ -800,3 +800,17 @@ pub(crate) struct UnexpectedResChangeTyToConstParamSugg {
|
|||||||
#[applicability]
|
#[applicability]
|
||||||
pub applicability: Applicability,
|
pub applicability: Applicability,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[suggestion(
|
||||||
|
resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg,
|
||||||
|
code = "{snippet}",
|
||||||
|
applicability = "maybe-incorrect",
|
||||||
|
style = "verbose"
|
||||||
|
)]
|
||||||
|
pub(crate) struct UnexpectedResUseAtOpInSlicePatWithRangeSugg {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub ident: Ident,
|
||||||
|
pub snippet: String,
|
||||||
|
}
|
||||||
|
@ -1077,24 +1077,34 @@ fn suggest_at_operator_in_slice_pat_with_range(
|
|||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
path: &[Segment],
|
path: &[Segment],
|
||||||
) {
|
) {
|
||||||
if let Some(pat) = self.diagnostic_metadata.current_pat
|
let Some(pat) = self.diagnostic_metadata.current_pat else { return };
|
||||||
&& let ast::PatKind::Range(Some(start), None, range) = &pat.kind
|
let (bound, side, range) = match &pat.kind {
|
||||||
&& let ExprKind::Path(None, range_path) = &start.kind
|
ast::PatKind::Range(Some(bound), None, range) => (bound, Side::Start, range),
|
||||||
|
ast::PatKind::Range(None, Some(bound), range) => (bound, Side::End, range),
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
if let ExprKind::Path(None, range_path) = &bound.kind
|
||||||
&& let [segment] = &range_path.segments[..]
|
&& let [segment] = &range_path.segments[..]
|
||||||
&& let [s] = path
|
&& let [s] = path
|
||||||
&& segment.ident == s.ident
|
&& segment.ident == s.ident
|
||||||
|
&& segment.ident.span.eq_ctxt(range.span)
|
||||||
{
|
{
|
||||||
// We've encountered `[first, rest..]` where the user might have meant
|
// We've encountered `[first, rest..]` (#88404) or `[first, ..rest]` (#120591)
|
||||||
// `[first, rest @ ..]` (#88404).
|
// where the user might have meant `[first, rest @ ..]`.
|
||||||
err.span_suggestion_verbose(
|
let (span, snippet) = match side {
|
||||||
segment.ident.span.between(range.span),
|
Side::Start => (segment.ident.span.between(range.span), " @ ".into()),
|
||||||
format!(
|
Side::End => (range.span.to(segment.ident.span), format!("{} @ ..", segment.ident)),
|
||||||
"if you meant to collect the rest of the slice in `{}`, use the at operator",
|
};
|
||||||
segment.ident,
|
err.subdiagnostic(errors::UnexpectedResUseAtOpInSlicePatWithRangeSugg {
|
||||||
),
|
span,
|
||||||
" @ ",
|
ident: segment.ident,
|
||||||
Applicability::MaybeIncorrect,
|
snippet,
|
||||||
);
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Side {
|
||||||
|
Start,
|
||||||
|
End,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,23 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
match &[1, 2, 3][..] {
|
match &[1, 2, 3][..] {
|
||||||
[1, rest..] => println!("{rest:?}"),
|
[1, rest..] => println!("{rest}"),
|
||||||
//~^ ERROR cannot find value `rest` in this scope
|
//~^ ERROR cannot find value `rest` in this scope
|
||||||
//~| ERROR cannot find value `rest` in this scope
|
//~| ERROR cannot find value `rest` in this scope
|
||||||
//~| ERROR `X..` patterns in slices are experimental
|
//~| ERROR `X..` patterns in slices are experimental
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
match &[4, 5, 6][..] {
|
||||||
|
[] => {}
|
||||||
|
[_, ..tail] => println!("{tail}"),
|
||||||
|
//~^ ERROR cannot find value `tail` in this scope
|
||||||
|
//~| ERROR cannot find value `tail` in this scope
|
||||||
|
//~| ERROR exclusive range pattern syntax is experimental
|
||||||
|
}
|
||||||
|
match &[7, 8, 9][..] {
|
||||||
|
[] => {}
|
||||||
|
[_, ...tail] => println!("{tail}"),
|
||||||
|
//~^ ERROR cannot find value `tail` in this scope
|
||||||
|
//~| ERROR cannot find value `tail` in this scope
|
||||||
|
//~| ERROR range-to patterns with `...` are not allowed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,82 @@
|
|||||||
|
error: range-to patterns with `...` are not allowed
|
||||||
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:13
|
||||||
|
|
|
||||||
|
LL | [_, ...tail] => println!("{tail}"),
|
||||||
|
| ^^^ help: use `..=` instead
|
||||||
|
|
||||||
error[E0425]: cannot find value `rest` in this scope
|
error[E0425]: cannot find value `rest` in this scope
|
||||||
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:13
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:13
|
||||||
|
|
|
|
||||||
LL | [1, rest..] => println!("{rest:?}"),
|
LL | [1, rest..] => println!("{rest}"),
|
||||||
| ^^^^ not found in this scope
|
| ^^^^ not found in this scope
|
||||||
|
|
|
|
||||||
help: if you meant to collect the rest of the slice in `rest`, use the at operator
|
help: if you meant to collect the rest of the slice in `rest`, use the at operator
|
||||||
|
|
|
|
||||||
LL | [1, rest @ ..] => println!("{rest:?}"),
|
LL | [1, rest @ ..] => println!("{rest}"),
|
||||||
| +
|
| +
|
||||||
|
|
||||||
error[E0425]: cannot find value `rest` in this scope
|
error[E0425]: cannot find value `rest` in this scope
|
||||||
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:35
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:35
|
||||||
|
|
|
|
||||||
LL | [1, rest..] => println!("{rest:?}"),
|
LL | [1, rest..] => println!("{rest}"),
|
||||||
|
| ^^^^ not found in this scope
|
||||||
|
|
||||||
|
error[E0425]: cannot find value `tail` in this scope
|
||||||
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:15
|
||||||
|
|
|
||||||
|
LL | [_, ..tail] => println!("{tail}"),
|
||||||
|
| ^^^^ not found in this scope
|
||||||
|
|
|
||||||
|
help: if you meant to collect the rest of the slice in `tail`, use the at operator
|
||||||
|
|
|
||||||
|
LL | [_, tail @ ..] => println!("{tail}"),
|
||||||
|
| ~~~~~~~~~
|
||||||
|
|
||||||
|
error[E0425]: cannot find value `tail` in this scope
|
||||||
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:35
|
||||||
|
|
|
||||||
|
LL | [_, ..tail] => println!("{tail}"),
|
||||||
|
| ^^^^ not found in this scope
|
||||||
|
|
||||||
|
error[E0425]: cannot find value `tail` in this scope
|
||||||
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:16
|
||||||
|
|
|
||||||
|
LL | [_, ...tail] => println!("{tail}"),
|
||||||
|
| ^^^^ not found in this scope
|
||||||
|
|
|
||||||
|
help: if you meant to collect the rest of the slice in `tail`, use the at operator
|
||||||
|
|
|
||||||
|
LL | [_, tail @ ..] => println!("{tail}"),
|
||||||
|
| ~~~~~~~~~
|
||||||
|
|
||||||
|
error[E0425]: cannot find value `tail` in this scope
|
||||||
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:36
|
||||||
|
|
|
||||||
|
LL | [_, ...tail] => println!("{tail}"),
|
||||||
| ^^^^ not found in this scope
|
| ^^^^ not found in this scope
|
||||||
|
|
||||||
error[E0658]: `X..` patterns in slices are experimental
|
error[E0658]: `X..` patterns in slices are experimental
|
||||||
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:13
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:13
|
||||||
|
|
|
|
||||||
LL | [1, rest..] => println!("{rest:?}"),
|
LL | [1, rest..] => println!("{rest}"),
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
|
= note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
|
||||||
= help: add `#![feature(half_open_range_patterns_in_slices)]` to the crate attributes to enable
|
= help: add `#![feature(half_open_range_patterns_in_slices)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0658]: exclusive range pattern syntax is experimental
|
||||||
|
--> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:13
|
||||||
|
|
|
||||||
|
LL | [_, ..tail] => println!("{tail}"),
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
|
||||||
|
= help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
= help: use an inclusive range pattern, like N..=M
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0425, E0658.
|
Some errors have detailed explanations: E0425, E0658.
|
||||||
For more information about an error, try `rustc --explain E0425`.
|
For more information about an error, try `rustc --explain E0425`.
|
||||||
|
Loading…
Reference in New Issue
Block a user