Skip to content

Commit 408f924

Browse files
committed
Auto merge of #18370 - duncpro:goto-def-ranges, r=Veykril
feat: resolve range patterns to their structs Closes #18367
2 parents 7cad4da + 273d9d7 commit 408f924

File tree

4 files changed

+124
-8
lines changed

4 files changed

+124
-8
lines changed

src/tools/rust-analyzer/crates/hir/src/semantics.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ impl<DB: HirDatabase> Semantics<'_, DB> {
203203
self.imp.descend_node_at_offset(node, offset).filter_map(|mut it| it.find_map(N::cast))
204204
}
205205

206+
pub fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option<Struct> {
207+
self.imp.resolve_range_pat(range_pat).map(Struct::from)
208+
}
209+
206210
pub fn resolve_range_expr(&self, range_expr: &ast::RangeExpr) -> Option<Struct> {
207211
self.imp.resolve_range_expr(range_expr).map(Struct::from)
208212
}
@@ -1367,6 +1371,10 @@ impl<'db> SemanticsImpl<'db> {
13671371
self.analyze(call.syntax())?.resolve_method_call_fallback(self.db, call)
13681372
}
13691373

1374+
fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option<StructId> {
1375+
self.analyze(range_pat.syntax())?.resolve_range_pat(self.db, range_pat)
1376+
}
1377+
13701378
fn resolve_range_expr(&self, range_expr: &ast::RangeExpr) -> Option<StructId> {
13711379
self.analyze(range_expr.syntax())?.resolve_range_expr(self.db, range_expr)
13721380
}

src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,25 @@ impl SourceAnalyzer {
348348
}
349349
}
350350

