aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_db/src/input.rs14
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs63
-rw-r--r--crates/ra_ide_api/src/change.rs3
-rw-r--r--crates/ra_ide_api/src/completion/complete_postfix.rs2
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap9
-rw-r--r--crates/ra_parser/src/grammar/items.rs29
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0014_default_fn_type.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0014_default_fn_type.txt58
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0132_default_fn_type.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0132_default_fn_type.txt55
10 files changed, 213 insertions, 28 deletions
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index a5f4e489f..c103503bd 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -31,9 +31,23 @@ pub struct SourceRootId(pub u32);
31 31
32#[derive(Default, Clone, Debug, PartialEq, Eq)] 32#[derive(Default, Clone, Debug, PartialEq, Eq)]
33pub struct SourceRoot { 33pub struct SourceRoot {
34 /// Sysroot or crates.io library.
35 ///
36 /// Libraries are considered mostly immutable, this assumption is used to
37 /// optimize salsa's query structure
38 pub is_library: bool,
34 pub files: FxHashMap<RelativePathBuf, FileId>, 39 pub files: FxHashMap<RelativePathBuf, FileId>,
35} 40}
36 41
42impl SourceRoot {
43 pub fn new() -> SourceRoot {
44 Default::default()
45 }
46 pub fn new_library() -> SourceRoot {
47 SourceRoot { is_library: true, ..SourceRoot::new() }
48 }
49}
50
37/// `CrateGraph` is a bit of information which turns a set of text files into a 51/// `CrateGraph` is a bit of information which turns a set of text files into a
38/// number of Rust crates. Each crate is defined by the `FileId` of its root module, 52/// number of Rust crates. Each crate is defined by the `FileId` of its root module,
39/// the set of cfg flags (not yet implemented) and the set of dependencies. Note 53/// the set of cfg flags (not yet implemented) and the set of dependencies. Note
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 46ec136bd..e023ff25a 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -4,6 +4,7 @@
4//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs. 4//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec;
7use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
8 9
9use crate::{ 10use crate::{
@@ -113,19 +114,32 @@ impl CrateImplBlocks {
113 } 114 }
114} 115}
115 116
116fn def_crate(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<Crate> { 117fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> {
118 // Types like slice can have inherent impls in several crates, (core and alloc).
119 // The correspoinding impls are marked with lang items, so we can use them to find the required crates.
120 macro_rules! lang_item_crate {
121 ($db:expr, $cur_crate:expr, $($name:expr),+ $(,)?) => {{
122 let mut v = ArrayVec::<[Crate; 2]>::new();
123 $(
124 v.push($db.lang_item($cur_crate, $name.into())?.krate($db)?);
125 )+
126 Some(v)
127 }};
128 }
129
117 match ty { 130 match ty {
118 Ty::Apply(a_ty) => match a_ty.ctor { 131 Ty::Apply(a_ty) => match a_ty.ctor {
119 TypeCtor::Adt(def_id) => def_id.krate(db), 132 TypeCtor::Adt(def_id) => Some(std::iter::once(def_id.krate(db)?).collect()),
120 TypeCtor::Bool => db.lang_item(cur_crate, "bool".into())?.krate(db), 133 TypeCtor::Bool => lang_item_crate!(db, cur_crate, "bool"),
121 TypeCtor::Char => db.lang_item(cur_crate, "char".into())?.krate(db), 134 TypeCtor::Char => lang_item_crate!(db, cur_crate, "char"),
122 TypeCtor::Float(UncertainFloatTy::Known(f)) => { 135 TypeCtor::Float(UncertainFloatTy::Known(f)) => {
123 db.lang_item(cur_crate, f.ty_to_string().into())?.krate(db) 136 lang_item_crate!(db, cur_crate, f.ty_to_string())
124 } 137 }
125 TypeCtor::Int(UncertainIntTy::Known(i)) => { 138 TypeCtor::Int(UncertainIntTy::Known(i)) => {
126 db.lang_item(cur_crate, i.ty_to_string().into())?.krate(db) 139 lang_item_crate!(db, cur_crate, i.ty_to_string())
127 } 140 }
128 TypeCtor::Str => db.lang_item(cur_crate, "str".into())?.krate(db), 141 TypeCtor::Str => lang_item_crate!(db, cur_crate, "str"),
142 TypeCtor::Slice => lang_item_crate!(db, cur_crate, "slice_alloc", "slice"),
129 _ => None, 143 _ => None,
130 }, 144 },
131 _ => None, 145 _ => None,
@@ -218,19 +232,17 @@ fn iterate_inherent_methods<T>(
218 krate: Crate, 232 krate: Crate,
219 mut callback: impl FnMut(&Ty, Function) -> Option<T>, 233 mut callback: impl FnMut(&Ty, Function) -> Option<T>,
220) -> Option<T> { 234) -> Option<T> {
221 let krate = match def_crate(db, krate, &ty.value) { 235 for krate in def_crates(db, krate, &ty.value)? {
222 Some(krate) => krate, 236 let impls = db.impls_in_crate(krate);
223 None => return None,
224 };
225 let impls = db.impls_in_crate(krate);
226 237
227 for impl_block in impls.lookup_impl_blocks(&ty.value) { 238 for impl_block in impls.lookup_impl_blocks(&ty.value) {
228 for item in impl_block.items(db) { 239 for item in impl_block.items(db) {
229 if let ImplItem::Method(f) = item { 240 if let ImplItem::Method(f) = item {
230 let data = f.data(db); 241 let data = f.data(db);
231 if name.map_or(true, |name| data.name() == name) && data.has_self_param() { 242 if name.map_or(true, |name| data.name() == name) && data.has_self_param() {
232 if let Some(result) = callback(&ty.value, f) { 243 if let Some(result) = callback(&ty.value, f) {
233 return Some(result); 244 return Some(result);
245 }
234 } 246 }
235 } 247 }
236 } 248 }
@@ -248,13 +260,14 @@ impl Ty {
248 krate: Crate, 260 krate: Crate,
249 mut callback: impl FnMut(ImplItem) -> Option<T>, 261 mut callback: impl FnMut(ImplItem) -> Option<T>,
250 ) -> Option<T> { 262 ) -> Option<T> {
251 let krate = def_crate(db, krate, &self)?; 263 for krate in def_crates(db, krate, &self)? {
252 let impls = db.impls_in_crate(krate); 264 let impls = db.impls_in_crate(krate);
253 265
254 for impl_block in impls.lookup_impl_blocks(&self) { 266 for impl_block in impls.lookup_impl_blocks(&self) {
255 for item in impl_block.items(db) { 267 for item in impl_block.items(db) {
256 if let Some(result) = callback(item) { 268 if let Some(result) = callback(item) {
257 return Some(result); 269 return Some(result);
270 }
258 } 271 }
259 } 272 }
260 } 273 }
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs
index 895b1e966..8d9918d16 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide_api/src/change.rs
@@ -163,7 +163,8 @@ impl RootDatabase {
163 if !change.new_roots.is_empty() { 163 if !change.new_roots.is_empty() {
164 let mut local_roots = Vec::clone(&self.local_roots()); 164 let mut local_roots = Vec::clone(&self.local_roots());
165 for (root_id, is_local) in change.new_roots { 165 for (root_id, is_local) in change.new_roots {
166 self.set_source_root(root_id, Default::default()); 166 let root = if is_local { SourceRoot::new() } else { SourceRoot::new_library() };
167 self.set_source_root(root_id, Arc::new(root));
167 if is_local { 168 if is_local {
168 local_roots.push(root_id); 169 local_roots.push(root_id);
169 } 170 }
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs
index 278b1b797..e20a12e2a 100644
--- a/crates/ra_ide_api/src/completion/complete_postfix.rs
+++ b/crates/ra_ide_api/src/completion/complete_postfix.rs
@@ -51,6 +51,8 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
51 ) 51 )
52 .add_to(acc); 52 .add_to(acc);
53 postfix_snippet(ctx, "dbg", "dbg!(expr)", &format!("dbg!({})", receiver_text)).add_to(acc); 53 postfix_snippet(ctx, "dbg", "dbg!(expr)", &format!("dbg!({})", receiver_text)).add_to(acc);
54 postfix_snippet(ctx, "box", "Box::new(expr)", &format!("Box::new({})", receiver_text))
55 .add_to(acc);
54 } 56 }
55} 57}
56 58
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap
index fcb292596..c1a40b7b4 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap
@@ -1,11 +1,18 @@
1--- 1---
2created: "2019-05-23T22:23:35.118738523Z" 2created: "2019-06-23T13:01:08.775536006Z"
3creator: [email protected] 3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs 4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions 5expression: kind_completions
6--- 6---
7[ 7[
8 CompletionItem { 8 CompletionItem {
9 label: "box",
10 source_range: [76; 76),
11 delete: [72; 76),
12 insert: "Box::new(bar)",
13 detail: "Box::new(expr)",
14 },
15 CompletionItem {
9 label: "dbg", 16 label: "dbg",
10 source_range: [76; 76), 17 source_range: [76; 76),
11 delete: [72; 76), 18 delete: [72; 76),
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index e85147e9e..424d0476d 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -103,7 +103,21 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
103 p.bump_remap(T![auto]); 103 p.bump_remap(T![auto]);
104 has_mods = true; 104 has_mods = true;
105 } 105 }
106 if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == T![impl] { 106
107 if p.at(IDENT)
108 && p.at_contextual_kw("default")
109 && (match p.nth(1) {
110 T![impl] => true,
111 T![fn] | T![type] => {
112 if let ItemFlavor::Mod = flavor {
113 true
114 } else {
115 false
116 }
117 }
118 _ => false,
119 })
120 {
107 p.bump_remap(T![default]); 121 p.bump_remap(T![default]);
108 has_mods = true; 122 has_mods = true;
109 } 123 }
@@ -163,12 +177,25 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
163 // test default_impl 177 // test default_impl
164 // default impl Foo {} 178 // default impl Foo {}
165 179
180 // test_err default_fn_type
181 // trait T {
182 // default type T = Bar;
183 // default fn foo() {}
184 // }
185
186 // test default_fn_type
187 // impl T for Foo {
188 // default type T = Bar;
189 // default fn foo() {}
190 // }
191
166 // test unsafe_default_impl 192 // test unsafe_default_impl
167 // unsafe default impl Foo {} 193 // unsafe default impl Foo {}
168 T![impl] => { 194 T![impl] => {
169 traits::impl_block(p); 195 traits::impl_block(p);
170 m.complete(p, IMPL_BLOCK); 196 m.complete(p, IMPL_BLOCK);
171 } 197 }
198
172 // test existential_type 199 // test existential_type
173 // existential type Foo: Fn() -> usize; 200 // existential type Foo: Fn() -> usize;
174 T![type] => { 201 T![type] => {
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0014_default_fn_type.rs b/crates/ra_syntax/tests/data/parser/inline/err/0014_default_fn_type.rs
new file mode 100644
index 000000000..15ba8f4a8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0014_default_fn_type.rs
@@ -0,0 +1,4 @@
1trait T {
2 default type T = Bar;
3 default fn foo() {}
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0014_default_fn_type.txt b/crates/ra_syntax/tests/data/parser/inline/err/0014_default_fn_type.txt
new file mode 100644
index 000000000..7da4e243f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0014_default_fn_type.txt
@@ -0,0 +1,58 @@
1SOURCE_FILE@[0; 62)
2 TRAIT_DEF@[0; 61)
3 TRAIT_KW@[0; 5) "trait"
4 WHITESPACE@[5; 6) " "
5 NAME@[6; 7)
6 IDENT@[6; 7) "T"
7 WHITESPACE@[7; 8) " "
8 ITEM_LIST@[8; 61)
9 L_CURLY@[8; 9) "{"
10 WHITESPACE@[9; 14) "\n "
11 MACRO_CALL@[14; 21)
12 PATH@[14; 21)
13 PATH_SEGMENT@[14; 21)
14 NAME_REF@[14; 21)
15 IDENT@[14; 21) "default"
16 WHITESPACE@[21; 22) " "
17 TYPE_ALIAS_DEF@[22; 35)
18 TYPE_KW@[22; 26) "type"
19 WHITESPACE@[26; 27) " "
20 NAME@[27; 28)
21 IDENT@[27; 28) "T"
22 WHITESPACE@[28; 29) " "
23 EQ@[29; 30) "="
24 WHITESPACE@[30; 31) " "
25 PATH_TYPE@[31; 34)
26 PATH@[31; 34)
27 PATH_SEGMENT@[31; 34)
28 NAME_REF@[31; 34)
29 IDENT@[31; 34) "Bar"
30 SEMI@[34; 35) ";"
31 WHITESPACE@[35; 40) "\n "
32 MACRO_CALL@[40; 47)
33 PATH@[40; 47)
34 PATH_SEGMENT@[40; 47)
35 NAME_REF@[40; 47)
36 IDENT@[40; 47) "default"
37 WHITESPACE@[47; 48) " "
38 FN_DEF@[48; 59)
39 FN_KW@[48; 50) "fn"
40 WHITESPACE@[50; 51) " "
41 NAME@[51; 54)
42 IDENT@[51; 54) "foo"
43 PARAM_LIST@[54; 56)
44 L_PAREN@[54; 55) "("
45 R_PAREN@[55; 56) ")"
46 WHITESPACE@[56; 57) " "
47 BLOCK@[57; 59)
48 L_CURLY@[57; 58) "{"
49 R_CURLY@[58; 59) "}"
50 WHITESPACE@[59; 60) "\n"
51 R_CURLY@[60; 61) "}"
52 WHITESPACE@[61; 62) "\n"
53error 21: expected EXCL
54error 21: expected `{`, `[`, `(`
55error 21: expected SEMI
56error 47: expected EXCL
57error 47: expected `{`, `[`, `(`
58error 47: expected SEMI
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0132_default_fn_type.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0132_default_fn_type.rs
new file mode 100644
index 000000000..8f5d61113
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0132_default_fn_type.rs
@@ -0,0 +1,4 @@
1impl T for Foo {
2 default type T = Bar;
3 default fn foo() {}
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0132_default_fn_type.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0132_default_fn_type.txt
new file mode 100644
index 000000000..384b203d3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0132_default_fn_type.txt
@@ -0,0 +1,55 @@
1SOURCE_FILE@[0; 69)
2 IMPL_BLOCK@[0; 68)
3 IMPL_KW@[0; 4) "impl"
4 WHITESPACE@[4; 5) " "
5 PATH_TYPE@[5; 6)
6 PATH@[5; 6)
7 PATH_SEGMENT@[5; 6)
8 NAME_REF@[5; 6)
9 IDENT@[5; 6) "T"
10 WHITESPACE@[6; 7) " "
11 FOR_KW@[7; 10) "for"
12 WHITESPACE@[10; 11) " "
13 PATH_TYPE@[11; 14)
14 PATH@[11; 14)
15 PATH_SEGMENT@[11; 14)
16 NAME_REF@[11; 14)
17 IDENT@[11; 14) "Foo"
18 WHITESPACE@[14; 15) " "
19 ITEM_LIST@[15; 68)
20 L_CURLY@[15; 16) "{"
21 WHITESPACE@[16; 21) "\n "
22 TYPE_ALIAS_DEF@[21; 42)
23 DEFAULT_KW@[21; 28) "default"
24 WHITESPACE@[28; 29) " "
25 TYPE_KW@[29; 33) "type"
26 WHITESPACE@[33; 34) " "
27 NAME@[34; 35)
28 IDENT@[34; 35) "T"
29 WHITESPACE@[35; 36) " "
30 EQ@[36; 37) "="
31 WHITESPACE@[37; 38) " "
32 PATH_TYPE@[38; 41)
33 PATH@[38; 41)
34 PATH_SEGMENT@[38; 41)
35 NAME_REF@[38; 41)
36 IDENT@[38; 41) "Bar"
37 SEMI@[41; 42) ";"
38 WHITESPACE@[42; 47) "\n "
39 FN_DEF@[47; 66)
40 DEFAULT_KW@[47; 54) "default"
41 WHITESPACE@[54; 55) " "
42 FN_KW@[55; 57) "fn"
43 WHITESPACE@[57; 58) " "
44 NAME@[58; 61)
45 IDENT@[58; 61) "foo"
46 PARAM_LIST@[61; 63)
47 L_PAREN@[61; 62) "("
48 R_PAREN@[62; 63) ")"
49 WHITESPACE@[63; 64) " "
50 BLOCK@[64; 66)
51 L_CURLY@[64; 65) "{"
52 R_CURLY@[65; 66) "}"
53 WHITESPACE@[66; 67) "\n"
54 R_CURLY@[67; 68) "}"
55 WHITESPACE@[68; 69) "\n"