aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/Cargo.toml1
-rw-r--r--crates/ra_hir/src/code_model.rs43
-rw-r--r--crates/ra_hir/src/lib.rs5
-rw-r--r--crates/ra_hir/src/name.rs30
-rw-r--r--crates/ra_hir/src/nameres.rs19
-rw-r--r--crates/ra_hir/src/nameres/tests.rs1
-rw-r--r--crates/ra_hir/src/nameres/tests/incremental.rs4
-rw-r--r--crates/ra_hir/src/nameres/tests/primitives.rs24
-rw-r--r--crates/ra_hir/src/ty/infer.rs3
-rw-r--r--crates/ra_hir/src/ty/lower.rs53
-rw-r--r--crates/ra_hir/src/ty/primitive.rs40
-rw-r--r--crates/ra_hir/src/ty/tests.rs18
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs20
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs2
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs7
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs13
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs5
-rw-r--r--crates/ra_ide_api/src/marks.rs1
-rw-r--r--crates/ra_ide_api/src/syntax_highlighting.rs88
-rw-r--r--crates/ra_lsp_server/src/conv.rs1
20 files changed, 260 insertions, 118 deletions
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index a86dfa6b2..78808e72f 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -13,6 +13,7 @@ parking_lot = "0.8.0"
13ena = "0.11" 13ena = "0.11"
14join_to_string = "0.1.3" 14join_to_string = "0.1.3"
15either = "1.5.2" 15either = "1.5.2"
16once_cell = "0.2"
16 17
17ra_syntax = { path = "../ra_syntax" } 18ra_syntax = { path = "../ra_syntax" }
18ra_arena = { path = "../ra_arena" } 19ra_arena = { path = "../ra_arena" }
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 69496b624..e3c765674 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -4,12 +4,12 @@ use ra_db::{CrateId, SourceRootId, Edition, FileId};
4use ra_syntax::{ast::{self, NameOwner, TypeAscriptionOwner}, TreeArc}; 4use ra_syntax::{ast::{self, NameOwner, TypeAscriptionOwner}, TreeArc};
5 5
6use crate::{ 6use crate::{
7 Name, AsName, AstId, Ty, HirFileId, Either, 7 Name, AsName, AstId, Ty, HirFileId, Either, KnownName,
8 HirDatabase, DefDatabase, 8 HirDatabase, DefDatabase,
9 type_ref::TypeRef, 9 type_ref::TypeRef,
10 nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, 10 nameres::{ModuleScope, Namespace, ImportId, CrateModuleId},
11 expr::{Body, BodySourceMap, validation::ExprValidator}, 11 expr::{Body, BodySourceMap, validation::ExprValidator},
12 ty::{TraitRef, InferenceResult}, 12 ty::{TraitRef, InferenceResult, primitive::{IntTy, FloatTy, Signedness, IntBitness, FloatBitness}},
13 adt::{EnumVariantId, StructFieldId, VariantDef}, 13 adt::{EnumVariantId, StructFieldId, VariantDef},
14 generics::HasGenericParams, 14 generics::HasGenericParams,
15 docs::{Documentation, Docs, docs_from_ast}, 15 docs::{Documentation, Docs, docs_from_ast},
@@ -75,6 +75,41 @@ pub struct Module {
75 pub(crate) module_id: CrateModuleId, 75 pub(crate) module_id: CrateModuleId,
76} 76}
77 77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
79pub enum BuiltinType {
80 Char,
81 Bool,
82 Str,
83 Int(IntTy),
84 Float(FloatTy),
85}
86
87impl BuiltinType {
88 #[rustfmt::skip]
89 pub(crate) const ALL: &'static [(KnownName, BuiltinType)] = &[
90 (KnownName::Char, BuiltinType::Char),
91 (KnownName::Bool, BuiltinType::Bool),
92 (KnownName::Str, BuiltinType::Str),
93
94 (KnownName::Isize, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize })),
95 (KnownName::I8, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 })),
96 (KnownName::I16, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 })),
97 (KnownName::I32, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 })),
98 (KnownName::I64, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 })),
99 (KnownName::I128, BuiltinType::Int(IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 })),
100
101 (KnownName::Usize, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize })),
102 (KnownName::U8, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 })),
103 (KnownName::U16, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 })),
104 (KnownName::U32, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 })),
105 (KnownName::U64, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 })),
106 (KnownName::U128, BuiltinType::Int(IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 })),
107
108 (KnownName::F32, BuiltinType::Float(FloatTy { bitness: FloatBitness::X32 })),
109 (KnownName::F64, BuiltinType::Float(FloatTy { bitness: FloatBitness::X64 })),
110 ];
111}
112
78/// The defs which can be visible in the module. 113/// The defs which can be visible in the module.
79#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 114#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
80pub enum ModuleDef { 115pub enum ModuleDef {
@@ -89,6 +124,7 @@ pub enum ModuleDef {
89 Static(Static), 124 Static(Static),
90 Trait(Trait), 125 Trait(Trait),
91 TypeAlias(TypeAlias), 126 TypeAlias(TypeAlias),
127 BuiltinType(BuiltinType),
92} 128}
93impl_froms!( 129impl_froms!(
94 ModuleDef: Module, 130 ModuleDef: Module,
@@ -100,7 +136,8 @@ impl_froms!(
100 Const, 136 Const,
101 Static, 137 Static,
102 Trait, 138 Trait,
103 TypeAlias 139 TypeAlias,
140 BuiltinType
104); 141);
105 142
106pub enum ModuleSource { 143pub enum ModuleSource {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index cb09c60f8..3e00eea26 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -6,7 +6,7 @@
6//! applied. So, the relation between syntax and HIR is many-to-one. 6//! applied. So, the relation between syntax and HIR is many-to-one.
7 7
8macro_rules! impl_froms { 8macro_rules! impl_froms {
9 ($e:ident: $($v:ident), *) => { 9 ($e:ident: $($v:ident),*) => {
10 $( 10 $(
11 impl From<$v> for $e { 11 impl From<$v> for $e {
12 fn from(it: $v) -> $e { 12 fn from(it: $v) -> $e {
@@ -80,5 +80,6 @@ pub use self::code_model::{
80 Function, FnSignature, 80 Function, FnSignature,
81 StructField, FieldSource, 81 StructField, FieldSource,
82 Static, Const, ConstSignature, 82 Static, Const, ConstSignature,
83 Trait, TypeAlias, MacroDef, Container 83 Trait, TypeAlias, MacroDef, Container,
84 BuiltinType,
84}; 85};
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index e3a82cf03..e9003e00b 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -123,7 +123,7 @@ impl AsName for ra_db::Dependency {
123// const ISIZE: Name = Name::new("isize") 123// const ISIZE: Name = Name::new("isize")
124// ``` 124// ```
125// but const-fn is not that powerful yet. 125// but const-fn is not that powerful yet.
126#[derive(Debug, PartialEq, Eq)] 126#[derive(Debug, Clone, Copy, PartialEq, Eq)]
127pub(crate) enum KnownName { 127pub(crate) enum KnownName {
128 Isize, 128 Isize,
129 I8, 129 I8,
@@ -151,3 +151,31 @@ pub(crate) enum KnownName {
151 151
152 MacroRules, 152 MacroRules,
153} 153}
154
155impl AsName for KnownName {
156 fn as_name(&self) -> Name {
157 let s = match self {
158 KnownName::Isize => "isize",
159 KnownName::I8 => "i8",
160 KnownName::I16 => "i16",
161 KnownName::I32 => "i32",
162 KnownName::I64 => "i64",
163 KnownName::I128 => "i128",
164 KnownName::Usize => "usize",
165 KnownName::U8 => "u8",
166 KnownName::U16 => "u16",
167 KnownName::U32 => "u32",
168 KnownName::U64 => "u64",
169 KnownName::U128 => "u128",
170 KnownName::F32 => "f32",
171 KnownName::F64 => "f64",
172 KnownName::Bool => "bool",
173 KnownName::Char => "char",
174 KnownName::Str => "str",
175 KnownName::SelfType => "Self",
176 KnownName::SelfParam => "self",
177 KnownName::MacroRules => "macro_rules",
178 };
179 Name::new(s.into())
180 }
181}
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 42dcac332..aa26345b2 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -62,9 +62,10 @@ use ra_db::{FileId, Edition};
62use test_utils::tested_by; 62use test_utils::tested_by;
63use ra_syntax::ast; 63use ra_syntax::ast;
64use ra_prof::profile; 64use ra_prof::profile;
65use once_cell::sync::Lazy;
65 66
66use crate::{ 67use crate::{
67 ModuleDef, Name, Crate, Module, MacroDef, 68 ModuleDef, Name, Crate, Module, MacroDef, AsName, BuiltinType,
68 DefDatabase, Path, PathKind, HirFileId, Trait, 69 DefDatabase, Path, PathKind, HirFileId, Trait,
69 ids::MacroDefId, 70 ids::MacroDefId,
70 diagnostics::DiagnosticSink, 71 diagnostics::DiagnosticSink,
@@ -140,12 +141,22 @@ pub struct ModuleScope {
140 macros: FxHashMap<Name, MacroDef>, 141 macros: FxHashMap<Name, MacroDef>,
141} 142}
142 143
144static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
145 BuiltinType::ALL
146 .iter()
147 .map(|&(known_name, ty)| {
148 (known_name.as_name(), Resolution { def: PerNs::types(ty.into()), import: None })
149 })
150 .collect()
151});
152
143impl ModuleScope { 153impl ModuleScope {
144 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a { 154 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
145 self.items.iter() 155 //FIXME: shadowing
156 self.items.iter().chain(BUILTIN_SCOPE.iter())
146 } 157 }
147 pub fn get(&self, name: &Name) -> Option<&Resolution> { 158 pub fn get(&self, name: &Name) -> Option<&Resolution> {
148 self.items.get(name) 159 self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name))
149 } 160 }
150 pub fn traits<'a>(&'a self) -> impl Iterator<Item = Trait> + 'a { 161 pub fn traits<'a>(&'a self) -> impl Iterator<Item = Trait> + 'a {
151 self.items.values().filter_map(|r| match r.def.take_types() { 162 self.items.values().filter_map(|r| match r.def.take_types() {
@@ -154,7 +165,7 @@ impl ModuleScope {
154 }) 165 })
155 } 166 }
156 fn get_item_or_macro(&self, name: &Name) -> Option<ItemOrMacro> { 167 fn get_item_or_macro(&self, name: &Name) -> Option<ItemOrMacro> {
157 match (self.items.get(name), self.macros.get(name)) { 168 match (self.get(name), self.macros.get(name)) {
158 (Some(item), _) if !item.def.is_none() => Some(Either::Left(item.def)), 169 (Some(item), _) if !item.def.is_none() => Some(Either::Left(item.def)),
159 (_, Some(macro_)) => Some(Either::Right(*macro_)), 170 (_, Some(macro_)) => Some(Either::Right(*macro_)),
160 _ => None, 171 _ => None,
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index ffb627c02..a15e62bbe 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -1,6 +1,7 @@
1mod macros; 1mod macros;
2mod globs; 2mod globs;
3mod incremental; 3mod incremental;
4mod primitives;
4 5
5use std::sync::Arc; 6use std::sync::Arc;
6 7
diff --git a/crates/ra_hir/src/nameres/tests/incremental.rs b/crates/ra_hir/src/nameres/tests/incremental.rs
index 001f76ac3..bc721f6e0 100644
--- a/crates/ra_hir/src/nameres/tests/incremental.rs
+++ b/crates/ra_hir/src/nameres/tests/incremental.rs
@@ -116,7 +116,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
116 let events = db.log_executed(|| { 116 let events = db.log_executed(|| {
117 let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap(); 117 let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();
118 let decls = module.declarations(&db); 118 let decls = module.declarations(&db);
119 assert_eq!(decls.len(), 1); 119 assert_eq!(decls.len(), 18);
120 }); 120 });
121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
122 } 122 }
@@ -126,7 +126,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
126 let events = db.log_executed(|| { 126 let events = db.log_executed(|| {
127 let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap(); 127 let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();
128 let decls = module.declarations(&db); 128 let decls = module.declarations(&db);
129 assert_eq!(decls.len(), 1); 129 assert_eq!(decls.len(), 18);
130 }); 130 });
131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
132 } 132 }
diff --git a/crates/ra_hir/src/nameres/tests/primitives.rs b/crates/ra_hir/src/nameres/tests/primitives.rs
new file mode 100644
index 000000000..734744835
--- /dev/null
+++ b/crates/ra_hir/src/nameres/tests/primitives.rs
@@ -0,0 +1,24 @@
1use super::*;
2
3#[test]
4fn primitive_reexport() {
5 let map = def_map(
6 "
7 //- /lib.rs
8 mod foo;
9 use foo::int;
10
11 //- /foo.rs
12 pub use i32 as int;
13 ",
14 );
15 assert_snapshot_matches!(map, @r###"
16 â‹®crate
17 â‹®foo: t
18 â‹®int: t
19 â‹®
20 â‹®crate::foo
21 â‹®int: t
22 "###
23 );
24}
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 7d8250292..e8ae33ead 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -649,7 +649,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
649 | TypableDef::Function(_) 649 | TypableDef::Function(_)
650 | TypableDef::Enum(_) 650 | TypableDef::Enum(_)
651 | TypableDef::Const(_) 651 | TypableDef::Const(_)
652 | TypableDef::Static(_) => (Ty::Unknown, None), 652 | TypableDef::Static(_)
653 | TypableDef::BuiltinType(_) => (Ty::Unknown, None),
653 } 654 }
654 } 655 }
655 656
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 7defa7a9b..71cd72234 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -10,9 +10,8 @@ use std::iter;
10 10
11use crate::{ 11use crate::{
12 Function, Struct, Union, StructField, Enum, EnumVariant, Path, ModuleDef, TypeAlias, Const, Static, 12 Function, Struct, Union, StructField, Enum, EnumVariant, Path, ModuleDef, TypeAlias, Const, Static,
13 HirDatabase, 13 HirDatabase, BuiltinType,
14 type_ref::TypeRef, 14 type_ref::TypeRef,
15 name::KnownName,
16 nameres::Namespace, 15 nameres::Namespace,
17 resolve::{Resolver, Resolution}, 16 resolve::{Resolver, Resolution},
18 path::{PathSegment, GenericArg}, 17 path::{PathSegment, GenericArg},
@@ -22,7 +21,7 @@ use crate::{
22 generics::{WherePredicate, GenericDef}, 21 generics::{WherePredicate, GenericDef},
23 ty::AdtDef, 22 ty::AdtDef,
24}; 23};
25use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef, GenericPredicate}; 24use super::{Ty, FnSig, Substs, TypeCtor, TraitRef, GenericPredicate};
26 25
27impl Ty { 26impl Ty {
28 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { 27 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self {
@@ -65,22 +64,6 @@ impl Ty {
65 } 64 }
66 65
67 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { 66 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self {
68 if let Some(name) = path.as_ident() {
69 // FIXME handle primitive type names in resolver as well?
70 if let Some(int_ty) = primitive::IntTy::from_type_name(name) {
71 return Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(int_ty)));
72 } else if let Some(float_ty) = primitive::FloatTy::from_type_name(name) {
73 return Ty::simple(TypeCtor::Float(primitive::UncertainFloatTy::Known(float_ty)));
74 } else if let Some(known) = name.as_known_name() {
75 match known {
76 KnownName::Bool => return Ty::simple(TypeCtor::Bool),
77 KnownName::Char => return Ty::simple(TypeCtor::Char),
78 KnownName::Str => return Ty::simple(TypeCtor::Str),
79 _ => {}
80 }
81 }
82 }
83
84 // Resolve the path (in type namespace) 67 // Resolve the path (in type namespace)
85 let resolution = resolver.resolve_path(db, path).take_types(); 68 let resolution = resolver.resolve_path(db, path).take_types();
86 69
@@ -128,7 +111,7 @@ impl Ty {
128 TypableDef::Enum(e) => Some(e.into()), 111 TypableDef::Enum(e) => Some(e.into()),
129 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()), 112 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()),
130 TypableDef::TypeAlias(t) => Some(t.into()), 113 TypableDef::TypeAlias(t) => Some(t.into()),
131 TypableDef::Const(_) | TypableDef::Static(_) => None, 114 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None,
132 }; 115 };
133 substs_from_path_segment(db, resolver, segment, def_generic, false) 116 substs_from_path_segment(db, resolver, segment, def_generic, false)
134 } 117 }
@@ -149,7 +132,8 @@ impl Ty {
149 | TypableDef::Enum(_) 132 | TypableDef::Enum(_)
150 | TypableDef::Const(_) 133 | TypableDef::Const(_)
151 | TypableDef::Static(_) 134 | TypableDef::Static(_)
152 | TypableDef::TypeAlias(_) => last, 135 | TypableDef::TypeAlias(_)
136 | TypableDef::BuiltinType(_) => last,
153 TypableDef::EnumVariant(_) => { 137 TypableDef::EnumVariant(_) => {
154 // the generic args for an enum variant may be either specified 138 // the generic args for an enum variant may be either specified
155 // on the segment referring to the enum, or on the segment 139 // on the segment referring to the enum, or on the segment
@@ -299,6 +283,7 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace
299 (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t), 283 (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t),
300 (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c), 284 (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c),
301 (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c), 285 (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c),
286 (TypableDef::BuiltinType(t), Namespace::Types) => type_for_builtin(t),
302 287
303 // 'error' cases: 288 // 'error' cases:
304 (TypableDef::Function(_), Namespace::Types) => Ty::Unknown, 289 (TypableDef::Function(_), Namespace::Types) => Ty::Unknown,
@@ -308,6 +293,7 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace
308 (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown, 293 (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown,
309 (TypableDef::Const(_), Namespace::Types) => Ty::Unknown, 294 (TypableDef::Const(_), Namespace::Types) => Ty::Unknown,
310 (TypableDef::Static(_), Namespace::Types) => Ty::Unknown, 295 (TypableDef::Static(_), Namespace::Types) => Ty::Unknown,
296 (TypableDef::BuiltinType(_), Namespace::Values) => Ty::Unknown,
311 } 297 }
312} 298}
313 299
@@ -399,6 +385,17 @@ fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty {
399 Ty::from_hir(db, &resolver, signature.type_ref()) 385 Ty::from_hir(db, &resolver, signature.type_ref())
400} 386}
401 387
388/// Build the declared type of a static.
389fn type_for_builtin(def: BuiltinType) -> Ty {
390 Ty::simple(match def {
391 BuiltinType::Char => TypeCtor::Char,
392 BuiltinType::Bool => TypeCtor::Bool,
393 BuiltinType::Str => TypeCtor::Str,
394 BuiltinType::Int(ty) => TypeCtor::Int(ty.into()),
395 BuiltinType::Float(ty) => TypeCtor::Float(ty.into()),
396 })
397}
398
402fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { 399fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
403 let var_data = def.variant_data(db); 400 let var_data = def.variant_data(db);
404 let fields = match var_data.fields() { 401 let fields = match var_data.fields() {
@@ -477,8 +474,19 @@ pub enum TypableDef {
477 TypeAlias(TypeAlias), 474 TypeAlias(TypeAlias),
478 Const(Const), 475 Const(Const),
479 Static(Static), 476 Static(Static),
477 BuiltinType(BuiltinType),
480} 478}
481impl_froms!(TypableDef: Function, Struct, Union, Enum, EnumVariant, TypeAlias, Const, Static); 479impl_froms!(
480 TypableDef: Function,
481 Struct,
482 Union,
483 Enum,
484 EnumVariant,
485 TypeAlias,
486 Const,
487 Static,
488 BuiltinType
489);
482 490
483impl From<ModuleDef> for Option<TypableDef> { 491impl From<ModuleDef> for Option<TypableDef> {
484 fn from(def: ModuleDef) -> Option<TypableDef> { 492 fn from(def: ModuleDef) -> Option<TypableDef> {
@@ -491,6 +499,7 @@ impl From<ModuleDef> for Option<TypableDef> {
491 ModuleDef::TypeAlias(t) => t.into(), 499 ModuleDef::TypeAlias(t) => t.into(),
492 ModuleDef::Const(v) => v.into(), 500 ModuleDef::Const(v) => v.into(),
493 ModuleDef::Static(v) => v.into(), 501 ModuleDef::Static(v) => v.into(),
502 ModuleDef::BuiltinType(t) => t.into(),
494 ModuleDef::Module(_) | ModuleDef::Trait(_) => return None, 503 ModuleDef::Module(_) | ModuleDef::Trait(_) => return None,
495 }; 504 };
496 Some(res) 505 Some(res)
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs
index b37326db7..62b75b764 100644
--- a/crates/ra_hir/src/ty/primitive.rs
+++ b/crates/ra_hir/src/ty/primitive.rs
@@ -1,7 +1,5 @@
1use std::fmt; 1use std::fmt;
2 2
3use crate::{Name, KnownName};
4
5#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 3#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
6pub enum Signedness { 4pub enum Signedness {
7 Signed, 5 Signed,
@@ -30,6 +28,12 @@ pub enum UncertainIntTy {
30 Known(IntTy), 28 Known(IntTy),
31} 29}
32 30
31impl From<IntTy> for UncertainIntTy {
32 fn from(ty: IntTy) -> Self {
33 UncertainIntTy::Known(ty)
34 }
35}
36
33impl fmt::Display for UncertainIntTy { 37impl fmt::Display for UncertainIntTy {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 match *self { 39 match *self {
@@ -45,6 +49,12 @@ pub enum UncertainFloatTy {
45 Known(FloatTy), 49 Known(FloatTy),
46} 50}
47 51
52impl From<FloatTy> for UncertainFloatTy {
53 fn from(ty: FloatTy) -> Self {
54 UncertainFloatTy::Known(ty)
55 }
56}
57
48impl fmt::Display for UncertainFloatTy { 58impl fmt::Display for UncertainFloatTy {
49 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 59 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50 match *self { 60 match *self {
@@ -138,24 +148,6 @@ impl IntTy {
138 } 148 }
139 } 149 }
140 150
141 pub(crate) fn from_type_name(name: &Name) -> Option<IntTy> {
142 match name.as_known_name()? {
143 KnownName::Isize => Some(IntTy::isize()),
144 KnownName::I8 => Some(IntTy::i8()),
145 KnownName::I16 => Some(IntTy::i16()),
146 KnownName::I32 => Some(IntTy::i32()),
147 KnownName::I64 => Some(IntTy::i64()),
148 KnownName::I128 => Some(IntTy::i128()),
149 KnownName::Usize => Some(IntTy::usize()),
150 KnownName::U8 => Some(IntTy::u8()),
151 KnownName::U16 => Some(IntTy::u16()),
152 KnownName::U32 => Some(IntTy::u32()),
153 KnownName::U64 => Some(IntTy::u64()),
154 KnownName::U128 => Some(IntTy::u128()),
155 _ => None,
156 }
157 }
158
159 pub(crate) fn from_suffix(suffix: &str) -> Option<IntTy> { 151 pub(crate) fn from_suffix(suffix: &str) -> Option<IntTy> {
160 match suffix { 152 match suffix {
161 "isize" => Some(IntTy::isize()), 153 "isize" => Some(IntTy::isize()),
@@ -208,14 +200,6 @@ impl FloatTy {
208 } 200 }
209 } 201 }
210 202
211 pub(crate) fn from_type_name(name: &Name) -> Option<FloatTy> {
212 match name.as_known_name()? {
213 KnownName::F32 => Some(FloatTy::f32()),
214 KnownName::F64 => Some(FloatTy::f64()),
215 _ => None,
216 }
217 }
218
219 pub(crate) fn from_suffix(suffix: &str) -> Option<FloatTy> { 203 pub(crate) fn from_suffix(suffix: &str) -> Option<FloatTy> {
220 match suffix { 204 match suffix {
221 "f32" => Some(FloatTy::f32()), 205 "f32" => Some(FloatTy::f32()),
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index da9aeec6d..c34e89af7 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -2717,6 +2717,24 @@ fn test() { (S {}).method()<|>; }
2717 assert_eq!(t, "{unknown}"); 2717 assert_eq!(t, "{unknown}");
2718} 2718}
2719 2719
2720#[test]
2721fn shadowing_primitive() {
2722 let t = type_at(
2723 r#"
2724//- /main.rs
2725struct i32;
2726struct Foo;
2727
2728impl i32 { fn foo(&self) -> Foo { Foo } }
2729
2730fn main() {
2731 let x: i32 = i32;
2732 x.foo()<|>;
2733}"#,
2734 );
2735 assert_eq!(t, "Foo");
2736}
2737
2720fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 2738fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
2721 let file = db.parse(pos.file_id).ok().unwrap(); 2739 let file = db.parse(pos.file_id).ok().unwrap();
2722 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); 2740 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index c41752ae7..99da24142 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -17,6 +17,12 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
17 hir::ModuleDef::Module(module) => { 17 hir::ModuleDef::Module(module) => {
18 let module_scope = module.scope(ctx.db); 18 let module_scope = module.scope(ctx.db);
19 for (name, res) in module_scope.entries() { 19 for (name, res) in module_scope.entries() {
20 if let Some(hir::ModuleDef::BuiltinType(..)) = res.def.as_ref().take_types() {
21 if ctx.use_item_syntax.is_some() {
22 tested_by!(dont_complete_primitive_in_use);
23 continue;
24 }
25 }
20 if Some(module) == ctx.module { 26 if Some(module) == ctx.module {
21 if let Some(import) = res.import { 27 if let Some(import) = res.import {
22 if let Either::A(use_tree) = module.import_source(ctx.db, import) { 28 if let Either::A(use_tree) = module.import_source(ctx.db, import) {
@@ -89,6 +95,20 @@ mod tests {
89 } 95 }
90 96
91 #[test] 97 #[test]
98 fn dont_complete_primitive_in_use() {
99 covers!(dont_complete_primitive_in_use);
100 let completions = do_completion(r"use self::<|>;", CompletionKind::BuiltinType);
101 assert!(completions.is_empty());
102 }
103
104 #[test]
105 fn completes_primitives() {
106 let completions =
107 do_completion(r"fn main() { let _: <|> = 92; }", CompletionKind::BuiltinType);
108 assert_eq!(completions.len(), 17);
109 }
110
111 #[test]
92 fn completes_mod_with_docs() { 112 fn completes_mod_with_docs() {
93 check_reference_completion( 113 check_reference_completion(
94 "mod_with_docs", 114 "mod_with_docs",
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index 6f1392231..6f2a60640 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -78,6 +78,7 @@ pub enum CompletionItemKind {
78 Keyword, 78 Keyword,
79 Module, 79 Module,
80 Function, 80 Function,
81 BuiltinType,
81 Struct, 82 Struct,
82 Enum, 83 Enum,
83 EnumVariant, 84 EnumVariant,
@@ -102,6 +103,7 @@ pub(crate) enum CompletionKind {
102 Magic, 103 Magic,
103 Snippet, 104 Snippet,
104 Postfix, 105 Postfix,
106 BuiltinType,
105} 107}
106 108
107#[derive(Debug, PartialEq, Eq, Copy, Clone)] 109#[derive(Debug, PartialEq, Eq, Copy, Clone)]
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index 064d379a4..d405161d6 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -57,6 +57,7 @@ impl Completions {
57 } 57 }
58 Some(it) => it, 58 Some(it) => it,
59 }; 59 };
60 let mut completion_kind = CompletionKind::Reference;
60 let (kind, docs) = match def { 61 let (kind, docs) = match def {
61 Resolution::Def(Module(it)) => (CompletionItemKind::Module, it.docs(ctx.db)), 62 Resolution::Def(Module(it)) => (CompletionItemKind::Module, it.docs(ctx.db)),
62 Resolution::Def(Function(func)) => { 63 Resolution::Def(Function(func)) => {
@@ -70,6 +71,10 @@ impl Completions {
70 Resolution::Def(Static(it)) => (CompletionItemKind::Static, it.docs(ctx.db)), 71 Resolution::Def(Static(it)) => (CompletionItemKind::Static, it.docs(ctx.db)),
71 Resolution::Def(Trait(it)) => (CompletionItemKind::Trait, it.docs(ctx.db)), 72 Resolution::Def(Trait(it)) => (CompletionItemKind::Trait, it.docs(ctx.db)),
72 Resolution::Def(TypeAlias(it)) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), 73 Resolution::Def(TypeAlias(it)) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)),
74 Resolution::Def(BuiltinType(..)) => {
75 completion_kind = CompletionKind::BuiltinType;
76 (CompletionItemKind::BuiltinType, None)
77 }
73 Resolution::GenericParam(..) => (CompletionItemKind::TypeParam, None), 78 Resolution::GenericParam(..) => (CompletionItemKind::TypeParam, None),
74 Resolution::LocalBinding(..) => (CompletionItemKind::Binding, None), 79 Resolution::LocalBinding(..) => (CompletionItemKind::Binding, None),
75 Resolution::SelfType(..) => ( 80 Resolution::SelfType(..) => (
@@ -77,7 +82,7 @@ impl Completions {
77 None, 82 None,
78 ), 83 ),
79 }; 84 };
80 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), local_name) 85 CompletionItem::new(completion_kind, ctx.source_range(), local_name)
81 .kind(kind) 86 .kind(kind)
82 .set_documentation(docs) 87 .set_documentation(docs)
83 .add_to(self) 88 .add_to(self)
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index ae729614f..e19c071b0 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -165,8 +165,11 @@ impl NavigationTarget {
165 } 165 }
166 } 166 }
167 167
168 pub(crate) fn from_def(db: &RootDatabase, module_def: hir::ModuleDef) -> NavigationTarget { 168 pub(crate) fn from_def(
169 match module_def { 169 db: &RootDatabase,
170 module_def: hir::ModuleDef,
171 ) -> Option<NavigationTarget> {
172 let nav = match module_def {
170 hir::ModuleDef::Module(module) => NavigationTarget::from_module(db, module), 173 hir::ModuleDef::Module(module) => NavigationTarget::from_module(db, module),
171 hir::ModuleDef::Function(func) => NavigationTarget::from_function(db, func), 174 hir::ModuleDef::Function(func) => NavigationTarget::from_function(db, func),
172 hir::ModuleDef::Struct(s) => { 175 hir::ModuleDef::Struct(s) => {
@@ -201,7 +204,11 @@ impl NavigationTarget {
201 let (file_id, node) = e.source(db); 204 let (file_id, node) = e.source(db);
202 NavigationTarget::from_named(file_id.original_file(db), &*node) 205 NavigationTarget::from_named(file_id.original_file(db), &*node)
203 } 206 }
204 } 207 hir::ModuleDef::BuiltinType(..) => {
208 return None;
209 }
210 };
211 Some(nav)
205 } 212 }
206 213
207 pub(crate) fn from_impl_block( 214 pub(crate) fn from_impl_block(
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 4f8554625..97b367115 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -62,7 +62,10 @@ pub(crate) fn reference_definition(
62 Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)), 62 Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)),
63 Some(FieldAccess(field)) => return Exact(NavigationTarget::from_field(db, field)), 63 Some(FieldAccess(field)) => return Exact(NavigationTarget::from_field(db, field)),
64 Some(AssocItem(assoc)) => return Exact(NavigationTarget::from_impl_item(db, assoc)), 64 Some(AssocItem(assoc)) => return Exact(NavigationTarget::from_impl_item(db, assoc)),
65 Some(Def(def)) => return Exact(NavigationTarget::from_def(db, def)), 65 Some(Def(def)) => match NavigationTarget::from_def(db, def) {
66 Some(nav) => return Exact(nav),
67 None => return Approximate(vec![]),
68 },
66 Some(SelfType(ty)) => { 69 Some(SelfType(ty)) => {
67 if let Some((def_id, _)) = ty.as_adt() { 70 if let Some((def_id, _)) = ty.as_adt() {
68 return Exact(NavigationTarget::from_adt_def(db, def_id)); 71 return Exact(NavigationTarget::from_adt_def(db, def_id));
diff --git a/crates/ra_ide_api/src/marks.rs b/crates/ra_ide_api/src/marks.rs
index cc894a7df..9cb991de5 100644
--- a/crates/ra_ide_api/src/marks.rs
+++ b/crates/ra_ide_api/src/marks.rs
@@ -6,4 +6,5 @@ test_utils::marks!(
6 goto_definition_works_for_named_fields 6 goto_definition_works_for_named_fields
7 call_info_bad_offset 7 call_info_bad_offset
8 dont_complete_current_use 8 dont_complete_current_use
9 dont_complete_primitive_in_use
9); 10);
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index 4b24754a8..3a04a51cd 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -30,14 +30,6 @@ fn is_control_keyword(kind: SyntaxKind) -> bool {
30 } 30 }
31} 31}
32 32
33fn is_prim_type(node: &ast::NameRef) -> bool {
34 match node.text().as_str() {
35 "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "u64" | "i64" | "u128" | "i128" | "usize"
36 | "isize" | "f32" | "f64" | "bool" | "char" | "str" => true,
37 _ => false,
38 }
39}
40
41pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { 33pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
42 let _p = profile("highlight"); 34 let _p = profile("highlight");
43 let source_file = db.parse(file_id).tree; 35 let source_file = db.parse(file_id).tree;
@@ -71,51 +63,47 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
71 NAME_REF => { 63 NAME_REF => {
72 if let Some(name_ref) = node.as_node().and_then(ast::NameRef::cast) { 64 if let Some(name_ref) = node.as_node().and_then(ast::NameRef::cast) {
73 // FIXME: revisit this after #1340 65 // FIXME: revisit this after #1340
74 if is_prim_type(name_ref) { 66 use crate::name_ref_kind::{classify_name_ref, NameRefKind::*};
75 "type" 67 use hir::{ModuleDef, ImplItem};
76 } else {
77 use crate::name_ref_kind::{classify_name_ref, NameRefKind::*};
78 use hir::{ModuleDef, ImplItem};
79 68
80 // FIXME: try to reuse the SourceAnalyzers 69 // FIXME: try to reuse the SourceAnalyzers
81 let analyzer = 70 let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
82 hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); 71 match classify_name_ref(db, &analyzer, name_ref) {
83 match classify_name_ref(db, &analyzer, name_ref) { 72 Some(Method(_)) => "function",
84 Some(Method(_)) => "function", 73 Some(Macro(_)) => "macro",
85 Some(Macro(_)) => "macro", 74 Some(FieldAccess(_)) => "field",
86 Some(FieldAccess(_)) => "field", 75 Some(AssocItem(ImplItem::Method(_))) => "function",
87 Some(AssocItem(ImplItem::Method(_))) => "function", 76 Some(AssocItem(ImplItem::Const(_))) => "constant",
88 Some(AssocItem(ImplItem::Const(_))) => "constant", 77 Some(AssocItem(ImplItem::TypeAlias(_))) => "type",
89 Some(AssocItem(ImplItem::TypeAlias(_))) => "type", 78 Some(Def(ModuleDef::Module(_))) => "module",
90 Some(Def(ModuleDef::Module(_))) => "module", 79 Some(Def(ModuleDef::Function(_))) => "function",
91 Some(Def(ModuleDef::Function(_))) => "function", 80 Some(Def(ModuleDef::Struct(_))) => "type",
92 Some(Def(ModuleDef::Struct(_))) => "type", 81 Some(Def(ModuleDef::Union(_))) => "type",
93 Some(Def(ModuleDef::Union(_))) => "type", 82 Some(Def(ModuleDef::Enum(_))) => "type",
94 Some(Def(ModuleDef::Enum(_))) => "type", 83 Some(Def(ModuleDef::EnumVariant(_))) => "constant",
95 Some(Def(ModuleDef::EnumVariant(_))) => "constant", 84 Some(Def(ModuleDef::Const(_))) => "constant",
96 Some(Def(ModuleDef::Const(_))) => "constant", 85 Some(Def(ModuleDef::Static(_))) => "constant",
97 Some(Def(ModuleDef::Static(_))) => "constant", 86 Some(Def(ModuleDef::Trait(_))) => "type",
98 Some(Def(ModuleDef::Trait(_))) => "type", 87 Some(Def(ModuleDef::TypeAlias(_))) => "type",
99 Some(Def(ModuleDef::TypeAlias(_))) => "type", 88 Some(Def(ModuleDef::BuiltinType(_))) => "type",
100 Some(SelfType(_)) => "type", 89 Some(SelfType(_)) => "type",
101 Some(Pat(ptr)) => { 90 Some(Pat(ptr)) => {
102 binding_hash = Some({ 91 binding_hash = Some({
103 let text = ptr 92 let text = ptr
104 .syntax_node_ptr() 93 .syntax_node_ptr()
105 .to_node(&source_file.syntax()) 94 .to_node(&source_file.syntax())
106 .text() 95 .text()
107 .to_smol_string(); 96 .to_smol_string();
108 let shadow_count = 97 let shadow_count =
109 bindings_shadow_count.entry(text.clone()).or_default(); 98 bindings_shadow_count.entry(text.clone()).or_default();
110 calc_binding_hash(file_id, &text, *shadow_count) 99 calc_binding_hash(file_id, &text, *shadow_count)
111 }); 100 });
112 101
113 "variable" 102 "variable"
114 }
115 Some(SelfParam(_)) => "type",
116 Some(GenericParam(_)) => "type",
117 None => "text",
118 } 103 }
104 Some(SelfParam(_)) => "type",
105 Some(GenericParam(_)) => "type",
106 None => "text",
119 } 107 }
120 } else { 108 } else {
121 "text" 109 "text"
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index 50a12ddbc..1b349d02a 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -65,6 +65,7 @@ impl Conv for CompletionItemKind {
65 CompletionItemKind::Struct => Struct, 65 CompletionItemKind::Struct => Struct,
66 CompletionItemKind::Enum => Enum, 66 CompletionItemKind::Enum => Enum,
67 CompletionItemKind::EnumVariant => EnumMember, 67 CompletionItemKind::EnumVariant => EnumMember,
68 CompletionItemKind::BuiltinType => Struct,
68 CompletionItemKind::Binding => Variable, 69 CompletionItemKind::Binding => Variable,
69 CompletionItemKind::Field => Field, 70 CompletionItemKind::Field => Field,
70 CompletionItemKind::Trait => Interface, 71 CompletionItemKind::Trait => Interface,