aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/adt.rs16
-rw-r--r--crates/ra_hir_def/src/builtin_type.rs32
-rw-r--r--crates/ra_hir_def/src/db.rs12
-rw-r--r--crates/ra_hir_def/src/lib.rs28
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs22
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs31
6 files changed, 102 insertions, 39 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index 8f41e55d2..a29c4d41e 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -8,7 +8,7 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
8 8
9use crate::{ 9use crate::{
10 db::DefDatabase2, type_ref::TypeRef, AstItemDef, EnumId, LocalEnumVariantId, 10 db::DefDatabase2, type_ref::TypeRef, AstItemDef, EnumId, LocalEnumVariantId,
11 LocalStructFieldId, StructId, UnionId, 11 LocalStructFieldId, StructOrUnionId,
12}; 12};
13 13
14/// Note that we use `StructData` for unions as well! 14/// Note that we use `StructData` for unions as well!
@@ -49,15 +49,11 @@ pub struct StructFieldData {
49} 49}
50 50
51impl StructData { 51impl StructData {
52 pub(crate) fn struct_data_query(db: &impl DefDatabase2, struct_: StructId) -> Arc<StructData> { 52 pub(crate) fn struct_data_query(
53 let src = struct_.source(db); 53 db: &impl DefDatabase2,
54 let name = src.ast.name().map(|n| n.as_name()); 54 id: StructOrUnionId,
55 let variant_data = VariantData::new(src.ast.kind()); 55 ) -> Arc<StructData> {
56 let variant_data = Arc::new(variant_data); 56 let src = id.source(db);
57 Arc::new(StructData { name, variant_data })
58 }
59 pub(crate) fn union_data_query(db: &impl DefDatabase2, struct_: UnionId) -> Arc<StructData> {
60 let src = struct_.source(db);
61 let name = src.ast.name().map(|n| n.as_name()); 57 let name = src.ast.name().map(|n| n.as_name());
62 let variant_data = VariantData::new(src.ast.kind()); 58 let variant_data = VariantData::new(src.ast.kind());
63 let variant_data = Arc::new(variant_data); 59 let variant_data = Arc::new(variant_data);
diff --git a/crates/ra_hir_def/src/builtin_type.rs b/crates/ra_hir_def/src/builtin_type.rs
index 12929caa9..2ec0c83fe 100644
--- a/crates/ra_hir_def/src/builtin_type.rs
+++ b/crates/ra_hir_def/src/builtin_type.rs
@@ -3,6 +3,8 @@
3//! A peculiarity of built-in types is that they are always available and are 3//! A peculiarity of built-in types is that they are always available and are
4//! not associated with any particular crate. 4//! not associated with any particular crate.
5 5
6use std::fmt;
7
6use hir_expand::name::{self, Name}; 8use hir_expand::name::{self, Name};
7 9
8#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 10#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
@@ -61,3 +63,33 @@ impl BuiltinType {
61 (name::F64, BuiltinType::Float { bitness: FloatBitness::X64 }), 63 (name::F64, BuiltinType::Float { bitness: FloatBitness::X64 }),
62 ]; 64 ];
63} 65}
66
67impl fmt::Display for BuiltinType {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 let type_name = match self {
70 BuiltinType::Char => "char",
71 BuiltinType::Bool => "bool",
72 BuiltinType::Str => "str",
73 BuiltinType::Int { signedness, bitness } => match (signedness, bitness) {
74 (Signedness::Signed, IntBitness::Xsize) => "isize",
75 (Signedness::Signed, IntBitness::X8) => "i8",
76 (Signedness::Signed, IntBitness::X16) => "i16",
77 (Signedness::Signed, IntBitness::X32) => "i32",
78 (Signedness::Signed, IntBitness::X64) => "i64",
79 (Signedness::Signed, IntBitness::X128) => "i128",
80
81 (Signedness::Unsigned, IntBitness::Xsize) => "usize",
82 (Signedness::Unsigned, IntBitness::X8) => "u8",
83 (Signedness::Unsigned, IntBitness::X16) => "u16",
84 (Signedness::Unsigned, IntBitness::X32) => "u32",
85 (Signedness::Unsigned, IntBitness::X64) => "u64",
86 (Signedness::Unsigned, IntBitness::X128) => "u128",
87 },
88 BuiltinType::Float { bitness } => match bitness {
89 FloatBitness::X32 => "f32",
90 FloatBitness::X64 => "f64",
91 },
92 };
93 f.write_str(type_name)
94 }
95}
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index a42348101..29cf71a59 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -11,7 +11,7 @@ use crate::{
11 raw::{ImportSourceMap, RawItems}, 11 raw::{ImportSourceMap, RawItems},
12 CrateDefMap, 12 CrateDefMap,
13 }, 13 },
14 EnumId, StructId, UnionId, 14 EnumId, StructOrUnionId,
15}; 15};
16 16
17#[salsa::query_group(InternDatabaseStorage)] 17#[salsa::query_group(InternDatabaseStorage)]
@@ -19,9 +19,8 @@ pub trait InternDatabase: SourceDatabase {
19 #[salsa::interned] 19 #[salsa::interned]
20 fn intern_function(&self, loc: crate::ItemLoc<ast::FnDef>) -> crate::FunctionId; 20 fn intern_function(&self, loc: crate::ItemLoc<ast::FnDef>) -> crate::FunctionId;
21 #[salsa::interned] 21 #[salsa::interned]
22 fn intern_struct(&self, loc: crate::ItemLoc<ast::StructDef>) -> crate::StructId; 22 fn intern_struct_or_union(&self, loc: crate::ItemLoc<ast::StructDef>)
23 #[salsa::interned] 23 -> crate::StructOrUnionId;
24 fn intern_union(&self, loc: crate::ItemLoc<ast::StructDef>) -> crate::UnionId;
25 #[salsa::interned] 24 #[salsa::interned]
26 fn intern_enum(&self, loc: crate::ItemLoc<ast::EnumDef>) -> crate::EnumId; 25 fn intern_enum(&self, loc: crate::ItemLoc<ast::EnumDef>) -> crate::EnumId;
27 #[salsa::interned] 26 #[salsa::interned]
@@ -49,10 +48,7 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
49 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>; 48 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
50 49
51 #[salsa::invoke(StructData::struct_data_query)] 50 #[salsa::invoke(StructData::struct_data_query)]
52 fn struct_data(&self, s: StructId) -> Arc<StructData>; 51 fn struct_data(&self, id: StructOrUnionId) -> Arc<StructData>;
53
54 #[salsa::invoke(StructData::union_data_query)]
55 fn union_data(&self, s: UnionId) -> Arc<StructData>;
56 52
57 #[salsa::invoke(EnumData::enum_data_query)] 53 #[salsa::invoke(EnumData::enum_data_query)]
58 fn enum_data(&self, e: EnumId) -> Arc<EnumData>; 54 fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 63ed2a098..239317efe 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -205,26 +205,30 @@ impl AstItemDef<ast::FnDef> for FunctionId {
205} 205}
206 206
207#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 207#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
208pub struct StructId(salsa::InternId); 208pub struct StructOrUnionId(salsa::InternId);
209impl_intern_key!(StructId); 209impl_intern_key!(StructOrUnionId);
210impl AstItemDef<ast::StructDef> for StructId { 210impl AstItemDef<ast::StructDef> for StructOrUnionId {
211 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self { 211 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self {
212 db.intern_struct(loc) 212 db.intern_struct_or_union(loc)
213 } 213 }
214 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> { 214 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> {
215 db.lookup_intern_struct(self) 215 db.lookup_intern_struct_or_union(self)
216 } 216 }
217} 217}
218 218
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
220pub struct UnionId(salsa::InternId); 220pub struct StructId(pub StructOrUnionId);
221impl_intern_key!(UnionId); 221impl From<StructId> for StructOrUnionId {
222impl AstItemDef<ast::StructDef> for UnionId { 222 fn from(id: StructId) -> StructOrUnionId {
223 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self { 223 id.0
224 db.intern_union(loc)
225 } 224 }
226 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> { 225}
227 db.lookup_intern_union(self) 226
227#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
228pub struct UnionId(pub StructOrUnionId);
229impl From<UnionId> for StructOrUnionId {
230 fn from(id: UnionId) -> StructOrUnionId {
231 id.0
228 } 232 }
229} 233}
230 234
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 30664278e..37d0f3093 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -20,7 +20,8 @@ use crate::{
20 }, 20 },
21 path::{Path, PathKind}, 21 path::{Path, PathKind},
22 AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId, 22 AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId,
23 LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, 23 LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, StructOrUnionId, TraitId, TypeAliasId,
24 UnionId,
24}; 25};
25 26
26pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { 27pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -36,11 +37,12 @@ pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) ->
36 ); 37 );
37 38
38 // look for the prelude 39 // look for the prelude
39 if def_map.prelude.is_none() { 40 // If the dependency defines a prelude, we overwrite an already defined
40 let map = db.crate_def_map(dep.crate_id); 41 // prelude. This is necessary to import the "std" prelude if a crate
41 if map.prelude.is_some() { 42 // depends on both "core" and "std".
42 def_map.prelude = map.prelude; 43 let dep_def_map = db.crate_def_map(dep.crate_id);
43 } 44 if dep_def_map.prelude.is_some() {
45 def_map.prelude = dep_def_map.prelude;
44 } 46 }
45 } 47 }
46 48
@@ -665,12 +667,14 @@ where
665 PerNs::values(FunctionId::from_ast_id(ctx, ast_id).into()) 667 PerNs::values(FunctionId::from_ast_id(ctx, ast_id).into())
666 } 668 }
667 raw::DefKind::Struct(ast_id) => { 669 raw::DefKind::Struct(ast_id) => {
668 let s = StructId::from_ast_id(ctx, ast_id).into(); 670 let id = StructOrUnionId::from_ast_id(ctx, ast_id).into();
671 let s = StructId(id).into();
669 PerNs::both(s, s) 672 PerNs::both(s, s)
670 } 673 }
671 raw::DefKind::Union(ast_id) => { 674 raw::DefKind::Union(ast_id) => {
672 let s = UnionId::from_ast_id(ctx, ast_id).into(); 675 let id = StructOrUnionId::from_ast_id(ctx, ast_id).into();
673 PerNs::both(s, s) 676 let u = UnionId(id).into();
677 PerNs::both(u, u)
674 } 678 }
675 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), 679 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
676 raw::DefKind::Const(ast_id) => PerNs::values(ConstId::from_ast_id(ctx, ast_id).into()), 680 raw::DefKind::Const(ast_id) => PerNs::values(ConstId::from_ast_id(ctx, ast_id).into()),
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 52bd0aa91..256f7d4be 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -464,6 +464,37 @@ fn values_dont_shadow_extern_crates() {
464} 464}
465 465
466#[test] 466#[test]
467fn std_prelude_takes_precedence_above_core_prelude() {
468 let map = def_map(
469 r#"
470 //- /main.rs crate:main deps:core,std
471 use {Foo, Bar};
472
473 //- /std.rs crate:std deps:core
474 #[prelude_import]
475 pub use self::prelude::*;
476 mod prelude {
477 pub struct Foo;
478 pub use core::prelude::Bar;
479 }
480
481 //- /core.rs crate:core
482 #[prelude_import]
483 pub use self::prelude::*;
484 mod prelude {
485 pub struct Bar;
486 }
487 "#,
488 );
489
490 assert_snapshot!(map, @r###"
491 ⋮crate
492 ⋮Bar: t v
493 ⋮Foo: t v
494 "###);
495}
496
497#[test]
467fn cfg_not_test() { 498fn cfg_not_test() {
468 let map = def_map( 499 let map = def_map(
469 r#" 500 r#"