Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 223238d

Browse files
committed
Auto merge of rust-lang#16759 - roife:fix-goto-def-for-constants-in-range-pattern, r=Veykril
fix: goto-definition for constants inside range pattern Fix rust-lang#15653. This PR addresses the issue where it was not possible to navigate to constants in range patterns, specifically including two major changes: 1. Previously, both the `start` and `end` fields in `Pat::Range` were of type `LiteralOrConst`. When performing `goto-definition` on constants inside range patterns, r-a would use `resolve_bind_pat_to_const` to find their definitions. However, because the content of a `Const` is not `Pat` but `Path`, it was not stored in the `source_map`, so `resolve_bind_pat_to_const` would returns `None`. This PR changes them to `Const(PatId)`, so that during the lowering process, they are considered as a `pat`, allowing their definitions to be found later through `resolve_bind_pat_to_const`. 2. The process related to range patterns in MIR-lowering has been modified to correctly handle the above changes.
2 parents 7c786ed + 9cc3a9c commit 223238d

File tree

5 files changed

+31
-13
lines changed

5 files changed

+31
-13
lines changed

crates/hir-def/src/body/lower.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,16 +1413,10 @@ impl ExprCollector<'_> {
14131413
ast::Pat::LiteralPat(it) => {
14141414
Some(Box::new(LiteralOrConst::Literal(pat_literal_to_hir(it)?.0)))
14151415
}
1416-
ast::Pat::IdentPat(p) => {
1417-
let name =
1418-
p.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
1419-
Some(Box::new(LiteralOrConst::Const(name.into())))
1416+
pat @ (ast::Pat::IdentPat(_) | ast::Pat::PathPat(_)) => {
1417+
let subpat = self.collect_pat(pat.clone(), binding_list);
1418+
Some(Box::new(LiteralOrConst::Const(subpat)))
14201419
}
1421-
ast::Pat::PathPat(p) => p
1422-
.path()
1423-
.and_then(|path| self.expander.parse_path(self.db, path))
1424-
.map(LiteralOrConst::Const)
1425-
.map(Box::new),
14261420
_ => None,
14271421
})
14281422
};

crates/hir-def/src/body/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ impl Printer<'_> {
635635
fn print_literal_or_const(&mut self, literal_or_const: &LiteralOrConst) {
636636
match literal_or_const {
637637
LiteralOrConst::Literal(l) => self.print_literal(l),
638-
LiteralOrConst::Const(c) => self.print_path(c),
638+
LiteralOrConst::Const(c) => self.print_pat(*c),
639639
}
640640
}
641641

crates/hir-def/src/hir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ pub enum Literal {
101101
/// Used in range patterns.
102102
pub enum LiteralOrConst {
103103
Literal(Literal),
104-
Const(Path),
104+
Const(PatId),
105105
}
106106

107107
impl Literal {

crates/hir-ty/src/mir/lower.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,10 +1364,16 @@ impl<'ctx> MirLowerCtx<'ctx> {
13641364
match loc {
13651365
LiteralOrConst::Literal(l) => self.lower_literal_to_operand(ty, l),
13661366
LiteralOrConst::Const(c) => {
1367-
let unresolved_name = || MirLowerError::unresolved_path(self.db, c);
1367+
let c = match &self.body.pats[*c] {
1368+
Pat::Path(p) => p,
1369+
_ => not_supported!(
1370+
"only `char` and numeric types are allowed in range patterns"
1371+
),
1372+
};
1373+
let unresolved_name = || MirLowerError::unresolved_path(self.db, c.as_ref());
13681374
let resolver = self.owner.resolver(self.db.upcast());
13691375
let pr = resolver
1370-
.resolve_path_in_value_ns(self.db.upcast(), c)
1376+
.resolve_path_in_value_ns(self.db.upcast(), c.as_ref())
13711377
.ok_or_else(unresolved_name)?;
13721378
match pr {
13731379
ResolveValueResult::ValueNs(v, _) => {

crates/ide/src/goto_definition.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,24 @@ fn bar() {
536536
);
537537
}
538538

539+
#[test]
540+
fn goto_definition_works_for_consts_inside_range_pattern() {
541+
check(
542+
r#"
543+
//- /lib.rs
544+
const A: u32 = 0;
545+
//^
546+
547+
fn bar(v: u32) {
548+
match v {
549+
0..=$0A => {}
550+
_ => {}
551+
}
552+
}
553+
"#,
554+
);
555+
}
556+
539557
#[test]
540558
fn goto_def_for_use_alias() {
541559
check(

0 commit comments

Comments
 (0)