Skip to content

Commit 12cb6e7

Browse files
committed
Auto merge of #15377 - Veykril:extern-crate-decl, r=Veykril
Add ExternCrateDecl to HIR Adding these doesn't really require much design effort as they represent a single import, unlike use trees which are one item that represent 0 or more imports. We only resolve to this definition when actually resolving on the name or alias of an `extern crate name as alias` item, not usages yet as that requires far more changes that won't lead anywhere without giving it more thought. Nevertheless the changes slightly improve IDE things, an example being hover on the decl showing the merged doc comments for example. cc rust-lang/rust-analyzer#14079
2 parents 8e18b0f + 6e2c3f6 commit 12cb6e7

40 files changed

+584
-166
lines changed

crates/hir-def/src/child_by_source.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use crate::{
1414
item_scope::ItemScope,
1515
nameres::DefMap,
1616
src::{HasChildSource, HasSource},
17-
AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, MacroId,
18-
ModuleDefId, ModuleId, TraitId, VariantId,
17+
AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, ExternCrateId, FieldId, ImplId,
18+
Lookup, MacroId, ModuleDefId, ModuleId, TraitId, VariantId,
1919
};
2020

2121
pub trait ChildBySource {
@@ -91,6 +91,7 @@ impl ChildBySource for ItemScope {
9191
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
9292
self.declarations().for_each(|item| add_module_def(db, res, file_id, item));
9393
self.impls().for_each(|imp| add_impl(db, res, file_id, imp));
94+
self.extern_crate_decls().for_each(|ext| add_extern_crate(db, res, file_id, ext));
9495
self.unnamed_consts().for_each(|konst| {
9596
let loc = konst.lookup(db);
9697
if loc.id.file_id() == file_id {
@@ -167,6 +168,17 @@ impl ChildBySource for ItemScope {
167168
map[keys::IMPL].insert(loc.source(db).value, imp)
168169
}
169170
}
171+
fn add_extern_crate(
172+
db: &dyn DefDatabase,
173+
map: &mut DynMap,
174+
file_id: HirFileId,
175+
ext: ExternCrateId,
176+
) {
177+
let loc = ext.lookup(db);
178+
if loc.id.file_id() == file_id {
179+
map[keys::EXTERN_CRATE].insert(loc.source(db).value, ext)
180+
}
181+
}
170182
}
171183
}
172184

crates/hir-def/src/data.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
pub mod adt;
44

5+
use base_db::CrateId;
56
use hir_expand::{
67
name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind,
78
};
@@ -467,6 +468,7 @@ pub struct ExternCrateDeclData {
467468
pub name: Name,
468469
pub alias: Option<ImportAlias>,
469470
pub visibility: RawVisibility,
471+
pub crate_id: Option<CrateId>,
470472
}
471473

472474
impl ExternCrateDeclData {
@@ -478,10 +480,21 @@ impl ExternCrateDeclData {
478480
let item_tree = loc.id.item_tree(db);
479481
let extern_crate = &item_tree[loc.id.value];
480482

483+
let name = extern_crate.name.clone();
484+
let crate_id = if name == hir_expand::name![self] {
485+
Some(loc.container.krate())
486+
} else {
487+
db.crate_def_map(loc.container.krate())
488+
.extern_prelude()
489+
.find(|&(prelude_name, ..)| *prelude_name == name)
490+
.map(|(_, root)| root.krate())
491+
};
492+
481493
Arc::new(Self {
482494
name: extern_crate.name.clone(),
483495
visibility: item_tree[extern_crate.visibility].clone(),
484496
alias: extern_crate.alias.clone(),
497+
crate_id,
485498
})
486499
}
487500
}

crates/hir-def/src/item_scope.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ impl ItemScope {
113113
self.declarations.iter().copied()
114114
}
115115

116+
pub fn extern_crate_decls(
117+
&self,
118+
) -> impl Iterator<Item = ExternCrateId> + ExactSizeIterator + '_ {
119+
self.extern_crate_decls.iter().copied()
120+
}
121+
116122
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
117123
self.impls.iter().copied()
118124
}

crates/hir-def/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ impl From<CrateRootModuleId> for ModuleDefId {
121121
}
122122
}
123123

