mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
goto definition on RangeFrom, RangeFull, RangeTo, and RangeToInclusive links to respective struct
This commit is contained in:
parent
c7a8be110d
commit
f54a863965
2 changed files with 73 additions and 44 deletions
|
@ -353,9 +353,17 @@ impl SourceAnalyzer {
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
range_expr: &ast::RangeExpr,
|
range_expr: &ast::RangeExpr,
|
||||||
) -> Option<StructId> {
|
) -> Option<StructId> {
|
||||||
let path = match range_expr.op_kind()? {
|
let path: ModPath = match (range_expr.op_kind()?, range_expr.start(), range_expr.end()) {
|
||||||
RangeOp::Exclusive => path![core::ops::Range],
|
(RangeOp::Exclusive, None, None) => path![core::ops::RangeFull],
|
||||||
RangeOp::Inclusive => path![core::ops::RangeInclusive],
|
(RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo],
|
||||||
|
(RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom],
|
||||||
|
(RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range],
|
||||||
|
(RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive],
|
||||||
|
(RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive],
|
||||||
|
|
||||||
|
// [E0586] inclusive ranges must be bounded at the end
|
||||||
|
(RangeOp::Inclusive, None, None) => return None,
|
||||||
|
(RangeOp::Inclusive, Some(_), None) => return None
|
||||||
};
|
};
|
||||||
self.resolver.resolve_known_struct(db.upcast(), &path)
|
self.resolver.resolve_known_struct(db.upcast(), &path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -449,55 +449,76 @@ mod tests {
|
||||||
assert!(navs.is_empty(), "didn't expect this to resolve anywhere: {navs:?}")
|
assert!(navs.is_empty(), "didn't expect this to resolve anywhere: {navs:?}")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn check_name(expected_name: &str, ra_fixture: &str) {
|
||||||
fn goto_def_range_inclusive_0() {
|
|
||||||
let ra_fixture = r#"
|
|
||||||
//- minicore: range
|
|
||||||
fn f(a: usize, b: usize) {
|
|
||||||
for _ in a.$0.=b {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
let (analysis, position, _) = fixture::annotations(ra_fixture);
|
let (analysis, position, _) = fixture::annotations(ra_fixture);
|
||||||
let mut navs =
|
let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
|
||||||
analysis.goto_definition(position).unwrap().expect("no definition found").info;
|
assert!(navs.len() < 2, "expected single navigation target but encountered {}", navs.len());
|
||||||
let Some(target) = navs.pop() else { panic!("no target found") };
|
let Some(target) = navs.into_iter().next() else {
|
||||||
assert_eq!(target.name, SmolStr::new_inline("RangeInclusive"));
|
panic!("expected single navigation target but encountered none");
|
||||||
}
|
};
|
||||||
|
assert_eq!(target.name, SmolStr::new_inline(expected_name));
|
||||||
#[test]
|
|
||||||
fn goto_def_range_inclusive_1() {
|
|
||||||
let ra_fixture = r#"
|
|
||||||
//- minicore: range
|
|
||||||
fn f(a: usize, b: usize) {
|
|
||||||
for _ in a..$0=b {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
let (analysis, position, _) = fixture::annotations(ra_fixture);
|
|
||||||
let mut navs =
|
|
||||||
analysis.goto_definition(position).unwrap().expect("no definition found").info;
|
|
||||||
let Some(target) = navs.pop() else { panic!("no target found") };
|
|
||||||
assert_eq!(target.name, SmolStr::new_inline("RangeInclusive"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_range() {
|
fn goto_def_range() {
|
||||||
let ra_fixture = r#"
|
check_name("Range", r#"
|
||||||
//- minicore: range
|
//- minicore: range
|
||||||
fn f(a: usize, b: usize) {
|
let x = 0.$0.1;
|
||||||
for _ in a.$0.b {
|
"#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_range_from() {
|
||||||
|
check_name("RangeFrom", r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(arr: &[i32]) -> &[i32] {
|
||||||
|
&arr[0.$0.]
|
||||||
}
|
}
|
||||||
"#;
|
"#
|
||||||
let (analysis, position, _) = fixture::annotations(ra_fixture);
|
);
|
||||||
let mut navs =
|
}
|
||||||
analysis.goto_definition(position).unwrap().expect("no definition found").info;
|
|
||||||
let Some(target) = navs.pop() else { panic!("no target found") };
|
#[test]
|
||||||
assert_eq!(target.name, SmolStr::new_inline("Range"));
|
fn goto_def_range_inclusive() {
|
||||||
|
check_name("RangeInclusive", r#"
|
||||||
|
//- minicore: range
|
||||||
|
let x = 0.$0.=1;
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_range_full() {
|
||||||
|
check_name("RangeFull", r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(arr: &[i32]) -> &[i32] {
|
||||||
|
&arr[.$0.]
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_range_to() {
|
||||||
|
check_name("RangeTo", r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(arr: &[i32]) -> &[i32] {
|
||||||
|
&arr[.$0.10]
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_range_to_inclusive() {
|
||||||
|
check_name("RangeToInclusive", r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(arr: &[i32]) -> &[i32] {
|
||||||
|
&arr[.$0.=10]
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue