Apply review suggestions

This commit is contained in:
delta17920 2025-12-14 15:08:01 +00:00
parent 3e78653ec3
commit 6fac0fac99
6 changed files with 221 additions and 62 deletions

View file

@ -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(

View file

@ -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

View file

@ -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

View file

@ -1,15 +1,40 @@
use std::ops::Range;
use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
fn test_basic_range(r: Range<u32>) {
fn test_range(r: Range<u32>) {
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<u32>) {
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<u32>) {
let start..=end = r;
//~^ ERROR cannot find value `start`
//~| ERROR cannot find value `end`
}
fn test_from(r: RangeFrom<u32>) {
let start.. = r;
//~^ ERROR cannot find value `start`
}
fn test_to(r: RangeTo<u32>) {
let ..end = r;
//~^ ERROR cannot find value `end`
}
fn test_to_inclusive(r: RangeToInclusive<u32>) {
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<u32>) {
let my::MISSING..end = r;
//~^ ERROR cannot find value `MISSING`
//~| ERROR cannot find value `end`
}
fn main() {}

View file

@ -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
|
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 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;
LL - let start..=end = r;
LL + let RangeInclusive { start, 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:10:17
|
LL | let min..max = r;
| ^^^ not found 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 min..max = r;
LL + let std::ops::Range { start: min, end: max } = r;
|
help: consider importing this function
|
LL + use std::cmp::max;
LL - let start..=end = r;
LL + let RangeInclusive { start, end } = r;
|
error: aborting due to 4 previous errors
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
|
LL | let ..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 collect the rest of the slice in `end`, use the at operator
|
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 RangeTo { end } = r;
|
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
|
= 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
|
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 my::MISSING..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 my::MISSING..end = r;
LL + let Range { start: my::MISSING, end } = r;
|
error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0425`.

View file

@ -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