diff options
129 files changed, 728 insertions, 2510 deletions
diff --git a/crates/gen_lsp_server/src/msg.rs b/crates/gen_lsp_server/src/msg.rs index 818111fe7..02c7a1858 100644 --- a/crates/gen_lsp_server/src/msg.rs +++ b/crates/gen_lsp_server/src/msg.rs | |||
@@ -80,10 +80,7 @@ impl RawMessage { | |||
80 | #[serde(flatten)] | 80 | #[serde(flatten)] |
81 | msg: RawMessage, | 81 | msg: RawMessage, |
82 | } | 82 | } |
83 | let text = to_string(&JsonRpc { | 83 | let text = to_string(&JsonRpc { jsonrpc: "2.0", msg: self })?; |
84 | jsonrpc: "2.0", | ||
85 | msg: self, | ||
86 | })?; | ||
87 | write_msg_text(w, &text)?; | 84 | write_msg_text(w, &text)?; |
88 | Ok(()) | 85 | Ok(()) |
89 | } | 86 | } |
@@ -95,11 +92,7 @@ impl RawRequest { | |||
95 | R: Request, | 92 | R: Request, |
96 | R::Params: serde::Serialize, | 93 | R::Params: serde::Serialize, |
97 | { | 94 | { |
98 | RawRequest { | 95 | RawRequest { id, method: R::METHOD.to_string(), params: to_value(params).unwrap() } |
99 | id, | ||
100 | method: R::METHOD.to_string(), | ||
101 | params: to_value(params).unwrap(), | ||
102 | } | ||
103 | } | 96 | } |
104 | pub fn cast<R>(self) -> ::std::result::Result<(u64, R::Params), RawRequest> | 97 | pub fn cast<R>(self) -> ::std::result::Result<(u64, R::Params), RawRequest> |
105 | where | 98 | where |
@@ -121,23 +114,11 @@ impl RawResponse { | |||
121 | R: Request, | 114 | R: Request, |
122 | R::Result: serde::Serialize, | 115 | R::Result: serde::Serialize, |
123 | { | 116 | { |
124 | RawResponse { | 117 | RawResponse { id, result: Some(to_value(&result).unwrap()), error: None } |
125 | id, | ||
126 | result: Some(to_value(&result).unwrap()), | ||
127 | error: None, | ||
128 | } | ||
129 | } | 118 | } |
130 | pub fn err(id: u64, code: i32, message: String) -> RawResponse { | 119 | pub fn err(id: u64, code: i32, message: String) -> RawResponse { |
131 | let error = RawResponseError { | 120 | let error = RawResponseError { code, message, data: None }; |
132 | code, | 121 | RawResponse { id, result: None, error: Some(error) } |
133 | message, | ||
134 | data: None, | ||
135 | }; | ||
136 | RawResponse { | ||
137 | id, | ||
138 | result: None, | ||
139 | error: Some(error), | ||
140 | } | ||
141 | } | 122 | } |
142 | } | 123 | } |
143 | 124 | ||
@@ -147,10 +128,7 @@ impl RawNotification { | |||
147 | N: Notification, | 128 | N: Notification, |
148 | N::Params: serde::Serialize, | 129 | N::Params: serde::Serialize, |
149 | { | 130 | { |
150 | RawNotification { | 131 | RawNotification { method: N::METHOD.to_string(), params: to_value(params).unwrap() } |
151 | method: N::METHOD.to_string(), | ||
152 | params: to_value(params).unwrap(), | ||
153 | } | ||
154 | } | 132 | } |
155 | pub fn is<N>(&self) -> bool | 133 | pub fn is<N>(&self) -> bool |
156 | where | 134 | where |
@@ -187,9 +165,8 @@ fn read_msg_text(inp: &mut impl BufRead) -> Result<Option<String>> { | |||
187 | } | 165 | } |
188 | let mut parts = buf.splitn(2, ": "); | 166 | let mut parts = buf.splitn(2, ": "); |
189 | let header_name = parts.next().unwrap(); | 167 | let header_name = parts.next().unwrap(); |
190 | let header_value = parts | 168 | let header_value = |
191 | .next() | 169 | parts.next().ok_or_else(|| format_err!("malformed header: {:?}", buf))?; |
192 | .ok_or_else(|| format_err!("malformed header: {:?}", buf))?; | ||
193 | if header_name == "Content-Length" { | 170 | if header_name == "Content-Length" { |
194 | size = Some(header_value.parse::<usize>()?); | 171 | size = Some(header_value.parse::<usize>()?); |
195 | } | 172 | } |
diff --git a/crates/gen_lsp_server/src/stdio.rs b/crates/gen_lsp_server/src/stdio.rs index 5c8e33854..dab2d8da8 100644 --- a/crates/gen_lsp_server/src/stdio.rs +++ b/crates/gen_lsp_server/src/stdio.rs | |||
@@ -13,9 +13,7 @@ pub fn stdio_transport() -> (Receiver<RawMessage>, Sender<RawMessage>, Threads) | |||
13 | let writer = thread::spawn(move || { | 13 | let writer = thread::spawn(move || { |
14 | let stdout = stdout(); | 14 | let stdout = stdout(); |
15 | let mut stdout = stdout.lock(); | 15 | let mut stdout = stdout.lock(); |
16 | writer_receiver | 16 | writer_receiver.into_iter().try_for_each(|it| it.write(&mut stdout))?; |
17 | .into_iter() | ||
18 | .try_for_each(|it| it.write(&mut stdout))?; | ||
19 | Ok(()) | 17 | Ok(()) |
20 | }); | 18 | }); |
21 | let (reader_sender, reader_receiver) = bounded::<RawMessage>(16); | 19 | let (reader_sender, reader_receiver) = bounded::<RawMessage>(16); |
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs index 97f554838..1c97c2662 100644 --- a/crates/ra_arena/src/lib.rs +++ b/crates/ra_arena/src/lib.rs | |||
@@ -44,10 +44,7 @@ pub struct Arena<ID: ArenaId, T> { | |||
44 | 44 | ||
45 | impl<ID: ArenaId, T: fmt::Debug> fmt::Debug for Arena<ID, T> { | 45 | impl<ID: ArenaId, T: fmt::Debug> fmt::Debug for Arena<ID, T> { |
46 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 46 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
47 | fmt.debug_struct("Arena") | 47 | fmt.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish() |
48 | .field("len", &self.len()) | ||
49 | .field("data", &self.data) | ||
50 | .finish() | ||
51 | } | 48 | } |
52 | } | 49 | } |
53 | 50 | ||
@@ -80,19 +77,13 @@ impl<ID: ArenaId, T> Arena<ID, T> { | |||
80 | ID::from_raw(id) | 77 | ID::from_raw(id) |
81 | } | 78 | } |
82 | pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> { | 79 | pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> { |
83 | self.data | 80 | self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) |
84 | .iter() | ||
85 | .enumerate() | ||
86 | .map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) | ||
87 | } | 81 | } |
88 | } | 82 | } |
89 | 83 | ||
90 | impl<ID: ArenaId, T> Default for Arena<ID, T> { | 84 | impl<ID: ArenaId, T> Default for Arena<ID, T> { |
91 | fn default() -> Arena<ID, T> { | 85 | fn default() -> Arena<ID, T> { |
92 | Arena { | 86 | Arena { data: Vec::new(), _ty: PhantomData } |
93 | data: Vec::new(), | ||
94 | _ty: PhantomData, | ||
95 | } | ||
96 | } | 87 | } |
97 | } | 88 | } |
98 | 89 | ||
@@ -116,9 +107,6 @@ impl<ID: ArenaId, T> FromIterator<T> for Arena<ID, T> { | |||
116 | where | 107 | where |
117 | I: IntoIterator<Item = T>, | 108 | I: IntoIterator<Item = T>, |
118 | { | 109 | { |
119 | Arena { | 110 | Arena { data: Vec::from_iter(iter), _ty: PhantomData } |
120 | data: Vec::from_iter(iter), | ||
121 | _ty: PhantomData, | ||
122 | } | ||
123 | } | 111 | } |
124 | } | 112 | } |
diff --git a/crates/ra_arena/src/map.rs b/crates/ra_arena/src/map.rs index be80edaf3..b73d4e365 100644 --- a/crates/ra_arena/src/map.rs +++ b/crates/ra_arena/src/map.rs | |||
@@ -42,10 +42,7 @@ impl<ID: ArenaId, T> ArenaMap<ID, T> { | |||
42 | } | 42 | } |
43 | 43 | ||
44 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> { | 44 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> { |
45 | self.v | 45 | self.v.iter().enumerate().filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_ref()?))) |
46 | .iter() | ||
47 | .enumerate() | ||
48 | .filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_ref()?))) | ||
49 | } | 46 | } |
50 | 47 | ||
51 | fn to_idx(id: ID) -> usize { | 48 | fn to_idx(id: ID) -> usize { |
@@ -66,9 +63,6 @@ impl<ID: ArenaId, T> std::ops::Index<ID> for ArenaMap<ID, T> { | |||
66 | 63 | ||
67 | impl<ID, T> Default for ArenaMap<ID, T> { | 64 | impl<ID, T> Default for ArenaMap<ID, T> { |
68 | fn default() -> Self { | 65 | fn default() -> Self { |
69 | ArenaMap { | 66 | ArenaMap { v: Vec::new(), _ty: PhantomData } |
70 | v: Vec::new(), | ||
71 | _ty: PhantomData, | ||
72 | } | ||
73 | } | 67 | } |
74 | } | 68 | } |
diff --git a/crates/ra_assists/src/add_derive.rs b/crates/ra_assists/src/add_derive.rs index 01a4079f6..caf21e079 100644 --- a/crates/ra_assists/src/add_derive.rs +++ b/crates/ra_assists/src/add_derive.rs | |||
@@ -30,10 +30,8 @@ pub(crate) fn add_derive(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
30 | 30 | ||
31 | // Insert `derive` after doc comments. | 31 | // Insert `derive` after doc comments. |
32 | fn derive_insertion_offset(nominal: &ast::NominalDef) -> Option<TextUnit> { | 32 | fn derive_insertion_offset(nominal: &ast::NominalDef) -> Option<TextUnit> { |
33 | let non_ws_child = nominal | 33 | let non_ws_child = |
34 | .syntax() | 34 | nominal.syntax().children().find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?; |
35 | .children() | ||
36 | .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?; | ||
37 | Some(non_ws_child.range().start()) | 35 | Some(non_ws_child.range().start()) |
38 | } | 36 | } |
39 | 37 | ||
diff --git a/crates/ra_assists/src/add_impl.rs b/crates/ra_assists/src/add_impl.rs index 699508f91..f2360bc89 100644 --- a/crates/ra_assists/src/add_impl.rs +++ b/crates/ra_assists/src/add_impl.rs | |||
@@ -21,17 +21,11 @@ pub(crate) fn add_impl(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
21 | buf.push_str(" "); | 21 | buf.push_str(" "); |
22 | buf.push_str(name.text().as_str()); | 22 | buf.push_str(name.text().as_str()); |
23 | if let Some(type_params) = type_params { | 23 | if let Some(type_params) = type_params { |
24 | let lifetime_params = type_params | 24 | let lifetime_params = |
25 | .lifetime_params() | 25 | type_params.lifetime_params().filter_map(|it| it.lifetime()).map(|it| it.text()); |
26 | .filter_map(|it| it.lifetime()) | 26 | let type_params = |
27 | .map(|it| it.text()); | 27 | type_params.type_params().filter_map(|it| it.name()).map(|it| it.text()); |
28 | let type_params = type_params | 28 | join(lifetime_params.chain(type_params)).surround_with("<", ">").to_buf(&mut buf); |
29 | .type_params() | ||
30 | .filter_map(|it| it.name()) | ||
31 | .map(|it| it.text()); | ||
32 | join(lifetime_params.chain(type_params)) | ||
33 | .surround_with("<", ">") | ||
34 | .to_buf(&mut buf); | ||
35 | } | 29 | } |
36 | buf.push_str(" {\n"); | 30 | buf.push_str(" {\n"); |
37 | edit.set_cursor(start_offset + TextUnit::of_str(&buf)); | 31 | edit.set_cursor(start_offset + TextUnit::of_str(&buf)); |
@@ -47,11 +41,7 @@ mod tests { | |||
47 | 41 | ||
48 | #[test] | 42 | #[test] |
49 | fn test_add_impl() { | 43 | fn test_add_impl() { |
50 | check_assist( | 44 | check_assist(add_impl, "struct Foo {<|>}\n", "struct Foo {}\n\nimpl Foo {\n<|>\n}\n"); |
51 | add_impl, | ||
52 | "struct Foo {<|>}\n", | ||
53 | "struct Foo {}\n\nimpl Foo {\n<|>\n}\n", | ||
54 | ); | ||
55 | check_assist( | 45 | check_assist( |
56 | add_impl, | 46 | add_impl, |
57 | "struct Foo<T: Clone> {<|>}", | 47 | "struct Foo<T: Clone> {<|>}", |
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index 6d09bde52..0bf640241 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs | |||
@@ -69,12 +69,7 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { | |||
69 | F: FnOnce(AssistCtx<DB>) -> T, | 69 | F: FnOnce(AssistCtx<DB>) -> T, |
70 | { | 70 | { |
71 | let source_file = &db.parse(frange.file_id); | 71 | let source_file = &db.parse(frange.file_id); |
72 | let ctx = AssistCtx { | 72 | let ctx = AssistCtx { db, frange, source_file, should_compute_edit }; |
73 | db, | ||
74 | frange, | ||
75 | source_file, | ||
76 | should_compute_edit, | ||
77 | }; | ||
78 | f(ctx) | 73 | f(ctx) |
79 | } | 74 | } |
80 | 75 | ||
@@ -83,9 +78,7 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { | |||
83 | label: impl Into<String>, | 78 | label: impl Into<String>, |
84 | f: impl FnOnce(&mut AssistBuilder), | 79 | f: impl FnOnce(&mut AssistBuilder), |
85 | ) -> Option<Assist> { | 80 | ) -> Option<Assist> { |
86 | let label = AssistLabel { | 81 | let label = AssistLabel { label: label.into() }; |
87 | label: label.into(), | ||
88 | }; | ||
89 | if !self.should_compute_edit { | 82 | if !self.should_compute_edit { |
90 | return Some(Assist::Unresolved(label)); | 83 | return Some(Assist::Unresolved(label)); |
91 | } | 84 | } |
@@ -146,9 +139,6 @@ impl AssistBuilder { | |||
146 | } | 139 | } |
147 | 140 | ||
148 | fn build(self) -> AssistAction { | 141 | fn build(self) -> AssistAction { |
149 | AssistAction { | 142 | AssistAction { edit: self.edit.finish(), cursor_position: self.cursor_position } |
150 | edit: self.edit.finish(), | ||
151 | cursor_position: self.cursor_position, | ||
152 | } | ||
153 | } | 143 | } |
154 | } | 144 | } |
diff --git a/crates/ra_assists/src/change_visibility.rs b/crates/ra_assists/src/change_visibility.rs index 4cd32985e..fa5f231c8 100644 --- a/crates/ra_assists/src/change_visibility.rs +++ b/crates/ra_assists/src/change_visibility.rs | |||
@@ -81,31 +81,11 @@ mod tests { | |||
81 | 81 | ||
82 | #[test] | 82 | #[test] |
83 | fn change_visibility_adds_pub_crate_to_items() { | 83 | fn change_visibility_adds_pub_crate_to_items() { |
84 | check_assist( | 84 | check_assist(change_visibility, "<|>fn foo() {}", "<|>pub(crate) fn foo() {}"); |
85 | change_visibility, | 85 | check_assist(change_visibility, "f<|>n foo() {}", "<|>pub(crate) fn foo() {}"); |
86 | "<|>fn foo() {}", | 86 | check_assist(change_visibility, "<|>struct Foo {}", "<|>pub(crate) struct Foo {}"); |
87 | "<|>pub(crate) fn foo() {}", | 87 | check_assist(change_visibility, "<|>mod foo {}", "<|>pub(crate) mod foo {}"); |
88 | ); | 88 | check_assist(change_visibility, "<|>trait Foo {}", "<|>pub(crate) trait Foo {}"); |
89 | check_assist( | ||
90 | change_visibility, | ||
91 | "f<|>n foo() {}", | ||
92 | "<|>pub(crate) fn foo() {}", | ||
93 | ); | ||
94 | check_assist( | ||
95 | change_visibility, | ||
96 | "<|>struct Foo {}", | ||
97 | "<|>pub(crate) struct Foo {}", | ||
98 | ); | ||
99 | check_assist( | ||
100 | change_visibility, | ||
101 | "<|>mod foo {}", | ||
102 | "<|>pub(crate) mod foo {}", | ||
103 | ); | ||
104 | check_assist( | ||
105 | change_visibility, | ||
106 | "<|>trait Foo {}", | ||
107 | "<|>pub(crate) trait Foo {}", | ||
108 | ); | ||
109 | check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}"); | 89 | check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}"); |
110 | check_assist( | 90 | check_assist( |
111 | change_visibility, | 91 | change_visibility, |
@@ -125,20 +105,12 @@ mod tests { | |||
125 | 105 | ||
126 | #[test] | 106 | #[test] |
127 | fn change_visibility_pub_to_pub_crate() { | 107 | fn change_visibility_pub_to_pub_crate() { |
128 | check_assist( | 108 | check_assist(change_visibility, "<|>pub fn foo() {}", "<|>pub(crate) fn foo() {}") |
129 | change_visibility, | ||
130 | "<|>pub fn foo() {}", | ||
131 | "<|>pub(crate) fn foo() {}", | ||
132 | ) | ||
133 | } | 109 | } |
134 | 110 | ||
135 | #[test] | 111 | #[test] |
136 | fn change_visibility_pub_crate_to_pub() { | 112 | fn change_visibility_pub_crate_to_pub() { |
137 | check_assist( | 113 | check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "<|>pub fn foo() {}") |
138 | change_visibility, | ||
139 | "<|>pub(crate) fn foo() {}", | ||
140 | "<|>pub fn foo() {}", | ||
141 | ) | ||
142 | } | 114 | } |
143 | 115 | ||
144 | #[test] | 116 | #[test] |
diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index 9aa37d94c..741f75e2a 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs | |||
@@ -27,10 +27,7 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
27 | let node_expr = syntax_mapping.node_expr(expr)?; | 27 | let node_expr = syntax_mapping.node_expr(expr)?; |
28 | let match_expr_ty = infer_result[node_expr].clone(); | 28 | let match_expr_ty = infer_result[node_expr].clone(); |
29 | let enum_def = match match_expr_ty { | 29 | let enum_def = match match_expr_ty { |
30 | Ty::Adt { | 30 | Ty::Adt { def_id: AdtDef::Enum(e), .. } => e, |
31 | def_id: AdtDef::Enum(e), | ||
32 | .. | ||
33 | } => e, | ||
34 | _ => return None, | 31 | _ => return None, |
35 | }; | 32 | }; |
36 | let enum_name = enum_def.name(ctx.db)?; | 33 | let enum_name = enum_def.name(ctx.db)?; |
diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs index f587b4fe6..4f7c9f3c2 100644 --- a/crates/ra_assists/src/introduce_variable.rs +++ b/crates/ra_assists/src/introduce_variable.rs | |||
@@ -81,11 +81,7 @@ fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> { | |||
81 | return Some((node, false)); | 81 | return Some((node, false)); |
82 | } | 82 | } |
83 | 83 | ||
84 | if let Some(expr) = node | 84 | if let Some(expr) = node.parent().and_then(ast::Block::cast).and_then(|it| it.expr()) { |
85 | .parent() | ||
86 | .and_then(ast::Block::cast) | ||
87 | .and_then(|it| it.expr()) | ||
88 | { | ||
89 | if expr.syntax() == node { | 85 | if expr.syntax() == node { |
90 | return Some((node, false)); | 86 | return Some((node, false)); |
91 | } | 87 | } |
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index 555af51bc..881db6347 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -89,9 +89,7 @@ fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assis | |||
89 | } | 89 | } |
90 | 90 | ||
91 | fn non_trivia_sibling(node: &SyntaxNode, direction: Direction) -> Option<&SyntaxNode> { | 91 | fn non_trivia_sibling(node: &SyntaxNode, direction: Direction) -> Option<&SyntaxNode> { |
92 | node.siblings(direction) | 92 | node.siblings(direction).skip(1).find(|node| !node.kind().is_trivia()) |
93 | .skip(1) | ||
94 | .find(|node| !node.kind().is_trivia()) | ||
95 | } | 93 | } |
96 | 94 | ||
97 | #[cfg(test)] | 95 | #[cfg(test)] |
@@ -110,10 +108,8 @@ mod helpers { | |||
110 | ) { | 108 | ) { |
111 | let (before_cursor_pos, before) = extract_offset(before); | 109 | let (before_cursor_pos, before) = extract_offset(before); |
112 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); | 110 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); |
113 | let frange = FileRange { | 111 | let frange = |
114 | file_id, | 112 | FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; |
115 | range: TextRange::offset_len(before_cursor_pos, 0.into()), | ||
116 | }; | ||
117 | let assist = | 113 | let assist = |
118 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); | 114 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); |
119 | let action = match assist { | 115 | let action = match assist { |
@@ -161,10 +157,8 @@ mod helpers { | |||
161 | ) { | 157 | ) { |
162 | let (before_cursor_pos, before) = extract_offset(before); | 158 | let (before_cursor_pos, before) = extract_offset(before); |
163 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); | 159 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); |
164 | let frange = FileRange { | 160 | let frange = |
165 | file_id, | 161 | FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; |
166 | range: TextRange::offset_len(before_cursor_pos, 0.into()), | ||
167 | }; | ||
168 | let assist = AssistCtx::with_ctx(&db, frange, true, assist); | 162 | let assist = AssistCtx::with_ctx(&db, frange, true, assist); |
169 | assert!(assist.is_none()); | 163 | assert!(assist.is_none()); |
170 | } | 164 | } |
diff --git a/crates/ra_assists/src/replace_if_let_with_match.rs b/crates/ra_assists/src/replace_if_let_with_match.rs index f6af47ec9..683f0d119 100644 --- a/crates/ra_assists/src/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/replace_if_let_with_match.rs | |||
@@ -30,11 +30,7 @@ fn build_match_expr( | |||
30 | ) -> String { | 30 | ) -> String { |
31 | let mut buf = String::new(); | 31 | let mut buf = String::new(); |
32 | buf.push_str(&format!("match {} {{\n", expr.syntax().text())); | 32 | buf.push_str(&format!("match {} {{\n", expr.syntax().text())); |
33 | buf.push_str(&format!( | 33 | buf.push_str(&format!(" {} => {}\n", pat1.syntax().text(), format_arm(arm1))); |
34 | " {} => {}\n", | ||
35 | pat1.syntax().text(), | ||
36 | format_arm(arm1) | ||
37 | )); | ||
38 | buf.push_str(&format!(" _ => {}\n", format_arm(arm2))); | 34 | buf.push_str(&format!(" _ => {}\n", format_arm(arm2))); |
39 | buf.push_str("}"); | 35 | buf.push_str("}"); |
40 | buf | 36 | buf |
diff --git a/crates/ra_assists/src/split_import.rs b/crates/ra_assists/src/split_import.rs index 7e34be087..fb69cef9c 100644 --- a/crates/ra_assists/src/split_import.rs +++ b/crates/ra_assists/src/split_import.rs | |||
@@ -8,9 +8,7 @@ use ra_syntax::{ | |||
8 | use crate::{AssistCtx, Assist}; | 8 | use crate::{AssistCtx, Assist}; |
9 | 9 | ||
10 | pub(crate) fn split_import(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 10 | pub(crate) fn split_import(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
11 | let colon_colon = ctx | 11 | let colon_colon = ctx.leaf_at_offset().find(|leaf| leaf.kind() == COLONCOLON)?; |
12 | .leaf_at_offset() | ||
13 | .find(|leaf| leaf.kind() == COLONCOLON)?; | ||
14 | let path = colon_colon.parent().and_then(ast::Path::cast)?; | 12 | let path = colon_colon.parent().and_then(ast::Path::cast)?; |
15 | let top_path = generate(Some(path), |it| it.parent_path()).last()?; | 13 | let top_path = generate(Some(path), |it| it.parent_path()).last()?; |
16 | 14 | ||
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 6b5be27be..a4debeb48 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs | |||
@@ -13,18 +13,8 @@ fn main() -> Result<()> { | |||
13 | .setting(clap::AppSettings::SubcommandRequiredElseHelp) | 13 | .setting(clap::AppSettings::SubcommandRequiredElseHelp) |
14 | .subcommand( | 14 | .subcommand( |
15 | SubCommand::with_name("render-test") | 15 | SubCommand::with_name("render-test") |
16 | .arg( | 16 | .arg(Arg::with_name("line").long("--line").required(true).takes_value(true)) |
17 | Arg::with_name("line") | 17 | .arg(Arg::with_name("file").long("--file").required(true).takes_value(true)), |
18 | .long("--line") | ||
19 | .required(true) | ||
20 | .takes_value(true), | ||
21 | ) | ||
22 | .arg( | ||
23 | Arg::with_name("file") | ||
24 | .long("--file") | ||
25 | .required(true) | ||
26 | .takes_value(true), | ||
27 | ), | ||
28 | ) | 18 | ) |
29 | .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump"))) | 19 | .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump"))) |
30 | .subcommand(SubCommand::with_name("symbols")) | 20 | .subcommand(SubCommand::with_name("symbols")) |
@@ -108,8 +98,5 @@ fn selections(file: &SourceFile, start: u32, end: u32) -> String { | |||
108 | .iter() | 98 | .iter() |
109 | .map(|r| (1 + u32::from(r.start()), 1 + u32::from(r.end()))) | 99 | .map(|r| (1 + u32::from(r.start()), 1 + u32::from(r.end()))) |
110 | .map(|(s, e)| format!("({} {})", s, e)); | 100 | .map(|(s, e)| format!("({} {})", s, e)); |
111 | join(ranges) | 101 | join(ranges).separator(" ").surround_with("(", ")").to_string() |
112 | .separator(" ") | ||
113 | .surround_with("(", ")") | ||
114 | .to_string() | ||
115 | } | 102 | } |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 275894252..614325a0f 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -64,10 +64,7 @@ struct CrateData { | |||
64 | 64 | ||
65 | impl CrateData { | 65 | impl CrateData { |
66 | fn new(file_id: FileId) -> CrateData { | 66 | fn new(file_id: FileId) -> CrateData { |
67 | CrateData { | 67 | CrateData { file_id, dependencies: Vec::new() } |
68 | file_id, | ||
69 | dependencies: Vec::new(), | ||
70 | } | ||
71 | } | 68 | } |
72 | 69 | ||
73 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | 70 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { |
@@ -112,10 +109,7 @@ impl CrateGraph { | |||
112 | self.arena[&crate_id].file_id | 109 | self.arena[&crate_id].file_id |
113 | } | 110 | } |
114 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | 111 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { |
115 | let (&crate_id, _) = self | 112 | let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; |
116 | .arena | ||
117 | .iter() | ||
118 | .find(|(_crate_id, data)| data.file_id == file_id)?; | ||
119 | Some(crate_id) | 113 | Some(crate_id) |
120 | } | 114 | } |
121 | pub fn dependencies<'a>( | 115 | pub fn dependencies<'a>( |
@@ -153,15 +147,9 @@ mod tests { | |||
153 | let crate1 = graph.add_crate_root(FileId(1u32)); | 147 | let crate1 = graph.add_crate_root(FileId(1u32)); |
154 | let crate2 = graph.add_crate_root(FileId(2u32)); | 148 | let crate2 = graph.add_crate_root(FileId(2u32)); |
155 | let crate3 = graph.add_crate_root(FileId(3u32)); | 149 | let crate3 = graph.add_crate_root(FileId(3u32)); |
156 | assert!(graph | 150 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
157 | .add_dep(crate1, SmolStr::new("crate2"), crate2) | 151 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
158 | .is_ok()); | 152 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); |
159 | assert!(graph | ||
160 | .add_dep(crate2, SmolStr::new("crate3"), crate3) | ||
161 | .is_ok()); | ||
162 | assert!(graph | ||
163 | .add_dep(crate3, SmolStr::new("crate1"), crate1) | ||
164 | .is_err()); | ||
165 | } | 153 | } |
166 | 154 | ||
167 | #[test] | 155 | #[test] |
@@ -170,11 +158,7 @@ mod tests { | |||
170 | let crate1 = graph.add_crate_root(FileId(1u32)); | 158 | let crate1 = graph.add_crate_root(FileId(1u32)); |
171 | let crate2 = graph.add_crate_root(FileId(2u32)); | 159 | let crate2 = graph.add_crate_root(FileId(2u32)); |
172 | let crate3 = graph.add_crate_root(FileId(3u32)); | 160 | let crate3 = graph.add_crate_root(FileId(3u32)); |
173 | assert!(graph | 161 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
174 | .add_dep(crate1, SmolStr::new("crate2"), crate2) | 162 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
175 | .is_ok()); | ||
176 | assert!(graph | ||
177 | .add_dep(crate2, SmolStr::new("crate3"), crate3) | ||
178 | .is_ok()); | ||
179 | } | 163 | } |
180 | } | 164 | } |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 66634e05b..31442713d 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -94,11 +94,8 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug { | |||
94 | fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { | 94 | fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { |
95 | let root = db.source_root(id); | 95 | let root = db.source_root(id); |
96 | let graph = db.crate_graph(); | 96 | let graph = db.crate_graph(); |
97 | let res = root | 97 | let res = |
98 | .files | 98 | root.files.values().filter_map(|&it| graph.crate_id_for_crate_root(it)).collect::<Vec<_>>(); |
99 | .values() | ||
100 | .filter_map(|&it| graph.crate_id_for_crate_root(it)) | ||
101 | .collect::<Vec<_>>(); | ||
102 | Arc::new(res) | 99 | Arc::new(res) |
103 | } | 100 | } |
104 | 101 | ||
diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs index 359cd893d..d27fa7682 100644 --- a/crates/ra_db/src/loc2id.rs +++ b/crates/ra_db/src/loc2id.rs | |||
@@ -30,10 +30,7 @@ where | |||
30 | LOC: Clone + Eq + Hash, | 30 | LOC: Clone + Eq + Hash, |
31 | { | 31 | { |
32 | fn default() -> Self { | 32 | fn default() -> Self { |
33 | Loc2IdMap { | 33 | Loc2IdMap { id2loc: Arena::default(), loc2id: FxHashMap::default() } |
34 | id2loc: Arena::default(), | ||
35 | loc2id: FxHashMap::default(), | ||
36 | } | ||
37 | } | 34 | } |
38 | } | 35 | } |
39 | 36 | ||
@@ -85,9 +82,7 @@ where | |||
85 | LOC: Clone + Eq + Hash, | 82 | LOC: Clone + Eq + Hash, |
86 | { | 83 | { |
87 | fn default() -> Self { | 84 | fn default() -> Self { |
88 | LocationIntener { | 85 | LocationIntener { map: Default::default() } |
89 | map: Default::default(), | ||
90 | } | ||
91 | } | 86 | } |
92 | } | 87 | } |
93 | 88 | ||
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index c549e2126..6d917bb1b 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -62,10 +62,7 @@ impl StructData { | |||
62 | } | 62 | } |
63 | 63 | ||
64 | fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> { | 64 | fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> { |
65 | enum_def | 65 | enum_def.variant_list().into_iter().flat_map(|it| it.variants()) |
66 | .variant_list() | ||
67 | .into_iter() | ||
68 | .flat_map(|it| it.variants()) | ||
69 | } | 66 | } |
70 | 67 | ||
71 | impl EnumVariant { | 68 | impl EnumVariant { |
@@ -83,9 +80,7 @@ impl EnumVariant { | |||
83 | (file_id, var) | 80 | (file_id, var) |
84 | } | 81 | } |
85 | pub(crate) fn variant_data(&self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { | 82 | pub(crate) fn variant_data(&self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { |
86 | db.enum_data(self.parent).variants[self.id] | 83 | db.enum_data(self.parent).variants[self.id].variant_data.clone() |
87 | .variant_data | ||
88 | .clone() | ||
89 | } | 84 | } |
90 | } | 85 | } |
91 | 86 | ||
@@ -222,14 +217,12 @@ impl StructField { | |||
222 | }; | 217 | }; |
223 | 218 | ||
224 | let field_sources = match struct_flavor { | 219 | let field_sources = match struct_flavor { |
225 | ast::StructFlavor::Tuple(fl) => fl | 220 | ast::StructFlavor::Tuple(fl) => { |
226 | .fields() | 221 | fl.fields().map(|it| FieldSource::Pos(it.to_owned())).collect() |
227 | .map(|it| FieldSource::Pos(it.to_owned())) | 222 | } |
228 | .collect(), | 223 | ast::StructFlavor::Named(fl) => { |
229 | ast::StructFlavor::Named(fl) => fl | 224 | fl.fields().map(|it| FieldSource::Named(it.to_owned())).collect() |
230 | .fields() | 225 | } |
231 | .map(|it| FieldSource::Named(it.to_owned())) | ||
232 | .collect(), | ||
233 | ast::StructFlavor::Unit => Vec::new(), | 226 | ast::StructFlavor::Unit => Vec::new(), |
234 | }; | 227 | }; |
235 | let field = field_sources | 228 | let field = field_sources |
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index a58bf8f87..cafc5279d 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -71,17 +71,7 @@ pub enum ModuleDef { | |||
71 | Trait(Trait), | 71 | Trait(Trait), |
72 | Type(Type), | 72 | Type(Type), |
73 | } | 73 | } |
74 | impl_froms!( | 74 | impl_froms!(ModuleDef: Module, Function, Struct, Enum, EnumVariant, Const, Static, Trait, Type); |
75 | ModuleDef: Module, | ||
76 | Function, | ||
77 | Struct, | ||
78 | Enum, | ||
79 | EnumVariant, | ||
80 | Const, | ||
81 | Static, | ||
82 | Trait, | ||
83 | Type | ||
84 | ); | ||
85 | 75 | ||
86 | pub enum ModuleSource { | 76 | pub enum ModuleSource { |
87 | SourceFile(TreeArc<ast::SourceFile>), | 77 | SourceFile(TreeArc<ast::SourceFile>), |
@@ -90,13 +80,8 @@ pub enum ModuleSource { | |||
90 | 80 | ||
91 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] | 81 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] |
92 | pub enum Problem { | 82 | pub enum Problem { |
93 | UnresolvedModule { | 83 | UnresolvedModule { candidate: RelativePathBuf }, |
94 | candidate: RelativePathBuf, | 84 | NotDirOwner { move_to: RelativePathBuf, candidate: RelativePathBuf }, |
95 | }, | ||
96 | NotDirOwner { | ||
97 | move_to: RelativePathBuf, | ||
98 | candidate: RelativePathBuf, | ||
99 | }, | ||
100 | } | 85 | } |
101 | 86 | ||
102 | impl Module { | 87 | impl Module { |
@@ -187,8 +172,7 @@ impl Module { | |||
187 | 172 | ||
188 | impl Docs for Module { | 173 | impl Docs for Module { |
189 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> { | 174 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> { |
190 | self.declaration_source(db) | 175 | self.declaration_source(db).and_then(|it| docs_from_ast(&*it.1)) |
191 | .and_then(|it| docs_from_ast(&*it.1)) | ||
192 | } | 176 | } |
193 | } | 177 | } |
194 | 178 | ||
@@ -206,9 +190,7 @@ pub enum FieldSource { | |||
206 | 190 | ||
207 | impl StructField { | 191 | impl StructField { |
208 | pub fn name(&self, db: &impl HirDatabase) -> Name { | 192 | pub fn name(&self, db: &impl HirDatabase) -> Name { |
209 | self.parent.variant_data(db).fields().unwrap()[self.id] | 193 | self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() |
210 | .name | ||
211 | .clone() | ||
212 | } | 194 | } |
213 | 195 | ||
214 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, FieldSource) { | 196 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, FieldSource) { |
@@ -257,10 +239,7 @@ impl Struct { | |||
257 | .fields() | 239 | .fields() |
258 | .into_iter() | 240 | .into_iter() |
259 | .flat_map(|it| it.iter()) | 241 | .flat_map(|it| it.iter()) |
260 | .map(|(id, _)| StructField { | 242 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
261 | parent: (*self).into(), | ||
262 | id, | ||
263 | }) | ||
264 | .collect() | 243 | .collect() |
265 | } | 244 | } |
266 | 245 | ||
@@ -271,10 +250,7 @@ impl Struct { | |||
271 | .into_iter() | 250 | .into_iter() |
272 | .flat_map(|it| it.iter()) | 251 | .flat_map(|it| it.iter()) |
273 | .find(|(_id, data)| data.name == *name) | 252 | .find(|(_id, data)| data.name == *name) |
274 | .map(|(id, _)| StructField { | 253 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
275 | parent: (*self).into(), | ||
276 | id, | ||
277 | }) | ||
278 | } | 254 | } |
279 | 255 | ||
280 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { | 256 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { |
@@ -292,11 +268,7 @@ impl Struct { | |||
292 | let r = self.module(db).resolver(db); | 268 | let r = self.module(db).resolver(db); |
293 | // ...and add generic params, if present | 269 | // ...and add generic params, if present |
294 | let p = self.generic_params(db); | 270 | let p = self.generic_params(db); |
295 | let r = if !p.params.is_empty() { | 271 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
296 | r.push_generic_params_scope(p) | ||
297 | } else { | ||
298 | r | ||
299 | }; | ||
300 | r | 272 | r |
301 | } | 273 | } |
302 | } | 274 | } |
@@ -356,11 +328,7 @@ impl Enum { | |||
356 | let r = self.module(db).resolver(db); | 328 | let r = self.module(db).resolver(db); |
357 | // ...and add generic params, if present | 329 | // ...and add generic params, if present |
358 | let p = self.generic_params(db); | 330 | let p = self.generic_params(db); |
359 | let r = if !p.params.is_empty() { | 331 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
360 | r.push_generic_params_scope(p) | ||
361 | } else { | ||
362 | r | ||
363 | }; | ||
364 | r | 332 | r |
365 | } | 333 | } |
366 | } | 334 | } |
@@ -400,10 +368,7 @@ impl EnumVariant { | |||
400 | .fields() | 368 | .fields() |
401 | .into_iter() | 369 | .into_iter() |
402 | .flat_map(|it| it.iter()) | 370 | .flat_map(|it| it.iter()) |
403 | .map(|(id, _)| StructField { | 371 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
404 | parent: (*self).into(), | ||
405 | id, | ||
406 | }) | ||
407 | .collect() | 372 | .collect() |
408 | } | 373 | } |
409 | 374 | ||
@@ -413,10 +378,7 @@ impl EnumVariant { | |||
413 | .into_iter() | 378 | .into_iter() |
414 | .flat_map(|it| it.iter()) | 379 | .flat_map(|it| it.iter()) |
415 | .find(|(_id, data)| data.name == *name) | 380 | .find(|(_id, data)| data.name == *name) |
416 | .map(|(id, _)| StructField { | 381 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
417 | parent: (*self).into(), | ||
418 | id, | ||
419 | }) | ||
420 | } | 382 | } |
421 | } | 383 | } |
422 | 384 | ||
@@ -488,10 +450,7 @@ impl Function { | |||
488 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { | 450 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { |
489 | let scopes = db.expr_scopes(*self); | 451 | let scopes = db.expr_scopes(*self); |
490 | let syntax_mapping = db.body_syntax_mapping(*self); | 452 | let syntax_mapping = db.body_syntax_mapping(*self); |
491 | ScopesWithSyntaxMapping { | 453 | ScopesWithSyntaxMapping { scopes, syntax_mapping } |
492 | scopes, | ||
493 | syntax_mapping, | ||
494 | } | ||
495 | } | 454 | } |
496 | 455 | ||
497 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { | 456 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { |
@@ -516,11 +475,7 @@ impl Function { | |||
516 | .unwrap_or_else(|| self.module(db).resolver(db)); | 475 | .unwrap_or_else(|| self.module(db).resolver(db)); |
517 | // ...and add generic params, if present | 476 | // ...and add generic params, if present |
518 | let p = self.generic_params(db); | 477 | let p = self.generic_params(db); |
519 | let r = if !p.params.is_empty() { | 478 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
520 | r.push_generic_params_scope(p) | ||
521 | } else { | ||
522 | r | ||
523 | }; | ||
524 | r | 479 | r |
525 | } | 480 | } |
526 | } | 481 | } |
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs index 8326c02c7..b9438fdb7 100644 --- a/crates/ra_hir/src/code_model_impl/function.rs +++ b/crates/ra_hir/src/code_model_impl/function.rs | |||
@@ -25,10 +25,7 @@ impl FnSignature { | |||
25 | func: Function, | 25 | func: Function, |
26 | ) -> Arc<FnSignature> { | 26 | ) -> Arc<FnSignature> { |
27 | let (_, node) = func.source(db); | 27 | let (_, node) = func.source(db); |
28 | let name = node | 28 | let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); |
29 | .name() | ||
30 | .map(|n| n.as_name()) | ||
31 | .unwrap_or_else(Name::missing); | ||
32 | let mut params = Vec::new(); | 29 | let mut params = Vec::new(); |
33 | let mut has_self_param = false; | 30 | let mut has_self_param = false; |
34 | if let Some(param_list) = node.param_list() { | 31 | if let Some(param_list) = node.param_list() { |
@@ -61,12 +58,7 @@ impl FnSignature { | |||
61 | TypeRef::unit() | 58 | TypeRef::unit() |
62 | }; | 59 | }; |
63 | 60 | ||
64 | let sig = FnSignature { | 61 | let sig = FnSignature { name, params, ret_type, has_self_param }; |
65 | name, | ||
66 | params, | ||
67 | ret_type, | ||
68 | has_self_param, | ||
69 | }; | ||
70 | Arc::new(sig) | 62 | Arc::new(sig) |
71 | } | 63 | } |
72 | } | 64 | } |
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs index 1517434b8..161ae6e18 100644 --- a/crates/ra_hir/src/code_model_impl/krate.rs +++ b/crates/ra_hir/src/code_model_impl/krate.rs | |||
@@ -11,9 +11,7 @@ impl Crate { | |||
11 | crate_graph | 11 | crate_graph |
12 | .dependencies(self.crate_id) | 12 | .dependencies(self.crate_id) |
13 | .map(|dep| { | 13 | .map(|dep| { |
14 | let krate = Crate { | 14 | let krate = Crate { crate_id: dep.crate_id() }; |
15 | crate_id: dep.crate_id(), | ||
16 | }; | ||
17 | let name = dep.as_name(); | 15 | let name = dep.as_name(); |
18 | CrateDependency { krate, name } | 16 | CrateDependency { krate, name } |
19 | }) | 17 | }) |
@@ -23,10 +21,7 @@ impl Crate { | |||
23 | let module_tree = db.module_tree(*self); | 21 | let module_tree = db.module_tree(*self); |
24 | let module_id = module_tree.modules().next()?; | 22 | let module_id = module_tree.modules().next()?; |
25 | 23 | ||
26 | let module = Module { | 24 | let module = Module { krate: *self, module_id }; |
27 | krate: *self, | ||
28 | module_id, | ||
29 | }; | ||
30 | Some(module) | 25 | Some(module) |
31 | } | 26 | } |
32 | } | 27 | } |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index f487b8532..1425fa693 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -12,10 +12,7 @@ use crate::{ | |||
12 | 12 | ||
13 | impl Module { | 13 | impl Module { |
14 | fn with_module_id(&self, module_id: ModuleId) -> Module { | 14 | fn with_module_id(&self, module_id: ModuleId) -> Module { |
15 | Module { | 15 | Module { module_id, krate: self.krate } |
16 | module_id, | ||
17 | krate: self.krate, | ||
18 | } | ||
19 | } | 16 | } |
20 | 17 | ||
21 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { | 18 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { |
@@ -42,10 +39,7 @@ impl Module { | |||
42 | ) -> Option<(FileId, TreeArc<ast::Module>)> { | 39 | ) -> Option<(FileId, TreeArc<ast::Module>)> { |
43 | let module_tree = db.module_tree(self.krate); | 40 | let module_tree = db.module_tree(self.krate); |
44 | let link = self.module_id.parent_link(&module_tree)?; | 41 | let link = self.module_id.parent_link(&module_tree)?; |
45 | let file_id = link | 42 | let file_id = link.owner(&module_tree).file_id(&module_tree).as_original_file(); |
46 | .owner(&module_tree) | ||
47 | .file_id(&module_tree) | ||
48 | .as_original_file(); | ||
49 | let src = link.source(&module_tree, db); | 43 | let src = link.source(&module_tree, db); |
50 | Some((file_id, src)) | 44 | Some((file_id, src)) |
51 | } | 45 | } |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 6826e966b..4e61d87ff 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -121,9 +121,7 @@ impl BodySyntaxMapping { | |||
121 | } | 121 | } |
122 | 122 | ||
123 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { | 123 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { |
124 | self.expr_syntax_mapping | 124 | self.expr_syntax_mapping.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
125 | .get(&SyntaxNodePtr::new(node.syntax())) | ||
126 | .cloned() | ||
127 | } | 125 | } |
128 | 126 | ||
129 | pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { | 127 | pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { |
@@ -135,9 +133,7 @@ impl BodySyntaxMapping { | |||
135 | } | 133 | } |
136 | 134 | ||
137 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | 135 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
138 | self.pat_syntax_mapping | 136 | self.pat_syntax_mapping.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
139 | .get(&SyntaxNodePtr::new(node.syntax())) | ||
140 | .cloned() | ||
141 | } | 137 | } |
142 | 138 | ||
143 | pub fn body(&self) -> &Arc<Body> { | 139 | pub fn body(&self) -> &Arc<Body> { |
@@ -262,11 +258,7 @@ pub struct StructLitField { | |||
262 | 258 | ||
263 | #[derive(Debug, Clone, Eq, PartialEq)] | 259 | #[derive(Debug, Clone, Eq, PartialEq)] |
264 | pub enum Statement { | 260 | pub enum Statement { |
265 | Let { | 261 | Let { pat: PatId, type_ref: Option<TypeRef>, initializer: Option<ExprId> }, |
266 | pat: PatId, | ||
267 | type_ref: Option<TypeRef>, | ||
268 | initializer: Option<ExprId>, | ||
269 | }, | ||
270 | Expr(ExprId), | 262 | Expr(ExprId), |
271 | } | 263 | } |
272 | 264 | ||
@@ -275,11 +267,7 @@ impl Expr { | |||
275 | match self { | 267 | match self { |
276 | Expr::Missing => {} | 268 | Expr::Missing => {} |
277 | Expr::Path(_) => {} | 269 | Expr::Path(_) => {} |
278 | Expr::If { | 270 | Expr::If { condition, then_branch, else_branch } => { |
279 | condition, | ||
280 | then_branch, | ||
281 | else_branch, | ||
282 | } => { | ||
283 | f(*condition); | 271 | f(*condition); |
284 | f(*then_branch); | 272 | f(*then_branch); |
285 | if let Some(else_branch) = else_branch { | 273 | if let Some(else_branch) = else_branch { |
@@ -457,11 +445,7 @@ impl Pat { | |||
457 | args.iter().map(|pat| *pat).for_each(f); | 445 | args.iter().map(|pat| *pat).for_each(f); |
458 | } | 446 | } |
459 | Pat::Ref { pat, .. } => f(*pat), | 447 | Pat::Ref { pat, .. } => f(*pat), |
460 | Pat::Slice { | 448 | Pat::Slice { prefix, rest, suffix } => { |
461 | prefix, | ||
462 | rest, | ||
463 | suffix, | ||
464 | } => { | ||
465 | let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); | 449 | let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); |
466 | total_iter.map(|pat| *pat).for_each(f); | 450 | total_iter.map(|pat| *pat).for_each(f); |
467 | } | 451 | } |
@@ -520,10 +504,7 @@ impl ExprCollector { | |||
520 | } | 504 | } |
521 | 505 | ||
522 | fn empty_block(&mut self) -> ExprId { | 506 | fn empty_block(&mut self) -> ExprId { |
523 | let block = Expr::Block { | 507 | let block = Expr::Block { statements: Vec::new(), tail: None }; |
524 | statements: Vec::new(), | ||
525 | tail: None, | ||
526 | }; | ||
527 | self.exprs.alloc(block) | 508 | self.exprs.alloc(block) |
528 | } | 509 | } |
529 | 510 | ||
@@ -549,24 +530,10 @@ impl ExprCollector { | |||
549 | .unwrap_or_else(|| self.empty_block()); | 530 | .unwrap_or_else(|| self.empty_block()); |
550 | let placeholder_pat = self.pats.alloc(Pat::Missing); | 531 | let placeholder_pat = self.pats.alloc(Pat::Missing); |
551 | let arms = vec![ | 532 | let arms = vec![ |
552 | MatchArm { | 533 | MatchArm { pats: vec![pat], expr: then_branch, guard: None }, |
553 | pats: vec![pat], | 534 | MatchArm { pats: vec![placeholder_pat], expr: else_branch, guard: None }, |
554 | expr: then_branch, | ||
555 | guard: None, | ||
556 | }, | ||
557 | MatchArm { | ||
558 | pats: vec![placeholder_pat], | ||
559 | expr: else_branch, | ||
560 | guard: None, | ||
561 | }, | ||
562 | ]; | 535 | ]; |
563 | self.alloc_expr( | 536 | self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr) |
564 | Expr::Match { | ||
565 | expr: match_expr, | ||
566 | arms, | ||
567 | }, | ||
568 | syntax_ptr, | ||
569 | ) | ||
570 | } else { | 537 | } else { |
571 | let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr())); | 538 | let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr())); |
572 | let then_branch = self.collect_block_opt(e.then_branch()); | 539 | let then_branch = self.collect_block_opt(e.then_branch()); |
@@ -577,14 +544,7 @@ impl ExprCollector { | |||
577 | self.collect_expr(expr) | 544 | self.collect_expr(expr) |
578 | } | 545 | } |
579 | }); | 546 | }); |
580 | self.alloc_expr( | 547 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) |
581 | Expr::If { | ||
582 | condition, | ||
583 | then_branch, | ||
584 | else_branch, | ||
585 | }, | ||
586 | syntax_ptr, | ||
587 | ) | ||
588 | } | 548 | } |
589 | } | 549 | } |
590 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), | 550 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), |
@@ -610,14 +570,7 @@ impl ExprCollector { | |||
610 | let iterable = self.collect_expr_opt(e.iterable()); | 570 | let iterable = self.collect_expr_opt(e.iterable()); |
611 | let pat = self.collect_pat_opt(e.pat()); | 571 | let pat = self.collect_pat_opt(e.pat()); |
612 | let body = self.collect_block_opt(e.loop_body()); | 572 | let body = self.collect_block_opt(e.loop_body()); |
613 | self.alloc_expr( | 573 | self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr) |
614 | Expr::For { | ||
615 | iterable, | ||
616 | pat, | ||
617 | body, | ||
618 | }, | ||
619 | syntax_ptr, | ||
620 | ) | ||
621 | } | 574 | } |
622 | ast::ExprKind::CallExpr(e) => { | 575 | ast::ExprKind::CallExpr(e) => { |
623 | let callee = self.collect_expr_opt(e.expr()); | 576 | let callee = self.collect_expr_opt(e.expr()); |
@@ -635,18 +588,8 @@ impl ExprCollector { | |||
635 | } else { | 588 | } else { |
636 | Vec::new() | 589 | Vec::new() |
637 | }; | 590 | }; |
638 | let method_name = e | 591 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
639 | .name_ref() | 592 | self.alloc_expr(Expr::MethodCall { receiver, method_name, args }, syntax_ptr) |
640 | .map(|nr| nr.as_name()) | ||
641 | .unwrap_or_else(Name::missing); | ||
642 | self.alloc_expr( | ||
643 | Expr::MethodCall { | ||
644 | receiver, | ||
645 | method_name, | ||
646 | args, | ||
647 | }, | ||
648 | syntax_ptr, | ||
649 | ) | ||
650 | } | 593 | } |
651 | ast::ExprKind::MatchExpr(e) => { | 594 | ast::ExprKind::MatchExpr(e) => { |
652 | let expr = self.collect_expr_opt(e.expr()); | 595 | let expr = self.collect_expr_opt(e.expr()); |
@@ -668,11 +611,8 @@ impl ExprCollector { | |||
668 | self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr) | 611 | self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr) |
669 | } | 612 | } |
670 | ast::ExprKind::PathExpr(e) => { | 613 | ast::ExprKind::PathExpr(e) => { |
671 | let path = e | 614 | let path = |
672 | .path() | 615 | e.path().and_then(Path::from_ast).map(Expr::Path).unwrap_or(Expr::Missing); |
673 | .and_then(Path::from_ast) | ||
674 | .map(Expr::Path) | ||
675 | .unwrap_or(Expr::Missing); | ||
676 | self.alloc_expr(path, syntax_ptr) | 616 | self.alloc_expr(path, syntax_ptr) |
677 | } | 617 | } |
678 | ast::ExprKind::ContinueExpr(_e) => { | 618 | ast::ExprKind::ContinueExpr(_e) => { |
@@ -721,21 +661,11 @@ impl ExprCollector { | |||
721 | Vec::new() | 661 | Vec::new() |
722 | }; | 662 | }; |
723 | let spread = e.spread().map(|s| self.collect_expr(s)); | 663 | let spread = e.spread().map(|s| self.collect_expr(s)); |
724 | self.alloc_expr( | 664 | self.alloc_expr(Expr::StructLit { path, fields, spread }, syntax_ptr) |
725 | Expr::StructLit { | ||
726 | path, | ||
727 | fields, | ||
728 | spread, | ||
729 | }, | ||
730 | syntax_ptr, | ||
731 | ) | ||
732 | } | 665 | } |
733 | ast::ExprKind::FieldExpr(e) => { | 666 | ast::ExprKind::FieldExpr(e) => { |
734 | let expr = self.collect_expr_opt(e.expr()); | 667 | let expr = self.collect_expr_opt(e.expr()); |
735 | let name = e | 668 | let name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
736 | .name_ref() | ||
737 | .map(|nr| nr.as_name()) | ||
738 | .unwrap_or_else(Name::missing); | ||
739 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) | 669 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) |
740 | } | 670 | } |
741 | ast::ExprKind::TryExpr(e) => { | 671 | ast::ExprKind::TryExpr(e) => { |
@@ -772,14 +702,7 @@ impl ExprCollector { | |||
772 | } | 702 | } |
773 | } | 703 | } |
774 | let body = self.collect_expr_opt(e.body()); | 704 | let body = self.collect_expr_opt(e.body()); |
775 | self.alloc_expr( | 705 | self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) |
776 | Expr::Lambda { | ||
777 | args, | ||
778 | arg_types, | ||
779 | body, | ||
780 | }, | ||
781 | syntax_ptr, | ||
782 | ) | ||
783 | } | 706 | } |
784 | ast::ExprKind::BinExpr(e) => { | 707 | ast::ExprKind::BinExpr(e) => { |
785 | let lhs = self.collect_expr_opt(e.lhs()); | 708 | let lhs = self.collect_expr_opt(e.lhs()); |
@@ -804,9 +727,8 @@ impl ExprCollector { | |||
804 | 727 | ||
805 | let lit = match child.flavor() { | 728 | let lit = match child.flavor() { |
806 | LiteralFlavor::IntNumber { suffix } => { | 729 | LiteralFlavor::IntNumber { suffix } => { |
807 | let known_name = suffix | 730 | let known_name = |
808 | .map(Name::new) | 731 | suffix.map(Name::new).and_then(|name| UncertainIntTy::from_name(&name)); |
809 | .and_then(|name| UncertainIntTy::from_name(&name)); | ||
810 | 732 | ||
811 | Literal::Int( | 733 | Literal::Int( |
812 | Default::default(), | 734 | Default::default(), |
@@ -857,11 +779,7 @@ impl ExprCollector { | |||
857 | let pat = self.collect_pat_opt(stmt.pat()); | 779 | let pat = self.collect_pat_opt(stmt.pat()); |
858 | let type_ref = stmt.type_ref().map(TypeRef::from_ast); | 780 | let type_ref = stmt.type_ref().map(TypeRef::from_ast); |
859 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 781 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
860 | Statement::Let { | 782 | Statement::Let { pat, type_ref, initializer } |
861 | pat, | ||
862 | type_ref, | ||
863 | initializer, | ||
864 | } | ||
865 | } | 783 | } |
866 | ast::StmtKind::ExprStmt(stmt) => { | 784 | ast::StmtKind::ExprStmt(stmt) => { |
867 | Statement::Expr(self.collect_expr_opt(stmt.expr())) | 785 | Statement::Expr(self.collect_expr_opt(stmt.expr())) |
@@ -869,10 +787,7 @@ impl ExprCollector { | |||
869 | }) | 787 | }) |
870 | .collect(); | 788 | .collect(); |
871 | let tail = block.expr().map(|e| self.collect_expr(e)); | 789 | let tail = block.expr().map(|e| self.collect_expr(e)); |
872 | self.alloc_expr( | 790 | self.alloc_expr(Expr::Block { statements, tail }, SyntaxNodePtr::new(block.syntax())) |
873 | Expr::Block { statements, tail }, | ||
874 | SyntaxNodePtr::new(block.syntax()), | ||
875 | ) | ||
876 | } | 791 | } |
877 | 792 | ||
878 | fn collect_block_opt(&mut self, block: Option<&ast::Block>) -> ExprId { | 793 | fn collect_block_opt(&mut self, block: Option<&ast::Block>) -> ExprId { |
@@ -886,17 +801,10 @@ impl ExprCollector { | |||
886 | fn collect_pat(&mut self, pat: &ast::Pat) -> PatId { | 801 | fn collect_pat(&mut self, pat: &ast::Pat) -> PatId { |
887 | let pattern = match pat.kind() { | 802 | let pattern = match pat.kind() { |
888 | ast::PatKind::BindPat(bp) => { | 803 | ast::PatKind::BindPat(bp) => { |
889 | let name = bp | 804 | let name = bp.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
890 | .name() | ||
891 | .map(|nr| nr.as_name()) | ||
892 | .unwrap_or_else(Name::missing); | ||
893 | let annotation = BindingAnnotation::new(bp.is_mutable(), bp.is_ref()); | 805 | let annotation = BindingAnnotation::new(bp.is_mutable(), bp.is_ref()); |
894 | let subpat = bp.pat().map(|subpat| self.collect_pat(subpat)); | 806 | let subpat = bp.pat().map(|subpat| self.collect_pat(subpat)); |
895 | Pat::Bind { | 807 | Pat::Bind { name, mode: annotation, subpat } |
896 | name, | ||
897 | mode: annotation, | ||
898 | subpat, | ||
899 | } | ||
900 | } | 808 | } |
901 | ast::PatKind::TupleStructPat(p) => { | 809 | ast::PatKind::TupleStructPat(p) => { |
902 | let path = p.path().and_then(Path::from_ast); | 810 | let path = p.path().and_then(Path::from_ast); |
@@ -919,9 +827,8 @@ impl ExprCollector { | |||
919 | ast::PatKind::PlaceholderPat(_) => Pat::Wild, | 827 | ast::PatKind::PlaceholderPat(_) => Pat::Wild, |
920 | ast::PatKind::StructPat(p) => { | 828 | ast::PatKind::StructPat(p) => { |
921 | let path = p.path().and_then(Path::from_ast); | 829 | let path = p.path().and_then(Path::from_ast); |
922 | let field_pat_list = p | 830 | let field_pat_list = |
923 | .field_pat_list() | 831 | p.field_pat_list().expect("every struct should have a field list"); |
924 | .expect("every struct should have a field list"); | ||
925 | let mut fields: Vec<_> = field_pat_list | 832 | let mut fields: Vec<_> = field_pat_list |
926 | .bind_pats() | 833 | .bind_pats() |
927 | .map(|bind_pat| { | 834 | .map(|bind_pat| { |
@@ -961,10 +868,7 @@ impl ExprCollector { | |||
961 | if let Some(param_list) = node.param_list() { | 868 | if let Some(param_list) = node.param_list() { |
962 | if let Some(self_param) = param_list.self_param() { | 869 | if let Some(self_param) = param_list.self_param() { |
963 | let self_param = SyntaxNodePtr::new( | 870 | let self_param = SyntaxNodePtr::new( |
964 | self_param | 871 | self_param.self_kw().expect("self param without self keyword").syntax(), |
965 | .self_kw() | ||
966 | .expect("self param without self keyword") | ||
967 | .syntax(), | ||
968 | ); | 872 | ); |
969 | let param_pat = self.alloc_pat( | 873 | let param_pat = self.alloc_pat( |
970 | Pat::Bind { | 874 | Pat::Bind { |
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index 368994bf7..44d5c2429 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs | |||
@@ -74,17 +74,11 @@ impl ExprScopes { | |||
74 | } | 74 | } |
75 | 75 | ||
76 | fn root_scope(&mut self) -> ScopeId { | 76 | fn root_scope(&mut self) -> ScopeId { |
77 | self.scopes.alloc(ScopeData { | 77 | self.scopes.alloc(ScopeData { parent: None, entries: vec![] }) |
78 | parent: None, | ||
79 | entries: vec![], | ||
80 | }) | ||
81 | } | 78 | } |
82 | 79 | ||
83 | fn new_scope(&mut self, parent: ScopeId) -> ScopeId { | 80 | fn new_scope(&mut self, parent: ScopeId) -> ScopeId { |
84 | self.scopes.alloc(ScopeData { | 81 | self.scopes.alloc(ScopeData { parent: Some(parent), entries: vec![] }) |
85 | parent: Some(parent), | ||
86 | entries: vec![], | ||
87 | }) | ||
88 | } | 82 | } |
89 | 83 | ||
90 | fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { | 84 | fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { |
@@ -92,10 +86,7 @@ impl ExprScopes { | |||
92 | Pat::Bind { name, .. } => { | 86 | Pat::Bind { name, .. } => { |
93 | // bind can have a subpattern, but it's actually not allowed | 87 | // bind can have a subpattern, but it's actually not allowed |
94 | // to bind to things in there | 88 | // to bind to things in there |
95 | let entry = ScopeEntry { | 89 | let entry = ScopeEntry { name: name.clone(), pat }; |
96 | name: name.clone(), | ||
97 | pat, | ||
98 | }; | ||
99 | self.scopes[scope].entries.push(entry) | 90 | self.scopes[scope].entries.push(entry) |
100 | } | 91 | } |
101 | p => p.walk_child_pats(|pat| self.add_bindings(body, scope, pat)), | 92 | p => p.walk_child_pats(|pat| self.add_bindings(body, scope, pat)), |
@@ -104,9 +95,7 @@ impl ExprScopes { | |||
104 | 95 | ||
105 | fn add_params_bindings(&mut self, scope: ScopeId, params: &[PatId]) { | 96 | fn add_params_bindings(&mut self, scope: ScopeId, params: &[PatId]) { |
106 | let body = Arc::clone(&self.body); | 97 | let body = Arc::clone(&self.body); |
107 | params | 98 | params.iter().for_each(|pat| self.add_bindings(&body, scope, *pat)); |
108 | .iter() | ||
109 | .for_each(|pat| self.add_bindings(&body, scope, *pat)); | ||
110 | } | 99 | } |
111 | 100 | ||
112 | fn set_scope(&mut self, node: ExprId, scope: ScopeId) { | 101 | fn set_scope(&mut self, node: ExprId, scope: ScopeId) { |
@@ -142,9 +131,7 @@ impl ScopeEntryWithSyntax { | |||
142 | 131 | ||
143 | impl ScopesWithSyntaxMapping { | 132 | impl ScopesWithSyntaxMapping { |
144 | fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a { | 133 | fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a { |
145 | generate(self.scope_for(node), move |&scope| { | 134 | generate(self.scope_for(node), move |&scope| self.scopes.scopes[scope].parent) |
146 | self.scopes.scopes[scope].parent | ||
147 | }) | ||
148 | } | 135 | } |
149 | 136 | ||
150 | pub fn scope_for_offset(&self, offset: TextUnit) -> Option<ScopeId> { | 137 | pub fn scope_for_offset(&self, offset: TextUnit) -> Option<ScopeId> { |
@@ -154,10 +141,7 @@ impl ScopesWithSyntaxMapping { | |||
154 | .filter_map(|(id, scope)| Some((self.syntax_mapping.expr_syntax(*id)?, scope))) | 141 | .filter_map(|(id, scope)| Some((self.syntax_mapping.expr_syntax(*id)?, scope))) |
155 | // find containing scope | 142 | // find containing scope |
156 | .min_by_key(|(ptr, _scope)| { | 143 | .min_by_key(|(ptr, _scope)| { |
157 | ( | 144 | (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len()) |
158 | !(ptr.range().start() <= offset && offset <= ptr.range().end()), | ||
159 | ptr.range().len(), | ||
160 | ) | ||
161 | }) | 145 | }) |
162 | .map(|(ptr, scope)| self.adjust(ptr, *scope, offset)) | 146 | .map(|(ptr, scope)| self.adjust(ptr, *scope, offset)) |
163 | } | 147 | } |
@@ -251,9 +235,7 @@ fn compute_block_scopes( | |||
251 | ) { | 235 | ) { |
252 | for stmt in statements { | 236 | for stmt in statements { |
253 | match stmt { | 237 | match stmt { |
254 | Statement::Let { | 238 | Statement::Let { pat, initializer, .. } => { |
255 | pat, initializer, .. | ||
256 | } => { | ||
257 | if let Some(expr) = initializer { | 239 | if let Some(expr) = initializer { |
258 | scopes.set_scope(*expr, scope); | 240 | scopes.set_scope(*expr, scope); |
259 | compute_expr_scopes(*expr, body, scopes, scope); | 241 | compute_expr_scopes(*expr, body, scopes, scope); |
@@ -278,21 +260,13 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope | |||
278 | Expr::Block { statements, tail } => { | 260 | Expr::Block { statements, tail } => { |
279 | compute_block_scopes(&statements, *tail, body, scopes, scope); | 261 | compute_block_scopes(&statements, *tail, body, scopes, scope); |
280 | } | 262 | } |
281 | Expr::For { | 263 | Expr::For { iterable, pat, body: body_expr } => { |
282 | iterable, | ||
283 | pat, | ||
284 | body: body_expr, | ||
285 | } => { | ||
286 | compute_expr_scopes(*iterable, body, scopes, scope); | 264 | compute_expr_scopes(*iterable, body, scopes, scope); |
287 | let scope = scopes.new_scope(scope); | 265 | let scope = scopes.new_scope(scope); |
288 | scopes.add_bindings(body, scope, *pat); | 266 | scopes.add_bindings(body, scope, *pat); |
289 | compute_expr_scopes(*body_expr, body, scopes, scope); | 267 | compute_expr_scopes(*body_expr, body, scopes, scope); |
290 | } | 268 | } |
291 | Expr::Lambda { | 269 | Expr::Lambda { args, body: body_expr, .. } => { |
292 | args, | ||
293 | body: body_expr, | ||
294 | .. | ||
295 | } => { | ||
296 | let scope = scopes.new_scope(scope); | 270 | let scope = scopes.new_scope(scope); |
297 | scopes.add_params_bindings(scope, &args); | 271 | scopes.add_params_bindings(scope, &args); |
298 | compute_expr_scopes(*body_expr, body, scopes, scope); | 272 | compute_expr_scopes(*body_expr, body, scopes, scope); |
@@ -341,9 +315,7 @@ mod tests { | |||
341 | let file = SourceFile::parse(&code); | 315 | let file = SourceFile::parse(&code); |
342 | let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); | 316 | let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); |
343 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); | 317 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); |
344 | let irrelevant_function = Function { | 318 | let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; |
345 | id: crate::ids::FunctionId::from_raw(0.into()), | ||
346 | }; | ||
347 | let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); | 319 | let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); |
348 | let scopes = ExprScopes::new(Arc::clone(body_hir.body())); | 320 | let scopes = ExprScopes::new(Arc::clone(body_hir.body())); |
349 | let scopes = ScopesWithSyntaxMapping { | 321 | let scopes = ScopesWithSyntaxMapping { |
@@ -444,9 +416,7 @@ mod tests { | |||
444 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); | 416 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); |
445 | let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); | 417 | let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); |
446 | 418 | ||
447 | let irrelevant_function = Function { | 419 | let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; |
448 | id: crate::ids::FunctionId::from_raw(0.into()), | ||
449 | }; | ||
450 | let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); | 420 | let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); |
451 | let scopes = ExprScopes::new(Arc::clone(body_hir.body())); | 421 | let scopes = ExprScopes::new(Arc::clone(body_hir.body())); |
452 | let scopes = ScopesWithSyntaxMapping { | 422 | let scopes = ScopesWithSyntaxMapping { |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index a82205f0b..c72360f44 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -58,14 +58,8 @@ impl GenericParams { | |||
58 | 58 | ||
59 | fn fill_params(&mut self, params: &ast::TypeParamList) { | 59 | fn fill_params(&mut self, params: &ast::TypeParamList) { |
60 | for (idx, type_param) in params.type_params().enumerate() { | 60 | for (idx, type_param) in params.type_params().enumerate() { |
61 | let name = type_param | 61 | let name = type_param.name().map(AsName::as_name).unwrap_or_else(Name::missing); |
62 | .name() | 62 | let param = GenericParam { idx: idx as u32, name }; |
63 | .map(AsName::as_name) | ||
64 | .unwrap_or_else(Name::missing); | ||
65 | let param = GenericParam { | ||
66 | idx: idx as u32, | ||
67 | name, | ||
68 | }; | ||
69 | self.params.push(param); | 63 | self.params.push(param); |
70 | } | 64 | } |
71 | } | 65 | } |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 95678bf70..ea13c1196 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -169,11 +169,7 @@ impl<N: AstNode> Hash for ItemLoc<N> { | |||
169 | 169 | ||
170 | impl<N: AstNode> Clone for ItemLoc<N> { | 170 | impl<N: AstNode> Clone for ItemLoc<N> { |
171 | fn clone(&self) -> ItemLoc<N> { | 171 | fn clone(&self) -> ItemLoc<N> { |
172 | ItemLoc { | 172 | ItemLoc { module: self.module, raw: self.raw, _ty: PhantomData } |
173 | module: self.module, | ||
174 | raw: self.raw, | ||
175 | _ty: PhantomData, | ||
176 | } | ||
177 | } | 173 | } |
178 | } | 174 | } |
179 | 175 | ||
@@ -186,11 +182,7 @@ pub(crate) struct LocationCtx<DB> { | |||
186 | 182 | ||
187 | impl<'a, DB: PersistentHirDatabase> LocationCtx<&'a DB> { | 183 | impl<'a, DB: PersistentHirDatabase> LocationCtx<&'a DB> { |
188 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { | 184 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { |
189 | LocationCtx { | 185 | LocationCtx { db, module, file_id } |
190 | db, | ||
191 | module, | ||
192 | file_id, | ||
193 | } | ||
194 | } | 186 | } |
195 | pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF | 187 | pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF |
196 | where | 188 | where |
@@ -205,15 +197,9 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | |||
205 | fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>; | 197 | fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>; |
206 | fn from_ast(ctx: LocationCtx<&impl PersistentHirDatabase>, ast: &N) -> Self { | 198 | fn from_ast(ctx: LocationCtx<&impl PersistentHirDatabase>, ast: &N) -> Self { |
207 | let items = ctx.db.file_items(ctx.file_id); | 199 | let items = ctx.db.file_items(ctx.file_id); |
208 | let raw = SourceItemId { | 200 | let raw = |
209 | file_id: ctx.file_id, | 201 | SourceItemId { file_id: ctx.file_id, item_id: items.id_of(ctx.file_id, ast.syntax()) }; |
210 | item_id: items.id_of(ctx.file_id, ast.syntax()), | 202 | let loc = ItemLoc { module: ctx.module, raw, _ty: PhantomData }; |
211 | }; | ||
212 | let loc = ItemLoc { | ||
213 | module: ctx.module, | ||
214 | raw, | ||
215 | _ty: PhantomData, | ||
216 | }; | ||
217 | 203 | ||
218 | Self::interner(ctx.db.as_ref()).loc2id(&loc) | 204 | Self::interner(ctx.db.as_ref()).loc2id(&loc) |
219 | } | 205 | } |
@@ -221,9 +207,8 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | |||
221 | let int = Self::interner(db.as_ref()); | 207 | let int = Self::interner(db.as_ref()); |
222 | let loc = int.id2loc(self); | 208 | let loc = int.id2loc(self); |
223 | let syntax = db.file_item(loc.raw); | 209 | let syntax = db.file_item(loc.raw); |
224 | let ast = N::cast(&syntax) | 210 | let ast = |
225 | .unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)) | 211 | N::cast(&syntax).unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)).to_owned(); |
226 | .to_owned(); | ||
227 | (loc.raw.file_id, ast) | 212 | (loc.raw.file_id, ast) |
228 | } | 213 | } |
229 | fn module(self, db: &impl HirDatabase) -> Module { | 214 | fn module(self, db: &impl HirDatabase) -> Module { |
@@ -317,10 +302,7 @@ pub struct SourceFileItems { | |||
317 | 302 | ||
318 | impl SourceFileItems { | 303 | impl SourceFileItems { |
319 | pub(crate) fn new(file_id: HirFileId, source_file: &SourceFile) -> SourceFileItems { | 304 | pub(crate) fn new(file_id: HirFileId, source_file: &SourceFile) -> SourceFileItems { |
320 | let mut res = SourceFileItems { | 305 | let mut res = SourceFileItems { file_id, arena: Arena::default() }; |
321 | file_id, | ||
322 | arena: Arena::default(), | ||
323 | }; | ||
324 | res.init(source_file); | 306 | res.init(source_file); |
325 | res | 307 | res |
326 | } | 308 | } |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 094dbedb3..b2fbee8d7 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -50,17 +50,11 @@ impl ImplBlock { | |||
50 | item: ImplItem, | 50 | item: ImplItem, |
51 | ) -> Option<ImplBlock> { | 51 | ) -> Option<ImplBlock> { |
52 | let impl_id = *module_impl_blocks.impls_by_def.get(&item)?; | 52 | let impl_id = *module_impl_blocks.impls_by_def.get(&item)?; |
53 | Some(ImplBlock { | 53 | Some(ImplBlock { module_impl_blocks, impl_id }) |
54 | module_impl_blocks, | ||
55 | impl_id, | ||
56 | }) | ||
57 | } | 54 | } |
58 | 55 | ||
59 | pub(crate) fn from_id(module_impl_blocks: Arc<ModuleImplBlocks>, impl_id: ImplId) -> ImplBlock { | 56 | pub(crate) fn from_id(module_impl_blocks: Arc<ModuleImplBlocks>, impl_id: ImplId) -> ImplBlock { |
60 | ImplBlock { | 57 | ImplBlock { module_impl_blocks, impl_id } |
61 | module_impl_blocks, | ||
62 | impl_id, | ||
63 | } | ||
64 | } | 58 | } |
65 | 59 | ||
66 | pub fn id(&self) -> ImplId { | 60 | pub fn id(&self) -> ImplId { |
@@ -144,11 +138,7 @@ impl ImplData { | |||
144 | } else { | 138 | } else { |
145 | Vec::new() | 139 | Vec::new() |
146 | }; | 140 | }; |
147 | ImplData { | 141 | ImplData { target_trait, target_type, items } |
148 | target_trait, | ||
149 | target_type, | ||
150 | items, | ||
151 | } | ||
152 | } | 142 | } |
153 | 143 | ||
154 | pub fn target_trait(&self) -> Option<&TypeRef> { | 144 | pub fn target_trait(&self) -> Option<&TypeRef> { |
@@ -212,10 +202,9 @@ impl ModuleImplBlocks { | |||
212 | let file_id: HirFileId = file_id.into(); | 202 | let file_id: HirFileId = file_id.into(); |
213 | let node = match &module_source { | 203 | let node = match &module_source { |
214 | ModuleSource::SourceFile(node) => node.syntax(), | 204 | ModuleSource::SourceFile(node) => node.syntax(), |
215 | ModuleSource::Module(node) => node | 205 | ModuleSource::Module(node) => { |
216 | .item_list() | 206 | node.item_list().expect("inline module should have item list").syntax() |
217 | .expect("inline module should have item list") | 207 | } |
218 | .syntax(), | ||
219 | }; | 208 | }; |
220 | 209 | ||
221 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { | 210 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { |
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs index cb8a9312e..95925159f 100644 --- a/crates/ra_hir/src/macros.rs +++ b/crates/ra_hir/src/macros.rs | |||
@@ -48,9 +48,7 @@ impl MacroDef { | |||
48 | 48 | ||
49 | let input = { | 49 | let input = { |
50 | let arg = macro_call.token_tree()?.syntax(); | 50 | let arg = macro_call.token_tree()?.syntax(); |
51 | MacroInput { | 51 | MacroInput { text: arg.text().to_string() } |
52 | text: arg.text().to_string(), | ||
53 | } | ||
54 | }; | 52 | }; |
55 | Some((def, input)) | 53 | Some((def, input)) |
56 | } | 54 | } |
@@ -68,20 +66,14 @@ impl MacroDef { | |||
68 | let ptr = SyntaxNodePtr::new(array_expr.syntax()); | 66 | let ptr = SyntaxNodePtr::new(array_expr.syntax()); |
69 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); | 67 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); |
70 | let ranges_map = vec![(src_range, array_expr.syntax().range())]; | 68 | let ranges_map = vec![(src_range, array_expr.syntax().range())]; |
71 | let res = MacroExpansion { | 69 | let res = MacroExpansion { text, ranges_map, ptr }; |
72 | text, | ||
73 | ranges_map, | ||
74 | ptr, | ||
75 | }; | ||
76 | Some(res) | 70 | Some(res) |
77 | } | 71 | } |
78 | fn expand_query_group(self, input: MacroInput) -> Option<MacroExpansion> { | 72 | fn expand_query_group(self, input: MacroInput) -> Option<MacroExpansion> { |
79 | let anchor = "trait "; | 73 | let anchor = "trait "; |
80 | let pos = input.text.find(anchor)? + anchor.len(); | 74 | let pos = input.text.find(anchor)? + anchor.len(); |
81 | let trait_name = input.text[pos..] | 75 | let trait_name = |
82 | .chars() | 76 | input.text[pos..].chars().take_while(|c| c.is_alphabetic()).collect::<String>(); |
83 | .take_while(|c| c.is_alphabetic()) | ||
84 | .collect::<String>(); | ||
85 | if trait_name.is_empty() { | 77 | if trait_name.is_empty() { |
86 | return None; | 78 | return None; |
87 | } | 79 | } |
@@ -92,11 +84,7 @@ impl MacroDef { | |||
92 | let name = trait_def.name()?; | 84 | let name = trait_def.name()?; |
93 | let ptr = SyntaxNodePtr::new(trait_def.syntax()); | 85 | let ptr = SyntaxNodePtr::new(trait_def.syntax()); |
94 | let ranges_map = vec![(src_range, name.syntax().range())]; | 86 | let ranges_map = vec![(src_range, name.syntax().range())]; |
95 | let res = MacroExpansion { | 87 | let res = MacroExpansion { text, ranges_map, ptr }; |
96 | text, | ||
97 | ranges_map, | ||
98 | ptr, | ||
99 | }; | ||
100 | Some(res) | 88 | Some(res) |
101 | } | 89 | } |
102 | } | 90 | } |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 87095fb21..950f89948 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -64,10 +64,7 @@ impl MockDatabase { | |||
64 | let mut source_root = SourceRoot::default(); | 64 | let mut source_root = SourceRoot::default(); |
65 | for entry in parse_fixture(fixture) { | 65 | for entry in parse_fixture(fixture) { |
66 | if entry.text.contains(CURSOR_MARKER) { | 66 | if entry.text.contains(CURSOR_MARKER) { |
67 | assert!( | 67 | assert!(position.is_none(), "only one marker (<|>) per fixture is allowed"); |
68 | position.is_none(), | ||
69 | "only one marker (<|>) per fixture is allowed" | ||
70 | ); | ||
71 | position = Some(self.add_file_with_position( | 68 | position = Some(self.add_file_with_position( |
72 | source_root_id, | 69 | source_root_id, |
73 | &mut source_root, | 70 | &mut source_root, |
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index a1aa3d8ce..1f19ee191 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs | |||
@@ -153,10 +153,8 @@ impl ModuleTree { | |||
153 | file_id: HirFileId, | 153 | file_id: HirFileId, |
154 | decl_id: Option<SourceFileItemId>, | 154 | decl_id: Option<SourceFileItemId>, |
155 | ) -> Option<ModuleId> { | 155 | ) -> Option<ModuleId> { |
156 | let (res, _) = self | 156 | let (res, _) = |
157 | .mods | 157 | self.mods.iter().find(|(_, m)| (m.file_id, m.decl_id) == (file_id, decl_id))?; |
158 | .iter() | ||
159 | .find(|(_, m)| (m.file_id, m.decl_id) == (file_id, decl_id))?; | ||
160 | Some(res) | 158 | Some(res) |
161 | } | 159 | } |
162 | 160 | ||
@@ -178,18 +176,10 @@ impl ModuleTree { | |||
178 | decl_id: Option<SourceFileItemId>, | 176 | decl_id: Option<SourceFileItemId>, |
179 | ) -> ModuleId { | 177 | ) -> ModuleId { |
180 | let is_root = parent.is_none(); | 178 | let is_root = parent.is_none(); |
181 | let id = self.alloc_mod(ModuleData { | 179 | let id = self.alloc_mod(ModuleData { file_id, decl_id, parent, children: Vec::new() }); |
182 | file_id, | ||
183 | decl_id, | ||
184 | parent, | ||
185 | children: Vec::new(), | ||
186 | }); | ||
187 | for sub in db.submodules(file_id, decl_id).iter() { | 180 | for sub in db.submodules(file_id, decl_id).iter() { |
188 | let link = self.alloc_link(LinkData { | 181 | let link = self.alloc_link(LinkData { |
189 | source: SourceItemId { | 182 | source: SourceItemId { file_id, item_id: sub.decl_id }, |
190 | file_id, | ||
191 | item_id: sub.decl_id, | ||
192 | }, | ||
193 | name: sub.name.clone(), | 183 | name: sub.name.clone(), |
194 | owner: id, | 184 | owner: id, |
195 | points_to: Vec::new(), | 185 | points_to: Vec::new(), |
@@ -244,9 +234,7 @@ impl ModuleId { | |||
244 | Some(tree.links[link].owner) | 234 | Some(tree.links[link].owner) |
245 | } | 235 | } |
246 | pub(crate) fn crate_root(self, tree: &ModuleTree) -> ModuleId { | 236 | pub(crate) fn crate_root(self, tree: &ModuleTree) -> ModuleId { |
247 | generate(Some(self), move |it| it.parent(tree)) | 237 | generate(Some(self), move |it| it.parent(tree)).last().unwrap() |
248 | .last() | ||
249 | .unwrap() | ||
250 | } | 238 | } |
251 | pub(crate) fn child(self, tree: &ModuleTree, name: &Name) -> Option<ModuleId> { | 239 | pub(crate) fn child(self, tree: &ModuleTree, name: &Name) -> Option<ModuleId> { |
252 | let link = tree.mods[self] | 240 | let link = tree.mods[self] |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 681aa9a67..b7382d9c3 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -83,40 +83,25 @@ pub struct PerNs<T> { | |||
83 | 83 | ||
84 | impl<T> Default for PerNs<T> { | 84 | impl<T> Default for PerNs<T> { |
85 | fn default() -> Self { | 85 | fn default() -> Self { |
86 | PerNs { | 86 | PerNs { types: None, values: None } |
87 | types: None, | ||
88 | values: None, | ||
89 | } | ||
90 | } | 87 | } |
91 | } | 88 | } |
92 | 89 | ||
93 | impl<T> PerNs<T> { | 90 | impl<T> PerNs<T> { |
94 | pub fn none() -> PerNs<T> { | 91 | pub fn none() -> PerNs<T> { |
95 | PerNs { | 92 | PerNs { types: None, values: None } |
96 | types: None, | ||
97 | values: None, | ||
98 | } | ||
99 | } | 93 | } |
100 | 94 | ||
101 | pub fn values(t: T) -> PerNs<T> { | 95 | pub fn values(t: T) -> PerNs<T> { |
102 | PerNs { | 96 | PerNs { types: None, values: Some(t) } |
103 | types: None, | ||
104 | values: Some(t), | ||
105 | } | ||
106 | } | 97 | } |
107 | 98 | ||
108 | pub fn types(t: T) -> PerNs<T> { | 99 | pub fn types(t: T) -> PerNs<T> { |
109 | PerNs { | 100 | PerNs { types: Some(t), values: None } |
110 | types: Some(t), | ||
111 | values: None, | ||
112 | } | ||
113 | } | 101 | } |
114 | 102 | ||
115 | pub fn both(types: T, values: T) -> PerNs<T> { | 103 | pub fn both(types: T, values: T) -> PerNs<T> { |
116 | PerNs { | 104 | PerNs { types: Some(types), values: Some(values) } |
117 | types: Some(types), | ||
118 | values: Some(values), | ||
119 | } | ||
120 | } | 105 | } |
121 | 106 | ||
122 | pub fn is_none(&self) -> bool { | 107 | pub fn is_none(&self) -> bool { |
@@ -147,31 +132,19 @@ impl<T> PerNs<T> { | |||
147 | } | 132 | } |
148 | 133 | ||
149 | pub fn as_ref(&self) -> PerNs<&T> { | 134 | pub fn as_ref(&self) -> PerNs<&T> { |
150 | PerNs { | 135 | PerNs { types: self.types.as_ref(), values: self.values.as_ref() } |
151 | types: self.types.as_ref(), | ||
152 | values: self.values.as_ref(), | ||
153 | } | ||
154 | } | 136 | } |
155 | 137 | ||
156 | pub fn combine(self, other: PerNs<T>) -> PerNs<T> { | 138 | pub fn combine(self, other: PerNs<T>) -> PerNs<T> { |
157 | PerNs { | 139 | PerNs { types: self.types.or(other.types), values: self.values.or(other.values) } |
158 | types: self.types.or(other.types), | ||
159 | values: self.values.or(other.values), | ||
160 | } | ||
161 | } | 140 | } |
162 | 141 | ||
163 | pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> { | 142 | pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> { |
164 | PerNs { | 143 | PerNs { types: self.types.and_then(&f), values: self.values.and_then(&f) } |
165 | types: self.types.and_then(&f), | ||
166 | values: self.values.and_then(&f), | ||
167 | } | ||
168 | } | 144 | } |
169 | 145 | ||
170 | pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> { | 146 | pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> { |
171 | PerNs { | 147 | PerNs { types: self.types.map(&f), values: self.values.map(&f) } |
172 | types: self.types.map(&f), | ||
173 | values: self.values.map(&f), | ||
174 | } | ||
175 | } | 148 | } |
176 | } | 149 | } |
177 | 150 | ||
@@ -233,9 +206,7 @@ where | |||
233 | for dep in self.krate.dependencies(self.db) { | 206 | for dep in self.krate.dependencies(self.db) { |
234 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); | 207 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); |
235 | if let Some(module) = dep.krate.root_module(self.db) { | 208 | if let Some(module) = dep.krate.root_module(self.db) { |
236 | self.result | 209 | self.result.extern_prelude.insert(dep.name.clone(), module.into()); |
237 | .extern_prelude | ||
238 | .insert(dep.name.clone(), module.into()); | ||
239 | } | 210 | } |
240 | } | 211 | } |
241 | } | 212 | } |
@@ -245,17 +216,11 @@ where | |||
245 | for (import_id, import_data) in input.imports.iter() { | 216 | for (import_id, import_data) in input.imports.iter() { |
246 | if let Some(last_segment) = import_data.path.segments.iter().last() { | 217 | if let Some(last_segment) = import_data.path.segments.iter().last() { |
247 | if !import_data.is_glob { | 218 | if !import_data.is_glob { |
248 | let name = import_data | 219 | let name = |
249 | .alias | 220 | import_data.alias.clone().unwrap_or_else(|| last_segment.name.clone()); |
250 | .clone() | 221 | module_items |
251 | .unwrap_or_else(|| last_segment.name.clone()); | 222 | .items |
252 | module_items.items.insert( | 223 | .insert(name, Resolution { def: PerNs::none(), import: Some(import_id) }); |
253 | name, | ||
254 | Resolution { | ||
255 | def: PerNs::none(), | ||
256 | import: Some(import_id), | ||
257 | }, | ||
258 | ); | ||
259 | } | 224 | } |
260 | } | 225 | } |
261 | } | 226 | } |
@@ -267,10 +232,7 @@ where | |||
267 | 232 | ||
268 | // Populate modules | 233 | // Populate modules |
269 | for (name, module_id) in module_id.children(&self.module_tree) { | 234 | for (name, module_id) in module_id.children(&self.module_tree) { |
270 | let module = Module { | 235 | let module = Module { module_id, krate: self.krate }; |
271 | module_id, | ||
272 | krate: self.krate, | ||
273 | }; | ||
274 | self.add_module_item(&mut module_items, name, PerNs::types(module.into())); | 236 | self.add_module_item(&mut module_items, name, PerNs::types(module.into())); |
275 | } | 237 | } |
276 | 238 | ||
@@ -305,20 +267,13 @@ where | |||
305 | if import.is_glob { | 267 | if import.is_glob { |
306 | return ReachedFixedPoint::Yes; | 268 | return ReachedFixedPoint::Yes; |
307 | }; | 269 | }; |
308 | let original_module = Module { | 270 | let original_module = Module { krate: self.krate, module_id }; |
309 | krate: self.krate, | ||
310 | module_id, | ||
311 | }; | ||
312 | let (def, reached_fixedpoint) = | 271 | let (def, reached_fixedpoint) = |
313 | self.result | 272 | self.result.resolve_path_fp(self.db, original_module, &import.path); |
314 | .resolve_path_fp(self.db, original_module, &import.path); | ||
315 | 273 | ||
316 | if reached_fixedpoint == ReachedFixedPoint::Yes { | 274 | if reached_fixedpoint == ReachedFixedPoint::Yes { |
317 | let last_segment = import.path.segments.last().unwrap(); | 275 | let last_segment = import.path.segments.last().unwrap(); |
318 | let name = import | 276 | let name = import.alias.clone().unwrap_or_else(|| last_segment.name.clone()); |
319 | .alias | ||
320 | .clone() | ||
321 | .unwrap_or_else(|| last_segment.name.clone()); | ||
322 | log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); | 277 | log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); |
323 | 278 | ||
324 | // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 | 279 | // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 |
@@ -330,10 +285,7 @@ where | |||
330 | } | 285 | } |
331 | } | 286 | } |
332 | self.update(module_id, |items| { | 287 | self.update(module_id, |items| { |
333 | let res = Resolution { | 288 | let res = Resolution { def, import: Some(import_id) }; |
334 | def, | ||
335 | import: Some(import_id), | ||
336 | }; | ||
337 | items.items.insert(name, res); | 289 | items.items.insert(name, res); |
338 | }); | 290 | }); |
339 | } | 291 | } |
@@ -358,12 +310,7 @@ impl ItemMap { | |||
358 | let module_tree = db.module_tree(krate); | 310 | let module_tree = db.module_tree(krate); |
359 | let input = module_tree | 311 | let input = module_tree |
360 | .modules() | 312 | .modules() |
361 | .map(|module_id| { | 313 | .map(|module_id| (module_id, db.lower_module_module(Module { krate, module_id }))) |
362 | ( | ||
363 | module_id, | ||
364 | db.lower_module_module(Module { krate, module_id }), | ||
365 | ) | ||
366 | }) | ||
367 | .collect::<FxHashMap<_, _>>(); | 314 | .collect::<FxHashMap<_, _>>(); |
368 | 315 | ||
369 | let resolver = Resolver::new(db, &input, krate); | 316 | let resolver = Resolver::new(db, &input, krate); |
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index 7e6e48ae0..7e9a3de2b 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs | |||
@@ -82,13 +82,9 @@ impl LoweredModule { | |||
82 | let mut source_map = ImportSourceMap::default(); | 82 | let mut source_map = ImportSourceMap::default(); |
83 | let mut res = LoweredModule::default(); | 83 | let mut res = LoweredModule::default(); |
84 | match source { | 84 | match source { |
85 | ModuleSource::SourceFile(it) => res.fill( | 85 | ModuleSource::SourceFile(it) => { |
86 | &mut source_map, | 86 | res.fill(&mut source_map, db, module, file_id, &mut it.items_with_macros()) |
87 | db, | 87 | } |
88 | module, | ||
89 | file_id, | ||
90 | &mut it.items_with_macros(), | ||
91 | ), | ||
92 | ModuleSource::Module(it) => { | 88 | ModuleSource::Module(it) => { |
93 | if let Some(item_list) = it.item_list() { | 89 | if let Some(item_list) = it.item_list() { |
94 | res.fill( | 90 | res.fill( |
@@ -121,10 +117,8 @@ impl LoweredModule { | |||
121 | } | 117 | } |
122 | ast::ItemOrMacro::Macro(macro_call) => { | 118 | ast::ItemOrMacro::Macro(macro_call) => { |
123 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); | 119 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); |
124 | let loc = MacroCallLoc { | 120 | let loc = |
125 | module, | 121 | MacroCallLoc { module, source_item_id: SourceItemId { file_id, item_id } }; |
126 | source_item_id: SourceItemId { file_id, item_id }, | ||
127 | }; | ||
128 | let id = loc.id(db); | 122 | let id = loc.id(db); |
129 | let file_id = HirFileId::from(id); | 123 | let file_id = HirFileId::from(id); |
130 | //FIXME: expand recursively | 124 | //FIXME: expand recursively |
@@ -163,22 +157,19 @@ impl LoweredModule { | |||
163 | ast::ModuleItemKind::FnDef(it) => { | 157 | ast::ModuleItemKind::FnDef(it) => { |
164 | if let Some(name) = it.name() { | 158 | if let Some(name) = it.name() { |
165 | let func = Function { id: ctx.to_def(it) }; | 159 | let func = Function { id: ctx.to_def(it) }; |
166 | self.declarations | 160 | self.declarations.insert(name.as_name(), PerNs::values(func.into())); |
167 | .insert(name.as_name(), PerNs::values(func.into())); | ||
168 | } | 161 | } |
169 | } | 162 | } |
170 | ast::ModuleItemKind::TraitDef(it) => { | 163 | ast::ModuleItemKind::TraitDef(it) => { |
171 | if let Some(name) = it.name() { | 164 | if let Some(name) = it.name() { |
172 | let t = Trait { id: ctx.to_def(it) }; | 165 | let t = Trait { id: ctx.to_def(it) }; |
173 | self.declarations | 166 | self.declarations.insert(name.as_name(), PerNs::types(t.into())); |
174 | .insert(name.as_name(), PerNs::types(t.into())); | ||
175 | } | 167 | } |
176 | } | 168 | } |
177 | ast::ModuleItemKind::TypeDef(it) => { | 169 | ast::ModuleItemKind::TypeDef(it) => { |
178 | if let Some(name) = it.name() { | 170 | if let Some(name) = it.name() { |
179 | let t = Type { id: ctx.to_def(it) }; | 171 | let t = Type { id: ctx.to_def(it) }; |
180 | self.declarations | 172 | self.declarations.insert(name.as_name(), PerNs::types(t.into())); |
181 | .insert(name.as_name(), PerNs::types(t.into())); | ||
182 | } | 173 | } |
183 | } | 174 | } |
184 | ast::ModuleItemKind::ImplBlock(_) => { | 175 | ast::ModuleItemKind::ImplBlock(_) => { |
@@ -207,15 +198,13 @@ impl LoweredModule { | |||
207 | ast::ModuleItemKind::ConstDef(it) => { | 198 | ast::ModuleItemKind::ConstDef(it) => { |
208 | if let Some(name) = it.name() { | 199 | if let Some(name) = it.name() { |
209 | let c = Const { id: ctx.to_def(it) }; | 200 | let c = Const { id: ctx.to_def(it) }; |
210 | self.declarations | 201 | self.declarations.insert(name.as_name(), PerNs::values(c.into())); |
211 | .insert(name.as_name(), PerNs::values(c.into())); | ||
212 | } | 202 | } |
213 | } | 203 | } |
214 | ast::ModuleItemKind::StaticDef(it) => { | 204 | ast::ModuleItemKind::StaticDef(it) => { |
215 | if let Some(name) = it.name() { | 205 | if let Some(name) = it.name() { |
216 | let s = Static { id: ctx.to_def(it) }; | 206 | let s = Static { id: ctx.to_def(it) }; |
217 | self.declarations | 207 | self.declarations.insert(name.as_name(), PerNs::values(s.into())); |
218 | .insert(name.as_name(), PerNs::values(s.into())); | ||
219 | } | 208 | } |
220 | } | 209 | } |
221 | ast::ModuleItemKind::Module(_) => { | 210 | ast::ModuleItemKind::Module(_) => { |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 0654dbaa1..3dfad6bf2 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -42,19 +42,11 @@ fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { | |||
42 | .collect::<Vec<_>>(); | 42 | .collect::<Vec<_>>(); |
43 | lines.sort(); | 43 | lines.sort(); |
44 | let actual = lines.join("\n"); | 44 | let actual = lines.join("\n"); |
45 | let expected = expected | 45 | let expected = expected.trim().lines().map(|it| it.trim()).collect::<Vec<_>>().join("\n"); |
46 | .trim() | ||
47 | .lines() | ||
48 | .map(|it| it.trim()) | ||
49 | .collect::<Vec<_>>() | ||
50 | .join("\n"); | ||
51 | assert_eq_text!(&expected, &actual); | 46 | assert_eq_text!(&expected, &actual); |
52 | 47 | ||
53 | fn dump_resolution(resolution: &Resolution) -> &'static str { | 48 | fn dump_resolution(resolution: &Resolution) -> &'static str { |
54 | match ( | 49 | match (resolution.def.types.is_some(), resolution.def.values.is_some()) { |
55 | resolution.def.types.is_some(), | ||
56 | resolution.def.values.is_some(), | ||
57 | ) { | ||
58 | (true, true) => "t v", | 50 | (true, true) => "t v", |
59 | (true, false) => "t", | 51 | (true, false) => "t", |
60 | (false, true) => "v", | 52 | (false, true) => "v", |
@@ -314,9 +306,7 @@ fn item_map_across_crates() { | |||
314 | let mut crate_graph = CrateGraph::default(); | 306 | let mut crate_graph = CrateGraph::default(); |
315 | let main_crate = crate_graph.add_crate_root(main_id); | 307 | let main_crate = crate_graph.add_crate_root(main_id); |
316 | let lib_crate = crate_graph.add_crate_root(lib_id); | 308 | let lib_crate = crate_graph.add_crate_root(lib_id); |
317 | crate_graph | 309 | crate_graph.add_dep(main_crate, "test_crate".into(), lib_crate).unwrap(); |
318 | .add_dep(main_crate, "test_crate".into(), lib_crate) | ||
319 | .unwrap(); | ||
320 | 310 | ||
321 | db.set_crate_graph(Arc::new(crate_graph)); | 311 | db.set_crate_graph(Arc::new(crate_graph)); |
322 | 312 | ||
@@ -357,9 +347,7 @@ fn extern_crate_rename() { | |||
357 | let mut crate_graph = CrateGraph::default(); | 347 | let mut crate_graph = CrateGraph::default(); |
358 | let main_crate = crate_graph.add_crate_root(main_id); | 348 | let main_crate = crate_graph.add_crate_root(main_id); |
359 | let lib_crate = crate_graph.add_crate_root(lib_id); | 349 | let lib_crate = crate_graph.add_crate_root(lib_id); |
360 | crate_graph | 350 | crate_graph.add_dep(main_crate, "alloc".into(), lib_crate).unwrap(); |
361 | .add_dep(main_crate, "alloc".into(), lib_crate) | ||
362 | .unwrap(); | ||
363 | 351 | ||
364 | db.set_crate_graph(Arc::new(crate_graph)); | 352 | db.set_crate_graph(Arc::new(crate_graph)); |
365 | 353 | ||
@@ -406,9 +394,7 @@ fn import_across_source_roots() { | |||
406 | let mut crate_graph = CrateGraph::default(); | 394 | let mut crate_graph = CrateGraph::default(); |
407 | let main_crate = crate_graph.add_crate_root(main_id); | 395 | let main_crate = crate_graph.add_crate_root(main_id); |
408 | let lib_crate = crate_graph.add_crate_root(lib_id); | 396 | let lib_crate = crate_graph.add_crate_root(lib_id); |
409 | crate_graph | 397 | crate_graph.add_dep(main_crate, "test_crate".into(), lib_crate).unwrap(); |
410 | .add_dep(main_crate, "test_crate".into(), lib_crate) | ||
411 | .unwrap(); | ||
412 | 398 | ||
413 | db.set_crate_graph(Arc::new(crate_graph)); | 399 | db.set_crate_graph(Arc::new(crate_graph)); |
414 | 400 | ||
@@ -447,9 +433,7 @@ fn reexport_across_crates() { | |||
447 | let mut crate_graph = CrateGraph::default(); | 433 | let mut crate_graph = CrateGraph::default(); |
448 | let main_crate = crate_graph.add_crate_root(main_id); | 434 | let main_crate = crate_graph.add_crate_root(main_id); |
449 | let lib_crate = crate_graph.add_crate_root(lib_id); | 435 | let lib_crate = crate_graph.add_crate_root(lib_id); |
450 | crate_graph | 436 | crate_graph.add_dep(main_crate, "test_crate".into(), lib_crate).unwrap(); |
451 | .add_dep(main_crate, "test_crate".into(), lib_crate) | ||
452 | .unwrap(); | ||
453 | 437 | ||
454 | db.set_crate_graph(Arc::new(crate_graph)); | 438 | db.set_crate_graph(Arc::new(crate_graph)); |
455 | 439 | ||
@@ -482,11 +466,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { | |||
482 | let events = db.log_executed(|| { | 466 | let events = db.log_executed(|| { |
483 | db.item_map(krate); | 467 | db.item_map(krate); |
484 | }); | 468 | }); |
485 | assert!( | 469 | assert!(!format!("{:?}", events).contains("item_map"), "{:#?}", events) |
486 | !format!("{:?}", events).contains("item_map"), | ||
487 | "{:#?}", | ||
488 | events | ||
489 | ) | ||
490 | } | 470 | } |
491 | } | 471 | } |
492 | 472 | ||
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index cb0a04500..6a24c8aa7 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -66,14 +66,9 @@ impl Path { | |||
66 | 66 | ||
67 | match segment.kind()? { | 67 | match segment.kind()? { |
68 | ast::PathSegmentKind::Name(name) => { | 68 | ast::PathSegmentKind::Name(name) => { |
69 | let args = segment | 69 | let args = |
70 | .type_arg_list() | 70 | segment.type_arg_list().and_then(GenericArgs::from_ast).map(Arc::new); |
71 | .and_then(GenericArgs::from_ast) | 71 | let segment = PathSegment { name: name.as_name(), args_and_bindings: args }; |
72 | .map(Arc::new); | ||
73 | let segment = PathSegment { | ||
74 | name: name.as_name(), | ||
75 | args_and_bindings: args, | ||
76 | }; | ||
77 | segments.push(segment); | 72 | segments.push(segment); |
78 | } | 73 | } |
79 | ast::PathSegmentKind::CrateKw => { | 74 | ast::PathSegmentKind::CrateKw => { |
@@ -153,10 +148,7 @@ impl From<Name> for Path { | |||
153 | fn from(name: Name) -> Path { | 148 | fn from(name: Name) -> Path { |
154 | Path { | 149 | Path { |
155 | kind: PathKind::Plain, | 150 | kind: PathKind::Plain, |
156 | segments: vec![PathSegment { | 151 | segments: vec![PathSegment { name, args_and_bindings: None }], |
157 | name, | ||
158 | args_and_bindings: None, | ||
159 | }], | ||
160 | } | 152 | } |
161 | } | 153 | } |
162 | } | 154 | } |
@@ -209,18 +201,13 @@ fn expand_use_tree<'a>( | |||
209 | } | 201 | } |
210 | 202 | ||
211 | fn convert_path(prefix: Option<Path>, path: &ast::Path) -> Option<Path> { | 203 | fn convert_path(prefix: Option<Path>, path: &ast::Path) -> Option<Path> { |
212 | let prefix = if let Some(qual) = path.qualifier() { | 204 | let prefix = |
213 | Some(convert_path(prefix, qual)?) | 205 | if let Some(qual) = path.qualifier() { Some(convert_path(prefix, qual)?) } else { prefix }; |
214 | } else { | ||
215 | prefix | ||
216 | }; | ||
217 | let segment = path.segment()?; | 206 | let segment = path.segment()?; |
218 | let res = match segment.kind()? { | 207 | let res = match segment.kind()? { |
219 | ast::PathSegmentKind::Name(name) => { | 208 | ast::PathSegmentKind::Name(name) => { |
220 | let mut res = prefix.unwrap_or_else(|| Path { | 209 | let mut res = prefix |
221 | kind: PathKind::Plain, | 210 | .unwrap_or_else(|| Path { kind: PathKind::Plain, segments: Vec::with_capacity(1) }); |
222 | segments: Vec::with_capacity(1), | ||
223 | }); | ||
224 | res.segments.push(PathSegment { | 211 | res.segments.push(PathSegment { |
225 | name: name.as_name(), | 212 | name: name.as_name(), |
226 | args_and_bindings: None, // no type args in use | 213 | args_and_bindings: None, // no type args in use |
@@ -231,28 +218,19 @@ fn convert_path(prefix: Option<Path>, path: &ast::Path) -> Option<Path> { | |||
231 | if prefix.is_some() { | 218 | if prefix.is_some() { |
232 | return None; | 219 | return None; |
233 | } | 220 | } |
234 | Path { | 221 | Path { kind: PathKind::Crate, segments: Vec::new() } |
235 | kind: PathKind::Crate, | ||
236 | segments: Vec::new(), | ||
237 | } | ||
238 | } | 222 | } |
239 | ast::PathSegmentKind::SelfKw => { | 223 | ast::PathSegmentKind::SelfKw => { |
240 | if prefix.is_some() { | 224 | if prefix.is_some() { |
241 | return None; | 225 | return None; |
242 | } | 226 | } |
243 | Path { | 227 | Path { kind: PathKind::Self_, segments: Vec::new() } |
244 | kind: PathKind::Self_, | ||
245 | segments: Vec::new(), | ||
246 | } | ||
247 | } | 228 | } |
248 | ast::PathSegmentKind::SuperKw => { | 229 | ast::PathSegmentKind::SuperKw => { |
249 | if prefix.is_some() { | 230 | if prefix.is_some() { |
250 | return None; | 231 | return None; |
251 | } | 232 | } |
252 | Path { | 233 | Path { kind: PathKind::Super, segments: Vec::new() } |
253 | kind: PathKind::Super, | ||
254 | segments: Vec::new(), | ||
255 | } | ||
256 | } | 234 | } |
257 | }; | 235 | }; |
258 | Some(res) | 236 | Some(res) |
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index b4d8da1e6..03113e7cc 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -23,7 +23,5 @@ pub(super) fn file_item( | |||
23 | source_item_id: SourceItemId, | 23 | source_item_id: SourceItemId, |
24 | ) -> TreeArc<SyntaxNode> { | 24 | ) -> TreeArc<SyntaxNode> { |
25 | let source_file = db.hir_parse(source_item_id.file_id); | 25 | let source_file = db.hir_parse(source_item_id.file_id); |
26 | db.file_items(source_item_id.file_id)[source_item_id.item_id] | 26 | db.file_items(source_item_id.file_id)[source_item_id.item_id].to_node(&source_file).to_owned() |
27 | .to_node(&source_file) | ||
28 | .to_owned() | ||
29 | } | 27 | } |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 0f60d4742..3d7ec5683 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -138,10 +138,7 @@ impl Resolver { | |||
138 | expr_scopes: Arc<ExprScopes>, | 138 | expr_scopes: Arc<ExprScopes>, |
139 | scope_id: ScopeId, | 139 | scope_id: ScopeId, |
140 | ) -> Resolver { | 140 | ) -> Resolver { |
141 | self.push_scope(Scope::ExprScope(ExprScope { | 141 | self.push_scope(Scope::ExprScope(ExprScope { expr_scopes, scope_id })) |
142 | expr_scopes, | ||
143 | scope_id, | ||
144 | })) | ||
145 | } | 142 | } |
146 | } | 143 | } |
147 | 144 | ||
@@ -170,11 +167,8 @@ impl Scope { | |||
170 | } | 167 | } |
171 | } | 168 | } |
172 | Scope::ExprScope(e) => { | 169 | Scope::ExprScope(e) => { |
173 | let entry = e | 170 | let entry = |
174 | .expr_scopes | 171 | e.expr_scopes.entries(e.scope_id).iter().find(|entry| entry.name() == name); |
175 | .entries(e.scope_id) | ||
176 | .iter() | ||
177 | .find(|entry| entry.name() == name); | ||
178 | match entry { | 172 | match entry { |
179 | Some(e) => PerNs::values(Resolution::LocalBinding(e.pat())), | 173 | Some(e) => PerNs::values(Resolution::LocalBinding(e.pat())), |
180 | None => PerNs::none(), | 174 | None => PerNs::none(), |
@@ -193,35 +187,24 @@ impl Scope { | |||
193 | // def: m.module.into(), | 187 | // def: m.module.into(), |
194 | // }), | 188 | // }), |
195 | // ); | 189 | // ); |
196 | m.item_map[m.module.module_id] | 190 | m.item_map[m.module.module_id].entries().for_each(|(name, res)| { |
197 | .entries() | 191 | f(name.clone(), res.def.map(Resolution::Def)); |
198 | .for_each(|(name, res)| { | 192 | }); |
199 | f(name.clone(), res.def.map(Resolution::Def)); | ||
200 | }); | ||
201 | m.item_map.extern_prelude.iter().for_each(|(name, def)| { | 193 | m.item_map.extern_prelude.iter().for_each(|(name, def)| { |
202 | f(name.clone(), PerNs::types(Resolution::Def(*def))); | 194 | f(name.clone(), PerNs::types(Resolution::Def(*def))); |
203 | }); | 195 | }); |
204 | } | 196 | } |
205 | Scope::GenericParams(gp) => { | 197 | Scope::GenericParams(gp) => { |
206 | for param in &gp.params { | 198 | for param in &gp.params { |
207 | f( | 199 | f(param.name.clone(), PerNs::types(Resolution::GenericParam(param.idx))) |
208 | param.name.clone(), | ||
209 | PerNs::types(Resolution::GenericParam(param.idx)), | ||
210 | ) | ||
211 | } | 200 | } |
212 | } | 201 | } |
213 | Scope::ImplBlockScope(i) => { | 202 | Scope::ImplBlockScope(i) => { |
214 | f( | 203 | f(Name::self_type(), PerNs::types(Resolution::SelfType(i.clone()))); |
215 | Name::self_type(), | ||
216 | PerNs::types(Resolution::SelfType(i.clone())), | ||
217 | ); | ||
218 | } | 204 | } |
219 | Scope::ExprScope(e) => { | 205 | Scope::ExprScope(e) => { |
220 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { | 206 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { |
221 | f( | 207 | f(e.name().clone(), PerNs::values(Resolution::LocalBinding(e.pat()))); |
222 | e.name().clone(), | ||
223 | PerNs::values(Resolution::LocalBinding(e.pat())), | ||
224 | ); | ||
225 | }); | 208 | }); |
226 | } | 209 | } |
227 | } | 210 | } |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 59f782277..625a2ce45 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -65,11 +65,7 @@ pub fn module_from_child_node( | |||
65 | file_id: FileId, | 65 | file_id: FileId, |
66 | child: &SyntaxNode, | 66 | child: &SyntaxNode, |
67 | ) -> Option<Module> { | 67 | ) -> Option<Module> { |
68 | if let Some(m) = child | 68 | if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) { |
69 | .ancestors() | ||
70 | .filter_map(ast::Module::cast) | ||
71 | .find(|it| !it.has_semi()) | ||
72 | { | ||
73 | module_from_inline(db, file_id.into(), m) | 69 | module_from_inline(db, file_id.into(), m) |
74 | } else { | 70 | } else { |
75 | module_from_file_id(db, file_id.into()) | 71 | module_from_file_id(db, file_id.into()) |
@@ -82,14 +78,13 @@ fn module_from_source( | |||
82 | decl_id: Option<SourceFileItemId>, | 78 | decl_id: Option<SourceFileItemId>, |
83 | ) -> Option<Module> { | 79 | ) -> Option<Module> { |
84 | let source_root_id = db.file_source_root(file_id.as_original_file()); | 80 | let source_root_id = db.file_source_root(file_id.as_original_file()); |
85 | db.source_root_crates(source_root_id) | 81 | db.source_root_crates(source_root_id).iter().map(|&crate_id| Crate { crate_id }).find_map( |
86 | .iter() | 82 | |krate| { |
87 | .map(|&crate_id| Crate { crate_id }) | ||
88 | .find_map(|krate| { | ||
89 | let module_tree = db.module_tree(krate); | 83 | let module_tree = db.module_tree(krate); |
90 | let module_id = module_tree.find_module_by_source(file_id, decl_id)?; | 84 | let module_id = module_tree.find_module_by_source(file_id, decl_id)?; |
91 | Some(Module { krate, module_id }) | 85 | Some(Module { krate, module_id }) |
92 | }) | 86 | }, |
87 | ) | ||
93 | } | 88 | } |
94 | 89 | ||
95 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { | 90 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { |
@@ -116,9 +111,7 @@ pub fn function_from_module( | |||
116 | let (file_id, _) = module.definition_source(db); | 111 | let (file_id, _) = module.definition_source(db); |
117 | let file_id = file_id.into(); | 112 | let file_id = file_id.into(); |
118 | let ctx = LocationCtx::new(db, module, file_id); | 113 | let ctx = LocationCtx::new(db, module, file_id); |
119 | Function { | 114 | Function { id: ctx.to_def(fn_def) } |
120 | id: ctx.to_def(fn_def), | ||
121 | } | ||
122 | } | 115 | } |
123 | 116 | ||
124 | pub fn function_from_child_node( | 117 | pub fn function_from_child_node( |
@@ -138,18 +131,14 @@ pub fn struct_from_module( | |||
138 | let (file_id, _) = module.definition_source(db); | 131 | let (file_id, _) = module.definition_source(db); |
139 | let file_id = file_id.into(); | 132 | let file_id = file_id.into(); |
140 | let ctx = LocationCtx::new(db, module, file_id); | 133 | let ctx = LocationCtx::new(db, module, file_id); |
141 | Struct { | 134 | Struct { id: ctx.to_def(struct_def) } |
142 | id: ctx.to_def(struct_def), | ||
143 | } | ||
144 | } | 135 | } |
145 | 136 | ||
146 | pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { | 137 | pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { |
147 | let (file_id, _) = module.definition_source(db); | 138 | let (file_id, _) = module.definition_source(db); |
148 | let file_id = file_id.into(); | 139 | let file_id = file_id.into(); |
149 | let ctx = LocationCtx::new(db, module, file_id); | 140 | let ctx = LocationCtx::new(db, module, file_id); |
150 | Enum { | 141 | Enum { id: ctx.to_def(enum_def) } |
151 | id: ctx.to_def(enum_def), | ||
152 | } | ||
153 | } | 142 | } |
154 | 143 | ||
155 | pub fn trait_from_module( | 144 | pub fn trait_from_module( |
@@ -160,9 +149,7 @@ pub fn trait_from_module( | |||
160 | let (file_id, _) = module.definition_source(db); | 149 | let (file_id, _) = module.definition_source(db); |
161 | let file_id = file_id.into(); | 150 | let file_id = file_id.into(); |
162 | let ctx = LocationCtx::new(db, module, file_id); | 151 | let ctx = LocationCtx::new(db, module, file_id); |
163 | Trait { | 152 | Trait { id: ctx.to_def(trait_def) } |
164 | id: ctx.to_def(trait_def), | ||
165 | } | ||
166 | } | 153 | } |
167 | 154 | ||
168 | pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> { | 155 | pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> { |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 86a7f8b83..453520bbe 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -305,10 +305,8 @@ impl Ty { | |||
305 | match type_ref { | 305 | match type_ref { |
306 | TypeRef::Never => Ty::Never, | 306 | TypeRef::Never => Ty::Never, |
307 | TypeRef::Tuple(inner) => { | 307 | TypeRef::Tuple(inner) => { |
308 | let inner_tys = inner | 308 | let inner_tys = |
309 | .iter() | 309 | inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); |
310 | .map(|tr| Ty::from_hir(db, resolver, tr)) | ||
311 | .collect::<Vec<_>>(); | ||
312 | Ty::Tuple(inner_tys.into()) | 310 | Ty::Tuple(inner_tys.into()) |
313 | } | 311 | } |
314 | TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), | 312 | TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), |
@@ -330,17 +328,11 @@ impl Ty { | |||
330 | } | 328 | } |
331 | TypeRef::Placeholder => Ty::Unknown, | 329 | TypeRef::Placeholder => Ty::Unknown, |
332 | TypeRef::Fn(params) => { | 330 | TypeRef::Fn(params) => { |
333 | let mut inner_tys = params | 331 | let mut inner_tys = |
334 | .iter() | 332 | params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); |
335 | .map(|tr| Ty::from_hir(db, resolver, tr)) | 333 | let return_ty = |
336 | .collect::<Vec<_>>(); | 334 | inner_tys.pop().expect("TypeRef::Fn should always have at least return type"); |
337 | let return_ty = inner_tys | 335 | let sig = FnSig { input: inner_tys, output: return_ty }; |
338 | .pop() | ||
339 | .expect("TypeRef::Fn should always have at least return type"); | ||
340 | let sig = FnSig { | ||
341 | input: inner_tys, | ||
342 | output: return_ty, | ||
343 | }; | ||
344 | Ty::FnPtr(Arc::new(sig)) | 336 | Ty::FnPtr(Arc::new(sig)) |
345 | } | 337 | } |
346 | TypeRef::Error => Ty::Unknown, | 338 | TypeRef::Error => Ty::Unknown, |
@@ -407,10 +399,7 @@ impl Ty { | |||
407 | resolved: TypableDef, | 399 | resolved: TypableDef, |
408 | ) -> Substs { | 400 | ) -> Substs { |
409 | let mut substs = Vec::new(); | 401 | let mut substs = Vec::new(); |
410 | let last = path | 402 | let last = path.segments.last().expect("path should have at least one segment"); |
411 | .segments | ||
412 | .last() | ||
413 | .expect("path should have at least one segment"); | ||
414 | let (def_generics, segment) = match resolved { | 403 | let (def_generics, segment) = match resolved { |
415 | TypableDef::Function(func) => (func.generic_params(db), last), | 404 | TypableDef::Function(func) => (func.generic_params(db), last), |
416 | TypableDef::Struct(s) => (s.generic_params(db), last), | 405 | TypableDef::Struct(s) => (s.generic_params(db), last), |
@@ -447,11 +436,8 @@ impl Ty { | |||
447 | } | 436 | } |
448 | // add placeholders for args that were not provided | 437 | // add placeholders for args that were not provided |
449 | // TODO: handle defaults | 438 | // TODO: handle defaults |
450 | let supplied_params = segment | 439 | let supplied_params = |
451 | .args_and_bindings | 440 | segment.args_and_bindings.as_ref().map(|ga| ga.args.len()).unwrap_or(0); |
452 | .as_ref() | ||
453 | .map(|ga| ga.args.len()) | ||
454 | .unwrap_or(0); | ||
455 | for _ in supplied_params..def_generics.params.len() { | 441 | for _ in supplied_params..def_generics.params.len() { |
456 | substs.push(Ty::Unknown); | 442 | substs.push(Ty::Unknown); |
457 | } | 443 | } |
@@ -531,17 +517,8 @@ impl Ty { | |||
531 | /// `Option<u32>` afterwards.) | 517 | /// `Option<u32>` afterwards.) |
532 | pub fn apply_substs(self, substs: Substs) -> Ty { | 518 | pub fn apply_substs(self, substs: Substs) -> Ty { |
533 | match self { | 519 | match self { |
534 | Ty::Adt { def_id, name, .. } => Ty::Adt { | 520 | Ty::Adt { def_id, name, .. } => Ty::Adt { def_id, name, substs }, |
535 | def_id, | 521 | Ty::FnDef { def, name, sig, .. } => Ty::FnDef { def, name, sig, substs }, |
536 | name, | ||
537 | substs, | ||
538 | }, | ||
539 | Ty::FnDef { def, name, sig, .. } => Ty::FnDef { | ||
540 | def, | ||
541 | name, | ||
542 | sig, | ||
543 | substs, | ||
544 | }, | ||
545 | _ => self, | 522 | _ => self, |
546 | } | 523 | } |
547 | } | 524 | } |
@@ -591,42 +568,25 @@ impl fmt::Display for Ty { | |||
591 | if ts.len() == 1 { | 568 | if ts.len() == 1 { |
592 | write!(f, "({},)", ts[0]) | 569 | write!(f, "({},)", ts[0]) |
593 | } else { | 570 | } else { |
594 | join(ts.iter()) | 571 | join(ts.iter()).surround_with("(", ")").separator(", ").to_fmt(f) |
595 | .surround_with("(", ")") | ||
596 | .separator(", ") | ||
597 | .to_fmt(f) | ||
598 | } | 572 | } |
599 | } | 573 | } |
600 | Ty::FnPtr(sig) => { | 574 | Ty::FnPtr(sig) => { |
601 | join(sig.input.iter()) | 575 | join(sig.input.iter()).surround_with("fn(", ")").separator(", ").to_fmt(f)?; |
602 | .surround_with("fn(", ")") | ||
603 | .separator(", ") | ||
604 | .to_fmt(f)?; | ||
605 | write!(f, " -> {}", sig.output) | 576 | write!(f, " -> {}", sig.output) |
606 | } | 577 | } |
607 | Ty::FnDef { | 578 | Ty::FnDef { name, substs, sig, .. } => { |
608 | name, substs, sig, .. | ||
609 | } => { | ||
610 | write!(f, "fn {}", name)?; | 579 | write!(f, "fn {}", name)?; |
611 | if substs.0.len() > 0 { | 580 | if substs.0.len() > 0 { |
612 | join(substs.0.iter()) | 581 | join(substs.0.iter()).surround_with("<", ">").separator(", ").to_fmt(f)?; |
613 | .surround_with("<", ">") | ||
614 | .separator(", ") | ||
615 | .to_fmt(f)?; | ||
616 | } | 582 | } |
617 | join(sig.input.iter()) | 583 | join(sig.input.iter()).surround_with("(", ")").separator(", ").to_fmt(f)?; |
618 | .surround_with("(", ")") | ||
619 | .separator(", ") | ||
620 | .to_fmt(f)?; | ||
621 | write!(f, " -> {}", sig.output) | 584 | write!(f, " -> {}", sig.output) |
622 | } | 585 | } |
623 | Ty::Adt { name, substs, .. } => { | 586 | Ty::Adt { name, substs, .. } => { |
624 | write!(f, "{}", name)?; | 587 | write!(f, "{}", name)?; |
625 | if substs.0.len() > 0 { | 588 | if substs.0.len() > 0 { |
626 | join(substs.0.iter()) | 589 | join(substs.0.iter()).surround_with("<", ">").separator(", ").to_fmt(f)?; |
627 | .surround_with("<", ">") | ||
628 | .separator(", ") | ||
629 | .to_fmt(f)?; | ||
630 | } | 590 | } |
631 | Ok(()) | 591 | Ok(()) |
632 | } | 592 | } |
@@ -646,31 +606,16 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | |||
646 | let resolver = def.resolver(db); | 606 | let resolver = def.resolver(db); |
647 | let generics = def.generic_params(db); | 607 | let generics = def.generic_params(db); |
648 | let name = def.name(db); | 608 | let name = def.name(db); |
649 | let input = signature | 609 | let input = |
650 | .params() | 610 | signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); |
651 | .iter() | ||
652 | .map(|tr| Ty::from_hir(db, &resolver, tr)) | ||
653 | .collect::<Vec<_>>(); | ||
654 | let output = Ty::from_hir(db, &resolver, signature.ret_type()); | 611 | let output = Ty::from_hir(db, &resolver, signature.ret_type()); |
655 | let sig = Arc::new(FnSig { input, output }); | 612 | let sig = Arc::new(FnSig { input, output }); |
656 | let substs = make_substs(&generics); | 613 | let substs = make_substs(&generics); |
657 | Ty::FnDef { | 614 | Ty::FnDef { def, sig, name, substs } |
658 | def, | ||
659 | sig, | ||
660 | name, | ||
661 | substs, | ||
662 | } | ||
663 | } | 615 | } |
664 | 616 | ||
665 | fn make_substs(generics: &GenericParams) -> Substs { | 617 | fn make_substs(generics: &GenericParams) -> Substs { |
666 | Substs( | 618 | Substs(generics.params.iter().map(|_p| Ty::Unknown).collect::<Vec<_>>().into()) |
667 | generics | ||
668 | .params | ||
669 | .iter() | ||
670 | .map(|_p| Ty::Unknown) | ||
671 | .collect::<Vec<_>>() | ||
672 | .into(), | ||
673 | ) | ||
674 | } | 619 | } |
675 | 620 | ||
676 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { | 621 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { |
@@ -935,11 +880,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
935 | } | 880 | } |
936 | 881 | ||
937 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs) -> bool { | 882 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs) -> bool { |
938 | substs1 | 883 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify(t1, t2)) |
939 | .0 | ||
940 | .iter() | ||
941 | .zip(substs2.0.iter()) | ||
942 | .all(|(t1, t2)| self.unify(t1, t2)) | ||
943 | } | 884 | } |
944 | 885 | ||
945 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | 886 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { |
@@ -961,25 +902,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
961 | }, | 902 | }, |
962 | (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2, | 903 | (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2, |
963 | ( | 904 | ( |
964 | Ty::Adt { | 905 | Ty::Adt { def_id: def_id1, substs: substs1, .. }, |
965 | def_id: def_id1, | 906 | Ty::Adt { def_id: def_id2, substs: substs2, .. }, |
966 | substs: substs1, | ||
967 | .. | ||
968 | }, | ||
969 | Ty::Adt { | ||
970 | def_id: def_id2, | ||
971 | substs: substs2, | ||
972 | .. | ||
973 | }, | ||
974 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2), | 907 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2), |
975 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), | 908 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), |
976 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), | 909 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), |
977 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), | 910 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), |
978 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, | 911 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, |
979 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => ts1 | 912 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => { |
980 | .iter() | 913 | ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify(t1, t2)) |
981 | .zip(ts2.iter()) | 914 | } |
982 | .all(|(t1, t2)| self.unify(t1, t2)), | ||
983 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 915 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
984 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 916 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) |
985 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { | 917 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { |
@@ -994,8 +926,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
994 | | (Ty::Infer(InferTy::FloatVar(tv)), other) | 926 | | (Ty::Infer(InferTy::FloatVar(tv)), other) |
995 | | (other, Ty::Infer(InferTy::FloatVar(tv))) => { | 927 | | (other, Ty::Infer(InferTy::FloatVar(tv))) => { |
996 | // the type var is unknown since we tried to resolve it | 928 | // the type var is unknown since we tried to resolve it |
997 | self.var_unification_table | 929 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); |
998 | .union_value(*tv, TypeVarValue::Known(other.clone())); | ||
999 | true | 930 | true |
1000 | } | 931 | } |
1001 | _ => false, | 932 | _ => false, |
@@ -1003,21 +934,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1003 | } | 934 | } |
1004 | 935 | ||
1005 | fn new_type_var(&mut self) -> Ty { | 936 | fn new_type_var(&mut self) -> Ty { |
1006 | Ty::Infer(InferTy::TypeVar( | 937 | Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) |
1007 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
1008 | )) | ||
1009 | } | 938 | } |
1010 | 939 | ||
1011 | fn new_integer_var(&mut self) -> Ty { | 940 | fn new_integer_var(&mut self) -> Ty { |
1012 | Ty::Infer(InferTy::IntVar( | 941 | Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) |
1013 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
1014 | )) | ||
1015 | } | 942 | } |
1016 | 943 | ||
1017 | fn new_float_var(&mut self) -> Ty { | 944 | fn new_float_var(&mut self) -> Ty { |
1018 | Ty::Infer(InferTy::FloatVar( | 945 | Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) |
1019 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
1020 | )) | ||
1021 | } | 946 | } |
1022 | 947 | ||
1023 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 948 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
@@ -1207,9 +1132,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1207 | 1132 | ||
1208 | for subpat in subpats { | 1133 | for subpat in subpats { |
1209 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); | 1134 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); |
1210 | let expected_ty = matching_field | 1135 | let expected_ty = |
1211 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 1136 | matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs); |
1212 | .subst(&substs); | ||
1213 | self.infer_pat(subpat.pat, &expected_ty); | 1137 | self.infer_pat(subpat.pat, &expected_ty); |
1214 | } | 1138 | } |
1215 | 1139 | ||
@@ -1249,25 +1173,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1249 | let subty = self.infer_pat(*pat, expectation); | 1173 | let subty = self.infer_pat(*pat, expectation); |
1250 | Ty::Ref(subty.into(), *mutability) | 1174 | Ty::Ref(subty.into(), *mutability) |
1251 | } | 1175 | } |
1252 | Pat::TupleStruct { | 1176 | Pat::TupleStruct { path: ref p, args: ref subpats } => { |
1253 | path: ref p, | 1177 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected) |
1254 | args: ref subpats, | 1178 | } |
1255 | } => self.infer_tuple_struct_pat(p.as_ref(), subpats, expected), | 1179 | Pat::Struct { path: ref p, args: ref fields } => { |
1256 | Pat::Struct { | 1180 | self.infer_struct_pat(p.as_ref(), fields, expected) |
1257 | path: ref p, | 1181 | } |
1258 | args: ref fields, | ||
1259 | } => self.infer_struct_pat(p.as_ref(), fields, expected), | ||
1260 | Pat::Path(path) => { | 1182 | Pat::Path(path) => { |
1261 | // TODO use correct resolver for the surrounding expression | 1183 | // TODO use correct resolver for the surrounding expression |
1262 | let resolver = self.resolver.clone(); | 1184 | let resolver = self.resolver.clone(); |
1263 | self.infer_path_expr(&resolver, &path) | 1185 | self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown) |
1264 | .unwrap_or(Ty::Unknown) | 1186 | } |
1265 | } | 1187 | Pat::Bind { mode, name: _name, subpat } => { |
1266 | Pat::Bind { | ||
1267 | mode, | ||
1268 | name: _name, | ||
1269 | subpat, | ||
1270 | } => { | ||
1271 | let subty = if let Some(subpat) = subpat { | 1188 | let subty = if let Some(subpat) = subpat { |
1272 | self.infer_pat(*subpat, expected) | 1189 | self.infer_pat(*subpat, expected) |
1273 | } else { | 1190 | } else { |
@@ -1294,11 +1211,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1294 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 1211 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
1295 | let ty = match &body[tgt_expr] { | 1212 | let ty = match &body[tgt_expr] { |
1296 | Expr::Missing => Ty::Unknown, | 1213 | Expr::Missing => Ty::Unknown, |
1297 | Expr::If { | 1214 | Expr::If { condition, then_branch, else_branch } => { |
1298 | condition, | ||
1299 | then_branch, | ||
1300 | else_branch, | ||
1301 | } => { | ||
1302 | // if let is desugared to match, so this is always simple if | 1215 | // if let is desugared to match, so this is always simple if |
1303 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); | 1216 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); |
1304 | let then_ty = self.infer_expr(*then_branch, expected); | 1217 | let then_ty = self.infer_expr(*then_branch, expected); |
@@ -1325,21 +1238,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1325 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 1238 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
1326 | Ty::unit() | 1239 | Ty::unit() |
1327 | } | 1240 | } |
1328 | Expr::For { | 1241 | Expr::For { iterable, body, pat } => { |
1329 | iterable, | ||
1330 | body, | ||
1331 | pat, | ||
1332 | } => { | ||
1333 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 1242 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
1334 | self.infer_pat(*pat, &Ty::Unknown); | 1243 | self.infer_pat(*pat, &Ty::Unknown); |
1335 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 1244 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
1336 | Ty::unit() | 1245 | Ty::unit() |
1337 | } | 1246 | } |
1338 | Expr::Lambda { | 1247 | Expr::Lambda { body, args, arg_types } => { |
1339 | body, | ||
1340 | args, | ||
1341 | arg_types, | ||
1342 | } => { | ||
1343 | assert_eq!(args.len(), arg_types.len()); | 1248 | assert_eq!(args.len(), arg_types.len()); |
1344 | 1249 | ||
1345 | for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { | 1250 | for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { |
@@ -1362,11 +1267,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1362 | Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), | 1267 | Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), |
1363 | Ty::FnDef { substs, sig, .. } => { | 1268 | Ty::FnDef { substs, sig, .. } => { |
1364 | let ret_ty = sig.output.clone().subst(&substs); | 1269 | let ret_ty = sig.output.clone().subst(&substs); |
1365 | let param_tys = sig | 1270 | let param_tys = |
1366 | .input | 1271 | sig.input.iter().map(|ty| ty.clone().subst(&substs)).collect(); |
1367 | .iter() | ||
1368 | .map(|ty| ty.clone().subst(&substs)) | ||
1369 | .collect(); | ||
1370 | (param_tys, ret_ty) | 1272 | (param_tys, ret_ty) |
1371 | } | 1273 | } |
1372 | _ => { | 1274 | _ => { |
@@ -1381,11 +1283,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1381 | } | 1283 | } |
1382 | ret_ty | 1284 | ret_ty |
1383 | } | 1285 | } |
1384 | Expr::MethodCall { | 1286 | Expr::MethodCall { receiver, args, method_name } => { |
1385 | receiver, | ||
1386 | args, | ||
1387 | method_name, | ||
1388 | } => { | ||
1389 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); | 1287 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); |
1390 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); | 1288 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); |
1391 | let method_ty = match resolved { | 1289 | let method_ty = match resolved { |
@@ -1399,11 +1297,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1399 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { | 1297 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { |
1400 | Ty::FnPtr(sig) => { | 1298 | Ty::FnPtr(sig) => { |
1401 | if !sig.input.is_empty() { | 1299 | if !sig.input.is_empty() { |
1402 | ( | 1300 | (sig.input[0].clone(), sig.input[1..].to_vec(), sig.output.clone()) |
1403 | sig.input[0].clone(), | ||
1404 | sig.input[1..].to_vec(), | ||
1405 | sig.output.clone(), | ||
1406 | ) | ||
1407 | } else { | 1301 | } else { |
1408 | (Ty::Unknown, Vec::new(), sig.output.clone()) | 1302 | (Ty::Unknown, Vec::new(), sig.output.clone()) |
1409 | } | 1303 | } |
@@ -1469,11 +1363,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1469 | } | 1363 | } |
1470 | Ty::Never | 1364 | Ty::Never |
1471 | } | 1365 | } |
1472 | Expr::StructLit { | 1366 | Expr::StructLit { path, fields, spread } => { |
1473 | path, | ||
1474 | fields, | ||
1475 | spread, | ||
1476 | } => { | ||
1477 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 1367 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
1478 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 1368 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
1479 | for field in fields { | 1369 | for field in fields { |
@@ -1497,14 +1387,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1497 | let i = name.to_string().parse::<usize>().ok(); | 1387 | let i = name.to_string().parse::<usize>().ok(); |
1498 | i.and_then(|i| fields.get(i).cloned()) | 1388 | i.and_then(|i| fields.get(i).cloned()) |
1499 | } | 1389 | } |
1500 | Ty::Adt { | 1390 | Ty::Adt { def_id: AdtDef::Struct(s), ref substs, .. } => { |
1501 | def_id: AdtDef::Struct(s), | 1391 | s.field(self.db, name).map(|field| { |
1502 | ref substs, | 1392 | self.write_field_resolution(tgt_expr, field); |
1503 | .. | 1393 | field.ty(self.db).subst(substs) |
1504 | } => s.field(self.db, name).map(|field| { | 1394 | }) |
1505 | self.write_field_resolution(tgt_expr, field); | 1395 | } |
1506 | field.ty(self.db).subst(substs) | ||
1507 | }), | ||
1508 | _ => None, | 1396 | _ => None, |
1509 | }) | 1397 | }) |
1510 | .unwrap_or(Ty::Unknown); | 1398 | .unwrap_or(Ty::Unknown); |
@@ -1635,15 +1523,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1635 | ) -> Ty { | 1523 | ) -> Ty { |
1636 | for stmt in statements { | 1524 | for stmt in statements { |
1637 | match stmt { | 1525 | match stmt { |
1638 | Statement::Let { | 1526 | Statement::Let { pat, type_ref, initializer } => { |
1639 | pat, | 1527 | let decl_ty = |
1640 | type_ref, | 1528 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); |
1641 | initializer, | ||
1642 | } => { | ||
1643 | let decl_ty = type_ref | ||
1644 | .as_ref() | ||
1645 | .map(|tr| self.make_ty(tr)) | ||
1646 | .unwrap_or(Ty::Unknown); | ||
1647 | let decl_ty = self.insert_type_vars(decl_ty); | 1529 | let decl_ty = self.insert_type_vars(decl_ty); |
1648 | let ty = if let Some(expr) = initializer { | 1530 | let ty = if let Some(expr) = initializer { |
1649 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); | 1531 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); |
@@ -1659,11 +1541,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1659 | } | 1541 | } |
1660 | } | 1542 | } |
1661 | } | 1543 | } |
1662 | let ty = if let Some(expr) = tail { | 1544 | let ty = if let Some(expr) = tail { self.infer_expr(expr, expected) } else { Ty::unit() }; |
1663 | self.infer_expr(expr, expected) | ||
1664 | } else { | ||
1665 | Ty::unit() | ||
1666 | }; | ||
1667 | ty | 1545 | ty |
1668 | } | 1546 | } |
1669 | 1547 | ||
@@ -1678,10 +1556,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1678 | } | 1556 | } |
1679 | 1557 | ||
1680 | fn infer_body(&mut self) { | 1558 | fn infer_body(&mut self) { |
1681 | self.infer_expr( | 1559 | self.infer_expr(self.body.body_expr(), &Expectation::has_type(self.return_ty.clone())); |
1682 | self.body.body_expr(), | ||
1683 | &Expectation::has_type(self.return_ty.clone()), | ||
1684 | ); | ||
1685 | } | 1560 | } |
1686 | } | 1561 | } |
1687 | 1562 | ||
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index a7d4517ee..da7587f01 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -46,18 +46,13 @@ impl CrateImplBlocks { | |||
46 | ty: &Ty, | 46 | ty: &Ty, |
47 | ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a { | 47 | ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a { |
48 | let fingerprint = TyFingerprint::for_impl(ty); | 48 | let fingerprint = TyFingerprint::for_impl(ty); |
49 | fingerprint | 49 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map( |
50 | .and_then(|f| self.impls.get(&f)) | 50 | move |(module_id, impl_id)| { |
51 | .into_iter() | 51 | let module = Module { krate: self.krate, module_id: *module_id }; |
52 | .flat_map(|i| i.iter()) | ||
53 | .map(move |(module_id, impl_id)| { | ||
54 | let module = Module { | ||
55 | krate: self.krate, | ||
56 | module_id: *module_id, | ||
57 | }; | ||
58 | let module_impl_blocks = db.impls_in_module(module); | 52 | let module_impl_blocks = db.impls_in_module(module); |
59 | (module, ImplBlock::from_id(module_impl_blocks, *impl_id)) | 53 | (module, ImplBlock::from_id(module_impl_blocks, *impl_id)) |
60 | }) | 54 | }, |
55 | ) | ||
61 | } | 56 | } |
62 | 57 | ||
63 | pub fn lookup_impl_blocks_for_trait<'a>( | 58 | pub fn lookup_impl_blocks_for_trait<'a>( |
@@ -66,18 +61,13 @@ impl CrateImplBlocks { | |||
66 | tr: &Trait, | 61 | tr: &Trait, |
67 | ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a { | 62 | ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a { |
68 | let id = tr.id; | 63 | let id = tr.id; |
69 | self.impls_by_trait | 64 | self.impls_by_trait.get(&id).into_iter().flat_map(|i| i.iter()).map( |
70 | .get(&id) | 65 | move |(module_id, impl_id)| { |
71 | .into_iter() | 66 | let module = Module { krate: self.krate, module_id: *module_id }; |
72 | .flat_map(|i| i.iter()) | ||
73 | .map(move |(module_id, impl_id)| { | ||
74 | let module = Module { | ||
75 | krate: self.krate, | ||
76 | module_id: *module_id, | ||
77 | }; | ||
78 | let module_impl_blocks = db.impls_in_module(module); | 67 | let module_impl_blocks = db.impls_in_module(module); |
79 | (module, ImplBlock::from_id(module_impl_blocks, *impl_id)) | 68 | (module, ImplBlock::from_id(module_impl_blocks, *impl_id)) |
80 | }) | 69 | }, |
70 | ) | ||
81 | } | 71 | } |
82 | 72 | ||
83 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) { | 73 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) { |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 30da8fc23..2621d1b55 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -634,11 +634,7 @@ fn infer(content: &str) -> String { | |||
634 | let (db, _, file_id) = MockDatabase::with_single_file(content); | 634 | let (db, _, file_id) = MockDatabase::with_single_file(content); |
635 | let source_file = db.parse(file_id); | 635 | let source_file = db.parse(file_id); |
636 | let mut acc = String::new(); | 636 | let mut acc = String::new(); |
637 | for fn_def in source_file | 637 | for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) { |
638 | .syntax() | ||
639 | .descendants() | ||
640 | .filter_map(ast::FnDef::cast) | ||
641 | { | ||
642 | let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); | 638 | let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); |
643 | let inference_result = func.infer(&db); | 639 | let inference_result = func.infer(&db); |
644 | let body_syntax_mapping = func.body_syntax_mapping(&db); | 640 | let body_syntax_mapping = func.body_syntax_mapping(&db); |
@@ -725,8 +721,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
725 | " | 721 | " |
726 | .to_string(); | 722 | .to_string(); |
727 | 723 | ||
728 | db.query_mut(ra_db::FileTextQuery) | 724 | db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text)); |
729 | .set(pos.file_id, Arc::new(new_text)); | ||
730 | 725 | ||
731 | { | 726 | { |
732 | let events = db.log_executed(|| { | 727 | let events = db.log_executed(|| { |
diff --git a/crates/ra_hir/src/type_ref.rs b/crates/ra_hir/src/type_ref.rs index c9db4e0a5..ee8b7376a 100644 --- a/crates/ra_hir/src/type_ref.rs +++ b/crates/ra_hir/src/type_ref.rs | |||
@@ -62,11 +62,9 @@ impl TypeRef { | |||
62 | ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), | 62 | ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), |
63 | TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()), | 63 | TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()), |
64 | NeverType(..) => TypeRef::Never, | 64 | NeverType(..) => TypeRef::Never, |
65 | PathType(inner) => inner | 65 | PathType(inner) => { |
66 | .path() | 66 | inner.path().and_then(Path::from_ast).map(TypeRef::Path).unwrap_or(TypeRef::Error) |
67 | .and_then(Path::from_ast) | 67 | } |
68 | .map(TypeRef::Path) | ||
69 | .unwrap_or(TypeRef::Error), | ||
70 | PointerType(inner) => { | 68 | PointerType(inner) => { |
71 | let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); | 69 | let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); |
72 | let mutability = Mutability::from_mutable(inner.is_mut()); | 70 | let mutability = Mutability::from_mutable(inner.is_mut()); |
@@ -83,10 +81,7 @@ impl TypeRef { | |||
83 | FnPointerType(inner) => { | 81 | FnPointerType(inner) => { |
84 | let ret_ty = TypeRef::from_ast_opt(inner.ret_type().and_then(|rt| rt.type_ref())); | 82 | let ret_ty = TypeRef::from_ast_opt(inner.ret_type().and_then(|rt| rt.type_ref())); |
85 | let mut params = if let Some(pl) = inner.param_list() { | 83 | let mut params = if let Some(pl) = inner.param_list() { |
86 | pl.params() | 84 | pl.params().map(|p| p.type_ref()).map(TypeRef::from_ast_opt).collect() |
87 | .map(|p| p.type_ref()) | ||
88 | .map(TypeRef::from_ast_opt) | ||
89 | .collect() | ||
90 | } else { | 85 | } else { |
91 | Vec::new() | 86 | Vec::new() |
92 | }; | 87 | }; |
diff --git a/crates/ra_ide_api/src/assists.rs b/crates/ra_ide_api/src/assists.rs index 2a96fdf47..7a9c66681 100644 --- a/crates/ra_ide_api/src/assists.rs +++ b/crates/ra_ide_api/src/assists.rs | |||
@@ -7,10 +7,7 @@ pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<SourceChange> | |||
7 | .into_iter() | 7 | .into_iter() |
8 | .map(|(label, action)| { | 8 | .map(|(label, action)| { |
9 | let file_id = frange.file_id; | 9 | let file_id = frange.file_id; |
10 | let file_edit = SourceFileEdit { | 10 | let file_edit = SourceFileEdit { file_id, edit: action.edit }; |
11 | file_id, | ||
12 | edit: action.edit, | ||
13 | }; | ||
14 | SourceChange { | 11 | SourceChange { |
15 | label: label.label, | 12 | label: label.label, |
16 | source_file_edits: vec![file_edit], | 13 | source_file_edits: vec![file_edit], |
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index a59ab7853..1b279615c 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -21,9 +21,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
21 | 21 | ||
22 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). | 22 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). |
23 | let file_symbols = crate::symbol_index::index_resolve(db, name_ref); | 23 | let file_symbols = crate::symbol_index::index_resolve(db, name_ref); |
24 | let symbol = file_symbols | 24 | let symbol = file_symbols.into_iter().find(|it| it.ptr.kind() == FN_DEF)?; |
25 | .into_iter() | ||
26 | .find(|it| it.ptr.kind() == FN_DEF)?; | ||
27 | let fn_file = db.parse(symbol.file_id); | 25 | let fn_file = db.parse(symbol.file_id); |
28 | let fn_def = symbol.ptr.to_node(&fn_file); | 26 | let fn_def = symbol.ptr.to_node(&fn_file); |
29 | let fn_def = ast::FnDef::cast(fn_def).unwrap(); | 27 | let fn_def = ast::FnDef::cast(fn_def).unwrap(); |
@@ -53,13 +51,8 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
53 | let start = arg_list_range.start(); | 51 | let start = arg_list_range.start(); |
54 | 52 | ||
55 | let range_search = TextRange::from_to(start, position.offset); | 53 | let range_search = TextRange::from_to(start, position.offset); |
56 | let mut commas: usize = arg_list | 54 | let mut commas: usize = |
57 | .syntax() | 55 | arg_list.syntax().text().slice(range_search).to_string().matches(',').count(); |
58 | .text() | ||
59 | .slice(range_search) | ||
60 | .to_string() | ||
61 | .matches(',') | ||
62 | .count(); | ||
63 | 56 | ||
64 | // If we have a method call eat the first param since it's just self. | 57 | // If we have a method call eat the first param since it's just self. |
65 | if has_self { | 58 | if has_self { |
@@ -96,11 +89,9 @@ impl<'a> FnCallNode<'a> { | |||
96 | _ => return None, | 89 | _ => return None, |
97 | }), | 90 | }), |
98 | 91 | ||
99 | FnCallNode::MethodCallExpr(call_expr) => call_expr | 92 | FnCallNode::MethodCallExpr(call_expr) => { |
100 | .syntax() | 93 | call_expr.syntax().children().filter_map(ast::NameRef::cast).nth(0) |
101 | .children() | 94 | } |
102 | .filter_map(ast::NameRef::cast) | ||
103 | .nth(0), | ||
104 | } | 95 | } |
105 | } | 96 | } |
106 | 97 | ||
@@ -117,12 +108,7 @@ impl CallInfo { | |||
117 | let label = crate::completion::function_label(node)?; | 108 | let label = crate::completion::function_label(node)?; |
118 | let doc = function.docs(db); | 109 | let doc = function.docs(db); |
119 | 110 | ||
120 | Some(CallInfo { | 111 | Some(CallInfo { parameters: param_list(node), label, doc, active_parameter: None }) |
121 | parameters: param_list(node), | ||
122 | label, | ||
123 | doc, | ||
124 | active_parameter: None, | ||
125 | }) | ||
126 | } | 112 | } |
127 | } | 113 | } |
128 | 114 | ||
@@ -136,10 +122,7 @@ fn param_list(node: &ast::FnDef) -> Vec<String> { | |||
136 | // Maybe use param.pat here? See if we can just extract the name? | 122 | // Maybe use param.pat here? See if we can just extract the name? |
137 | //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); | 123 | //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); |
138 | res.extend( | 124 | res.extend( |
139 | param_list | 125 | param_list.params().filter_map(|p| p.pat()).map(|pat| pat.syntax().text().to_string()), |
140 | .params() | ||
141 | .filter_map(|p| p.pat()) | ||
142 | .map(|pat| pat.syntax().text().to_string()), | ||
143 | ); | 126 | ); |
144 | } | 127 | } |
145 | res | 128 | res |
@@ -378,10 +361,7 @@ pub fn foo() { | |||
378 | "#, | 361 | "#, |
379 | ); | 362 | ); |
380 | 363 | ||
381 | assert_eq!( | 364 | assert_eq!(info.parameters, vec!["&mut self".to_string(), "ctx".to_string()]); |
382 | info.parameters, | ||
383 | vec!["&mut self".to_string(), "ctx".to_string()] | ||
384 | ); | ||
385 | assert_eq!(info.active_parameter, Some(1)); | 365 | assert_eq!(info.active_parameter, Some(1)); |
386 | assert_eq!( | 366 | assert_eq!( |
387 | info.doc.map(|it| it.into()), | 367 | info.doc.map(|it| it.into()), |
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 992955740..3f041f9c3 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs | |||
@@ -65,16 +65,8 @@ impl AnalysisChange { | |||
65 | path: RelativePathBuf, | 65 | path: RelativePathBuf, |
66 | text: Arc<String>, | 66 | text: Arc<String>, |
67 | ) { | 67 | ) { |
68 | let file = AddFile { | 68 | let file = AddFile { file_id, path, text }; |
69 | file_id, | 69 | self.roots_changed.entry(root_id).or_default().added.push(file); |
70 | path, | ||
71 | text, | ||
72 | }; | ||
73 | self.roots_changed | ||
74 | .entry(root_id) | ||
75 | .or_default() | ||
76 | .added | ||
77 | .push(file); | ||
78 | } | 70 | } |
79 | 71 | ||
80 | pub fn change_file(&mut self, file_id: FileId, new_text: Arc<String>) { | 72 | pub fn change_file(&mut self, file_id: FileId, new_text: Arc<String>) { |
@@ -83,11 +75,7 @@ impl AnalysisChange { | |||
83 | 75 | ||
84 | pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { | 76 | pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { |
85 | let file = RemoveFile { file_id, path }; | 77 | let file = RemoveFile { file_id, path }; |
86 | self.roots_changed | 78 | self.roots_changed.entry(root_id).or_default().removed.push(file); |
87 | .entry(root_id) | ||
88 | .or_default() | ||
89 | .removed | ||
90 | .push(file); | ||
91 | } | 79 | } |
92 | 80 | ||
93 | pub fn add_library(&mut self, data: LibraryData) { | 81 | pub fn add_library(&mut self, data: LibraryData) { |
@@ -155,17 +143,9 @@ impl LibraryData { | |||
155 | let mut root_change = RootChange::default(); | 143 | let mut root_change = RootChange::default(); |
156 | root_change.added = files | 144 | root_change.added = files |
157 | .into_iter() | 145 | .into_iter() |
158 | .map(|(file_id, path, text)| AddFile { | 146 | .map(|(file_id, path, text)| AddFile { file_id, path, text }) |
159 | file_id, | ||
160 | path, | ||
161 | text, | ||
162 | }) | ||
163 | .collect(); | 147 | .collect(); |
164 | LibraryData { | 148 | LibraryData { root_id, root_change, symbol_index } |
165 | root_id, | ||
166 | root_change, | ||
167 | symbol_index, | ||
168 | } | ||
169 | } | 149 | } |
170 | } | 150 | } |
171 | 151 | ||
@@ -226,10 +206,7 @@ impl RootDatabase { | |||
226 | self.last_gc_check = time::Instant::now(); | 206 | self.last_gc_check = time::Instant::now(); |
227 | let retained_trees = syntax_tree_stats(self).retained; | 207 | let retained_trees = syntax_tree_stats(self).retained; |
228 | if retained_trees > 100 { | 208 | if retained_trees > 100 { |
229 | log::info!( | 209 | log::info!("automatic garbadge collection, {} retained trees", retained_trees); |
230 | "automatic garbadge collection, {} retained trees", | ||
231 | retained_trees | ||
232 | ); | ||
233 | self.collect_garbage(); | 210 | self.collect_garbage(); |
234 | } | 211 | } |
235 | } | 212 | } |
@@ -238,9 +215,7 @@ impl RootDatabase { | |||
238 | pub(crate) fn collect_garbage(&mut self) { | 215 | pub(crate) fn collect_garbage(&mut self) { |
239 | self.last_gc = time::Instant::now(); | 216 | self.last_gc = time::Instant::now(); |
240 | 217 | ||
241 | let sweep = SweepStrategy::default() | 218 | let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); |
242 | .discard_values() | ||
243 | .sweep_all_revisions(); | ||
244 | 219 | ||
245 | self.query(ra_db::ParseQuery).sweep(sweep); | 220 | self.query(ra_db::ParseQuery).sweep(sweep); |
246 | 221 | ||
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index bad51cc51..a673dbdcf 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs | |||
@@ -25,9 +25,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { | |||
25 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { | 25 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { |
26 | for receiver in receiver.autoderef(ctx.db) { | 26 | for receiver in receiver.autoderef(ctx.db) { |
27 | match receiver { | 27 | match receiver { |
28 | Ty::Adt { | 28 | Ty::Adt { def_id, ref substs, .. } => { |
29 | def_id, ref substs, .. | ||
30 | } => { | ||
31 | match def_id { | 29 | match def_id { |
32 | AdtDef::Struct(s) => { | 30 | AdtDef::Struct(s) => { |
33 | for field in s.fields(ctx.db) { | 31 | for field in s.fields(ctx.db) { |
diff --git a/crates/ra_ide_api/src/completion/complete_fn_param.rs b/crates/ra_ide_api/src/completion/complete_fn_param.rs index 8d4df4ea1..43532226f 100644 --- a/crates/ra_ide_api/src/completion/complete_fn_param.rs +++ b/crates/ra_ide_api/src/completion/complete_fn_param.rs | |||
@@ -43,13 +43,12 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) | |||
43 | node: &'a N, | 43 | node: &'a N, |
44 | params: &mut FxHashMap<String, (u32, &'a ast::Param)>, | 44 | params: &mut FxHashMap<String, (u32, &'a ast::Param)>, |
45 | ) { | 45 | ) { |
46 | node.functions() | 46 | node.functions().filter_map(|it| it.param_list()).flat_map(|it| it.params()).for_each( |
47 | .filter_map(|it| it.param_list()) | 47 | |param| { |
48 | .flat_map(|it| it.params()) | ||
49 | .for_each(|param| { | ||
50 | let text = param.syntax().text().to_string(); | 48 | let text = param.syntax().text().to_string(); |
51 | params.entry(text).or_insert((0, param)).0 += 1; | 49 | params.entry(text).or_insert((0, param)).0 += 1; |
52 | }) | 50 | }, |
51 | ) | ||
53 | } | 52 | } |
54 | } | 53 | } |
55 | 54 | ||
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index 0b9948d4b..c47a14e9f 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -31,14 +31,10 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
31 | hir::ModuleDef::Enum(e) => { | 31 | hir::ModuleDef::Enum(e) => { |
32 | e.variants(ctx.db).into_iter().for_each(|variant| { | 32 | e.variants(ctx.db).into_iter().for_each(|variant| { |
33 | if let Some(name) = variant.name(ctx.db) { | 33 | if let Some(name) = variant.name(ctx.db) { |
34 | let detail_types = variant | 34 | let detail_types = |
35 | .fields(ctx.db) | 35 | variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db)); |
36 | .into_iter() | 36 | let detail = |
37 | .map(|field| field.ty(ctx.db)); | 37 | join(detail_types).separator(", ").surround_with("(", ")").to_string(); |
38 | let detail = join(detail_types) | ||
39 | .separator(", ") | ||
40 | .surround_with("(", ")") | ||
41 | .to_string(); | ||
42 | 38 | ||
43 | CompletionItem::new( | 39 | CompletionItem::new( |
44 | CompletionKind::Reference, | 40 | CompletionKind::Reference, |
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs index e3a739d6d..10a3c8db7 100644 --- a/crates/ra_ide_api/src/completion/complete_postfix.rs +++ b/crates/ra_ide_api/src/completion/complete_postfix.rs | |||
@@ -17,11 +17,7 @@ use ra_text_edit::TextEditBuilder; | |||
17 | 17 | ||
18 | fn postfix_snippet(ctx: &CompletionContext, label: &str, snippet: &str) -> Builder { | 18 | fn postfix_snippet(ctx: &CompletionContext, label: &str, snippet: &str) -> Builder { |
19 | let replace_range = ctx.source_range(); | 19 | let replace_range = ctx.source_range(); |
20 | let receiver_range = ctx | 20 | let receiver_range = ctx.dot_receiver.expect("no receiver available").syntax().range(); |
21 | .dot_receiver | ||
22 | .expect("no receiver available") | ||
23 | .syntax() | ||
24 | .range(); | ||
25 | let delete_range = TextRange::from_to(receiver_range.start(), replace_range.start()); | 21 | let delete_range = TextRange::from_to(receiver_range.start(), replace_range.start()); |
26 | let mut builder = TextEditBuilder::default(); | 22 | let mut builder = TextEditBuilder::default(); |
27 | builder.delete(delete_range); | 23 | builder.delete(delete_range); |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 8674b1e66..445788407 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -7,13 +7,9 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
7 | let names = ctx.resolver.all_names(); | 7 | let names = ctx.resolver.all_names(); |
8 | 8 | ||
9 | names.into_iter().for_each(|(name, res)| { | 9 | names.into_iter().for_each(|(name, res)| { |
10 | CompletionItem::new( | 10 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) |
11 | CompletionKind::Reference, | 11 | .from_resolution(ctx, &res) |
12 | ctx.source_range(), | 12 | .add_to(acc) |
13 | name.to_string(), | ||
14 | ) | ||
15 | .from_resolution(ctx, &res) | ||
16 | .add_to(acc) | ||
17 | }); | 13 | }); |
18 | } | 14 | } |
19 | 15 | ||
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index 8abab0221..82bd4d606 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs | |||
@@ -108,12 +108,8 @@ impl<'a> CompletionContext<'a> { | |||
108 | } | 108 | } |
109 | fn classify_name_ref(&mut self, original_file: &'a SourceFile, name_ref: &ast::NameRef) { | 109 | fn classify_name_ref(&mut self, original_file: &'a SourceFile, name_ref: &ast::NameRef) { |
110 | let name_range = name_ref.syntax().range(); | 110 | let name_range = name_ref.syntax().range(); |
111 | let top_node = name_ref | 111 | let top_node = |
112 | .syntax() | 112 | name_ref.syntax().ancestors().take_while(|it| it.range() == name_range).last().unwrap(); |
113 | .ancestors() | ||
114 | .take_while(|it| it.range() == name_range) | ||
115 | .last() | ||
116 | .unwrap(); | ||
117 | 113 | ||
118 | match top_node.parent().map(|it| it.kind()) { | 114 | match top_node.parent().map(|it| it.kind()) { |
119 | Some(SOURCE_FILE) | Some(ITEM_LIST) => { | 115 | Some(SOURCE_FILE) | Some(ITEM_LIST) => { |
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index 92e6e78bf..7b8972af0 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs | |||
@@ -105,10 +105,7 @@ impl CompletionItem { | |||
105 | } | 105 | } |
106 | /// What string is used for filtering. | 106 | /// What string is used for filtering. |
107 | pub fn lookup(&self) -> &str { | 107 | pub fn lookup(&self) -> &str { |
108 | self.lookup | 108 | self.lookup.as_ref().map(|it| it.as_str()).unwrap_or_else(|| self.label()) |
109 | .as_ref() | ||
110 | .map(|it| it.as_str()) | ||
111 | .unwrap_or_else(|| self.label()) | ||
112 | } | 109 | } |
113 | 110 | ||
114 | pub fn insert_text_format(&self) -> InsertTextFormat { | 111 | pub fn insert_text_format(&self) -> InsertTextFormat { |
@@ -214,10 +211,7 @@ impl Builder { | |||
214 | ) -> Builder { | 211 | ) -> Builder { |
215 | use hir::ModuleDef::*; | 212 | use hir::ModuleDef::*; |
216 | 213 | ||
217 | let def = resolution | 214 | let def = resolution.as_ref().take_types().or_else(|| resolution.as_ref().take_values()); |
218 | .as_ref() | ||
219 | .take_types() | ||
220 | .or_else(|| resolution.as_ref().take_values()); | ||
221 | let def = match def { | 215 | let def = match def { |
222 | None => return self, | 216 | None => return self, |
223 | Some(it) => it, | 217 | Some(it) => it, |
@@ -323,10 +317,8 @@ pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind | |||
323 | }; | 317 | }; |
324 | let completions = completions(&analysis.db, position).unwrap(); | 318 | let completions = completions(&analysis.db, position).unwrap(); |
325 | let completion_items: Vec<CompletionItem> = completions.into(); | 319 | let completion_items: Vec<CompletionItem> = completions.into(); |
326 | let mut kind_completions: Vec<CompletionItem> = completion_items | 320 | let mut kind_completions: Vec<CompletionItem> = |
327 | .into_iter() | 321 | completion_items.into_iter().filter(|c| c.completion_kind == kind).collect(); |
328 | .filter(|c| c.completion_kind == kind) | ||
329 | .collect(); | ||
330 | kind_completions.sort_by_key(|c| c.label.clone()); | 322 | kind_completions.sort_by_key(|c| c.label.clone()); |
331 | assert_debug_snapshot_matches!(test_name, kind_completions); | 323 | assert_debug_snapshot_matches!(test_name, kind_completions); |
332 | } | 324 | } |
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index a499ac7c6..53d95fb4c 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs | |||
@@ -21,10 +21,8 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
21 | let source_root = db.file_source_root(file_id); | 21 | let source_root = db.file_source_root(file_id); |
22 | let diag = match problem { | 22 | let diag = match problem { |
23 | Problem::UnresolvedModule { candidate } => { | 23 | Problem::UnresolvedModule { candidate } => { |
24 | let create_file = FileSystemEdit::CreateFile { | 24 | let create_file = |
25 | source_root, | 25 | FileSystemEdit::CreateFile { source_root, path: candidate.clone() }; |
26 | path: candidate.clone(), | ||
27 | }; | ||
28 | let fix = SourceChange { | 26 | let fix = SourceChange { |
29 | label: "create module".to_string(), | 27 | label: "create module".to_string(), |
30 | source_file_edits: Vec::new(), | 28 | source_file_edits: Vec::new(), |
@@ -44,10 +42,8 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
44 | dst_source_root: source_root, | 42 | dst_source_root: source_root, |
45 | dst_path: move_to.clone(), | 43 | dst_path: move_to.clone(), |
46 | }; | 44 | }; |
47 | let create_file = FileSystemEdit::CreateFile { | 45 | let create_file = |
48 | source_root, | 46 | FileSystemEdit::CreateFile { source_root, path: move_to.join(candidate) }; |
49 | path: move_to.join(candidate), | ||
50 | }; | ||
51 | let fix = SourceChange { | 47 | let fix = SourceChange { |
52 | label: "move file and create module".to_string(), | 48 | label: "move file and create module".to_string(), |
53 | source_file_edits: Vec::new(), | 49 | source_file_edits: Vec::new(), |
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs index f61feaf1b..4051728e1 100644 --- a/crates/ra_ide_api/src/extend_selection.rs +++ b/crates/ra_ide_api/src/extend_selection.rs | |||
@@ -31,9 +31,7 @@ fn extend_selection_in_macro( | |||
31 | } | 31 | } |
32 | 32 | ||
33 | fn find_macro_call(node: &SyntaxNode, range: TextRange) -> Option<&ast::MacroCall> { | 33 | fn find_macro_call(node: &SyntaxNode, range: TextRange) -> Option<&ast::MacroCall> { |
34 | find_covering_node(node, range) | 34 | find_covering_node(node, range).ancestors().find_map(ast::MacroCall::cast) |
35 | .ancestors() | ||
36 | .find_map(ast::MacroCall::cast) | ||
37 | } | 35 | } |
38 | 36 | ||
39 | #[cfg(test)] | 37 | #[cfg(test)] |
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 69f2d2bf6..413720960 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -50,18 +50,13 @@ pub(crate) fn reference_definition( | |||
50 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax()) | 50 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax()) |
51 | { | 51 | { |
52 | // Check if it is a method | 52 | // Check if it is a method |
53 | if let Some(method_call) = name_ref | 53 | if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) { |
54 | .syntax() | ||
55 | .parent() | ||
56 | .and_then(ast::MethodCallExpr::cast) | ||
57 | { | ||
58 | tested_by!(goto_definition_works_for_methods); | 54 | tested_by!(goto_definition_works_for_methods); |
59 | let infer_result = function.infer(db); | 55 | let infer_result = function.infer(db); |
60 | let syntax_mapping = function.body_syntax_mapping(db); | 56 | let syntax_mapping = function.body_syntax_mapping(db); |
61 | let expr = ast::Expr::cast(method_call.syntax()).unwrap(); | 57 | let expr = ast::Expr::cast(method_call.syntax()).unwrap(); |
62 | if let Some(func) = syntax_mapping | 58 | if let Some(func) = |
63 | .node_expr(expr) | 59 | syntax_mapping.node_expr(expr).and_then(|it| infer_result.method_resolution(it)) |
64 | .and_then(|it| infer_result.method_resolution(it)) | ||
65 | { | 60 | { |
66 | return Exact(NavigationTarget::from_function(db, func)); | 61 | return Exact(NavigationTarget::from_function(db, func)); |
67 | }; | 62 | }; |
@@ -72,9 +67,8 @@ pub(crate) fn reference_definition( | |||
72 | let infer_result = function.infer(db); | 67 | let infer_result = function.infer(db); |
73 | let syntax_mapping = function.body_syntax_mapping(db); | 68 | let syntax_mapping = function.body_syntax_mapping(db); |
74 | let expr = ast::Expr::cast(field_expr.syntax()).unwrap(); | 69 | let expr = ast::Expr::cast(field_expr.syntax()).unwrap(); |
75 | if let Some(field) = syntax_mapping | 70 | if let Some(field) = |
76 | .node_expr(expr) | 71 | syntax_mapping.node_expr(expr).and_then(|it| infer_result.field_resolution(it)) |
77 | .and_then(|it| infer_result.field_resolution(it)) | ||
78 | { | 72 | { |
79 | return Exact(NavigationTarget::from_field(db, field)); | 73 | return Exact(NavigationTarget::from_field(db, field)); |
80 | }; | 74 | }; |
@@ -82,29 +76,19 @@ pub(crate) fn reference_definition( | |||
82 | } | 76 | } |
83 | // Try name resolution | 77 | // Try name resolution |
84 | let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax()); | 78 | let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax()); |
85 | if let Some(path) = name_ref | 79 | if let Some(path) = |
86 | .syntax() | 80 | name_ref.syntax().ancestors().find_map(ast::Path::cast).and_then(hir::Path::from_ast) |
87 | .ancestors() | ||
88 | .find_map(ast::Path::cast) | ||
89 | .and_then(hir::Path::from_ast) | ||
90 | { | 81 | { |
91 | let resolved = resolver.resolve_path(db, &path); | 82 | let resolved = resolver.resolve_path(db, &path); |
92 | match resolved | 83 | match resolved.clone().take_types().or_else(|| resolved.take_values()) { |
93 | .clone() | ||
94 | .take_types() | ||
95 | .or_else(|| resolved.take_values()) | ||
96 | { | ||
97 | Some(Resolution::Def(def)) => return Exact(NavigationTarget::from_def(db, def)), | 84 | Some(Resolution::Def(def)) => return Exact(NavigationTarget::from_def(db, def)), |
98 | Some(Resolution::LocalBinding(pat)) => { | 85 | Some(Resolution::LocalBinding(pat)) => { |
99 | let body = resolver.body().expect("no body for local binding"); | 86 | let body = resolver.body().expect("no body for local binding"); |
100 | let syntax_mapping = body.syntax_mapping(db); | 87 | let syntax_mapping = body.syntax_mapping(db); |
101 | let ptr = syntax_mapping | 88 | let ptr = |
102 | .pat_syntax(pat) | 89 | syntax_mapping.pat_syntax(pat).expect("pattern not found in syntax mapping"); |
103 | .expect("pattern not found in syntax mapping"); | 90 | let name = |
104 | let name = path | 91 | path.as_ident().cloned().expect("local binding from a multi-segment path"); |
105 | .as_ident() | ||
106 | .cloned() | ||
107 | .expect("local binding from a multi-segment path"); | ||
108 | let nav = NavigationTarget::from_scope_entry(file_id, name, ptr); | 92 | let nav = NavigationTarget::from_scope_entry(file_id, name, ptr); |
109 | return Exact(nav); | 93 | return Exact(nav); |
110 | } | 94 | } |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index f993a461c..60b81567c 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -33,13 +33,9 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
33 | } | 33 | } |
34 | if range.is_none() { | 34 | if range.is_none() { |
35 | let node = find_leaf_at_offset(file.syntax(), position.offset).find_map(|leaf| { | 35 | let node = find_leaf_at_offset(file.syntax(), position.offset).find_map(|leaf| { |
36 | leaf.ancestors() | 36 | leaf.ancestors().find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some()) |
37 | .find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some()) | ||
38 | })?; | 37 | })?; |
39 | let frange = FileRange { | 38 | let frange = FileRange { file_id: position.file_id, range: node.range() }; |
40 | file_id: position.file_id, | ||
41 | range: node.range(), | ||
42 | }; | ||
43 | res.extend(type_of(db, frange).map(Into::into)); | 39 | res.extend(type_of(db, frange).map(Into::into)); |
44 | range = Some(node.range()); | 40 | range = Some(node.range()); |
45 | }; | 41 | }; |
@@ -126,10 +122,8 @@ impl NavigationTarget { | |||
126 | where | 122 | where |
127 | T: ast::NameOwner + ast::VisibilityOwner, | 123 | T: ast::NameOwner + ast::VisibilityOwner, |
128 | { | 124 | { |
129 | let mut string = node | 125 | let mut string = |
130 | .visibility() | 126 | node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); |
131 | .map(|v| format!("{} ", v.syntax().text())) | ||
132 | .unwrap_or_default(); | ||
133 | string.push_str(label); | 127 | string.push_str(label); |
134 | node.name()?.syntax().text().push_to(&mut string); | 128 | node.name()?.syntax().text().push_to(&mut string); |
135 | Some(string) | 129 | Some(string) |
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index 4fb054139..444c4aeb2 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs | |||
@@ -83,9 +83,7 @@ mod tests { | |||
83 | 83 | ||
84 | let navs = analysis.goto_implementation(pos).unwrap().unwrap().info; | 84 | let navs = analysis.goto_implementation(pos).unwrap().unwrap().info; |
85 | assert_eq!(navs.len(), expected.len()); | 85 | assert_eq!(navs.len(), expected.len()); |
86 | navs.into_iter() | 86 | navs.into_iter().enumerate().for_each(|(i, nav)| nav.assert_match(expected[i])); |
87 | .enumerate() | ||
88 | .for_each(|(i, nav)| nav.assert_match(expected[i])); | ||
89 | } | 87 | } |
90 | 88 | ||
91 | #[test] | 89 | #[test] |
@@ -109,10 +107,7 @@ mod tests { | |||
109 | impl Foo {} | 107 | impl Foo {} |
110 | impl Foo {} | 108 | impl Foo {} |
111 | ", | 109 | ", |
112 | &[ | 110 | &["impl IMPL_BLOCK FileId(1) [12; 23)", "impl IMPL_BLOCK FileId(1) [24; 35)"], |
113 | "impl IMPL_BLOCK FileId(1) [12; 23)", | ||
114 | "impl IMPL_BLOCK FileId(1) [24; 35)", | ||
115 | ], | ||
116 | ); | 111 | ); |
117 | } | 112 | } |
118 | 113 | ||
@@ -129,10 +124,7 @@ mod tests { | |||
129 | impl super::Foo {} | 124 | impl super::Foo {} |
130 | } | 125 | } |
131 | ", | 126 | ", |
132 | &[ | 127 | &["impl IMPL_BLOCK FileId(1) [24; 42)", "impl IMPL_BLOCK FileId(1) [57; 75)"], |
133 | "impl IMPL_BLOCK FileId(1) [24; 42)", | ||
134 | "impl IMPL_BLOCK FileId(1) [57; 75)", | ||
135 | ], | ||
136 | ); | 128 | ); |
137 | } | 129 | } |
138 | 130 | ||
@@ -149,10 +141,7 @@ mod tests { | |||
149 | //- /b.rs | 141 | //- /b.rs |
150 | impl crate::Foo {} | 142 | impl crate::Foo {} |
151 | ", | 143 | ", |
152 | &[ | 144 | &["impl IMPL_BLOCK FileId(2) [0; 18)", "impl IMPL_BLOCK FileId(3) [0; 18)"], |
153 | "impl IMPL_BLOCK FileId(2) [0; 18)", | ||
154 | "impl IMPL_BLOCK FileId(3) [0; 18)", | ||
155 | ], | ||
156 | ); | 145 | ); |
157 | } | 146 | } |
158 | 147 | ||
@@ -183,10 +172,7 @@ mod tests { | |||
183 | //- /b.rs | 172 | //- /b.rs |
184 | impl crate::T for crate::Foo {} | 173 | impl crate::T for crate::Foo {} |
185 | ", | 174 | ", |
186 | &[ | 175 | &["impl IMPL_BLOCK FileId(2) [0; 31)", "impl IMPL_BLOCK FileId(3) [0; 31)"], |
187 | "impl IMPL_BLOCK FileId(2) [0; 31)", | ||
188 | "impl IMPL_BLOCK FileId(3) [0; 31)", | ||
189 | ], | ||
190 | ); | 176 | ); |
191 | } | 177 | } |
192 | } | 178 | } |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 1f43b7623..2d090d9b4 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -90,15 +90,8 @@ pub struct SourceFileEdit { | |||
90 | 90 | ||
91 | #[derive(Debug)] | 91 | #[derive(Debug)] |
92 | pub enum FileSystemEdit { | 92 | pub enum FileSystemEdit { |
93 | CreateFile { | 93 | CreateFile { source_root: SourceRootId, path: RelativePathBuf }, |
94 | source_root: SourceRootId, | 94 | MoveFile { src: FileId, dst_source_root: SourceRootId, dst_path: RelativePathBuf }, |
95 | path: RelativePathBuf, | ||
96 | }, | ||
97 | MoveFile { | ||
98 | src: FileId, | ||
99 | dst_source_root: SourceRootId, | ||
100 | dst_path: RelativePathBuf, | ||
101 | }, | ||
102 | } | 95 | } |
103 | 96 | ||
104 | #[derive(Debug)] | 97 | #[derive(Debug)] |
@@ -179,9 +172,7 @@ impl AnalysisHost { | |||
179 | /// Returns a snapshot of the current state, which you can query for | 172 | /// Returns a snapshot of the current state, which you can query for |
180 | /// semantic information. | 173 | /// semantic information. |
181 | pub fn analysis(&self) -> Analysis { | 174 | pub fn analysis(&self) -> Analysis { |
182 | Analysis { | 175 | Analysis { db: self.db.snapshot() } |
183 | db: self.db.snapshot(), | ||
184 | } | ||
185 | } | 176 | } |
186 | 177 | ||
187 | /// Applies changes to the current state of the world. If there are | 178 | /// Applies changes to the current state of the world. If there are |
@@ -401,17 +392,12 @@ impl Analysis { | |||
401 | 392 | ||
402 | impl SourceChange { | 393 | impl SourceChange { |
403 | pub(crate) fn from_local_edit(file_id: FileId, edit: LocalEdit) -> SourceChange { | 394 | pub(crate) fn from_local_edit(file_id: FileId, edit: LocalEdit) -> SourceChange { |
404 | let file_edit = SourceFileEdit { | 395 | let file_edit = SourceFileEdit { file_id, edit: edit.edit }; |
405 | file_id, | ||
406 | edit: edit.edit, | ||
407 | }; | ||
408 | SourceChange { | 396 | SourceChange { |
409 | label: edit.label, | 397 | label: edit.label, |
410 | source_file_edits: vec![file_edit], | 398 | source_file_edits: vec![file_edit], |
411 | file_system_edits: vec![], | 399 | file_system_edits: vec![], |
412 | cursor_position: edit | 400 | cursor_position: edit.cursor_position.map(|offset| FilePosition { offset, file_id }), |
413 | .cursor_position | ||
414 | .map(|offset| FilePosition { offset, file_id }), | ||
415 | } | 401 | } |
416 | } | 402 | } |
417 | } | 403 | } |
diff --git a/crates/ra_ide_api/src/mock_analysis.rs b/crates/ra_ide_api/src/mock_analysis.rs index 834b30541..8d8603062 100644 --- a/crates/ra_ide_api/src/mock_analysis.rs +++ b/crates/ra_ide_api/src/mock_analysis.rs | |||
@@ -41,10 +41,7 @@ impl MockAnalysis { | |||
41 | let mut res = MockAnalysis::new(); | 41 | let mut res = MockAnalysis::new(); |
42 | for entry in parse_fixture(fixture) { | 42 | for entry in parse_fixture(fixture) { |
43 | if entry.text.contains(CURSOR_MARKER) { | 43 | if entry.text.contains(CURSOR_MARKER) { |
44 | assert!( | 44 | assert!(position.is_none(), "only one marker (<|>) per fixture is allowed"); |
45 | position.is_none(), | ||
46 | "only one marker (<|>) per fixture is allowed" | ||
47 | ); | ||
48 | position = Some(res.add_file_with_position(&entry.meta, &entry.text)); | 45 | position = Some(res.add_file_with_position(&entry.meta, &entry.text)); |
49 | } else { | 46 | } else { |
50 | res.add_file(&entry.meta, &entry.text); | 47 | res.add_file(&entry.meta, &entry.text); |
@@ -97,9 +94,7 @@ impl MockAnalysis { | |||
97 | let other_crate = crate_graph.add_crate_root(file_id); | 94 | let other_crate = crate_graph.add_crate_root(file_id); |
98 | let crate_name = path.parent().unwrap().file_name().unwrap(); | 95 | let crate_name = path.parent().unwrap().file_name().unwrap(); |
99 | if let Some(root_crate) = root_crate { | 96 | if let Some(root_crate) = root_crate { |
100 | crate_graph | 97 | crate_graph.add_dep(root_crate, crate_name.into(), other_crate).unwrap(); |
101 | .add_dep(root_crate, crate_name.into(), other_crate) | ||
102 | .unwrap(); | ||
103 | } | 98 | } |
104 | } | 99 | } |
105 | change.add_file(source_root, file_id, path, Arc::new(contents)); | 100 | change.add_file(source_root, file_id, path, Arc::new(contents)); |
diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index 617908aed..a2e4b6506 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs | |||
@@ -72,10 +72,7 @@ impl NavigationTarget { | |||
72 | 72 | ||
73 | pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { | 73 | pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { |
74 | let (file_id, source) = module.definition_source(db); | 74 | let (file_id, source) = module.definition_source(db); |
75 | let name = module | 75 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
76 | .name(db) | ||
77 | .map(|it| it.to_string().into()) | ||
78 | .unwrap_or_default(); | ||
79 | match source { | 76 | match source { |
80 | ModuleSource::SourceFile(node) => { | 77 | ModuleSource::SourceFile(node) => { |
81 | NavigationTarget::from_syntax(file_id, name, None, node.syntax()) | 78 | NavigationTarget::from_syntax(file_id, name, None, node.syntax()) |
@@ -87,10 +84,7 @@ impl NavigationTarget { | |||
87 | } | 84 | } |
88 | 85 | ||
89 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { | 86 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { |
90 | let name = module | 87 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
91 | .name(db) | ||
92 | .map(|it| it.to_string().into()) | ||
93 | .unwrap_or_default(); | ||
94 | if let Some((file_id, source)) = module.declaration_source(db) { | 88 | if let Some((file_id, source)) = module.declaration_source(db) { |
95 | return NavigationTarget::from_syntax(file_id, name, None, source.syntax()); | 89 | return NavigationTarget::from_syntax(file_id, name, None, source.syntax()); |
96 | } | 90 | } |
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index b129f3134..2cb1cc9be 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs | |||
@@ -305,9 +305,7 @@ mod tests { | |||
305 | } | 305 | } |
306 | } | 306 | } |
307 | } | 307 | } |
308 | let result = text_edit_bulder | 308 | let result = text_edit_bulder.finish().apply(&*analysis.file_text(file_id.unwrap())); |
309 | .finish() | ||
310 | .apply(&*analysis.file_text(file_id.unwrap())); | ||
311 | assert_eq_text!(expected, &*result); | 309 | assert_eq_text!(expected, &*result); |
312 | } | 310 | } |
313 | } | 311 | } |
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs index dc8c40ea6..d64b5a4e0 100644 --- a/crates/ra_ide_api/src/runnables.rs +++ b/crates/ra_ide_api/src/runnables.rs | |||
@@ -23,11 +23,7 @@ pub enum RunnableKind { | |||
23 | 23 | ||
24 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 24 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
25 | let source_file = db.parse(file_id); | 25 | let source_file = db.parse(file_id); |
26 | source_file | 26 | source_file.syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect() |
27 | .syntax() | ||
28 | .descendants() | ||
29 | .filter_map(|i| runnable(db, file_id, i)) | ||
30 | .collect() | ||
31 | } | 27 | } |
32 | 28 | ||
33 | fn runnable(db: &RootDatabase, file_id: FileId, item: &SyntaxNode) -> Option<Runnable> { | 29 | fn runnable(db: &RootDatabase, file_id: FileId, item: &SyntaxNode) -> Option<Runnable> { |
@@ -45,20 +41,13 @@ fn runnable_fn(fn_def: &ast::FnDef) -> Option<Runnable> { | |||
45 | let kind = if name == "main" { | 41 | let kind = if name == "main" { |
46 | RunnableKind::Bin | 42 | RunnableKind::Bin |
47 | } else if fn_def.has_atom_attr("test") { | 43 | } else if fn_def.has_atom_attr("test") { |
48 | RunnableKind::Test { | 44 | RunnableKind::Test { name: name.to_string() } |
49 | name: name.to_string(), | ||
50 | } | ||
51 | } else if fn_def.has_atom_attr("bench") { | 45 | } else if fn_def.has_atom_attr("bench") { |
52 | RunnableKind::Bench { | 46 | RunnableKind::Bench { name: name.to_string() } |
53 | name: name.to_string(), | ||
54 | } | ||
55 | } else { | 47 | } else { |
56 | return None; | 48 | return None; |
57 | }; | 49 | }; |
58 | Some(Runnable { | 50 | Some(Runnable { range: fn_def.syntax().range(), kind }) |
59 | range: fn_def.syntax().range(), | ||
60 | kind, | ||
61 | }) | ||
62 | } | 51 | } |
63 | 52 | ||
64 | fn runnable_mod(db: &RootDatabase, file_id: FileId, module: &ast::Module) -> Option<Runnable> { | 53 | fn runnable_mod(db: &RootDatabase, file_id: FileId, module: &ast::Module) -> Option<Runnable> { |
@@ -77,16 +66,8 @@ fn runnable_mod(db: &RootDatabase, file_id: FileId, module: &ast::Module) -> Opt | |||
77 | let module = hir::source_binder::module_from_child_node(db, file_id, module.syntax())?; | 66 | let module = hir::source_binder::module_from_child_node(db, file_id, module.syntax())?; |
78 | 67 | ||
79 | // FIXME: thread cancellation instead of `.ok`ing | 68 | // FIXME: thread cancellation instead of `.ok`ing |
80 | let path = module | 69 | let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::"); |
81 | .path_to_root(db) | 70 | Some(Runnable { range, kind: RunnableKind::TestMod { path } }) |
82 | .into_iter() | ||
83 | .rev() | ||
84 | .filter_map(|it| it.name(db)) | ||
85 | .join("::"); | ||
86 | Some(Runnable { | ||
87 | range, | ||
88 | kind: RunnableKind::TestMod { path }, | ||
89 | }) | ||
90 | } | 71 | } |
91 | 72 | ||
92 | #[cfg(test)] | 73 | #[cfg(test)] |
diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs index bd355dd78..e0fc1c123 100644 --- a/crates/ra_ide_api/src/status.rs +++ b/crates/ra_ide_api/src/status.rs | |||
@@ -22,9 +22,7 @@ pub(crate) fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { | |||
22 | pub(crate) fn status(db: &RootDatabase) -> String { | 22 | pub(crate) fn status(db: &RootDatabase) -> String { |
23 | let files_stats = db.query(FileTextQuery).entries::<FilesStats>(); | 23 | let files_stats = db.query(FileTextQuery).entries::<FilesStats>(); |
24 | let syntax_tree_stats = syntax_tree_stats(db); | 24 | let syntax_tree_stats = syntax_tree_stats(db); |
25 | let symbols_stats = db | 25 | let symbols_stats = db.query(LibrarySymbolsQuery).entries::<LibrarySymbolsStats>(); |
26 | .query(LibrarySymbolsQuery) | ||
27 | .entries::<LibrarySymbolsStats>(); | ||
28 | let n_defs = { | 26 | let n_defs = { |
29 | let interner: &hir::HirInterner = db.as_ref(); | 27 | let interner: &hir::HirInterner = db.as_ref(); |
30 | interner.len() | 28 | interner.len() |
@@ -75,11 +73,7 @@ pub(crate) struct SyntaxTreeStats { | |||
75 | 73 | ||
76 | impl fmt::Display for SyntaxTreeStats { | 74 | impl fmt::Display for SyntaxTreeStats { |
77 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 75 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
78 | write!( | 76 | write!(fmt, "{} trees, {} ({}) retained", self.total, self.retained, self.retained_size,) |
79 | fmt, | ||
80 | "{} trees, {} ({}) retained", | ||
81 | self.total, self.retained, self.retained_size, | ||
82 | ) | ||
83 | } | 77 | } |
84 | } | 78 | } |
85 | 79 | ||
@@ -144,20 +138,13 @@ impl MemoryStats { | |||
144 | 138 | ||
145 | #[cfg(not(feature = "jemalloc"))] | 139 | #[cfg(not(feature = "jemalloc"))] |
146 | fn current() -> MemoryStats { | 140 | fn current() -> MemoryStats { |
147 | MemoryStats { | 141 | MemoryStats { allocated: Bytes(0), resident: Bytes(0) } |
148 | allocated: Bytes(0), | ||
149 | resident: Bytes(0), | ||
150 | } | ||
151 | } | 142 | } |
152 | } | 143 | } |
153 | 144 | ||
154 | impl fmt::Display for MemoryStats { | 145 | impl fmt::Display for MemoryStats { |
155 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 146 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
156 | write!( | 147 | write!(fmt, "{} allocated {} resident", self.allocated, self.resident,) |
157 | fmt, | ||
158 | "{} allocated {} resident", | ||
159 | self.allocated, self.resident, | ||
160 | ) | ||
161 | } | 148 | } |
162 | } | 149 | } |
163 | 150 | ||
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index 3d0b2369e..de0f46134 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs | |||
@@ -101,10 +101,7 @@ pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> | |||
101 | } | 101 | } |
102 | 102 | ||
103 | let snap = Snap(db.snapshot()); | 103 | let snap = Snap(db.snapshot()); |
104 | files | 104 | files.par_iter().map_with(snap, |db, &file_id| db.0.file_symbols(file_id)).collect() |
105 | .par_iter() | ||
106 | .map_with(snap, |db, &file_id| db.0.file_symbols(file_id)) | ||
107 | .collect() | ||
108 | }; | 105 | }; |
109 | query.search(&buf) | 106 | query.search(&buf) |
110 | } | 107 | } |
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 6c4391e1e..a435fe56e 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs | |||
@@ -9,20 +9,12 @@ use crate::{ | |||
9 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { | 9 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { |
10 | let source_file = db.parse(file_id); | 10 | let source_file = db.parse(file_id); |
11 | let mut res = ra_ide_api_light::highlight(source_file.syntax()); | 11 | let mut res = ra_ide_api_light::highlight(source_file.syntax()); |
12 | for macro_call in source_file | 12 | for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) { |
13 | .syntax() | ||
14 | .descendants() | ||
15 | .filter_map(ast::MacroCall::cast) | ||
16 | { | ||
17 | if let Some((off, exp)) = hir::MacroDef::ast_expand(macro_call) { | 13 | if let Some((off, exp)) = hir::MacroDef::ast_expand(macro_call) { |
18 | let mapped_ranges = ra_ide_api_light::highlight(&exp.syntax()) | 14 | let mapped_ranges = |
19 | .into_iter() | 15 | ra_ide_api_light::highlight(&exp.syntax()).into_iter().filter_map(|r| { |
20 | .filter_map(|r| { | ||
21 | let mapped_range = exp.map_range_back(r.range)?; | 16 | let mapped_range = exp.map_range_back(r.range)?; |
22 | let res = HighlightedRange { | 17 | let res = HighlightedRange { range: mapped_range + off, tag: r.tag }; |
23 | range: mapped_range + off, | ||
24 | tag: r.tag, | ||
25 | }; | ||
26 | Some(res) | 18 | Some(res) |
27 | }); | 19 | }); |
28 | res.extend(mapped_ranges); | 20 | res.extend(mapped_ranges); |
diff --git a/crates/ra_ide_api_light/src/diagnostics.rs b/crates/ra_ide_api_light/src/diagnostics.rs index 2b695dfdf..7c383ca2a 100644 --- a/crates/ra_ide_api_light/src/diagnostics.rs +++ b/crates/ra_ide_api_light/src/diagnostics.rs | |||
@@ -72,14 +72,7 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement( | |||
72 | single_use_tree: &ast::UseTree, | 72 | single_use_tree: &ast::UseTree, |
73 | ) -> Option<TextEdit> { | 73 | ) -> Option<TextEdit> { |
74 | let use_tree_list_node = single_use_tree.syntax().parent()?; | 74 | let use_tree_list_node = single_use_tree.syntax().parent()?; |
75 | if single_use_tree | 75 | if single_use_tree.path()?.segment()?.syntax().first_child()?.kind() == SyntaxKind::SELF_KW { |
76 | .path()? | ||
77 | .segment()? | ||
78 | .syntax() | ||
79 | .first_child()? | ||
80 | .kind() | ||
81 | == SyntaxKind::SELF_KW | ||
82 | { | ||
83 | let start = use_tree_list_node.prev_sibling()?.range().start(); | 76 | let start = use_tree_list_node.prev_sibling()?.range().start(); |
84 | let end = use_tree_list_node.range().end(); | 77 | let end = use_tree_list_node.range().end(); |
85 | let range = TextRange::from_to(start, end); | 78 | let range = TextRange::from_to(start, end); |
@@ -145,9 +138,8 @@ mod tests { | |||
145 | for node in file.syntax().descendants() { | 138 | for node in file.syntax().descendants() { |
146 | func(&mut diagnostics, node); | 139 | func(&mut diagnostics, node); |
147 | } | 140 | } |
148 | let diagnostic = diagnostics | 141 | let diagnostic = |
149 | .pop() | 142 | diagnostics.pop().unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before)); |
150 | .unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before)); | ||
151 | let fix = diagnostic.fix.unwrap(); | 143 | let fix = diagnostic.fix.unwrap(); |
152 | let actual = fix.edit.apply(&before); | 144 | let actual = fix.edit.apply(&before); |
153 | assert_eq_text!(after, &actual); | 145 | assert_eq_text!(after, &actual); |
@@ -162,21 +154,9 @@ mod tests { | |||
162 | ", | 154 | ", |
163 | check_unnecessary_braces_in_use_statement, | 155 | check_unnecessary_braces_in_use_statement, |
164 | ); | 156 | ); |
165 | check_apply( | 157 | check_apply("use {b};", "use b;", check_unnecessary_braces_in_use_statement); |
166 | "use {b};", | 158 | check_apply("use a::{c};", "use a::c;", check_unnecessary_braces_in_use_statement); |
167 | "use b;", | 159 | check_apply("use a::{self};", "use a;", check_unnecessary_braces_in_use_statement); |
168 | check_unnecessary_braces_in_use_statement, | ||
169 | ); | ||
170 | check_apply( | ||
171 | "use a::{c};", | ||
172 | "use a::c;", | ||
173 | check_unnecessary_braces_in_use_statement, | ||
174 | ); | ||
175 | check_apply( | ||
176 | "use a::{self};", | ||
177 | "use a;", | ||
178 | check_unnecessary_braces_in_use_statement, | ||
179 | ); | ||
180 | check_apply( | 160 | check_apply( |
181 | "use a::{c, d::{e}};", | 161 | "use a::{c, d::{e}};", |
182 | "use a::{c, d::e};", | 162 | "use a::{c, d::e};", |
diff --git a/crates/ra_ide_api_light/src/extend_selection.rs b/crates/ra_ide_api_light/src/extend_selection.rs index f396dfe3f..28d62f290 100644 --- a/crates/ra_ide_api_light/src/extend_selection.rs +++ b/crates/ra_ide_api_light/src/extend_selection.rs | |||
@@ -43,11 +43,7 @@ pub fn extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange | |||
43 | let node = find_covering_node(root, range); | 43 | let node = find_covering_node(root, range); |
44 | 44 | ||
45 | // Using shallowest node with same range allows us to traverse siblings. | 45 | // Using shallowest node with same range allows us to traverse siblings. |
46 | let node = node | 46 | let node = node.ancestors().take_while(|n| n.range() == node.range()).last().unwrap(); |
47 | .ancestors() | ||
48 | .take_while(|n| n.range() == node.range()) | ||
49 | .last() | ||
50 | .unwrap(); | ||
51 | 47 | ||
52 | if range == node.range() { | 48 | if range == node.range() { |
53 | if string_kinds.contains(&node.kind()) { | 49 | if string_kinds.contains(&node.kind()) { |
@@ -145,10 +141,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> { | |||
145 | } | 141 | } |
146 | 142 | ||
147 | if let Some(comma_node) = nearby_comma(node, Direction::Prev) { | 143 | if let Some(comma_node) = nearby_comma(node, Direction::Prev) { |
148 | return Some(TextRange::from_to( | 144 | return Some(TextRange::from_to(comma_node.range().start(), node.range().end())); |
149 | comma_node.range().start(), | ||
150 | node.range().end(), | ||
151 | )); | ||
152 | } | 145 | } |
153 | 146 | ||
154 | if let Some(comma_node) = nearby_comma(node, Direction::Next) { | 147 | if let Some(comma_node) = nearby_comma(node, Direction::Next) { |
@@ -160,10 +153,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> { | |||
160 | .filter(|node| is_single_line_ws(node)) | 153 | .filter(|node| is_single_line_ws(node)) |
161 | .unwrap_or(comma_node); | 154 | .unwrap_or(comma_node); |
162 | 155 | ||
163 | return Some(TextRange::from_to( | 156 | return Some(TextRange::from_to(node.range().start(), final_node.range().end())); |
164 | node.range().start(), | ||
165 | final_node.range().end(), | ||
166 | )); | ||
167 | } | 157 | } |
168 | 158 | ||
169 | return None; | 159 | return None; |
@@ -217,36 +207,15 @@ mod tests { | |||
217 | #[test] | 207 | #[test] |
218 | fn test_extend_selection_list() { | 208 | fn test_extend_selection_list() { |
219 | do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]); | 209 | do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]); |
220 | do_check( | 210 | do_check(r#"fn foo(<|>x: i32, y: i32) {}"#, &["x", "x: i32", "x: i32, "]); |
221 | r#"fn foo(<|>x: i32, y: i32) {}"#, | 211 | do_check(r#"fn foo(<|>x: i32,y: i32) {}"#, &["x", "x: i32", "x: i32,"]); |
222 | &["x", "x: i32", "x: i32, "], | 212 | do_check(r#"fn foo(x: i32, <|>y: i32) {}"#, &["y", "y: i32", ", y: i32"]); |
223 | ); | 213 | do_check(r#"fn foo(x: i32, <|>y: i32, ) {}"#, &["y", "y: i32", ", y: i32"]); |
224 | do_check( | 214 | do_check(r#"fn foo(x: i32,<|>y: i32) {}"#, &["y", "y: i32", ",y: i32"]); |
225 | r#"fn foo(<|>x: i32,y: i32) {}"#, | ||
226 | &["x", "x: i32", "x: i32,"], | ||
227 | ); | ||
228 | do_check( | ||
229 | r#"fn foo(x: i32, <|>y: i32) {}"#, | ||
230 | &["y", "y: i32", ", y: i32"], | ||
231 | ); | ||
232 | do_check( | ||
233 | r#"fn foo(x: i32, <|>y: i32, ) {}"#, | ||
234 | &["y", "y: i32", ", y: i32"], | ||
235 | ); | ||
236 | do_check( | ||
237 | r#"fn foo(x: i32,<|>y: i32) {}"#, | ||
238 | &["y", "y: i32", ",y: i32"], | ||
239 | ); | ||
240 | 215 | ||
241 | do_check( | 216 | do_check(r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, &["22", "22 , "]); |
242 | r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, | ||
243 | &["22", "22 , "], | ||
244 | ); | ||
245 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]); | 217 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]); |
246 | do_check( | 218 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, &["33", ", 33"]); |
247 | r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, | ||
248 | &["33", ", 33"], | ||
249 | ); | ||
250 | 219 | ||
251 | do_check( | 220 | do_check( |
252 | r#" | 221 | r#" |
@@ -292,11 +261,7 @@ struct B { | |||
292 | <|> | 261 | <|> |
293 | } | 262 | } |
294 | "#, | 263 | "#, |
295 | &[ | 264 | &["\n \n", "{\n \n}", "/// bla\n/// bla\nstruct B {\n \n}"], |
296 | "\n \n", | ||
297 | "{\n \n}", | ||
298 | "/// bla\n/// bla\nstruct B {\n \n}", | ||
299 | ], | ||
300 | ) | 265 | ) |
301 | } | 266 | } |
302 | 267 | ||
diff --git a/crates/ra_ide_api_light/src/folding_ranges.rs b/crates/ra_ide_api_light/src/folding_ranges.rs index c73637323..357a7dee1 100644 --- a/crates/ra_ide_api_light/src/folding_ranges.rs +++ b/crates/ra_ide_api_light/src/folding_ranges.rs | |||
@@ -30,30 +30,21 @@ pub fn folding_ranges(file: &SourceFile) -> Vec<Fold> { | |||
30 | // Fold items that span multiple lines | 30 | // Fold items that span multiple lines |
31 | if let Some(kind) = fold_kind(node.kind()) { | 31 | if let Some(kind) = fold_kind(node.kind()) { |
32 | if node.text().contains('\n') { | 32 | if node.text().contains('\n') { |
33 | res.push(Fold { | 33 | res.push(Fold { range: node.range(), kind }); |
34 | range: node.range(), | ||
35 | kind, | ||
36 | }); | ||
37 | } | 34 | } |
38 | } | 35 | } |
39 | 36 | ||
40 | // Fold groups of comments | 37 | // Fold groups of comments |
41 | if node.kind() == COMMENT && !visited_comments.contains(&node) { | 38 | if node.kind() == COMMENT && !visited_comments.contains(&node) { |
42 | if let Some(range) = contiguous_range_for_comment(node, &mut visited_comments) { | 39 | if let Some(range) = contiguous_range_for_comment(node, &mut visited_comments) { |
43 | res.push(Fold { | 40 | res.push(Fold { range, kind: FoldKind::Comment }) |
44 | range, | ||
45 | kind: FoldKind::Comment, | ||
46 | }) | ||
47 | } | 41 | } |
48 | } | 42 | } |
49 | 43 | ||
50 | // Fold groups of imports | 44 | // Fold groups of imports |
51 | if node.kind() == USE_ITEM && !visited_imports.contains(&node) { | 45 | if node.kind() == USE_ITEM && !visited_imports.contains(&node) { |
52 | if let Some(range) = contiguous_range_for_group(node, &mut visited_imports) { | 46 | if let Some(range) = contiguous_range_for_group(node, &mut visited_imports) { |
53 | res.push(Fold { | 47 | res.push(Fold { range, kind: FoldKind::Imports }) |
54 | range, | ||
55 | kind: FoldKind::Imports, | ||
56 | }) | ||
57 | } | 48 | } |
58 | } | 49 | } |
59 | 50 | ||
@@ -62,10 +53,7 @@ pub fn folding_ranges(file: &SourceFile) -> Vec<Fold> { | |||
62 | if let Some(range) = | 53 | if let Some(range) = |
63 | contiguous_range_for_group_unless(node, has_visibility, &mut visited_mods) | 54 | contiguous_range_for_group_unless(node, has_visibility, &mut visited_mods) |
64 | { | 55 | { |
65 | res.push(Fold { | 56 | res.push(Fold { range, kind: FoldKind::Mods }) |
66 | range, | ||
67 | kind: FoldKind::Mods, | ||
68 | }) | ||
69 | } | 57 | } |
70 | } | 58 | } |
71 | } | 59 | } |
@@ -84,9 +72,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> { | |||
84 | } | 72 | } |
85 | 73 | ||
86 | fn has_visibility(node: &SyntaxNode) -> bool { | 74 | fn has_visibility(node: &SyntaxNode) -> bool { |
87 | ast::Module::cast(node) | 75 | ast::Module::cast(node).and_then(|m| m.visibility()).is_some() |
88 | .and_then(|m| m.visibility()) | ||
89 | .is_some() | ||
90 | } | 76 | } |
91 | 77 | ||
92 | fn contiguous_range_for_group<'a>( | 78 | fn contiguous_range_for_group<'a>( |
@@ -125,10 +111,7 @@ fn contiguous_range_for_group_unless<'a>( | |||
125 | } | 111 | } |
126 | 112 | ||
127 | if first != last { | 113 | if first != last { |
128 | Some(TextRange::from_to( | 114 | Some(TextRange::from_to(first.range().start(), last.range().end())) |
129 | first.range().start(), | ||
130 | last.range().end(), | ||
131 | )) | ||
132 | } else { | 115 | } else { |
133 | // The group consists of only one element, therefore it cannot be folded | 116 | // The group consists of only one element, therefore it cannot be folded |
134 | None | 117 | None |
@@ -169,10 +152,7 @@ fn contiguous_range_for_comment<'a>( | |||
169 | } | 152 | } |
170 | 153 | ||
171 | if first != last { | 154 | if first != last { |
172 | Some(TextRange::from_to( | 155 | Some(TextRange::from_to(first.range().start(), last.range().end())) |
173 | first.range().start(), | ||
174 | last.range().end(), | ||
175 | )) | ||
176 | } else { | 156 | } else { |
177 | // The group consists of only one element, therefore it cannot be folded | 157 | // The group consists of only one element, therefore it cannot be folded |
178 | None | 158 | None |
@@ -199,10 +179,8 @@ mod tests { | |||
199 | fold_kinds.len(), | 179 | fold_kinds.len(), |
200 | "The amount of fold kinds is different than the expected amount" | 180 | "The amount of fold kinds is different than the expected amount" |
201 | ); | 181 | ); |
202 | for ((fold, range), fold_kind) in folds | 182 | for ((fold, range), fold_kind) in |
203 | .into_iter() | 183 | folds.into_iter().zip(ranges.into_iter()).zip(fold_kinds.into_iter()) |
204 | .zip(ranges.into_iter()) | ||
205 | .zip(fold_kinds.into_iter()) | ||
206 | { | 184 | { |
207 | assert_eq!(fold.range.start(), range.start()); | 185 | assert_eq!(fold.range.start(), range.start()); |
208 | assert_eq!(fold.range.end(), range.end()); | 186 | assert_eq!(fold.range.end(), range.end()); |
@@ -280,12 +258,7 @@ mod with_attribute_next;</fold> | |||
280 | fn main() <fold>{ | 258 | fn main() <fold>{ |
281 | }</fold>"#; | 259 | }</fold>"#; |
282 | 260 | ||
283 | let folds = &[ | 261 | let folds = &[FoldKind::Mods, FoldKind::Mods, FoldKind::Mods, FoldKind::Block]; |
284 | FoldKind::Mods, | ||
285 | FoldKind::Mods, | ||
286 | FoldKind::Mods, | ||
287 | FoldKind::Block, | ||
288 | ]; | ||
289 | do_check(text, folds); | 262 | do_check(text, folds); |
290 | } | 263 | } |
291 | 264 | ||
diff --git a/crates/ra_ide_api_light/src/formatting.rs b/crates/ra_ide_api_light/src/formatting.rs index 46ffa7d96..8bc03f974 100644 --- a/crates/ra_ide_api_light/src/formatting.rs +++ b/crates/ra_ide_api_light/src/formatting.rs | |||
@@ -32,10 +32,7 @@ fn prev_leaves(node: &SyntaxNode) -> impl Iterator<Item = &SyntaxNode> { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | fn prev_leaf(node: &SyntaxNode) -> Option<&SyntaxNode> { | 34 | fn prev_leaf(node: &SyntaxNode) -> Option<&SyntaxNode> { |
35 | generate(node.ancestors().find_map(SyntaxNode::prev_sibling), |it| { | 35 | generate(node.ancestors().find_map(SyntaxNode::prev_sibling), |it| it.last_child()).last() |
36 | it.last_child() | ||
37 | }) | ||
38 | .last() | ||
39 | } | 36 | } |
40 | 37 | ||
41 | pub fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> { | 38 | pub fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> { |
diff --git a/crates/ra_ide_api_light/src/join_lines.rs b/crates/ra_ide_api_light/src/join_lines.rs index ab7c5b4b5..03770c52e 100644 --- a/crates/ra_ide_api_light/src/join_lines.rs +++ b/crates/ra_ide_api_light/src/join_lines.rs | |||
@@ -50,11 +50,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> LocalEdit { | |||
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | LocalEdit { | 53 | LocalEdit { label: "join lines".to_string(), edit: edit.finish(), cursor_position: None } |
54 | label: "join lines".to_string(), | ||
55 | edit: edit.finish(), | ||
56 | cursor_position: None, | ||
57 | } | ||
58 | } | 54 | } |
59 | 55 | ||
60 | fn remove_newline( | 56 | fn remove_newline( |
@@ -71,10 +67,7 @@ fn remove_newline( | |||
71 | )]; | 67 | )]; |
72 | let spaces = suff.bytes().take_while(|&b| b == b' ').count(); | 68 | let spaces = suff.bytes().take_while(|&b| b == b' ').count(); |
73 | 69 | ||
74 | edit.replace( | 70 | edit.replace(TextRange::offset_len(offset, ((spaces + 1) as u32).into()), " ".to_string()); |
75 | TextRange::offset_len(offset, ((spaces + 1) as u32).into()), | ||
76 | " ".to_string(), | ||
77 | ); | ||
78 | return; | 71 | return; |
79 | } | 72 | } |
80 | 73 | ||
@@ -109,11 +102,7 @@ fn remove_newline( | |||
109 | edit.delete(TextRange::from_to(prev.range().start(), node.range().end())); | 102 | edit.delete(TextRange::from_to(prev.range().start(), node.range().end())); |
110 | } else if prev.kind() == COMMA && next.kind() == R_CURLY { | 103 | } else if prev.kind() == COMMA && next.kind() == R_CURLY { |
111 | // Removes: comma, newline (incl. surrounding whitespace) | 104 | // Removes: comma, newline (incl. surrounding whitespace) |
112 | let space = if let Some(left) = prev.prev_sibling() { | 105 | let space = if let Some(left) = prev.prev_sibling() { compute_ws(left, next) } else { " " }; |
113 | compute_ws(left, next) | ||
114 | } else { | ||
115 | " " | ||
116 | }; | ||
117 | edit.replace( | 106 | edit.replace( |
118 | TextRange::from_to(prev.range().start(), node.range().end()), | 107 | TextRange::from_to(prev.range().start(), node.range().end()), |
119 | space.to_string(), | 108 | space.to_string(), |
@@ -134,20 +123,14 @@ fn join_single_expr_block(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Opti | |||
134 | let block = ast::Block::cast(node.parent()?)?; | 123 | let block = ast::Block::cast(node.parent()?)?; |
135 | let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; | 124 | let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; |
136 | let expr = extract_trivial_expression(block)?; | 125 | let expr = extract_trivial_expression(block)?; |
137 | edit.replace( | 126 | edit.replace(block_expr.syntax().range(), expr.syntax().text().to_string()); |
138 | block_expr.syntax().range(), | ||
139 | expr.syntax().text().to_string(), | ||
140 | ); | ||
141 | Some(()) | 127 | Some(()) |
142 | } | 128 | } |
143 | 129 | ||
144 | fn join_single_use_tree(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> { | 130 | fn join_single_use_tree(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> { |
145 | let use_tree_list = ast::UseTreeList::cast(node.parent()?)?; | 131 | let use_tree_list = ast::UseTreeList::cast(node.parent()?)?; |
146 | let (tree,) = use_tree_list.use_trees().collect_tuple()?; | 132 | let (tree,) = use_tree_list.use_trees().collect_tuple()?; |
147 | edit.replace( | 133 | edit.replace(use_tree_list.syntax().range(), tree.syntax().text().to_string()); |
148 | use_tree_list.syntax().range(), | ||
149 | tree.syntax().text().to_string(), | ||
150 | ); | ||
151 | Some(()) | 134 | Some(()) |
152 | } | 135 | } |
153 | 136 | ||
diff --git a/crates/ra_ide_api_light/src/lib.rs b/crates/ra_ide_api_light/src/lib.rs index 17044270c..f3078f51e 100644 --- a/crates/ra_ide_api_light/src/lib.rs +++ b/crates/ra_ide_api_light/src/lib.rs | |||
@@ -63,9 +63,8 @@ pub struct Diagnostic { | |||
63 | } | 63 | } |
64 | 64 | ||
65 | pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { | 65 | pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { |
66 | const BRACES: &[SyntaxKind] = &[ | 66 | const BRACES: &[SyntaxKind] = |
67 | L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE, | 67 | &[L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE]; |
68 | ]; | ||
69 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset) | 68 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset) |
70 | .filter_map(|node| { | 69 | .filter_map(|node| { |
71 | let idx = BRACES.iter().position(|&brace| brace == node.kind())?; | 70 | let idx = BRACES.iter().position(|&brace| brace == node.kind())?; |
@@ -74,9 +73,7 @@ pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { | |||
74 | .next()?; | 73 | .next()?; |
75 | let parent = brace_node.parent()?; | 74 | let parent = brace_node.parent()?; |
76 | let matching_kind = BRACES[brace_idx ^ 1]; | 75 | let matching_kind = BRACES[brace_idx ^ 1]; |
77 | let matching_node = parent | 76 | let matching_node = parent.children().find(|node| node.kind() == matching_kind)?; |
78 | .children() | ||
79 | .find(|node| node.kind() == matching_kind)?; | ||
80 | Some(matching_node.range().start()) | 77 | Some(matching_node.range().start()) |
81 | } | 78 | } |
82 | 79 | ||
@@ -122,10 +119,7 @@ pub fn highlight(root: &SyntaxNode) -> Vec<HighlightedRange> { | |||
122 | continue; | 119 | continue; |
123 | } | 120 | } |
124 | }; | 121 | }; |
125 | res.push(HighlightedRange { | 122 | res.push(HighlightedRange { range: node.range(), tag }) |
126 | range: node.range(), | ||
127 | tag, | ||
128 | }) | ||
129 | } | 123 | } |
130 | res | 124 | res |
131 | } | 125 | } |
diff --git a/crates/ra_ide_api_light/src/line_index.rs b/crates/ra_ide_api_light/src/line_index.rs index 131737743..bf004c33a 100644 --- a/crates/ra_ide_api_light/src/line_index.rs +++ b/crates/ra_ide_api_light/src/line_index.rs | |||
@@ -54,10 +54,7 @@ impl LineIndex { | |||
54 | 54 | ||
55 | let char_len = TextUnit::of_char(c); | 55 | let char_len = TextUnit::of_char(c); |
56 | if char_len.to_usize() > 1 { | 56 | if char_len.to_usize() > 1 { |
57 | utf16_chars.push(Utf16Char { | 57 | utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + char_len }); |
58 | start: curr_col, | ||
59 | end: curr_col + char_len, | ||
60 | }); | ||
61 | } | 58 | } |
62 | 59 | ||
63 | curr_col += char_len; | 60 | curr_col += char_len; |
@@ -68,10 +65,7 @@ impl LineIndex { | |||
68 | utf16_lines.insert(line, utf16_chars); | 65 | utf16_lines.insert(line, utf16_chars); |
69 | } | 66 | } |
70 | 67 | ||
71 | LineIndex { | 68 | LineIndex { newlines, utf16_lines } |
72 | newlines, | ||
73 | utf16_lines, | ||
74 | } | ||
75 | } | 69 | } |