351+
pub(crate) fn resolve_range_pat(
352+
&self,
353+
db: &dyn HirDatabase,
354+
range_pat: &ast::RangePat,
355+
) -> Option<StructId> {
356+
let path: ModPath = match (range_pat.op_kind()?, range_pat.start(), range_pat.end()) {
357+
(RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo],
358+
(RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom],
359+
(RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range],
360+
(RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive],
361+
(RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive],
362+
363+
(RangeOp::Exclusive, None, None) => return None,
364+
(RangeOp::Inclusive, None, None) => return None,
365+
(RangeOp::Inclusive, Some(_), None) => return None,
366+
};
367+
self.resolver.resolve_known_struct(db.upcast(), &path)
368+
}
369+
351370
pub(crate) fn resolve_range_expr(
352371
&self,
353372
db: &dyn HirDatabase,

src/tools/rust-analyzer/crates/ide-db/src/defs.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ impl IdentClass {
330330
.map(IdentClass::NameClass)
331331
.or_else(|| NameRefClass::classify_lifetime(sema, &lifetime).map(IdentClass::NameRefClass))
332332
},
333-
ast::RangeExpr(range_expr) => OperatorClass::classify_range(sema, &range_expr).map(IdentClass::Operator),
333+
ast::RangePat(range_pat) => OperatorClass::classify_range_pat(sema, &range_pat).map(IdentClass::Operator),
334+
ast::RangeExpr(range_expr) => OperatorClass::classify_range_expr(sema, &range_expr).map(IdentClass::Operator),
334335
ast::AwaitExpr(await_expr) => OperatorClass::classify_await(sema, &await_expr).map(IdentClass::Operator),
335336
ast::BinExpr(bin_expr) => OperatorClass::classify_bin(sema, &bin_expr).map(IdentClass::Operator),
336337
ast::IndexExpr(index_expr) => OperatorClass::classify_index(sema, &index_expr).map(IdentClass::Operator),
@@ -570,7 +571,14 @@ pub enum OperatorClass {
570571
}
571572

572573
impl OperatorClass {
573-
pub fn classify_range(
574+
pub fn classify_range_pat(
575+
sema: &Semantics<'_, RootDatabase>,
576+
range_pat: &ast::RangePat,
577+
) -> Option<OperatorClass> {
578+
sema.resolve_range_pat(range_pat).map(OperatorClass::Range)
579+
}
580+
581+
pub fn classify_range_expr(
574582
sema: &Semantics<'_, RootDatabase>,
575583
range_expr: &ast::RangeExpr,
576584
) -> Option<OperatorClass> {

src/tools/rust-analyzer/crates/ide/src/goto_definition.rs

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub(crate) fn goto_definition(
9898
return Some(vec![x]);
9999
}
100100
}
101+
101102
Some(
102103
IdentClass::classify_node(sema, &parent)?
103104
.definitions()
@@ -460,7 +461,87 @@ mod tests {
460461
}
461462

462463
#[test]
463-
fn goto_def_range() {
464+
fn goto_def_pat_range_to_inclusive() {
465+
check_name(
466+
"RangeToInclusive",
467+
r#"
468+
//- minicore: range
469+
fn f(ch: char) -> bool {
470+
match ch {
471+
..$0='z' => true,
472+
_ => false
473+
}
474+
}
475+
"#,
476+
);
477+
}
478+
479+
#[test]
480+
fn goto_def_pat_range_to() {
481+
check_name(
482+
"RangeTo",
483+
r#"
484+
//- minicore: range
485+
fn f(ch: char) -> bool {
486+
match ch {
487+
.$0.'z' => true,
488+
_ => false
489+
}
490+
}
491+
"#,
492+
);
493+
}
494+
495+
#[test]
496+
fn goto_def_pat_range() {
497+
check_name(
498+
"Range",
499+
r#"
500+
//- minicore: range
501+
fn f(ch: char) -> bool {
502+
match ch {
503+
'a'.$0.'z' => true,
504+
_ => false
505+
}
506+
}
507+
"#,
508+
);
509+
}
510+
511+
#[test]
512+
fn goto_def_pat_range_inclusive() {
513+
check_name(
514+
"RangeInclusive",
515+
r#"
516+
//- minicore: range
517+
fn f(ch: char) -> bool {
518+
match ch {
519+
'a'..$0='z' => true,
520+
_ => false
521+
}
522+
}
523+
"#,
524+
);
525+
}
526+
527+
#[test]
528+
fn goto_def_pat_range_from() {
529+
check_name(
530+
"RangeFrom",
531+
r#"
532+
//- minicore: range
533+
fn f(ch: char) -> bool {
534+
match ch {
535+
'a'..$0 => true,
536+
_ => false
537+
}
538+
}
539+
"#,
540+
);
541+
}
542+
543+
#[test]
544+
fn goto_def_expr_range() {
464545
check_name(
465546
"Range",
466547
r#"
@@ -471,7 +552,7 @@ let x = 0.$0.1;
471552
}
472553

473554
#[test]
474-
fn goto_def_range_from() {
555+
fn goto_def_expr_range_from() {
475556
check_name(
476557
"RangeFrom",
477558
r#"
@@ -484,7 +565,7 @@ fn f(arr: &[i32]) -> &[i32] {
484565
}
485566

486567
#[test]
487-
fn goto_def_range_inclusive() {
568+
fn goto_def_expr_range_inclusive() {
488569
check_name(
489570
"RangeInclusive",
490571
r#"
@@ -495,7 +576,7 @@ let x = 0.$0.=1;
495576
}
496577

497578
#[test]
498-
fn goto_def_range_full() {
579+
fn goto_def_expr_range_full() {
499580
check_name(
500581
"RangeFull",
501582
r#"
@@ -508,7 +589,7 @@ fn f(arr: &[i32]) -> &[i32] {
508589
}
509590

510591
#[test]
511-
fn goto_def_range_to() {
592+
fn goto_def_expr_range_to() {
512593
check_name(
513594
"RangeTo",
514595
r#"
@@ -521,7 +602,7 @@ fn f(arr: &[i32]) -> &[i32] {
521602
}
522603

523604
#[test]
524-
fn goto_def_range_to_inclusive() {
605+
fn goto_def_expr_range_to_inclusive() {
525606
check_name(
526607
"RangeToInclusive",
527608
r#"

0 commit comments

Comments
 (0)