124+
impl From<CrateId> for CrateRootModuleId {
125+
fn from(krate: CrateId) -> Self {
126+
CrateRootModuleId { krate }
127+
}
128+
}
129+
124130
impl TryFrom<ModuleId> for CrateRootModuleId {
125131
type Error = ();
126132

crates/hir-def/src/nameres/tests/incremental.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,17 @@ pub type Ty = ();
213213

214214
for (_, res) in module_data.scope.resolutions() {
215215
match res.values.or(res.types).unwrap().0 {
216-
ModuleDefId::FunctionId(f) => drop(db.function_data(f)),
216+
ModuleDefId::FunctionId(f) => _ = db.function_data(f),
217217
ModuleDefId::AdtId(adt) => match adt {
218-
AdtId::StructId(it) => drop(db.struct_data(it)),
219-
AdtId::UnionId(it) => drop(db.union_data(it)),
220-
AdtId::EnumId(it) => drop(db.enum_data(it)),
218+
AdtId::StructId(it) => _ = db.struct_data(it),
219+
AdtId::UnionId(it) => _ = db.union_data(it),
220+
AdtId::EnumId(it) => _ = db.enum_data(it),
221221
},
222-
ModuleDefId::ConstId(it) => drop(db.const_data(it)),
223-
ModuleDefId::StaticId(it) => drop(db.static_data(it)),
224-
ModuleDefId::TraitId(it) => drop(db.trait_data(it)),
225-
ModuleDefId::TraitAliasId(it) => drop(db.trait_alias_data(it)),
226-
ModuleDefId::TypeAliasId(it) => drop(db.type_alias_data(it)),
222+
ModuleDefId::ConstId(it) => _ = db.const_data(it),
223+
ModuleDefId::StaticId(it) => _ = db.static_data(it),
224+
ModuleDefId::TraitId(it) => _ = db.trait_data(it),
225+
ModuleDefId::TraitAliasId(it) => _ = db.trait_alias_data(it),
226+
ModuleDefId::TypeAliasId(it) => _ = db.type_alias_data(it),
227227
ModuleDefId::EnumVariantId(_)
228228
| ModuleDefId::ModuleId(_)
229229
| ModuleDefId::MacroId(_)

crates/hir/src/attrs.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use hir_ty::db::HirDatabase;
1212
use syntax::{ast, AstNode};
1313

1414
use crate::{
15-
Adt, AssocItem, Const, ConstParam, Enum, Field, Function, GenericParam, Impl, LifetimeParam,
16-
Macro, Module, ModuleDef, Static, Struct, Trait, TraitAlias, TypeAlias, TypeParam, Union,
17-
Variant,
15+
Adt, AssocItem, Const, ConstParam, Enum, ExternCrateDecl, Field, Function, GenericParam, Impl,
16+
LifetimeParam, Macro, Module, ModuleDef, Static, Struct, Trait, TraitAlias, TypeAlias,
17+
TypeParam, Union, Variant,
1818
};
1919

2020
pub trait HasAttrs {
@@ -120,6 +120,39 @@ impl HasAttrs for AssocItem {
120120
}
121121
}
122122

123+
impl HasAttrs for ExternCrateDecl {
124+
fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner {
125+
let def = AttrDefId::ExternCrateId(self.into());
126+
db.attrs_with_owner(def)
127+
}
128+
fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
129+
let crate_docs = self.resolved_crate(db)?.root_module().attrs(db).docs().map(String::from);
130+
let def = AttrDefId::ExternCrateId(self.into());
131+
let decl_docs = db.attrs(def).docs().map(String::from);
132+
match (decl_docs, crate_docs) {
133+
(None, None) => None,
134+
(Some(decl_docs), None) => Some(decl_docs),
135+
(None, Some(crate_docs)) => Some(crate_docs),
136+
(Some(mut decl_docs), Some(crate_docs)) => {
137+
decl_docs.push('\n');
138+
decl_docs.push('\n');
139+
decl_docs += &crate_docs;
140+
Some(decl_docs)
141+
}
142+
}
143+
.map(Documentation::new)
144+
}
145+
fn resolve_doc_path(
146+
self,
147+
db: &dyn HirDatabase,
148+
link: &str,
149+
ns: Option<Namespace>,
150+
) -> Option<ModuleDef> {
151+
let def = AttrDefId::ExternCrateId(self.into());
152+
resolve_doc_path(db, def, link, ns).map(ModuleDef::from)
153+
}
154+
}
155+
123156
/// Resolves the item `link` points to in the scope of `def`.
124157
fn resolve_doc_path(
125158
db: &dyn HirDatabase,

crates/hir/src/db.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,3 @@ pub use hir_expand::db::{
1010
MacroExpandQuery, ParseMacroExpansionErrorQuery, ParseMacroExpansionQuery,
1111
};
1212
pub use hir_ty::db::*;
13-
14-
#[test]
15-
fn hir_database_is_object_safe() {
16-
fn _assert_object_safe(_: &dyn HirDatabase) {}
17-
}

crates/hir/src/display.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ use hir_ty::{
1818
};
1919

2020
use crate::{
21-
Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Enum, Field, Function, GenericParam,
22-
HasCrate, HasVisibility, LifetimeParam, Macro, Module, Static, Struct, Trait, TraitAlias,
23-
TyBuilder, Type, TypeAlias, TypeOrConstParam, TypeParam, Union, Variant,
21+
Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Enum, ExternCrateDecl, Field,
22+
Function, GenericParam, HasCrate, HasVisibility, LifetimeParam, Macro, Module, Static, Struct,
23+
Trait, TraitAlias, TyBuilder, Type, TypeAlias, TypeOrConstParam, TypeParam, Union, Variant,
2424
};
2525

2626
impl HirDisplay for Function {
@@ -238,6 +238,18 @@ impl HirDisplay for Type {
238238
}
239239
}
240240

241+
impl HirDisplay for ExternCrateDecl {
242+
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
243+
write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
244+
f.write_str("extern crate ")?;
245+
write!(f, "{}", self.name(f.db).display(f.db.upcast()))?;
246+
if let Some(alias) = self.alias(f.db) {
247+
write!(f, " as {alias}",)?;
248+
}
249+
Ok(())
250+
}
251+
}
252+
241253
impl HirDisplay for GenericParam {
242254
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
243255
match self {

crates/hir/src/from_id.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
};
1616

1717
macro_rules! from_id {
18-
($(($id:path, $ty:path)),*) => {$(
18+
($(($id:path, $ty:path)),* $(,)?) => {$(
1919
impl From<$id> for $ty {
2020
fn from(id: $id) -> $ty {
2121
$ty { id }
@@ -47,7 +47,8 @@ from_id![
4747
(hir_def::TypeParamId, crate::TypeParam),
4848
(hir_def::ConstParamId, crate::ConstParam),
4949
(hir_def::LifetimeParamId, crate::LifetimeParam),
50-
(hir_def::MacroId, crate::Macro)
50+
(hir_def::MacroId, crate::Macro),
51+
(hir_def::ExternCrateId, crate::ExternCrateDecl),
5152
];
5253

5354
impl From<AdtId> for Adt {

crates/hir/src/has_source.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use hir_expand::{HirFileId, InFile};
1111
use syntax::ast;
1212

1313
use crate::{
14-
db::HirDatabase, Adt, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam,
15-
LocalSource, Macro, Module, Static, Struct, Trait, TraitAlias, TypeAlias, TypeOrConstParam,
16-
Union, Variant,
14+
db::HirDatabase, Adt, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl,
15+
LifetimeParam, LocalSource, Macro, Module, Static, Struct, Trait, TraitAlias, TypeAlias,
16+
TypeOrConstParam, Union, Variant,
1717
};
1818

1919
pub trait HasSource {
@@ -207,3 +207,11 @@ impl HasSource for LocalSource {
207207
Some(self.source)
208208
}
209209
}
210+
211+
impl HasSource for ExternCrateDecl {
212+
type Ast = ast::ExternCrate;
213+
214+
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
215+
Some(self.id.lookup(db.upcast()).source(db.upcast()))
216+
}
217+
}

0 commit comments

Comments
 (0)