Skip to content

Commit 117f9b7

Browse files
committed
Auto merge of rust-lang#14939 - Veykril:nav-focus-ranges, r=Veykril
fix: Fix nav target calculation discarding file ids from differing macro upmapping Fixes rust-lang/rust-analyzer#14792 Turns out there was the assumption that upmapping from a macro will always end in the same root file, which is no longer the case thanks to `include!`
2 parents 7f2ac29 + a7d604d commit 117f9b7

File tree

2 files changed

+55
-57
lines changed

2 files changed

+55
-57
lines changed

crates/ide/src/navigation_target.rs

+53-55
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::fmt;
55
use either::Either;
66
use hir::{
77
symbols::FileSymbol, AssocItem, Documentation, FieldSource, HasAttrs, HasContainer, HasSource,
8-
HirDisplay, InFile, LocalSource, ModuleSource,
8+
HirDisplay, HirFileId, InFile, LocalSource, ModuleSource,
99
};
1010
use ide_db::{
1111
base_db::{FileId, FileRange},
@@ -92,10 +92,9 @@ impl NavigationTarget {
9292

9393
pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
9494
let name = module.name(db).map(|it| it.to_smol_str()).unwrap_or_default();
95-
if let Some(src @ InFile { value, .. }) = &module.declaration_source(db) {
96-
let FileRange { file_id, range: full_range } = src.syntax().original_file_range(db);
97-
let focus_range =
98-
value.name().and_then(|it| orig_focus_range(db, src.file_id, it.syntax()));
95+
if let Some(InFile { value, file_id }) = &module.declaration_source(db) {
96+
let (file_id, full_range, focus_range) =
97+
orig_range_with_focus(db, *file_id, value.syntax(), value.name());
9998
let mut res = NavigationTarget::from_syntax(
10099
file_id,
101100
name,
@@ -131,14 +130,15 @@ impl NavigationTarget {
131130
/// Allows `NavigationTarget` to be created from a `NameOwner`
132131
pub(crate) fn from_named(
133132
db: &RootDatabase,
134-
node @ InFile { file_id, value }: InFile<&dyn ast::HasName>,
133+
InFile { file_id, value }: InFile<&dyn ast::HasName>,
135134
kind: SymbolKind,
136135
) -> NavigationTarget {
137136
let name = value.name().map(|it| it.text().into()).unwrap_or_else(|| "_".into());
138-
let focus_range = value.name().and_then(|it| orig_focus_range(db, file_id, it.syntax()));
139-
let FileRange { file_id, range } = node.map(|it| it.syntax()).original_file_range(db);
140137

141-
NavigationTarget::from_syntax(file_id, name, focus_range, range, kind)
138+
let (file_id, full_range, focus_range) =
139+
orig_range_with_focus(db, file_id, value.syntax(), value.name());
140+
141+
NavigationTarget::from_syntax(file_id, name, focus_range, full_range, kind)
142142
}
143143

144144
fn from_syntax(
@@ -165,15 +165,21 @@ impl NavigationTarget {
165165
impl TryToNav for FileSymbol {
166166
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
167167
let full_range = self.loc.original_range(db);
168-
let name_range = self.loc.original_name_range(db)?;
168+
let focus_range = self.loc.original_name_range(db).and_then(|it| {
169+
if it.file_id == full_range.file_id {
170+
Some(it.range)
171+
} else {
172+
None
173+
}
174+
});
169175

170176
Some(NavigationTarget {
171177
file_id: full_range.file_id,
172178
name: if self.is_alias { self.def.name(db)?.to_smol_str() } else { self.name.clone() },
173179
alias: if self.is_alias { Some(self.name.clone()) } else { None },
174180
kind: Some(hir::ModuleDefId::from(self.def).into()),
175181
full_range: full_range.range,
176-
focus_range: Some(name_range.range),
182+
focus_range,
177183
container_name: self.container_name.clone(),
178184
description: match self.def {
179185
hir::ModuleDef::Module(it) => Some(it.display(db).to_string()),
@@ -340,15 +346,11 @@ impl ToNav for hir::Module {
340346
let name = self.name(db).map(|it| it.to_smol_str()).unwrap_or_default();
341347
let (syntax, focus) = match &value {
342348
ModuleSource::SourceFile(node) => (node.syntax(), None),
343-
ModuleSource::Module(node) => (
344-
node.syntax(),
345-
node.name().and_then(|it| orig_focus_range(db, file_id, it.syntax())),
346-
),
349+
ModuleSource::Module(node) => (node.syntax(), node.name()),
347350
ModuleSource::BlockExpr(node) => (node.syntax(), None),
348351
};
349-
let FileRange { file_id, range: full_range } =
350-
InFile::new(file_id, syntax).original_file_range(db);
351-
NavigationTarget::from_syntax(file_id, name, focus, full_range, SymbolKind::Module)
352+
let (file_id, full_range, focus_range) = orig_range_with_focus(db, file_id, syntax, focus);
353+
NavigationTarget::from_syntax(file_id, name, focus_range, full_range, SymbolKind::Module)
352354
}
353355
}
354356

@@ -357,17 +359,14 @@ impl TryToNav for hir::Impl {
357359
let InFile { file_id, value } = self.source(db)?;
358360
let derive_attr = self.is_builtin_derive(db);
359361

360-
let focus_range = if derive_attr.is_some() {
361-
None
362-
} else {
363-
value.self_ty().and_then(|ty| orig_focus_range(db, file_id, ty.syntax()))
364-
};
362+
let focus = if derive_attr.is_some() { None } else { value.self_ty() };
365363

366-
let FileRange { file_id, range: full_range } = match &derive_attr {
367-
Some(attr) => attr.syntax().original_file_range(db),
368-
None => InFile::new(file_id, value.syntax()).original_file_range(db),
364+
let syntax = match &derive_attr {
365+
Some(attr) => attr.value.syntax(),
366+
None => value.syntax(),
369367
};
370368

369+
let (file_id, full_range, focus_range) = orig_range_with_focus(db, file_id, syntax, focus);
371370
Some(NavigationTarget::from_syntax(
372371
file_id,
373372
"impl".into(),
@@ -456,9 +455,8 @@ impl ToNav for LocalSource {
456455
Either::Left(bind_pat) => (bind_pat.syntax(), bind_pat.name()),
457456
Either::Right(it) => (it.syntax(), it.name()),
458457
};
459-
let focus_range = name.and_then(|it| orig_focus_range(db, file_id, it.syntax()));
460-
let FileRange { file_id, range: full_range } =
461-
InFile::new(file_id, node).original_file_range(db);
458+
459+
let (file_id, full_range, focus_range) = orig_range_with_focus(db, file_id, node, name);
462460

463461
let name = local.name(db).to_smol_str();
464462
let kind = if local.is_self(db) {
@@ -493,9 +491,8 @@ impl ToNav for hir::Label {
493491
let InFile { file_id, value } = self.source(db);
494492
let name = self.name(db).to_smol_str();
495493

496-
let range = |syntax: &_| InFile::new(file_id, syntax).original_file_range(db);
497-
let FileRange { file_id, range: full_range } = range(value.syntax());
498-
let focus_range = value.lifetime().map(|lt| range(lt.syntax()).range);
494+
let (file_id, full_range, focus_range) =
495+
orig_range_with_focus(db, file_id, value.syntax(), value.lifetime());
499496

500497
NavigationTarget {
501498
file_id,
@@ -525,19 +522,14 @@ impl TryToNav for hir::TypeParam {
525522
Either::Right(x) => Either::Right(x),
526523
};
527524

528-
let range = |syntax: &_| InFile::new(file_id, syntax).original_file_range(db);
529-
let focus_range = |syntax: &_| InFile::new(file_id, syntax).original_file_range_opt(db);
530-
let FileRange { file_id, range: full_range } = match &value {
531-
Either::Left(type_param) => range(type_param.syntax()),
532-
Either::Right(trait_) => trait_
533-
.name()
534-
.and_then(|name| focus_range(name.syntax()))
535-
.unwrap_or_else(|| range(trait_.syntax())),
525+
let syntax = match &value {
526+
Either::Left(type_param) => type_param.syntax(),
527+
Either::Right(trait_) => trait_.syntax(),
536528
};
537-
let focus_range = value
538-
.either(|it| it.name(), |it| it.name())
539-
.and_then(|it| focus_range(it.syntax()))
540-
.map(|it| it.range);
529+
let focus = value.as_ref().either(|it| it.name(), |it| it.name());
530+
531+
let (file_id, full_range, focus_range) = orig_range_with_focus(db, file_id, syntax, focus);
532+
541533
Some(NavigationTarget {
542534
file_id,
543535
name,
@@ -563,15 +555,15 @@ impl TryToNav for hir::LifetimeParam {
563555
let InFile { file_id, value } = self.source(db)?;
564556
let name = self.name(db).to_smol_str();
565557

566-
let FileRange { file_id, range: full_range } =
558+
let FileRange { file_id, range } =
567559
InFile::new(file_id, value.syntax()).original_file_range(db);
568560
Some(NavigationTarget {
569561
file_id,
570562
name,
571563
alias: None,
572564
kind: Some(SymbolKind::LifetimeParam),
573-
full_range,
574-
focus_range: Some(full_range),
565+
full_range: range,
566+
focus_range: Some(range),
575567
container_name: None,
576568
description: None,
577569
docs: None,
@@ -592,9 +584,8 @@ impl TryToNav for hir::ConstParam {
592584
}
593585
};
594586

595-
let focus_range = value.name().and_then(|it| orig_focus_range(db, file_id, it.syntax()));
596-
let FileRange { file_id, range: full_range } =
597-
InFile::new(file_id, value.syntax()).original_file_range(db);
587+
let (file_id, full_range, focus_range) =
588+
orig_range_with_focus(db, file_id, value.syntax(), value.name());
598589
Some(NavigationTarget {
599590
file_id,
600591
name,
@@ -609,12 +600,19 @@ impl TryToNav for hir::ConstParam {
609600
}
610601
}
611602

612-
fn orig_focus_range(
603+
fn orig_range_with_focus(
613604
db: &RootDatabase,
614-
file_id: hir::HirFileId,
615-
syntax: &SyntaxNode,
616-
) -> Option<TextRange> {
617-
InFile::new(file_id, syntax).original_file_range_opt(db).map(|it| it.range)
605+
hir_file: HirFileId,
606+
value: &SyntaxNode,
607+
name: Option<impl AstNode>,
608+
) -> (FileId, TextRange, Option<TextRange>) {
609+
let FileRange { file_id, range: full_range } =
610+
InFile::new(hir_file, value).original_file_range(db);
611+
let focus_range = name
612+
.and_then(|it| InFile::new(hir_file, it.syntax()).original_file_range_opt(db))
613+
.and_then(|range| if range.file_id == file_id { Some(range.range) } else { None });
614+
615+
(file_id, full_range, focus_range)
618616
}
619617

620618
#[cfg(test)]

crates/ide/src/references.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ trait Foo where Self$0 {
12891289
impl Foo for () {}
12901290
"#,
12911291
expect![[r#"
1292-
Self TypeParam FileId(0) 6..9 6..9
1292+
Self TypeParam FileId(0) 0..44 6..9
12931293
12941294
FileId(0) 16..20
12951295
FileId(0) 37..41
@@ -1380,7 +1380,7 @@ fn foo<T: Bar>(_: impl Bar, _: &dyn Bar) {}
13801380
trait Foo = where Self$0: ;
13811381
"#,
13821382
expect![[r#"
1383-
Self TypeParam FileId(0) 6..9 6..9
1383+
Self TypeParam FileId(0) 0..25 6..9
13841384
13851385
FileId(0) 18..22
13861386
"#]],

0 commit comments

Comments
 (0)