Skip to content

Commit 1eb9d15

Browse files
authored
Merge pull request #18967 from Veykril/push-pwonkmwqmmol
Properly record meaningful imports as re-exports in symbol index
2 parents fe034ed + 4193abc commit 1eb9d15

File tree

25 files changed

+368
-265
lines changed

25 files changed

+368
-265
lines changed

Diff for: src/tools/rust-analyzer/Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ dependencies = [
523523
"hir-def",
524524
"hir-expand",
525525
"hir-ty",
526+
"indexmap",
526527
"intern",
527528
"itertools",
528529
"rustc-hash 2.0.0",

Diff for: src/tools/rust-analyzer/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exclude = ["crates/proc-macro-srv/proc-macro-test/imp"]
44
resolver = "2"
55

66
[workspace.package]
7-
rust-version = "1.82"
7+
rust-version = "1.83"
88
edition = "2021"
99
license = "MIT OR Apache-2.0"
1010
authors = ["rust-analyzer team"]

Diff for: src/tools/rust-analyzer/crates/hir-def/src/data.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ bitflags::bitflags! {
244244
#[derive(Debug, Clone, PartialEq, Eq)]
245245
pub struct TraitData {
246246
pub name: Name,
247-
pub items: Vec<(Name, AssocItemId)>,
247+
pub items: Box<[(Name, AssocItemId)]>,
248248
pub flags: TraitFlags,
249249
pub visibility: RawVisibility,
250250
// box it as the vec is usually empty anyways
@@ -360,7 +360,7 @@ impl TraitAliasData {
360360
pub struct ImplData {
361361
pub target_trait: Option<TraitRef>,
362362
pub self_ty: TypeRefId,
363-
pub items: Box<[AssocItemId]>,
363+
pub items: Box<[(Name, AssocItemId)]>,
364364
pub is_negative: bool,
365365
pub is_unsafe: bool,
366366
// box it as the vec is usually empty anyways
@@ -393,7 +393,6 @@ impl ImplData {
393393
collector.collect(&item_tree, tree_id.tree_id(), &impl_def.items);
394394

395395
let (items, macro_calls, diagnostics) = collector.finish();
396-
let items = items.into_iter().map(|(_, item)| item).collect();
397396

398397
(
399398
Arc::new(ImplData {
@@ -648,12 +647,12 @@ impl<'a> AssocItemCollector<'a> {
648647
fn finish(
649648
self,
650649
) -> (
651-
Vec<(Name, AssocItemId)>,
650+
Box<[(Name, AssocItemId)]>,
652651
Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
653652
Vec<DefDiagnostic>,
654653
) {
655654
(
656-
self.items,
655+
self.items.into_boxed_slice(),
657656
if self.macro_calls.is_empty() { None } else { Some(Box::new(self.macro_calls)) },
658657
self.diagnostics,
659658
)

Diff for: src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,20 @@ impl ItemScope {
162162
.map(move |name| (name, self.get(name)))
163163
}
164164

165+
pub fn values(&self) -> impl Iterator<Item = (&Name, Item<ModuleDefId, ImportId>)> + '_ {
166+
self.values.iter().map(|(n, &i)| (n, i))
167+
}
168+
169+
pub fn types(
170+
&self,
171+
) -> impl Iterator<Item = (&Name, Item<ModuleDefId, ImportOrExternCrate>)> + '_ {
172+
self.types.iter().map(|(n, &i)| (n, i))
173+
}
174+
175+
pub fn macros(&self) -> impl Iterator<Item = (&Name, Item<MacroId, ImportId>)> + '_ {
176+
self.macros.iter().map(|(n, &i)| (n, i))
177+
}
178+
165179
pub fn imports(&self) -> impl Iterator<Item = ImportId> + '_ {
166180
self.use_imports_types
167181
.keys()
@@ -263,11 +277,6 @@ impl ItemScope {
263277
self.unnamed_consts.iter().copied()
264278
}
265279

266-
/// Iterate over all module scoped macros
267-
pub(crate) fn macros(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
268-
self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_)))
269-
}
270-
271280
/// Iterate over all legacy textual scoped macros visible at the end of the module
272281
pub fn legacy_macros(&self) -> impl Iterator<Item = (&Name, &[MacroId])> + '_ {
273282
self.legacy_macros.iter().map(|(name, def)| (name, &**def))

Diff for: src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl LangItems {
107107
for (_, module_data) in crate_def_map.modules() {
108108
for impl_def in module_data.scope.impls() {
109109
lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef);
110-
for assoc in db.impl_data(impl_def).items.iter().copied() {
110+
for &(_, assoc) in db.impl_data(impl_def).items.iter() {
111111
match assoc {
112112
AssocItemId::FunctionId(f) => {
113113
lang_items.collect_lang_item(db, f, LangItemTarget::Function)

Diff for: src/tools/rust-analyzer/crates/hir-def/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ impl ModuleId {
502502
}
503503

504504
/// Whether this module represents the crate root module
505-
fn is_crate_root(&self) -> bool {
505+
pub fn is_crate_root(&self) -> bool {
506506
self.local_id == DefMap::ROOT && self.block.is_none()
507507
}
508508
}

Diff for: src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -717,8 +717,8 @@ impl DefCollector<'_> {
717717
}
718718
}
719719
None => {
720-
for (name, def) in root_scope.macros() {
721-
self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate));
720+
for (name, it) in root_scope.macros() {
721+
self.def_map.macro_use_prelude.insert(name.clone(), (it.def, extern_crate));
722722
}
723723
}
724724
}

Diff for: src/tools/rust-analyzer/crates/hir-def/src/visibility.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,12 @@ impl Visibility {
240240

241241
if a_ancestors.any(|m| m == mod_b.local_id) {
242242
// B is above A
243-
return Some(Visibility::Module(mod_a, expl_b));
243+
return Some(Visibility::Module(mod_a, expl_a));
244244
}
245245

246246
if b_ancestors.any(|m| m == mod_a.local_id) {
247247
// A is above B
248-
return Some(Visibility::Module(mod_b, expl_a));
248+
return Some(Visibility::Module(mod_b, expl_b));
249249
}
250250

251251
None

Diff for: src/tools/rust-analyzer/crates/hir-expand/src/name.rs

+33-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use syntax::utils::is_raw_identifier;
1111
/// and declarations. In theory, names should also carry hygiene info, but we are
1212
/// not there yet!
1313
///
14-
/// Note that the rawness (`r#`) of names does not depend on whether they are written raw.
14+
/// Note that the rawness (`r#`) of names is not preserved. Names are always stored without a `r#` prefix.
1515
/// This is because we want to show (in completions etc.) names as raw depending on the needs
1616
/// of the current crate, for example if it is edition 2021 complete `gen` even if the defining
1717
/// crate is in edition 2024 and wrote `r#gen`, and the opposite holds as well.
@@ -77,6 +77,7 @@ impl Name {
7777
/// Hopefully, this should allow us to integrate hygiene cleaner in the
7878
/// future, and to switch to interned representation of names.
7979
fn new_text(text: &str) -> Name {
80+
debug_assert!(!text.starts_with("r#"));
8081
Name { symbol: Symbol::intern(text), ctx: () }
8182
}
8283

@@ -91,15 +92,34 @@ impl Name {
9192

9293
pub fn new_root(text: &str) -> Name {
9394
// The edition doesn't matter for hygiene.
94-
Self::new(text, SyntaxContextId::root(Edition::Edition2015))
95+
Self::new(text.trim_start_matches("r#"), SyntaxContextId::root(Edition::Edition2015))
9596
}
9697

9798
pub fn new_tuple_field(idx: usize) -> Name {
98-
Name { symbol: Symbol::intern(&idx.to_string()), ctx: () }
99+
let symbol = match idx {
100+
0 => sym::INTEGER_0.clone(),
101+
1 => sym::INTEGER_1.clone(),
102+
2 => sym::INTEGER_2.clone(),
103+
3 => sym::INTEGER_3.clone(),
104+
4 => sym::INTEGER_4.clone(),
105+
5 => sym::INTEGER_5.clone(),
106+
6 => sym::INTEGER_6.clone(),
107+
7 => sym::INTEGER_7.clone(),
108+
8 => sym::INTEGER_8.clone(),
109+
9 => sym::INTEGER_9.clone(),
110+
10 => sym::INTEGER_10.clone(),
111+
11 => sym::INTEGER_11.clone(),
112+
12 => sym::INTEGER_12.clone(),
113+
13 => sym::INTEGER_13.clone(),
114+
14 => sym::INTEGER_14.clone(),
115+
15 => sym::INTEGER_15.clone(),
116+
_ => Symbol::intern(&idx.to_string()),
117+
};
118+
Name { symbol, ctx: () }
99119
}
100120

101121
pub fn new_lifetime(lt: &ast::Lifetime) -> Name {
102-
Name { symbol: Symbol::intern(lt.text().as_str()), ctx: () }
122+
Self::new_text(lt.text().as_str().trim_start_matches("r#"))
103123
}
104124

105125
/// Resolve a name from the text of token.
@@ -142,15 +162,18 @@ impl Name {
142162
}
143163

144164
/// Returns the text this name represents if it isn't a tuple field.
165+
///
166+
/// Do not use this for user-facing text, use `display` instead to handle editions properly.
145167
pub fn as_str(&self) -> &str {
146168
self.symbol.as_str()
147169
}
148170

171+
// FIXME: Remove this
149172
pub fn unescaped(&self) -> UnescapedName<'_> {
150173
UnescapedName(self)
151174
}
152175

153-
pub fn is_escaped(&self, edition: Edition) -> bool {
176+
pub fn needs_escape(&self, edition: Edition) -> bool {
154177
is_raw_identifier(self.symbol.as_str(), edition)
155178
}
156179

@@ -173,16 +196,19 @@ impl Name {
173196
&self.symbol
174197
}
175198

176-
pub const fn new_symbol(symbol: Symbol, ctx: SyntaxContextId) -> Self {
199+
pub fn new_symbol(symbol: Symbol, ctx: SyntaxContextId) -> Self {
200+
debug_assert!(!symbol.as_str().starts_with("r#"));
177201
_ = ctx;
178202
Self { symbol, ctx: () }
179203
}
180204

181205
// FIXME: This needs to go once we have hygiene
182-
pub const fn new_symbol_root(sym: Symbol) -> Self {
206+
pub fn new_symbol_root(sym: Symbol) -> Self {
207+
debug_assert!(!sym.as_str().starts_with("r#"));
183208
Self { symbol: sym, ctx: () }
184209
}
185210

211+
// FIXME: Remove this
186212
#[inline]
187213
pub fn eq_ident(&self, ident: &str) -> bool {
188214
self.as_str() == ident.trim_start_matches("r#")

Diff for: src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ fn impl_def_datum(
856856
let associated_ty_value_ids = impl_data
857857
.items
858858
.iter()
859-
.filter_map(|item| match item {
859+
.filter_map(|(_, item)| match item {
860860
AssocItemId::TypeAliasId(type_alias) => Some(*type_alias),
861861
_ => None,
862862
})

Diff for: src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs

+12-14
Original file line numberDiff line numberDiff line change
@@ -746,16 +746,9 @@ fn lookup_impl_assoc_item_for_trait_ref(
746746
let table = InferenceTable::new(db, env);
747747

748748
let (impl_data, impl_subst) = find_matching_impl(impls, table, trait_ref)?;
749-
let item = impl_data.items.iter().find_map(|&it| match it {
750-
AssocItemId::FunctionId(f) => {
751-
(db.function_data(f).name == *name).then_some(AssocItemId::FunctionId(f))
752-
}
753-
AssocItemId::ConstId(c) => db
754-
.const_data(c)
755-
.name
756-
.as_ref()
757-
.map(|n| n == name)
758-
.and_then(|result| if result { Some(AssocItemId::ConstId(c)) } else { None }),
749+
let item = impl_data.items.iter().find_map(|(n, it)| match *it {
750+
AssocItemId::FunctionId(f) => (n == name).then_some(AssocItemId::FunctionId(f)),
751+
AssocItemId::ConstId(c) => (n == name).then_some(AssocItemId::ConstId(c)),
759752
AssocItemId::TypeAliasId(_) => None,
760753
})?;
761754
Some((item, impl_subst))
@@ -850,7 +843,7 @@ fn is_inherent_impl_coherent(
850843
};
851844
rustc_has_incoherent_inherent_impls
852845
&& !impl_data.items.is_empty()
853-
&& impl_data.items.iter().copied().all(|assoc| match assoc {
846+
&& impl_data.items.iter().all(|&(_, assoc)| match assoc {
854847
AssocItemId::FunctionId(it) => db.function_data(it).rustc_allow_incoherent_impl,
855848
AssocItemId::ConstId(it) => db.const_data(it).rustc_allow_incoherent_impl,
856849
AssocItemId::TypeAliasId(it) => db.type_alias_data(it).rustc_allow_incoherent_impl,
@@ -1399,7 +1392,7 @@ fn iterate_inherent_methods(
13991392
callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
14001393
) -> ControlFlow<()> {
14011394
for &impl_id in impls.for_self_ty(self_ty) {
1402-
for &item in table.db.impl_data(impl_id).items.iter() {
1395+
for &(ref item_name, item) in table.db.impl_data(impl_id).items.iter() {
14031396
let visible = match is_valid_impl_method_candidate(
14041397
table,
14051398
self_ty,
@@ -1408,6 +1401,7 @@ fn iterate_inherent_methods(
14081401
name,
14091402
impl_id,
14101403
item,
1404+
item_name,
14111405
) {
14121406
IsValidCandidate::Yes => true,
14131407
IsValidCandidate::NotVisible => false,
@@ -1467,6 +1461,7 @@ fn is_valid_impl_method_candidate(
14671461
name: Option<&Name>,
14681462
impl_id: ImplId,
14691463
item: AssocItemId,
1464+
item_name: &Name,
14701465
) -> IsValidCandidate {
14711466
match item {
14721467
AssocItemId::FunctionId(f) => is_valid_impl_fn_candidate(
@@ -1477,11 +1472,12 @@ fn is_valid_impl_method_candidate(
14771472
receiver_ty,
14781473
self_ty,
14791474
visible_from_module,
1475+
item_name,
14801476
),
14811477
AssocItemId::ConstId(c) => {
14821478
let db = table.db;
14831479
check_that!(receiver_ty.is_none());
1484-
check_that!(name.is_none_or(|n| db.const_data(c).name.as_ref() == Some(n)));
1480+
check_that!(name.is_none_or(|n| n == item_name));
14851481

14861482
if let Some(from_module) = visible_from_module {
14871483
if !db.const_visibility(c).is_visible_from(db.upcast(), from_module) {
@@ -1565,11 +1561,13 @@ fn is_valid_impl_fn_candidate(
15651561
receiver_ty: Option<&Ty>,
15661562
self_ty: &Ty,
15671563
visible_from_module: Option<ModuleId>,
1564+
item_name: &Name,
15681565
) -> IsValidCandidate {
1566+
check_that!(name.is_none_or(|n| n == item_name));
1567+
15691568
let db = table.db;
15701569
let data = db.function_data(fn_id);
15711570

1572-
check_that!(name.is_none_or(|n| n == &data.name));
15731571
if let Some(from_module) = visible_from_module {
15741572
if !db.function_visibility(fn_id).is_visible_from(db.upcast(), from_module) {
15751573
cov_mark::hit!(autoderef_candidate_not_visible);

Diff for: src/tools/rust-analyzer/crates/hir-ty/src/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ pub(crate) fn visit_module(
435435
visit_scope(db, crate_def_map, &crate_def_map[module_id].scope, cb);
436436
for impl_id in crate_def_map[module_id].scope.impls() {
437437
let impl_data = db.impl_data(impl_id);
438-
for &item in impl_data.items.iter() {
438+
for &(_, item) in impl_data.items.iter() {
439439
match item {
440440
AssocItemId::FunctionId(it) => {
441441
let body = db.body(it.into());

Diff for: src/tools/rust-analyzer/crates/hir/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ itertools.workspace = true
2020
smallvec.workspace = true
2121
tracing.workspace = true
2222
triomphe.workspace = true
23+
indexmap.workspace = true
2324

2425
# local deps
2526
base-db.workspace = true

0 commit comments

Comments
 (0)