diff options
author | Seivan Heidari <[email protected]> | 2019-11-21 00:11:41 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-11-21 00:11:41 +0000 |
commit | 358a1bcd708c622836723e5201b6de77cc9ff327 (patch) | |
tree | aeff9c96a6059fa2b02e7c87ec88753bc7993d8d | |
parent | 1e2d090ab8a9bda18f148b894b7948eb05b976e6 (diff) | |
parent | 612a72fc4ea4376920f2a7da7b3c334227c1716c (diff) |
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
82 files changed, 1451 insertions, 1067 deletions
diff --git a/.cargo/config b/.cargo/config index 9a04b9462..560ab3075 100644 --- a/.cargo/config +++ b/.cargo/config | |||
@@ -2,3 +2,4 @@ | |||
2 | xtask = "run --package xtask --bin xtask --" | 2 | xtask = "run --package xtask --bin xtask --" |
3 | install-ra = "run --package xtask --bin xtask -- install" # for backwards compat | 3 | install-ra = "run --package xtask --bin xtask -- install" # for backwards compat |
4 | tq = "test -- -q" | 4 | tq = "test -- -q" |
5 | qt = "tq" | ||
@@ -58,6 +58,7 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frls-2.2E0 | |||
58 | 58 | ||
59 | * API docs: https://rust-analyzer.github.io/rust-analyzer/ra_ide_api/ | 59 | * API docs: https://rust-analyzer.github.io/rust-analyzer/ra_ide_api/ |
60 | 60 | ||
61 | |||
61 | ## License | 62 | ## License |
62 | 63 | ||
63 | Rust analyzer is primarily distributed under the terms of both the MIT | 64 | Rust analyzer is primarily distributed under the terms of both the MIT |
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs index 91af161ee..cef669cb5 100644 --- a/crates/ra_assists/src/assists/add_missing_impl_members.rs +++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs | |||
@@ -174,7 +174,7 @@ fn resolve_target_trait_def( | |||
174 | .path()?; | 174 | .path()?; |
175 | 175 | ||
176 | match analyzer.resolve_path(db, &ast_path) { | 176 | match analyzer.resolve_path(db, &ast_path) { |
177 | Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def.source(db).ast), | 177 | Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def.source(db).value), |
178 | _ => None, | 178 | _ => None, |
179 | } | 179 | } |
180 | } | 180 | } |
diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs index 2038afdc6..b5f8afb4e 100644 --- a/crates/ra_assists/src/assists/add_new.rs +++ b/crates/ra_assists/src/assists/add_new.rs | |||
@@ -141,7 +141,7 @@ fn find_struct_impl( | |||
141 | })?; | 141 | })?; |
142 | 142 | ||
143 | let struct_ty = { | 143 | let struct_ty = { |
144 | let src = hir::Source { file_id: ctx.frange.file_id.into(), ast: strukt.clone() }; | 144 | let src = hir::Source { file_id: ctx.frange.file_id.into(), value: strukt.clone() }; |
145 | hir::Struct::from_source(db, src).unwrap().ty(db) | 145 | hir::Struct::from_source(db, src).unwrap().ty(db) |
146 | }; | 146 | }; |
147 | 147 | ||
@@ -152,7 +152,7 @@ fn find_struct_impl( | |||
152 | return false; | 152 | return false; |
153 | } | 153 | } |
154 | 154 | ||
155 | let src = hir::Source { file_id: ctx.frange.file_id.into(), ast: impl_blk.clone() }; | 155 | let src = hir::Source { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() }; |
156 | let blk = hir::ImplBlock::from_source(db, src).unwrap(); | 156 | let blk = hir::ImplBlock::from_source(db, src).unwrap(); |
157 | 157 | ||
158 | let same_ty = blk.target_ty(db) == struct_ty; | 158 | let same_ty = blk.target_ty(db) == struct_ty; |
diff --git a/crates/ra_assists/src/assists/fill_match_arms.rs b/crates/ra_assists/src/assists/fill_match_arms.rs index b851c2082..9354466d9 100644 --- a/crates/ra_assists/src/assists/fill_match_arms.rs +++ b/crates/ra_assists/src/assists/fill_match_arms.rs | |||
@@ -84,7 +84,7 @@ fn resolve_enum_def( | |||
84 | let expr_ty = analyzer.type_of(db, &expr)?; | 84 | let expr_ty = analyzer.type_of(db, &expr)?; |
85 | 85 | ||
86 | analyzer.autoderef(db, expr_ty).find_map(|ty| match ty.as_adt() { | 86 | analyzer.autoderef(db, expr_ty).find_map(|ty| match ty.as_adt() { |
87 | Some((Adt::Enum(e), _)) => Some(e.source(db).ast), | 87 | Some((Adt::Enum(e), _)) => Some(e.source(db).value), |
88 | _ => None, | 88 | _ => None, |
89 | }) | 89 | }) |
90 | } | 90 | } |
diff --git a/crates/ra_assists/src/assists/replace_if_let_with_match.rs b/crates/ra_assists/src/assists/replace_if_let_with_match.rs index dff84d865..3272801ff 100644 --- a/crates/ra_assists/src/assists/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/assists/replace_if_let_with_match.rs | |||
@@ -66,8 +66,8 @@ fn build_match_expr( | |||
66 | 66 | ||
67 | fn format_arm(block: &ast::BlockExpr) -> String { | 67 | fn format_arm(block: &ast::BlockExpr) -> String { |
68 | match extract_trivial_expression(block) { | 68 | match extract_trivial_expression(block) { |
69 | None => block.syntax().text().to_string(), | 69 | Some(e) if !e.syntax().text().contains_char('\n') => format!("{},", e.syntax().text()), |
70 | Some(e) => format!("{},", e.syntax().text()), | 70 | _ => block.syntax().text().to_string(), |
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
@@ -103,6 +103,34 @@ impl VariantData { | |||
103 | } | 103 | } |
104 | 104 | ||
105 | #[test] | 105 | #[test] |
106 | fn test_replace_if_let_with_match_doesnt_unwrap_multiline_expressions() { | ||
107 | check_assist( | ||
108 | replace_if_let_with_match, | ||
109 | " | ||
110 | fn foo() { | ||
111 | if <|>let VariantData::Struct(..) = a { | ||
112 | bar( | ||
113 | 123 | ||
114 | ) | ||
115 | } else { | ||
116 | false | ||
117 | } | ||
118 | } ", | ||
119 | " | ||
120 | fn foo() { | ||
121 | <|>match a { | ||
122 | VariantData::Struct(..) => { | ||
123 | bar( | ||
124 | 123 | ||
125 | ) | ||
126 | } | ||
127 | _ => false, | ||
128 | } | ||
129 | } ", | ||
130 | ) | ||
131 | } | ||
132 | |||
133 | #[test] | ||
106 | fn replace_if_let_with_match_target() { | 134 | fn replace_if_let_with_match_target() { |
107 | check_assist_target( | 135 | check_assist_target( |
108 | replace_if_let_with_match, | 136 | replace_if_let_with_match, |
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 3429a3c49..9cd21e4b6 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -98,7 +98,7 @@ pub fn run( | |||
98 | let src = f.source(db); | 98 | let src = f.source(db); |
99 | let original_file = src.file_id.original_file(db); | 99 | let original_file = src.file_id.original_file(db); |
100 | let path = db.file_relative_path(original_file); | 100 | let path = db.file_relative_path(original_file); |
101 | let syntax_range = src.ast.syntax().text_range(); | 101 | let syntax_range = src.value.syntax().text_range(); |
102 | write!(msg, " ({:?} {})", path, syntax_range).unwrap(); | 102 | write!(msg, " ({:?} {})", path, syntax_range).unwrap(); |
103 | } | 103 | } |
104 | bar.set_message(&msg); | 104 | bar.set_message(&msg); |
@@ -135,7 +135,7 @@ pub fn run( | |||
135 | let path = db.file_relative_path(original_file); | 135 | let path = db.file_relative_path(original_file); |
136 | let line_index = host.analysis().file_line_index(original_file).unwrap(); | 136 | let line_index = host.analysis().file_line_index(original_file).unwrap(); |
137 | let text_range = src | 137 | let text_range = src |
138 | .ast | 138 | .value |
139 | .either(|it| it.syntax().text_range(), |it| it.syntax().text_range()); | 139 | .either(|it| it.syntax().text_range(), |it| it.syntax().text_range()); |
140 | let (start, end) = ( | 140 | let (start, end) = ( |
141 | line_index.line_col(text_range.start()), | 141 | line_index.line_col(text_range.start()), |
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs index a30ed4cbb..10f592257 100644 --- a/crates/ra_fmt/src/lib.rs +++ b/crates/ra_fmt/src/lib.rs | |||
@@ -38,9 +38,6 @@ fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { | |||
38 | pub fn extract_trivial_expression(expr: &ast::BlockExpr) -> Option<ast::Expr> { | 38 | pub fn extract_trivial_expression(expr: &ast::BlockExpr) -> Option<ast::Expr> { |
39 | let block = expr.block()?; | 39 | let block = expr.block()?; |
40 | let expr = block.expr()?; | 40 | let expr = block.expr()?; |
41 | if expr.syntax().text().contains_char('\n') { | ||
42 | return None; | ||
43 | } | ||
44 | let non_trivial_children = block.syntax().children().filter(|it| match it.kind() { | 41 | let non_trivial_children = block.syntax().children().filter(|it| match it.kind() { |
45 | WHITESPACE | T!['{'] | T!['}'] => false, | 42 | WHITESPACE | T!['{'] | T!['}'] => false, |
46 | _ => it != expr.syntax(), | 43 | _ => it != expr.syntax(), |
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs deleted file mode 100644 index 945f236c2..000000000 --- a/crates/ra_hir/src/adt.rs +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | //! This module contains the implementation details of the HIR for ADTs, i.e. | ||
2 | //! structs and enums (and unions). | ||
3 | |||
4 | use std::sync::Arc; | ||
5 | |||
6 | use hir_def::adt::VariantData; | ||
7 | |||
8 | use crate::{ | ||
9 | db::{DefDatabase, HirDatabase}, | ||
10 | EnumVariant, Module, Name, Struct, StructField, | ||
11 | }; | ||
12 | |||
13 | impl Struct { | ||
14 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | ||
15 | db.struct_data(self.id.into()).variant_data.clone() | ||
16 | } | ||
17 | } | ||
18 | |||
19 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
20 | pub enum VariantDef { | ||
21 | Struct(Struct), | ||
22 | EnumVariant(EnumVariant), | ||
23 | } | ||
24 | impl_froms!(VariantDef: Struct, EnumVariant); | ||
25 | |||
26 | impl VariantDef { | ||
27 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | ||
28 | match self { | ||
29 | VariantDef::Struct(it) => it.fields(db), | ||
30 | VariantDef::EnumVariant(it) => it.fields(db), | ||
31 | } | ||
32 | } | ||
33 | |||
34 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
35 | match self { | ||
36 | VariantDef::Struct(it) => it.field(db, name), | ||
37 | VariantDef::EnumVariant(it) => it.field(db, name), | ||
38 | } | ||
39 | } | ||
40 | |||
41 | pub fn module(self, db: &impl HirDatabase) -> Module { | ||
42 | match self { | ||
43 | VariantDef::Struct(it) => it.module(db), | ||
44 | VariantDef::EnumVariant(it) => it.module(db), | ||
45 | } | ||
46 | } | ||
47 | |||
48 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | ||
49 | match self { | ||
50 | VariantDef::Struct(it) => it.variant_data(db), | ||
51 | VariantDef::EnumVariant(it) => it.variant_data(db), | ||
52 | } | ||
53 | } | ||
54 | } | ||
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 731cc1fff..a132d128b 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -10,8 +10,10 @@ use hir_def::{ | |||
10 | adt::VariantData, | 10 | adt::VariantData, |
11 | body::scope::ExprScopes, | 11 | body::scope::ExprScopes, |
12 | builtin_type::BuiltinType, | 12 | builtin_type::BuiltinType, |
13 | traits::TraitData, | ||
13 | type_ref::{Mutability, TypeRef}, | 14 | type_ref::{Mutability, TypeRef}, |
14 | CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, | 15 | AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, |
16 | LocalStructFieldId, Lookup, ModuleId, UnionId, | ||
15 | }; | 17 | }; |
16 | use hir_expand::{ | 18 | use hir_expand::{ |
17 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
@@ -21,7 +23,6 @@ use ra_db::{CrateId, Edition}; | |||
21 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | 23 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; |
22 | 24 | ||
23 | use crate::{ | 25 | use crate::{ |
24 | adt::VariantDef, | ||
25 | db::{AstDatabase, DefDatabase, HirDatabase}, | 26 | db::{AstDatabase, DefDatabase, HirDatabase}, |
26 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, | 27 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, |
27 | generics::{GenericDef, HasGenericParams}, | 28 | generics::{GenericDef, HasGenericParams}, |
@@ -29,8 +30,7 @@ use crate::{ | |||
29 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, | 30 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, |
30 | TypeAliasId, | 31 | TypeAliasId, |
31 | }, | 32 | }, |
32 | resolve::{Resolver, Scope, TypeNs}, | 33 | resolve::{HasResolver, TypeNs}, |
33 | traits::TraitData, | ||
34 | ty::{InferenceResult, Namespace, TraitRef}, | 34 | ty::{InferenceResult, Namespace, TraitRef}, |
35 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, | 35 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, |
36 | }; | 36 | }; |
@@ -139,7 +139,7 @@ impl Module { | |||
139 | ) -> Either<ast::UseTree, ast::ExternCrateItem> { | 139 | ) -> Either<ast::UseTree, ast::ExternCrateItem> { |
140 | let src = self.definition_source(db); | 140 | let src = self.definition_source(db); |
141 | let (_, source_map) = db.raw_items_with_source_map(src.file_id); | 141 | let (_, source_map) = db.raw_items_with_source_map(src.file_id); |
142 | source_map.get(&src.ast, import) | 142 | source_map.get(&src.value, import) |
143 | } | 143 | } |
144 | 144 | ||
145 | /// Returns the crate this module is part of. | 145 | /// Returns the crate this module is part of. |
@@ -206,7 +206,7 @@ impl Module { | |||
206 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), | 206 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), |
207 | crate::ModuleDef::Module(m) => { | 207 | crate::ModuleDef::Module(m) => { |
208 | // Only add diagnostics from inline modules | 208 | // Only add diagnostics from inline modules |
209 | if let ModuleSource::Module(_) = m.definition_source(db).ast { | 209 | if let ModuleSource::Module(_) = m.definition_source(db).value { |
210 | m.diagnostics(db, sink) | 210 | m.diagnostics(db, sink) |
211 | } | 211 | } |
212 | } | 212 | } |
@@ -223,22 +223,9 @@ impl Module { | |||
223 | } | 223 | } |
224 | } | 224 | } |
225 | 225 | ||
226 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
227 | let def_map = db.crate_def_map(self.id.krate); | ||
228 | Resolver::default().push_module_scope(def_map, self.id.module_id) | ||
229 | } | ||
230 | |||
231 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { | 226 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { |
232 | let def_map = db.crate_def_map(self.id.krate); | 227 | let def_map = db.crate_def_map(self.id.krate); |
233 | def_map[self.id.module_id] | 228 | def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect() |
234 | .scope | ||
235 | .entries() | ||
236 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) | ||
237 | .flat_map(|per_ns| { | ||
238 | per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) | ||
239 | }) | ||
240 | .map(ModuleDef::from) | ||
241 | .collect() | ||
242 | } | 229 | } |
243 | 230 | ||
244 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { | 231 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { |
@@ -323,15 +310,8 @@ impl Struct { | |||
323 | db.type_for_def(self.into(), Namespace::Values) | 310 | db.type_for_def(self.into(), Namespace::Values) |
324 | } | 311 | } |
325 | 312 | ||
326 | // FIXME move to a more general type | 313 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
327 | /// Builds a resolver for type references inside this struct. | 314 | db.struct_data(self.id.into()).variant_data.clone() |
328 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | ||
329 | // take the outer scope... | ||
330 | let r = self.module(db).resolver(db); | ||
331 | // ...and add generic params, if present | ||
332 | let p = self.generic_params(db); | ||
333 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | ||
334 | r | ||
335 | } | 315 | } |
336 | } | 316 | } |
337 | 317 | ||
@@ -345,24 +325,13 @@ impl Union { | |||
345 | db.struct_data(self.id.into()).name.clone() | 325 | db.struct_data(self.id.into()).name.clone() |
346 | } | 326 | } |
347 | 327 | ||
348 | pub fn module(self, db: &impl HirDatabase) -> Module { | 328 | pub fn module(self, db: &impl DefDatabase) -> Module { |
349 | Module { id: self.id.0.module(db) } | 329 | Module { id: self.id.0.module(db) } |
350 | } | 330 | } |
351 | 331 | ||
352 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 332 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
353 | db.type_for_def(self.into(), Namespace::Types) | 333 | db.type_for_def(self.into(), Namespace::Types) |
354 | } | 334 | } |
355 | |||
356 | // FIXME move to a more general type | ||
357 | /// Builds a resolver for type references inside this union. | ||
358 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | ||
359 | // take the outer scope... | ||
360 | let r = self.module(db).resolver(db); | ||
361 | // ...and add generic params, if present | ||
362 | let p = self.generic_params(db); | ||
363 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | ||
364 | r | ||
365 | } | ||
366 | } | 335 | } |
367 | 336 | ||
368 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 337 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -402,17 +371,6 @@ impl Enum { | |||
402 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 371 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
403 | db.type_for_def(self.into(), Namespace::Types) | 372 | db.type_for_def(self.into(), Namespace::Types) |
404 | } | 373 | } |
405 | |||
406 | // FIXME: move to a more general type | ||
407 | /// Builds a resolver for type references inside this struct. | ||
408 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | ||
409 | // take the outer scope... | ||
410 | let r = self.module(db).resolver(db); | ||
411 | // ...and add generic params, if present | ||
412 | let p = self.generic_params(db); | ||
413 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | ||
414 | r.push_scope(Scope::AdtScope(self.into())) | ||
415 | } | ||
416 | } | 374 | } |
417 | 375 | ||
418 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 376 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -474,22 +432,52 @@ impl Adt { | |||
474 | } | 432 | } |
475 | } | 433 | } |
476 | 434 | ||
435 | pub fn module(self, db: &impl DefDatabase) -> Module { | ||
436 | match self { | ||
437 | Adt::Struct(s) => s.module(db), | ||
438 | Adt::Union(s) => s.module(db), | ||
439 | Adt::Enum(e) => e.module(db), | ||
440 | } | ||
441 | } | ||
442 | |||
477 | pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> { | 443 | pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> { |
478 | Some( | 444 | Some(self.module(db).krate()) |
479 | match self { | 445 | } |
480 | Adt::Struct(s) => s.module(db), | 446 | } |
481 | Adt::Union(s) => s.module(db), | 447 | |
482 | Adt::Enum(e) => e.module(db), | 448 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
483 | } | 449 | pub enum VariantDef { |
484 | .krate(), | 450 | Struct(Struct), |
485 | ) | 451 | EnumVariant(EnumVariant), |
452 | } | ||
453 | impl_froms!(VariantDef: Struct, EnumVariant); | ||
454 | |||
455 | impl VariantDef { | ||
456 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | ||
457 | match self { | ||
458 | VariantDef::Struct(it) => it.fields(db), | ||
459 | VariantDef::EnumVariant(it) => it.fields(db), | ||
460 | } | ||
461 | } | ||
462 | |||
463 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
464 | match self { | ||
465 | VariantDef::Struct(it) => it.field(db, name), | ||
466 | VariantDef::EnumVariant(it) => it.field(db, name), | ||
467 | } | ||
468 | } | ||
469 | |||
470 | pub fn module(self, db: &impl HirDatabase) -> Module { | ||
471 | match self { | ||
472 | VariantDef::Struct(it) => it.module(db), | ||
473 | VariantDef::EnumVariant(it) => it.module(db), | ||
474 | } | ||
486 | } | 475 | } |
487 | 476 | ||
488 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | 477 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
489 | match self { | 478 | match self { |
490 | Adt::Struct(it) => it.resolver(db), | 479 | VariantDef::Struct(it) => it.variant_data(db), |
491 | Adt::Union(it) => it.resolver(db), | 480 | VariantDef::EnumVariant(it) => it.variant_data(db), |
492 | Adt::Enum(it) => it.resolver(db), | ||
493 | } | 481 | } |
494 | } | 482 | } |
495 | } | 483 | } |
@@ -505,15 +493,6 @@ pub enum DefWithBody { | |||
505 | impl_froms!(DefWithBody: Function, Const, Static); | 493 | impl_froms!(DefWithBody: Function, Const, Static); |
506 | 494 | ||
507 | impl DefWithBody { | 495 | impl DefWithBody { |
508 | /// Builds a resolver for code inside this item. | ||
509 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | ||
510 | match self { | ||
511 | DefWithBody::Const(c) => c.resolver(db), | ||
512 | DefWithBody::Function(f) => f.resolver(db), | ||
513 | DefWithBody::Static(s) => s.resolver(db), | ||
514 | } | ||
515 | } | ||
516 | |||
517 | pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> { | 496 | pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> { |
518 | match self { | 497 | match self { |
519 | DefWithBody::Const(c) => c.krate(db), | 498 | DefWithBody::Const(c) => c.krate(db), |
@@ -598,10 +577,10 @@ impl FnData { | |||
598 | func: Function, | 577 | func: Function, |
599 | ) -> Arc<FnData> { | 578 | ) -> Arc<FnData> { |
600 | let src = func.source(db); | 579 | let src = func.source(db); |
601 | let name = src.ast.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); | 580 | let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); |
602 | let mut params = Vec::new(); | 581 | let mut params = Vec::new(); |
603 | let mut has_self_param = false; | 582 | let mut has_self_param = false; |
604 | if let Some(param_list) = src.ast.param_list() { | 583 | if let Some(param_list) = src.value.param_list() { |
605 | if let Some(self_param) = param_list.self_param() { | 584 | if let Some(self_param) = param_list.self_param() { |
606 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { | 585 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { |
607 | TypeRef::from_ast(type_ref) | 586 | TypeRef::from_ast(type_ref) |
@@ -625,7 +604,7 @@ impl FnData { | |||
625 | params.push(type_ref); | 604 | params.push(type_ref); |
626 | } | 605 | } |
627 | } | 606 | } |
628 | let ret_type = if let Some(type_ref) = src.ast.ret_type().and_then(|rt| rt.type_ref()) { | 607 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { |
629 | TypeRef::from_ast(type_ref) | 608 | TypeRef::from_ast(type_ref) |
630 | } else { | 609 | } else { |
631 | TypeRef::unit() | 610 | TypeRef::unit() |
@@ -655,7 +634,7 @@ impl FnData { | |||
655 | 634 | ||
656 | impl Function { | 635 | impl Function { |
657 | pub fn module(self, db: &impl DefDatabase) -> Module { | 636 | pub fn module(self, db: &impl DefDatabase) -> Module { |
658 | Module { id: self.id.module(db) } | 637 | self.id.lookup(db).module(db).into() |
659 | } | 638 | } |
660 | 639 | ||
661 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 640 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -688,35 +667,28 @@ impl Function { | |||
688 | 667 | ||
689 | /// The containing impl block, if this is a method. | 668 | /// The containing impl block, if this is a method. |
690 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | 669 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { |
691 | ImplBlock::containing(db, self.into()) | 670 | match self.container(db) { |
671 | Some(Container::ImplBlock(it)) => Some(it), | ||
672 | _ => None, | ||
673 | } | ||
692 | } | 674 | } |
693 | 675 | ||
694 | /// The containing trait, if this is a trait method definition. | 676 | /// The containing trait, if this is a trait method definition. |
695 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 677 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
696 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 678 | match self.container(db) { |
679 | Some(Container::Trait(it)) => Some(it), | ||
680 | _ => None, | ||
681 | } | ||
697 | } | 682 | } |
698 | 683 | ||
699 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 684 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
700 | if let Some(impl_block) = self.impl_block(db) { | 685 | match self.id.lookup(db).container { |
701 | Some(impl_block.into()) | 686 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), |
702 | } else if let Some(trait_) = self.parent_trait(db) { | 687 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), |
703 | Some(trait_.into()) | 688 | ContainerId::ModuleId(_) => None, |
704 | } else { | ||
705 | None | ||
706 | } | 689 | } |
707 | } | 690 | } |
708 | 691 | ||
709 | // FIXME: move to a more general type for 'body-having' items | ||
710 | /// Builds a resolver for code inside this item. | ||
711 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | ||
712 | // take the outer scope... | ||
713 | let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); | ||
714 | // ...and add generic params, if present | ||
715 | let p = self.generic_params(db); | ||
716 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | ||
717 | r | ||
718 | } | ||
719 | |||
720 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 692 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
721 | let infer = self.infer(db); | 693 | let infer = self.infer(db); |
722 | infer.add_diagnostics(db, self, sink); | 694 | infer.add_diagnostics(db, self, sink); |
@@ -732,7 +704,7 @@ pub struct Const { | |||
732 | 704 | ||
733 | impl Const { | 705 | impl Const { |
734 | pub fn module(self, db: &impl DefDatabase) -> Module { | 706 | pub fn module(self, db: &impl DefDatabase) -> Module { |
735 | Module { id: self.id.module(db) } | 707 | Module { id: self.id.lookup(db).module(db) } |
736 | } | 708 | } |
737 | 709 | ||
738 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 710 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -751,35 +723,29 @@ impl Const { | |||
751 | db.infer(self.into()) | 723 | db.infer(self.into()) |
752 | } | 724 | } |
753 | 725 | ||
754 | /// The containing impl block, if this is a method. | 726 | /// The containing impl block, if this is a type alias. |
755 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | 727 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { |
756 | ImplBlock::containing(db, self.into()) | 728 | match self.container(db) { |
729 | Some(Container::ImplBlock(it)) => Some(it), | ||
730 | _ => None, | ||
731 | } | ||
757 | } | 732 | } |
758 | 733 | ||
734 | /// The containing trait, if this is a trait type alias definition. | ||
759 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 735 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
760 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 736 | match self.container(db) { |
737 | Some(Container::Trait(it)) => Some(it), | ||
738 | _ => None, | ||
739 | } | ||
761 | } | 740 | } |
762 | 741 | ||
763 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 742 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
764 | if let Some(impl_block) = self.impl_block(db) { | 743 | match self.id.lookup(db).container { |
765 | Some(impl_block.into()) | 744 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), |
766 | } else if let Some(trait_) = self.parent_trait(db) { | 745 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), |
767 | Some(trait_.into()) | 746 | ContainerId::ModuleId(_) => None, |
768 | } else { | ||
769 | None | ||
770 | } | 747 | } |
771 | } | 748 | } |
772 | |||
773 | // FIXME: move to a more general type for 'body-having' items | ||
774 | /// Builds a resolver for code inside this item. | ||
775 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | ||
776 | // take the outer scope... | ||
777 | let r = self | ||
778 | .impl_block(db) | ||
779 | .map(|ib| ib.resolver(db)) | ||
780 | .unwrap_or_else(|| self.module(db).resolver(db)); | ||
781 | r | ||
782 | } | ||
783 | } | 749 | } |
784 | 750 | ||
785 | #[derive(Debug, Clone, PartialEq, Eq)] | 751 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -801,7 +767,7 @@ impl ConstData { | |||
801 | db: &(impl DefDatabase + AstDatabase), | 767 | db: &(impl DefDatabase + AstDatabase), |
802 | konst: Const, | 768 | konst: Const, |
803 | ) -> Arc<ConstData> { | 769 | ) -> Arc<ConstData> { |
804 | let node = konst.source(db).ast; | 770 | let node = konst.source(db).value; |
805 | const_data_for(&node) | 771 | const_data_for(&node) |
806 | } | 772 | } |
807 | 773 | ||
@@ -809,7 +775,7 @@ impl ConstData { | |||
809 | db: &(impl DefDatabase + AstDatabase), | 775 | db: &(impl DefDatabase + AstDatabase), |
810 | konst: Static, | 776 | konst: Static, |
811 | ) -> Arc<ConstData> { | 777 | ) -> Arc<ConstData> { |
812 | let node = konst.source(db).ast; | 778 | let node = konst.source(db).value; |
813 | const_data_for(&node) | 779 | const_data_for(&node) |
814 | } | 780 | } |
815 | } | 781 | } |
@@ -839,12 +805,6 @@ impl Static { | |||
839 | db.static_data(self) | 805 | db.static_data(self) |
840 | } | 806 | } |
841 | 807 | ||
842 | /// Builds a resolver for code inside this item. | ||
843 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | ||
844 | // take the outer scope... | ||
845 | self.module(db).resolver(db) | ||
846 | } | ||
847 | |||
848 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 808 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
849 | db.infer(self.into()) | 809 | db.infer(self.into()) |
850 | } | 810 | } |
@@ -861,11 +821,11 @@ impl Trait { | |||
861 | } | 821 | } |
862 | 822 | ||
863 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 823 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
864 | self.trait_data(db).name().clone() | 824 | self.trait_data(db).name.clone() |
865 | } | 825 | } |
866 | 826 | ||
867 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { | 827 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { |
868 | self.trait_data(db).items().to_vec() | 828 | self.trait_data(db).items.iter().map(|it| (*it).into()).collect() |
869 | } | 829 | } |
870 | 830 | ||
871 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | 831 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { |
@@ -912,10 +872,10 @@ impl Trait { | |||
912 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { | 872 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { |
913 | let trait_data = self.trait_data(db); | 873 | let trait_data = self.trait_data(db); |
914 | trait_data | 874 | trait_data |
915 | .items() | 875 | .items |
916 | .iter() | 876 | .iter() |
917 | .filter_map(|item| match item { | 877 | .filter_map(|item| match item { |
918 | AssocItem::TypeAlias(t) => Some(*t), | 878 | AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)), |
919 | _ => None, | 879 | _ => None, |
920 | }) | 880 | }) |
921 | .find(|t| &t.name(db) == name) | 881 | .find(|t| &t.name(db) == name) |
@@ -930,7 +890,7 @@ impl Trait { | |||
930 | } | 890 | } |
931 | 891 | ||
932 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { | 892 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { |
933 | db.trait_data(self) | 893 | db.trait_data(self.id) |
934 | } | 894 | } |
935 | 895 | ||
936 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { | 896 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { |
@@ -938,15 +898,7 @@ impl Trait { | |||
938 | } | 898 | } |
939 | 899 | ||
940 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { | 900 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { |
941 | self.trait_data(db).is_auto() | 901 | self.trait_data(db).auto |
942 | } | ||
943 | |||
944 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
945 | let r = self.module(db).resolver(db); | ||
946 | // add generic params, if present | ||
947 | let p = self.generic_params(db); | ||
948 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | ||
949 | r | ||
950 | } | 902 | } |
951 | } | 903 | } |
952 | 904 | ||
@@ -957,30 +909,34 @@ pub struct TypeAlias { | |||
957 | 909 | ||
958 | impl TypeAlias { | 910 | impl TypeAlias { |
959 | pub fn module(self, db: &impl DefDatabase) -> Module { | 911 | pub fn module(self, db: &impl DefDatabase) -> Module { |
960 | Module { id: self.id.module(db) } | 912 | Module { id: self.id.lookup(db).module(db) } |
961 | } | 913 | } |
962 | 914 | ||
963 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 915 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
964 | Some(self.module(db).krate()) | 916 | Some(self.module(db).krate()) |
965 | } | 917 | } |
966 | 918 | ||
967 | /// The containing impl block, if this is a method. | 919 | /// The containing impl block, if this is a type alias. |
968 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | 920 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { |
969 | ImplBlock::containing(db, self.into()) | 921 | match self.container(db) { |
922 | Some(Container::ImplBlock(it)) => Some(it), | ||
923 | _ => None, | ||
924 | } | ||
970 | } | 925 | } |
971 | 926 | ||
972 | /// The containing trait, if this is a trait method definition. | 927 | /// The containing trait, if this is a trait type alias definition. |
973 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 928 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
974 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 929 | match self.container(db) { |
930 | Some(Container::Trait(it)) => Some(it), | ||
931 | _ => None, | ||
932 | } | ||
975 | } | 933 | } |
976 | 934 | ||
977 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 935 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
978 | if let Some(impl_block) = self.impl_block(db) { | 936 | match self.id.lookup(db).container { |
979 | Some(impl_block.into()) | 937 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), |
980 | } else if let Some(trait_) = self.parent_trait(db) { | 938 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), |
981 | Some(trait_.into()) | 939 | ContainerId::ModuleId(_) => None, |
982 | } else { | ||
983 | None | ||
984 | } | 940 | } |
985 | } | 941 | } |
986 | 942 | ||
@@ -995,19 +951,6 @@ impl TypeAlias { | |||
995 | pub fn name(self, db: &impl DefDatabase) -> Name { | 951 | pub fn name(self, db: &impl DefDatabase) -> Name { |
996 | db.type_alias_data(self).name.clone() | 952 | db.type_alias_data(self).name.clone() |
997 | } | 953 | } |
998 | |||
999 | /// Builds a resolver for the type references in this type alias. | ||
1000 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | ||
1001 | // take the outer scope... | ||
1002 | let r = self | ||
1003 | .impl_block(db) | ||
1004 | .map(|ib| ib.resolver(db)) | ||
1005 | .unwrap_or_else(|| self.module(db).resolver(db)); | ||
1006 | // ...and add generic params, if present | ||
1007 | let p = self.generic_params(db); | ||
1008 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | ||
1009 | r | ||
1010 | } | ||
1011 | } | 954 | } |
1012 | 955 | ||
1013 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 956 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -1023,15 +966,6 @@ pub enum Container { | |||
1023 | } | 966 | } |
1024 | impl_froms!(Container: Trait, ImplBlock); | 967 | impl_froms!(Container: Trait, ImplBlock); |
1025 | 968 | ||
1026 | impl Container { | ||
1027 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
1028 | match self { | ||
1029 | Container::Trait(trait_) => trait_.resolver(db), | ||
1030 | Container::ImplBlock(impl_block) => impl_block.resolver(db), | ||
1031 | } | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 969 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
1036 | pub enum AssocItem { | 970 | pub enum AssocItem { |
1037 | Function(Function), | 971 | Function(Function), |
diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs index f7db36b66..9e304217c 100644 --- a/crates/ra_hir/src/code_model/attrs.rs +++ b/crates/ra_hir/src/code_model/attrs.rs | |||
@@ -49,9 +49,9 @@ pub(crate) fn attributes_query( | |||
49 | AttrDef::Module(it) => { | 49 | AttrDef::Module(it) => { |
50 | let src = it.declaration_source(db)?; | 50 | let src = it.declaration_source(db)?; |
51 | let hygiene = Hygiene::new(db, src.file_id); | 51 | let hygiene = Hygiene::new(db, src.file_id); |
52 | Attr::from_attrs_owner(&src.ast, &hygiene) | 52 | Attr::from_attrs_owner(&src.value, &hygiene) |
53 | } | 53 | } |
54 | AttrDef::StructField(it) => match it.source(db).ast { | 54 | AttrDef::StructField(it) => match it.source(db).value { |
55 | FieldSource::Named(named) => { | 55 | FieldSource::Named(named) => { |
56 | let src = it.source(db); | 56 | let src = it.source(db); |
57 | let hygiene = Hygiene::new(db, src.file_id); | 57 | let hygiene = Hygiene::new(db, src.file_id); |
@@ -82,7 +82,7 @@ where | |||
82 | { | 82 | { |
83 | let src = node.source(db); | 83 | let src = node.source(db); |
84 | let hygiene = Hygiene::new(db, src.file_id); | 84 | let hygiene = Hygiene::new(db, src.file_id); |
85 | Attr::from_attrs_owner(&src.ast, &hygiene) | 85 | Attr::from_attrs_owner(&src.value, &hygiene) |
86 | } | 86 | } |
87 | 87 | ||
88 | impl<T: Into<AttrDef> + Copy> Attrs for T { | 88 | impl<T: Into<AttrDef> + Copy> Attrs for T { |
diff --git a/crates/ra_hir/src/code_model/docs.rs b/crates/ra_hir/src/code_model/docs.rs index 8533b4f5e..e40efef34 100644 --- a/crates/ra_hir/src/code_model/docs.rs +++ b/crates/ra_hir/src/code_model/docs.rs | |||
@@ -70,23 +70,23 @@ pub(crate) fn documentation_query( | |||
70 | def: DocDef, | 70 | def: DocDef, |
71 | ) -> Option<Documentation> { | 71 | ) -> Option<Documentation> { |
72 | match def { | 72 | match def { |
73 | DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.ast), | 73 | DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.value), |
74 | DocDef::StructField(it) => match it.source(db).ast { | 74 | DocDef::StructField(it) => match it.source(db).value { |
75 | FieldSource::Named(named) => docs_from_ast(&named), | 75 | FieldSource::Named(named) => docs_from_ast(&named), |
76 | FieldSource::Pos(..) => None, | 76 | FieldSource::Pos(..) => None, |
77 | }, | 77 | }, |
78 | DocDef::Adt(it) => match it { | 78 | DocDef::Adt(it) => match it { |
79 | Adt::Struct(it) => docs_from_ast(&it.source(db).ast), | 79 | Adt::Struct(it) => docs_from_ast(&it.source(db).value), |
80 | Adt::Enum(it) => docs_from_ast(&it.source(db).ast), | 80 | Adt::Enum(it) => docs_from_ast(&it.source(db).value), |
81 | Adt::Union(it) => docs_from_ast(&it.source(db).ast), | 81 | Adt::Union(it) => docs_from_ast(&it.source(db).value), |
82 | }, | 82 | }, |
83 | DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).ast), | 83 | DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).value), |
84 | DocDef::Static(it) => docs_from_ast(&it.source(db).ast), | 84 | DocDef::Static(it) => docs_from_ast(&it.source(db).value), |
85 | DocDef::Const(it) => docs_from_ast(&it.source(db).ast), | 85 | DocDef::Const(it) => docs_from_ast(&it.source(db).value), |
86 | DocDef::Function(it) => docs_from_ast(&it.source(db).ast), | 86 | DocDef::Function(it) => docs_from_ast(&it.source(db).value), |
87 | DocDef::Trait(it) => docs_from_ast(&it.source(db).ast), | 87 | DocDef::Trait(it) => docs_from_ast(&it.source(db).value), |
88 | DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).ast), | 88 | DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).value), |
89 | DocDef::MacroDef(it) => docs_from_ast(&it.source(db).ast), | 89 | DocDef::MacroDef(it) => docs_from_ast(&it.source(db).value), |
90 | } | 90 | } |
91 | } | 91 | } |
92 | 92 | ||
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 247ae3e55..4aa427de4 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,13 +1,13 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{HasSource as _, Lookup}; | ||
3 | use ra_syntax::ast::{self, AstNode}; | 4 | use ra_syntax::ast::{self, AstNode}; |
4 | 5 | ||
5 | use crate::{ | 6 | use crate::{ |
6 | adt::VariantDef, | ||
7 | db::{AstDatabase, DefDatabase, HirDatabase}, | 7 | db::{AstDatabase, DefDatabase, HirDatabase}, |
8 | ids::AstItemDef, | 8 | ids::AstItemDef, |
9 | Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module, | 9 | Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module, |
10 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, | 10 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | pub use hir_expand::Source; | 13 | pub use hir_expand::Source; |
@@ -25,9 +25,9 @@ impl Module { | |||
25 | let def_map = db.crate_def_map(self.id.krate); | 25 | let def_map = db.crate_def_map(self.id.krate); |
26 | let decl_id = def_map[self.id.module_id].declaration; | 26 | let decl_id = def_map[self.id.module_id].declaration; |
27 | let file_id = def_map[self.id.module_id].definition; | 27 | let file_id = def_map[self.id.module_id].definition; |
28 | let ast = ModuleSource::new(db, file_id, decl_id); | 28 | let value = ModuleSource::new(db, file_id, decl_id); |
29 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); | 29 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); |
30 | Source { file_id, ast } | 30 | Source { file_id, value } |
31 | } | 31 | } |
32 | 32 | ||
33 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | 33 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. |
@@ -38,8 +38,8 @@ impl Module { | |||
38 | ) -> Option<Source<ast::Module>> { | 38 | ) -> Option<Source<ast::Module>> { |
39 | let def_map = db.crate_def_map(self.id.krate); | 39 | let def_map = db.crate_def_map(self.id.krate); |
40 | let decl = def_map[self.id.module_id].declaration?; | 40 | let decl = def_map[self.id.module_id].declaration?; |
41 | let ast = decl.to_node(db); | 41 | let value = decl.to_node(db); |
42 | Some(Source { file_id: decl.file_id(), ast }) | 42 | Some(Source { file_id: decl.file_id(), value }) |
43 | } | 43 | } |
44 | } | 44 | } |
45 | 45 | ||
@@ -53,11 +53,11 @@ impl HasSource for StructField { | |||
53 | let (file_id, struct_kind) = match self.parent { | 53 | let (file_id, struct_kind) = match self.parent { |
54 | VariantDef::Struct(s) => { | 54 | VariantDef::Struct(s) => { |
55 | ss = s.source(db); | 55 | ss = s.source(db); |
56 | (ss.file_id, ss.ast.kind()) | 56 | (ss.file_id, ss.value.kind()) |
57 | } | 57 | } |
58 | VariantDef::EnumVariant(e) => { | 58 | VariantDef::EnumVariant(e) => { |
59 | es = e.source(db); | 59 | es = e.source(db); |
60 | (es.file_id, es.ast.kind()) | 60 | (es.file_id, es.value.kind()) |
61 | } | 61 | } |
62 | }; | 62 | }; |
63 | 63 | ||
@@ -66,13 +66,13 @@ impl HasSource for StructField { | |||
66 | ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(), | 66 | ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(), |
67 | ast::StructKind::Unit => Vec::new(), | 67 | ast::StructKind::Unit => Vec::new(), |
68 | }; | 68 | }; |
69 | let ast = field_sources | 69 | let value = field_sources |
70 | .into_iter() | 70 | .into_iter() |
71 | .zip(fields.iter()) | 71 | .zip(fields.iter()) |
72 | .find(|(_syntax, (id, _))| *id == self.id) | 72 | .find(|(_syntax, (id, _))| *id == self.id) |
73 | .unwrap() | 73 | .unwrap() |
74 | .0; | 74 | .0; |
75 | Source { file_id, ast } | 75 | Source { file_id, value } |
76 | } | 76 | } |
77 | } | 77 | } |
78 | impl HasSource for Struct { | 78 | impl HasSource for Struct { |
@@ -98,8 +98,8 @@ impl HasSource for EnumVariant { | |||
98 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> { | 98 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> { |
99 | let enum_data = db.enum_data(self.parent.id); | 99 | let enum_data = db.enum_data(self.parent.id); |
100 | let src = self.parent.id.source(db); | 100 | let src = self.parent.id.source(db); |
101 | let ast = src | 101 | let value = src |
102 | .ast | 102 | .value |
103 | .variant_list() | 103 | .variant_list() |
104 | .into_iter() | 104 | .into_iter() |
105 | .flat_map(|it| it.variants()) | 105 | .flat_map(|it| it.variants()) |
@@ -107,19 +107,19 @@ impl HasSource for EnumVariant { | |||
107 | .find(|(_syntax, (id, _))| *id == self.id) | 107 | .find(|(_syntax, (id, _))| *id == self.id) |
108 | .unwrap() | 108 | .unwrap() |
109 | .0; | 109 | .0; |
110 | Source { file_id: src.file_id, ast } | 110 | Source { file_id: src.file_id, value } |
111 | } | 111 | } |
112 | } | 112 | } |
113 | impl HasSource for Function { | 113 | impl HasSource for Function { |
114 | type Ast = ast::FnDef; | 114 | type Ast = ast::FnDef; |
115 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { | 115 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { |
116 | self.id.source(db) | 116 | self.id.lookup(db).source(db) |
117 | } | 117 | } |
118 | } | 118 | } |
119 | impl HasSource for Const { | 119 | impl HasSource for Const { |
120 | type Ast = ast::ConstDef; | 120 | type Ast = ast::ConstDef; |
121 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> { | 121 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> { |
122 | self.id.source(db) | 122 | self.id.lookup(db).source(db) |
123 | } | 123 | } |
124 | } | 124 | } |
125 | impl HasSource for Static { | 125 | impl HasSource for Static { |
@@ -137,13 +137,13 @@ impl HasSource for Trait { | |||
137 | impl HasSource for TypeAlias { | 137 | impl HasSource for TypeAlias { |
138 | type Ast = ast::TypeAliasDef; | 138 | type Ast = ast::TypeAliasDef; |
139 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { | 139 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { |
140 | self.id.source(db) | 140 | self.id.lookup(db).source(db) |
141 | } | 141 | } |
142 | } | 142 | } |
143 | impl HasSource for MacroDef { | 143 | impl HasSource for MacroDef { |
144 | type Ast = ast::MacroCall; | 144 | type Ast = ast::MacroCall; |
145 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::MacroCall> { | 145 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::MacroCall> { |
146 | Source { file_id: self.id.ast_id.file_id(), ast: self.id.ast_id.to_node(db) } | 146 | Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } |
147 | } | 147 | } |
148 | } | 148 | } |
149 | 149 | ||
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index d75d71d66..a9982a70f 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -8,10 +8,9 @@ use ra_syntax::SmolStr; | |||
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | debug::HirDebugDatabase, | 10 | debug::HirDebugDatabase, |
11 | generics::{GenericDef, GenericParams}, | 11 | generics::GenericDef, |
12 | ids, | 12 | ids, |
13 | lang_item::{LangItemTarget, LangItems}, | 13 | lang_item::{LangItemTarget, LangItems}, |
14 | traits::TraitData, | ||
15 | ty::{ | 14 | ty::{ |
16 | method_resolution::CrateImplBlocks, | 15 | method_resolution::CrateImplBlocks, |
17 | traits::{AssocTyValue, Impl}, | 16 | traits::{AssocTyValue, Impl}, |
@@ -25,8 +24,9 @@ use crate::{ | |||
25 | 24 | ||
26 | pub use hir_def::db::{ | 25 | pub use hir_def::db::{ |
27 | BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, | 26 | BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, |
28 | EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, | 27 | EnumDataQuery, ExprScopesQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, |
29 | RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, | 28 | InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, |
29 | TraitDataQuery, | ||
30 | }; | 30 | }; |
31 | pub use hir_expand::db::{ | 31 | pub use hir_expand::db::{ |
32 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 32 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
@@ -37,15 +37,6 @@ pub use hir_expand::db::{ | |||
37 | #[salsa::query_group(DefDatabaseStorage)] | 37 | #[salsa::query_group(DefDatabaseStorage)] |
38 | #[salsa::requires(AstDatabase)] | 38 | #[salsa::requires(AstDatabase)] |
39 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { | 39 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { |
40 | #[salsa::invoke(crate::traits::TraitData::trait_data_query)] | ||
41 | fn trait_data(&self, t: Trait) -> Arc<TraitData>; | ||
42 | |||
43 | #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)] | ||
44 | fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex; | ||
45 | |||
46 | #[salsa::invoke(crate::generics::GenericParams::generic_params_query)] | ||
47 | fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>; | ||
48 | |||
49 | #[salsa::invoke(FnData::fn_data_query)] | 40 | #[salsa::invoke(FnData::fn_data_query)] |
50 | fn fn_data(&self, func: Function) -> Arc<FnData>; | 41 | fn fn_data(&self, func: Function) -> Arc<FnData>; |
51 | 42 | ||
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs index 1751e7be3..7d1b64858 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs | |||
@@ -21,7 +21,7 @@ impl Diagnostic for NoSuchField { | |||
21 | } | 21 | } |
22 | 22 | ||
23 | fn source(&self) -> Source<SyntaxNodePtr> { | 23 | fn source(&self) -> Source<SyntaxNodePtr> { |
24 | Source { file_id: self.file, ast: self.field.into() } | 24 | Source { file_id: self.file, value: self.field.into() } |
25 | } | 25 | } |
26 | 26 | ||
27 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 27 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
@@ -41,7 +41,7 @@ impl Diagnostic for MissingFields { | |||
41 | "fill structure fields".to_string() | 41 | "fill structure fields".to_string() |
42 | } | 42 | } |
43 | fn source(&self) -> Source<SyntaxNodePtr> { | 43 | fn source(&self) -> Source<SyntaxNodePtr> { |
44 | Source { file_id: self.file, ast: self.field_list.into() } | 44 | Source { file_id: self.file, value: self.field_list.into() } |
45 | } | 45 | } |
46 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 46 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
47 | self | 47 | self |
@@ -53,7 +53,7 @@ impl AstDiagnostic for MissingFields { | |||
53 | 53 | ||
54 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { | 54 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { |
55 | let root = db.parse_or_expand(self.source().file_id).unwrap(); | 55 | let root = db.parse_or_expand(self.source().file_id).unwrap(); |
56 | let node = self.source().ast.to_node(&root); | 56 | let node = self.source().value.to_node(&root); |
57 | ast::RecordFieldList::cast(node).unwrap() | 57 | ast::RecordFieldList::cast(node).unwrap() |
58 | } | 58 | } |
59 | } | 59 | } |
@@ -69,7 +69,7 @@ impl Diagnostic for MissingOkInTailExpr { | |||
69 | "wrap return expression in Ok".to_string() | 69 | "wrap return expression in Ok".to_string() |
70 | } | 70 | } |
71 | fn source(&self) -> Source<SyntaxNodePtr> { | 71 | fn source(&self) -> Source<SyntaxNodePtr> { |
72 | Source { file_id: self.file, ast: self.expr.into() } | 72 | Source { file_id: self.file, value: self.expr.into() } |
73 | } | 73 | } |
74 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 74 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
75 | self | 75 | self |
@@ -81,7 +81,7 @@ impl AstDiagnostic for MissingOkInTailExpr { | |||
81 | 81 | ||
82 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { | 82 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { |
83 | let root = db.parse_or_expand(self.file).unwrap(); | 83 | let root = db.parse_or_expand(self.file).unwrap(); |
84 | let node = self.source().ast.to_node(&root); | 84 | let node = self.source().value.to_node(&root); |
85 | ast::Expr::cast(node).unwrap() | 85 | ast::Expr::cast(node).unwrap() |
86 | } | 86 | } |
87 | } | 87 | } |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index e3733779e..869879bdf 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -11,6 +11,7 @@ use rustc_hash::FxHashSet; | |||
11 | use crate::{ | 11 | use crate::{ |
12 | db::HirDatabase, | 12 | db::HirDatabase, |
13 | diagnostics::{MissingFields, MissingOkInTailExpr}, | 13 | diagnostics::{MissingFields, MissingOkInTailExpr}, |
14 | resolve::HasResolver, | ||
14 | ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, | 15 | ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, |
15 | Adt, DefWithBody, Function, HasBody, Name, Path, Resolver, | 16 | Adt, DefWithBody, Function, HasBody, Name, Path, Resolver, |
16 | }; | 17 | }; |
@@ -116,7 +117,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
116 | let source_map = self.func.body_source_map(db); | 117 | let source_map = self.func.body_source_map(db); |
117 | 118 | ||
118 | if let Some(source_ptr) = source_map.expr_syntax(id) { | 119 | if let Some(source_ptr) = source_map.expr_syntax(id) { |
119 | if let Some(expr) = source_ptr.ast.a() { | 120 | if let Some(expr) = source_ptr.value.a() { |
120 | let root = source_ptr.file_syntax(db); | 121 | let root = source_ptr.file_syntax(db); |
121 | if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) { | 122 | if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) { |
122 | if let Some(field_list) = record_lit.record_field_list() { | 123 | if let Some(field_list) = record_lit.record_field_list() { |
@@ -161,7 +162,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
161 | let source_map = self.func.body_source_map(db); | 162 | let source_map = self.func.body_source_map(db); |
162 | 163 | ||
163 | if let Some(source_ptr) = source_map.expr_syntax(id) { | 164 | if let Some(source_ptr) = source_map.expr_syntax(id) { |
164 | if let Some(expr) = source_ptr.ast.a() { | 165 | if let Some(expr) = source_ptr.value.a() { |
165 | self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr }); | 166 | self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr }); |
166 | } | 167 | } |
167 | } | 168 | } |
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index f2203e995..b7692d407 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -3,9 +3,9 @@ | |||
3 | //! It's unclear if we need this long-term, but it's definitelly useful while we | 3 | //! It's unclear if we need this long-term, but it's definitelly useful while we |
4 | //! are splitting the hir. | 4 | //! are splitting the hir. |
5 | 5 | ||
6 | use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, ModuleDefId}; | 6 | use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId}; |
7 | 7 | ||
8 | use crate::{Adt, AssocItem, DefWithBody, EnumVariant, ModuleDef}; | 8 | use crate::{Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef}; |
9 | 9 | ||
10 | macro_rules! from_id { | 10 | macro_rules! from_id { |
11 | ($(($id:path, $ty:path)),*) => {$( | 11 | ($(($id:path, $ty:path)),*) => {$( |
@@ -41,6 +41,16 @@ impl From<AdtId> for Adt { | |||
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
44 | impl From<Adt> for AdtId { | ||
45 | fn from(id: Adt) -> Self { | ||
46 | match id { | ||
47 | Adt::Struct(it) => AdtId::StructId(it.id), | ||
48 | Adt::Union(it) => AdtId::UnionId(it.id), | ||
49 | Adt::Enum(it) => AdtId::EnumId(it.id), | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
44 | impl From<EnumVariantId> for EnumVariant { | 54 | impl From<EnumVariantId> for EnumVariant { |
45 | fn from(id: EnumVariantId) -> Self { | 55 | fn from(id: EnumVariantId) -> Self { |
46 | EnumVariant { parent: id.parent.into(), id: id.local_id } | 56 | EnumVariant { parent: id.parent.into(), id: id.local_id } |
@@ -82,3 +92,33 @@ impl From<AssocItemId> for AssocItem { | |||
82 | } | 92 | } |
83 | } | 93 | } |
84 | } | 94 | } |
95 | |||
96 | impl From<GenericDef> for GenericDefId { | ||
97 | fn from(def: GenericDef) -> Self { | ||
98 | match def { | ||
99 | GenericDef::Function(it) => GenericDefId::FunctionId(it.id), | ||
100 | GenericDef::Adt(it) => GenericDefId::AdtId(it.into()), | ||
101 | GenericDef::Trait(it) => GenericDefId::TraitId(it.id), | ||
102 | GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), | ||
103 | GenericDef::ImplBlock(it) => GenericDefId::ImplId(it.id), | ||
104 | GenericDef::EnumVariant(it) => { | ||
105 | GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id }) | ||
106 | } | ||
107 | GenericDef::Const(it) => GenericDefId::ConstId(it.id), | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | |||
112 | impl From<GenericDefId> for GenericDef { | ||
113 | fn from(def: GenericDefId) -> Self { | ||
114 | match def { | ||
115 | GenericDefId::FunctionId(it) => GenericDef::Function(it.into()), | ||
116 | GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), | ||
117 | GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), | ||
118 | GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), | ||
119 | GenericDefId::ImplId(it) => GenericDef::ImplBlock(it.into()), | ||
120 | GenericDefId::EnumVariantId(it) => GenericDef::EnumVariant(it.into()), | ||
121 | GenericDefId::ConstId(it) => GenericDef::Const(it.into()), | ||
122 | } | ||
123 | } | ||
124 | } | ||
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 1c26756c9..b86307c58 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -4,15 +4,15 @@ use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId}; | |||
4 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | 4 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; |
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | ast::{self, AstNode, NameOwner}, | 6 | ast::{self, AstNode, NameOwner}, |
7 | match_ast, | 7 | match_ast, AstPtr, SyntaxNode, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 11 | db::{AstDatabase, DefDatabase, HirDatabase}, |
12 | ids::{AstItemDef, LocationCtx}, | 12 | ids::{AstItemDef, LocationCtx}, |
13 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, ImplBlock, | 13 | AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, |
14 | Local, MacroDef, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, | 14 | ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, |
15 | Union, VariantDef, | 15 | StructField, Trait, TypeAlias, Union, VariantDef, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | pub trait FromSource: Sized { | 18 | pub trait FromSource: Sized { |
@@ -52,15 +52,54 @@ impl FromSource for Trait { | |||
52 | impl FromSource for Function { | 52 | impl FromSource for Function { |
53 | type Ast = ast::FnDef; | 53 | type Ast = ast::FnDef; |
54 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 54 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
55 | let id = from_source(db, src)?; | 55 | let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { |
56 | Some(Function { id }) | 56 | Container::Trait(it) => it.items(db), |
57 | Container::ImplBlock(it) => it.items(db), | ||
58 | Container::Module(m) => { | ||
59 | return m | ||
60 | .declarations(db) | ||
61 | .into_iter() | ||
62 | .filter_map(|it| match it { | ||
63 | ModuleDef::Function(it) => Some(it), | ||
64 | _ => None, | ||
65 | }) | ||
66 | .find(|it| same_source(&it.source(db), &src)) | ||
67 | } | ||
68 | }; | ||
69 | items | ||
70 | .into_iter() | ||
71 | .filter_map(|it| match it { | ||
72 | AssocItem::Function(it) => Some(it), | ||
73 | _ => None, | ||
74 | }) | ||
75 | .find(|it| same_source(&it.source(db), &src)) | ||
57 | } | 76 | } |
58 | } | 77 | } |
78 | |||
59 | impl FromSource for Const { | 79 | impl FromSource for Const { |
60 | type Ast = ast::ConstDef; | 80 | type Ast = ast::ConstDef; |
61 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 81 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
62 | let id = from_source(db, src)?; | 82 | let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { |
63 | Some(Const { id }) | 83 | Container::Trait(it) => it.items(db), |
84 | Container::ImplBlock(it) => it.items(db), | ||
85 | Container::Module(m) => { | ||
86 | return m | ||
87 | .declarations(db) | ||
88 | .into_iter() | ||
89 | .filter_map(|it| match it { | ||
90 | ModuleDef::Const(it) => Some(it), | ||
91 | _ => None, | ||
92 | }) | ||
93 | .find(|it| same_source(&it.source(db), &src)) | ||
94 | } | ||
95 | }; | ||
96 | items | ||
97 | .into_iter() | ||
98 | .filter_map(|it| match it { | ||
99 | AssocItem::Const(it) => Some(it), | ||
100 | _ => None, | ||
101 | }) | ||
102 | .find(|it| same_source(&it.source(db), &src)) | ||
64 | } | 103 | } |
65 | } | 104 | } |
66 | impl FromSource for Static { | 105 | impl FromSource for Static { |
@@ -73,8 +112,27 @@ impl FromSource for Static { | |||
73 | impl FromSource for TypeAlias { | 112 | impl FromSource for TypeAlias { |
74 | type Ast = ast::TypeAliasDef; | 113 | type Ast = ast::TypeAliasDef; |
75 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 114 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
76 | let id = from_source(db, src)?; | 115 | let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { |
77 | Some(TypeAlias { id }) | 116 | Container::Trait(it) => it.items(db), |
117 | Container::ImplBlock(it) => it.items(db), | ||
118 | Container::Module(m) => { | ||
119 | return m | ||
120 | .declarations(db) | ||
121 | .into_iter() | ||
122 | .filter_map(|it| match it { | ||
123 | ModuleDef::TypeAlias(it) => Some(it), | ||
124 | _ => None, | ||
125 | }) | ||
126 | .find(|it| same_source(&it.source(db), &src)) | ||
127 | } | ||
128 | }; | ||
129 | items | ||
130 | .into_iter() | ||
131 | .filter_map(|it| match it { | ||
132 | AssocItem::TypeAlias(it) => Some(it), | ||
133 | _ => None, | ||
134 | }) | ||
135 | .find(|it| same_source(&it.source(db), &src)) | ||
78 | } | 136 | } |
79 | } | 137 | } |
80 | 138 | ||
@@ -87,7 +145,7 @@ impl FromSource for MacroDef { | |||
87 | let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; | 145 | let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; |
88 | let krate = module.krate().crate_id(); | 146 | let krate = module.krate().crate_id(); |
89 | 147 | ||
90 | let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.ast)); | 148 | let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value)); |
91 | 149 | ||
92 | let id: MacroDefId = MacroDefId { krate, ast_id, kind }; | 150 | let id: MacroDefId = MacroDefId { krate, ast_id, kind }; |
93 | Some(MacroDef { id }) | 151 | Some(MacroDef { id }) |
@@ -105,26 +163,26 @@ impl FromSource for ImplBlock { | |||
105 | impl FromSource for EnumVariant { | 163 | impl FromSource for EnumVariant { |
106 | type Ast = ast::EnumVariant; | 164 | type Ast = ast::EnumVariant; |
107 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 165 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
108 | let parent_enum = src.ast.parent_enum(); | 166 | let parent_enum = src.value.parent_enum(); |
109 | let src_enum = Source { file_id: src.file_id, ast: parent_enum }; | 167 | let src_enum = Source { file_id: src.file_id, value: parent_enum }; |
110 | let variants = Enum::from_source(db, src_enum)?.variants(db); | 168 | let variants = Enum::from_source(db, src_enum)?.variants(db); |
111 | variants.into_iter().find(|v| v.source(db) == src) | 169 | variants.into_iter().find(|v| same_source(&v.source(db), &src)) |
112 | } | 170 | } |
113 | } | 171 | } |
114 | 172 | ||
115 | impl FromSource for StructField { | 173 | impl FromSource for StructField { |
116 | type Ast = FieldSource; | 174 | type Ast = FieldSource; |
117 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 175 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
118 | let variant_def: VariantDef = match src.ast { | 176 | let variant_def: VariantDef = match src.value { |
119 | FieldSource::Named(ref field) => { | 177 | FieldSource::Named(ref field) => { |
120 | let ast = field.syntax().ancestors().find_map(ast::StructDef::cast)?; | 178 | let value = field.syntax().ancestors().find_map(ast::StructDef::cast)?; |
121 | let src = Source { file_id: src.file_id, ast }; | 179 | let src = Source { file_id: src.file_id, value }; |
122 | let def = Struct::from_source(db, src)?; | 180 | let def = Struct::from_source(db, src)?; |
123 | VariantDef::from(def) | 181 | VariantDef::from(def) |
124 | } | 182 | } |
125 | FieldSource::Pos(ref field) => { | 183 | FieldSource::Pos(ref field) => { |
126 | let ast = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; | 184 | let value = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; |
127 | let src = Source { file_id: src.file_id, ast }; | 185 | let src = Source { file_id: src.file_id, value }; |
128 | let def = EnumVariant::from_source(db, src)?; | 186 | let def = EnumVariant::from_source(db, src)?; |
129 | VariantDef::from(def) | 187 | VariantDef::from(def) |
130 | } | 188 | } |
@@ -142,12 +200,12 @@ impl FromSource for StructField { | |||
142 | impl Local { | 200 | impl Local { |
143 | pub fn from_source(db: &impl HirDatabase, src: Source<ast::BindPat>) -> Option<Self> { | 201 | pub fn from_source(db: &impl HirDatabase, src: Source<ast::BindPat>) -> Option<Self> { |
144 | let file_id = src.file_id; | 202 | let file_id = src.file_id; |
145 | let parent: DefWithBody = src.ast.syntax().ancestors().find_map(|it| { | 203 | let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| { |
146 | let res = match_ast! { | 204 | let res = match_ast! { |
147 | match it { | 205 | match it { |
148 | ast::ConstDef(ast) => { Const::from_source(db, Source { ast, file_id})?.into() }, | 206 | ast::ConstDef(value) => { Const::from_source(db, Source { value, file_id})?.into() }, |
149 | ast::StaticDef(ast) => { Static::from_source(db, Source { ast, file_id})?.into() }, | 207 | ast::StaticDef(value) => { Static::from_source(db, Source { value, file_id})?.into() }, |
150 | ast::FnDef(ast) => { Function::from_source(db, Source { ast, file_id})?.into() }, | 208 | ast::FnDef(value) => { Function::from_source(db, Source { value, file_id})?.into() }, |
151 | _ => return None, | 209 | _ => return None, |
152 | } | 210 | } |
153 | }; | 211 | }; |
@@ -162,33 +220,33 @@ impl Local { | |||
162 | 220 | ||
163 | impl Module { | 221 | impl Module { |
164 | pub fn from_declaration(db: &impl DefDatabase, src: Source<ast::Module>) -> Option<Self> { | 222 | pub fn from_declaration(db: &impl DefDatabase, src: Source<ast::Module>) -> Option<Self> { |
165 | let parent_declaration = src.ast.syntax().ancestors().skip(1).find_map(ast::Module::cast); | 223 | let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); |
166 | 224 | ||
167 | let parent_module = match parent_declaration { | 225 | let parent_module = match parent_declaration { |
168 | Some(parent_declaration) => { | 226 | Some(parent_declaration) => { |
169 | let src_parent = Source { file_id: src.file_id, ast: parent_declaration }; | 227 | let src_parent = Source { file_id: src.file_id, value: parent_declaration }; |
170 | Module::from_declaration(db, src_parent) | 228 | Module::from_declaration(db, src_parent) |
171 | } | 229 | } |
172 | _ => { | 230 | _ => { |
173 | let src_parent = Source { | 231 | let src_parent = Source { |
174 | file_id: src.file_id, | 232 | file_id: src.file_id, |
175 | ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), | 233 | value: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), |
176 | }; | 234 | }; |
177 | Module::from_definition(db, src_parent) | 235 | Module::from_definition(db, src_parent) |
178 | } | 236 | } |
179 | }?; | 237 | }?; |
180 | 238 | ||
181 | let child_name = src.ast.name()?; | 239 | let child_name = src.value.name()?; |
182 | parent_module.child(db, &child_name.as_name()) | 240 | parent_module.child(db, &child_name.as_name()) |
183 | } | 241 | } |
184 | 242 | ||
185 | pub fn from_definition(db: &impl DefDatabase, src: Source<ModuleSource>) -> Option<Self> { | 243 | pub fn from_definition(db: &impl DefDatabase, src: Source<ModuleSource>) -> Option<Self> { |
186 | match src.ast { | 244 | match src.value { |
187 | ModuleSource::Module(ref module) => { | 245 | ModuleSource::Module(ref module) => { |
188 | assert!(!module.has_semi()); | 246 | assert!(!module.has_semi()); |
189 | return Module::from_declaration( | 247 | return Module::from_declaration( |
190 | db, | 248 | db, |
191 | Source { file_id: src.file_id, ast: module.clone() }, | 249 | Source { file_id: src.file_id, value: module.clone() }, |
192 | ); | 250 | ); |
193 | } | 251 | } |
194 | ModuleSource::SourceFile(_) => (), | 252 | ModuleSource::SourceFile(_) => (), |
@@ -214,5 +272,47 @@ where | |||
214 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); | 272 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); |
215 | let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; | 273 | let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; |
216 | let ctx = LocationCtx::new(db, module.id, src.file_id); | 274 | let ctx = LocationCtx::new(db, module.id, src.file_id); |
217 | Some(DEF::from_ast(ctx, &src.ast)) | 275 | Some(DEF::from_ast(ctx, &src.value)) |
276 | } | ||
277 | |||
278 | enum Container { | ||
279 | Trait(Trait), | ||
280 | ImplBlock(ImplBlock), | ||
281 | Module(Module), | ||
282 | } | ||
283 | |||
284 | impl Container { | ||
285 | fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option<Container> { | ||
286 | // FIXME: this doesn't try to handle nested declarations | ||
287 | for container in src.value.ancestors() { | ||
288 | let res = match_ast! { | ||
289 | match container { | ||
290 | ast::TraitDef(it) => { | ||
291 | let c = Trait::from_source(db, src.with_value(it))?; | ||
292 | Container::Trait(c) | ||
293 | }, | ||
294 | ast::ImplBlock(it) => { | ||
295 | let c = ImplBlock::from_source(db, src.with_value(it))?; | ||
296 | Container::ImplBlock(c) | ||
297 | }, | ||
298 | _ => { continue }, | ||
299 | } | ||
300 | }; | ||
301 | return Some(res); | ||
302 | } | ||
303 | |||
304 | let module_source = ModuleSource::from_child_node(db, src); | ||
305 | let c = Module::from_definition(db, src.with_value(module_source))?; | ||
306 | Some(Container::Module(c)) | ||
307 | } | ||
308 | } | ||
309 | |||
310 | /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are | ||
311 | /// equal if they point to exactly the same object. | ||
312 | /// | ||
313 | /// In general, we do not guarantee that we have exactly one instance of a | ||
314 | /// syntax tree for each file. We probably should add such guarantee, but, for | ||
315 | /// the time being, we will use identity-less AstPtr comparison. | ||
316 | fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool { | ||
317 | s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new) | ||
218 | } | 318 | } |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index c35482ae8..f1bf2ee9d 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -1,50 +1,12 @@ | |||
1 | //! Many kinds of items or constructs can have generic parameters: functions, | 1 | //! Temp module to wrap hir_def::generics |
2 | //! structs, impls, traits, etc. This module provides a common HIR for these | ||
3 | //! generic parameters. See also the `Generics` type and the `generics_of` query | ||
4 | //! in rustc. | ||
5 | |||
6 | use std::sync::Arc; | 2 | use std::sync::Arc; |
7 | 3 | ||
8 | use hir_def::{ | ||
9 | path::Path, | ||
10 | type_ref::{TypeBound, TypeRef}, | ||
11 | }; | ||
12 | use hir_expand::name::{self, AsName}; | ||
13 | use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner}; | ||
14 | |||
15 | use crate::{ | 4 | use crate::{ |
16 | db::{AstDatabase, DefDatabase, HirDatabase}, | 5 | db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, |
17 | Adt, Const, Container, Enum, EnumVariant, Function, HasSource, ImplBlock, Name, Struct, Trait, | ||
18 | TypeAlias, Union, | 6 | TypeAlias, Union, |
19 | }; | 7 | }; |
20 | 8 | ||
21 | /// Data about a generic parameter (to a function, struct, impl, ...). | 9 | pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate}; |
22 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
23 | pub struct GenericParam { | ||
24 | // FIXME: give generic params proper IDs | ||
25 | pub idx: u32, | ||
26 | pub name: Name, | ||
27 | pub default: Option<Path>, | ||
28 | } | ||
29 | |||
30 | /// Data about the generic parameters of a function, struct, impl, etc. | ||
31 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
32 | pub struct GenericParams { | ||
33 | pub(crate) def: GenericDef, | ||
34 | pub(crate) parent_params: Option<Arc<GenericParams>>, | ||
35 | pub(crate) params: Vec<GenericParam>, | ||
36 | pub(crate) where_predicates: Vec<WherePredicate>, | ||
37 | } | ||
38 | |||
39 | /// A single predicate from a where clause, i.e. `where Type: Trait`. Combined | ||
40 | /// where clauses like `where T: Foo + Bar` are turned into multiple of these. | ||
41 | /// It might still result in multiple actual predicates though, because of | ||
42 | /// associated type bindings like `Iterator<Item = u32>`. | ||
43 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
44 | pub struct WherePredicate { | ||
45 | pub(crate) type_ref: TypeRef, | ||
46 | pub(crate) bound: TypeBound, | ||
47 | } | ||
48 | 10 | ||
49 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 11 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
50 | pub enum GenericDef { | 12 | pub enum GenericDef { |
@@ -69,150 +31,6 @@ impl_froms!( | |||
69 | Const | 31 | Const |
70 | ); | 32 | ); |
71 | 33 | ||
72 | impl GenericParams { | ||
73 | pub(crate) fn generic_params_query( | ||
74 | db: &(impl DefDatabase + AstDatabase), | ||
75 | def: GenericDef, | ||
76 | ) -> Arc<GenericParams> { | ||
77 | let parent = match def { | ||
78 | GenericDef::Function(it) => it.container(db).map(GenericDef::from), | ||
79 | GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), | ||
80 | GenericDef::Const(it) => it.container(db).map(GenericDef::from), | ||
81 | GenericDef::EnumVariant(it) => Some(it.parent_enum(db).into()), | ||
82 | GenericDef::Adt(_) | GenericDef::Trait(_) => None, | ||
83 | GenericDef::ImplBlock(_) => None, | ||
84 | }; | ||
85 | let mut generics = GenericParams { | ||
86 | def, | ||
87 | params: Vec::new(), | ||
88 | parent_params: parent.map(|p| db.generic_params(p)), | ||
89 | where_predicates: Vec::new(), | ||
90 | }; | ||
91 | let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; | ||
92 | // FIXME: add `: Sized` bound for everything except for `Self` in traits | ||
93 | match def { | ||
94 | GenericDef::Function(it) => generics.fill(&it.source(db).ast, start), | ||
95 | GenericDef::Adt(Adt::Struct(it)) => generics.fill(&it.source(db).ast, start), | ||
96 | GenericDef::Adt(Adt::Union(it)) => generics.fill(&it.source(db).ast, start), | ||
97 | GenericDef::Adt(Adt::Enum(it)) => generics.fill(&it.source(db).ast, start), | ||
98 | GenericDef::Trait(it) => { | ||
99 | // traits get the Self type as an implicit first type parameter | ||
100 | generics.params.push(GenericParam { | ||
101 | idx: start, | ||
102 | name: name::SELF_TYPE, | ||
103 | default: None, | ||
104 | }); | ||
105 | generics.fill(&it.source(db).ast, start + 1); | ||
106 | // add super traits as bounds on Self | ||
107 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar | ||
108 | let self_param = TypeRef::Path(name::SELF_TYPE.into()); | ||
109 | generics.fill_bounds(&it.source(db).ast, self_param); | ||
110 | } | ||
111 | GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start), | ||
112 | // Note that we don't add `Self` here: in `impl`s, `Self` is not a | ||
113 | // type-parameter, but rather is a type-alias for impl's target | ||
114 | // type, so this is handled by the resolver. | ||
115 | GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start), | ||
116 | GenericDef::EnumVariant(_) | GenericDef::Const(_) => {} | ||
117 | } | ||
118 | |||
119 | Arc::new(generics) | ||
120 | } | ||
121 | |||
122 | fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) { | ||
123 | if let Some(params) = node.type_param_list() { | ||
124 | self.fill_params(params, start) | ||
125 | } | ||
126 | if let Some(where_clause) = node.where_clause() { | ||
127 | self.fill_where_predicates(where_clause); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) { | ||
132 | for bound in | ||
133 | node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) | ||
134 | { | ||
135 | self.add_where_predicate_from_bound(bound, type_ref.clone()); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { | ||
140 | for (idx, type_param) in params.type_params().enumerate() { | ||
141 | let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); | ||
142 | // FIXME: Use `Path::from_src` | ||
143 | let default = type_param.default_type().and_then(|t| t.path()).and_then(Path::from_ast); | ||
144 | |||
145 | let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; | ||
146 | self.params.push(param); | ||
147 | |||
148 | let type_ref = TypeRef::Path(name.into()); | ||
149 | self.fill_bounds(&type_param, type_ref); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) { | ||
154 | for pred in where_clause.predicates() { | ||
155 | let type_ref = match pred.type_ref() { | ||
156 | Some(type_ref) => type_ref, | ||
157 | None => continue, | ||
158 | }; | ||
159 | let type_ref = TypeRef::from_ast(type_ref); | ||
160 | for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { | ||
161 | self.add_where_predicate_from_bound(bound, type_ref.clone()); | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { | ||
167 | if bound.has_question_mark() { | ||
168 | // FIXME: remove this bound | ||
169 | return; | ||
170 | } | ||
171 | let bound = TypeBound::from_ast(bound); | ||
172 | self.where_predicates.push(WherePredicate { type_ref, bound }); | ||
173 | } | ||
174 | |||
175 | pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { | ||
176 | self.params.iter().find(|p| &p.name == name) | ||
177 | } | ||
178 | |||
179 | pub fn count_parent_params(&self) -> usize { | ||
180 | self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0) | ||
181 | } | ||
182 | |||
183 | pub fn count_params_including_parent(&self) -> usize { | ||
184 | let parent_count = self.count_parent_params(); | ||
185 | parent_count + self.params.len() | ||
186 | } | ||
187 | |||
188 | fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) { | ||
189 | if let Some(parent) = &self.parent_params { | ||
190 | parent.for_each_param(f); | ||
191 | } | ||
192 | self.params.iter().for_each(f); | ||
193 | } | ||
194 | |||
195 | pub fn params_including_parent(&self) -> Vec<&GenericParam> { | ||
196 | let mut vec = Vec::with_capacity(self.count_params_including_parent()); | ||
197 | self.for_each_param(&mut |p| vec.push(p)); | ||
198 | vec | ||
199 | } | ||
200 | } | ||
201 | |||
202 | impl GenericDef { | ||
203 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver { | ||
204 | match self { | ||
205 | GenericDef::Function(inner) => inner.resolver(db), | ||
206 | GenericDef::Adt(adt) => adt.resolver(db), | ||
207 | GenericDef::Trait(inner) => inner.resolver(db), | ||
208 | GenericDef::TypeAlias(inner) => inner.resolver(db), | ||
209 | GenericDef::ImplBlock(inner) => inner.resolver(db), | ||
210 | GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), | ||
211 | GenericDef::Const(inner) => inner.resolver(db), | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | |||
216 | impl From<Container> for GenericDef { | 34 | impl From<Container> for GenericDef { |
217 | fn from(c: Container) -> Self { | 35 | fn from(c: Container) -> Self { |
218 | match c { | 36 | match c { |
@@ -231,6 +49,6 @@ where | |||
231 | T: Into<GenericDef> + Copy, | 49 | T: Into<GenericDef> + Copy, |
232 | { | 50 | { |
233 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> { | 51 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> { |
234 | db.generic_params(self.into()) | 52 | db.generic_params(self.into().into()) |
235 | } | 53 | } |
236 | } | 54 | } |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 0c2bb8fee..964a3da8c 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -5,8 +5,7 @@ use ra_syntax::ast::{self}; | |||
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | db::{AstDatabase, DefDatabase, HirDatabase}, | 7 | db::{AstDatabase, DefDatabase, HirDatabase}, |
8 | generics::HasGenericParams, | 8 | resolve::HasResolver, |
9 | resolve::Resolver, | ||
10 | ty::Ty, | 9 | ty::Ty, |
11 | AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, | 10 | AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, |
12 | }; | 11 | }; |
@@ -19,14 +18,6 @@ impl HasSource for ImplBlock { | |||
19 | } | 18 | } |
20 | 19 | ||
21 | impl ImplBlock { | 20 | impl ImplBlock { |
22 | pub(crate) fn containing(db: &impl DefDatabase, item: AssocItem) -> Option<ImplBlock> { | ||
23 | let module = item.module(db); | ||
24 | let crate_def_map = db.crate_def_map(module.id.krate); | ||
25 | crate_def_map[module.id.module_id].impls.iter().copied().map(ImplBlock::from).find(|it| { | ||
26 | db.impl_data(it.id).items().iter().copied().map(AssocItem::from).any(|it| it == item) | ||
27 | }) | ||
28 | } | ||
29 | |||
30 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | 21 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
31 | db.impl_data(self.id).target_trait().cloned() | 22 | db.impl_data(self.id).target_trait().cloned() |
32 | } | 23 | } |
@@ -59,13 +50,4 @@ impl ImplBlock { | |||
59 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | 50 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { |
60 | Crate { crate_id: self.module(db).id.krate } | 51 | Crate { crate_id: self.module(db).id.krate } |
61 | } | 52 | } |
62 | |||
63 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { | ||
64 | let r = self.module(db).resolver(db); | ||
65 | // add generic params, if present | ||
66 | let p = self.generic_params(db); | ||
67 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | ||
68 | let r = r.push_impl_block_scope(self.clone()); | ||
69 | r | ||
70 | } | ||
71 | } | 53 | } |
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs index fa2ef8a17..89fd85f59 100644 --- a/crates/ra_hir/src/lang_item.rs +++ b/crates/ra_hir/src/lang_item.rs | |||
@@ -97,7 +97,7 @@ impl LangItems { | |||
97 | // Look for impl targets | 97 | // Look for impl targets |
98 | for impl_block in module.impl_blocks(db) { | 98 | for impl_block in module.impl_blocks(db) { |
99 | let src = impl_block.source(db); | 99 | let src = impl_block.source(db); |
100 | if let Some(lang_item_name) = lang_item_name(&src.ast) { | 100 | if let Some(lang_item_name) = lang_item_name(&src.value) { |
101 | self.items | 101 | self.items |
102 | .entry(lang_item_name) | 102 | .entry(lang_item_name) |
103 | .or_insert_with(|| LangItemTarget::ImplBlock(impl_block)); | 103 | .or_insert_with(|| LangItemTarget::ImplBlock(impl_block)); |
@@ -144,7 +144,7 @@ impl LangItems { | |||
144 | T: Copy + HasSource<Ast = N>, | 144 | T: Copy + HasSource<Ast = N>, |
145 | N: AttrsOwner, | 145 | N: AttrsOwner, |
146 | { | 146 | { |
147 | let node = item.source(db).ast; | 147 | let node = item.source(db).value; |
148 | if let Some(lang_item_name) = lang_item_name(&node) { | 148 | if let Some(lang_item_name) = lang_item_name(&node) { |
149 | self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); | 149 | self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); |
150 | } | 150 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index da33c9591..31da74d2f 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -32,8 +32,6 @@ pub mod db; | |||
32 | pub mod source_binder; | 32 | pub mod source_binder; |
33 | 33 | ||
34 | mod ids; | 34 | mod ids; |
35 | mod adt; | ||
36 | mod traits; | ||
37 | mod type_alias; | 35 | mod type_alias; |
38 | mod ty; | 36 | mod ty; |
39 | mod impl_block; | 37 | mod impl_block; |
@@ -57,15 +55,14 @@ mod marks; | |||
57 | use crate::resolve::Resolver; | 55 | use crate::resolve::Resolver; |
58 | 56 | ||
59 | pub use crate::{ | 57 | pub use crate::{ |
60 | adt::VariantDef, | ||
61 | code_model::ImplBlock, | ||
62 | code_model::{ | 58 | code_model::{ |
63 | attrs::{AttrDef, Attrs}, | 59 | attrs::{AttrDef, Attrs}, |
64 | docs::{DocDef, Docs, Documentation}, | 60 | docs::{DocDef, Docs, Documentation}, |
65 | src::{HasBodySource, HasSource}, | 61 | src::{HasBodySource, HasSource}, |
66 | Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, | 62 | Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, |
67 | EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, Local, MacroDef, Module, | 63 | EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, |
68 | ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, | 64 | MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, |
65 | Union, VariantDef, | ||
69 | }, | 66 | }, |
70 | expr::ExprScopes, | 67 | expr::ExprScopes, |
71 | from_source::FromSource, | 68 | from_source::FromSource, |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 79b92180a..eca8e0596 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -14,9 +14,9 @@ use crate::{ | |||
14 | code_model::Crate, | 14 | code_model::Crate, |
15 | db::{DefDatabase, HirDatabase}, | 15 | db::{DefDatabase, HirDatabase}, |
16 | expr::{ExprScopes, PatId, ScopeId}, | 16 | expr::{ExprScopes, PatId, ScopeId}, |
17 | generics::GenericParams, | 17 | generics::{GenericParams, HasGenericParams}, |
18 | Adt, Const, DefWithBody, Enum, EnumVariant, Function, ImplBlock, Local, MacroDef, ModuleDef, | 18 | Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, |
19 | PerNs, Static, Struct, Trait, TypeAlias, | 19 | MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | #[derive(Debug, Clone, Default)] | 22 | #[derive(Debug, Clone, Default)] |
@@ -43,7 +43,7 @@ pub(crate) enum Scope { | |||
43 | /// All the items and imported names of a module | 43 | /// All the items and imported names of a module |
44 | ModuleScope(ModuleItemMap), | 44 | ModuleScope(ModuleItemMap), |
45 | /// Brings the generic parameters of an item into scope | 45 | /// Brings the generic parameters of an item into scope |
46 | GenericParams(Arc<GenericParams>), | 46 | GenericParams { def: GenericDef, params: Arc<GenericParams> }, |
47 | /// Brings `Self` in `impl` block into scope | 47 | /// Brings `Self` in `impl` block into scope |
48 | ImplBlockScope(ImplBlock), | 48 | ImplBlockScope(ImplBlock), |
49 | /// Brings `Self` in enum, struct and union definitions into scope | 49 | /// Brings `Self` in enum, struct and union definitions into scope |
@@ -141,9 +141,9 @@ impl Resolver { | |||
141 | for scope in self.scopes.iter().rev() { | 141 | for scope in self.scopes.iter().rev() { |
142 | match scope { | 142 | match scope { |
143 | Scope::ExprScope(_) => continue, | 143 | Scope::ExprScope(_) => continue, |
144 | Scope::GenericParams(_) | Scope::ImplBlockScope(_) if skip_to_mod => continue, | 144 | Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, |
145 | 145 | ||
146 | Scope::GenericParams(params) => { | 146 | Scope::GenericParams { params, .. } => { |
147 | if let Some(param) = params.find_by_name(first_name) { | 147 | if let Some(param) = params.find_by_name(first_name) { |
148 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 148 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; |
149 | return Some((TypeNs::GenericParam(param.idx), idx)); | 149 | return Some((TypeNs::GenericParam(param.idx), idx)); |
@@ -212,7 +212,7 @@ impl Resolver { | |||
212 | match scope { | 212 | match scope { |
213 | Scope::AdtScope(_) | 213 | Scope::AdtScope(_) |
214 | | Scope::ExprScope(_) | 214 | | Scope::ExprScope(_) |
215 | | Scope::GenericParams(_) | 215 | | Scope::GenericParams { .. } |
216 | | Scope::ImplBlockScope(_) | 216 | | Scope::ImplBlockScope(_) |
217 | if skip_to_mod => | 217 | if skip_to_mod => |
218 | { | 218 | { |
@@ -232,13 +232,13 @@ impl Resolver { | |||
232 | } | 232 | } |
233 | Scope::ExprScope(_) => continue, | 233 | Scope::ExprScope(_) => continue, |
234 | 234 | ||
235 | Scope::GenericParams(params) if n_segments > 1 => { | 235 | Scope::GenericParams { params, .. } if n_segments > 1 => { |
236 | if let Some(param) = params.find_by_name(first_name) { | 236 | if let Some(param) = params.find_by_name(first_name) { |
237 | let ty = TypeNs::GenericParam(param.idx); | 237 | let ty = TypeNs::GenericParam(param.idx); |
238 | return Some(ResolveValueResult::Partial(ty, 1)); | 238 | return Some(ResolveValueResult::Partial(ty, 1)); |
239 | } | 239 | } |
240 | } | 240 | } |
241 | Scope::GenericParams(_) => continue, | 241 | Scope::GenericParams { .. } => continue, |
242 | 242 | ||
243 | Scope::ImplBlockScope(impl_) if n_segments > 1 => { | 243 | Scope::ImplBlockScope(impl_) if n_segments > 1 => { |
244 | if first_name == &name::SELF_TYPE { | 244 | if first_name == &name::SELF_TYPE { |
@@ -361,7 +361,7 @@ impl Resolver { | |||
361 | self.scopes | 361 | self.scopes |
362 | .iter() | 362 | .iter() |
363 | .filter_map(|scope| match scope { | 363 | .filter_map(|scope| match scope { |
364 | Scope::GenericParams(params) => Some(params), | 364 | Scope::GenericParams { params, .. } => Some(params), |
365 | _ => None, | 365 | _ => None, |
366 | }) | 366 | }) |
367 | .flat_map(|params| params.where_predicates.iter()) | 367 | .flat_map(|params| params.where_predicates.iter()) |
@@ -369,7 +369,7 @@ impl Resolver { | |||
369 | 369 | ||
370 | pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> { | 370 | pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> { |
371 | self.scopes.iter().find_map(|scope| match scope { | 371 | self.scopes.iter().find_map(|scope| match scope { |
372 | Scope::GenericParams(params) => Some(params.def), | 372 | Scope::GenericParams { def, .. } => Some(*def), |
373 | _ => None, | 373 | _ => None, |
374 | }) | 374 | }) |
375 | } | 375 | } |
@@ -381,8 +381,17 @@ impl Resolver { | |||
381 | self | 381 | self |
382 | } | 382 | } |
383 | 383 | ||
384 | pub(crate) fn push_generic_params_scope(self, params: Arc<GenericParams>) -> Resolver { | 384 | pub(crate) fn push_generic_params_scope( |
385 | self.push_scope(Scope::GenericParams(params)) | 385 | self, |
386 | db: &impl DefDatabase, | ||
387 | def: GenericDef, | ||
388 | ) -> Resolver { | ||
389 | let params = def.generic_params(db); | ||
390 | if params.params.is_empty() { | ||
391 | self | ||
392 | } else { | ||
393 | self.push_scope(Scope::GenericParams { def, params }) | ||
394 | } | ||
386 | } | 395 | } |
387 | 396 | ||
388 | pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { | 397 | pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { |
@@ -457,8 +466,8 @@ impl Scope { | |||
457 | }); | 466 | }); |
458 | } | 467 | } |
459 | } | 468 | } |
460 | Scope::GenericParams(gp) => { | 469 | Scope::GenericParams { params, .. } => { |
461 | for param in &gp.params { | 470 | for param in params.params.iter() { |
462 | f(param.name.clone(), ScopeDef::GenericParam(param.idx)) | 471 | f(param.name.clone(), ScopeDef::GenericParam(param.idx)) |
463 | } | 472 | } |
464 | } | 473 | } |
@@ -477,3 +486,103 @@ impl Scope { | |||
477 | } | 486 | } |
478 | } | 487 | } |
479 | } | 488 | } |
489 | |||
490 | pub(crate) trait HasResolver { | ||
491 | /// Builds a resolver for type references inside this def. | ||
492 | fn resolver(self, db: &impl DefDatabase) -> Resolver; | ||
493 | } | ||
494 | |||
495 | impl HasResolver for Module { | ||
496 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
497 | let def_map = db.crate_def_map(self.id.krate); | ||
498 | Resolver::default().push_module_scope(def_map, self.id.module_id) | ||
499 | } | ||
500 | } | ||
501 | |||
502 | impl HasResolver for Trait { | ||
503 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
504 | self.module(db).resolver(db).push_generic_params_scope(db, self.into()) | ||
505 | } | ||
506 | } | ||
507 | |||
508 | impl<T: Into<Adt>> HasResolver for T { | ||
509 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
510 | let def = self.into(); | ||
511 | def.module(db) | ||
512 | .resolver(db) | ||
513 | .push_generic_params_scope(db, def.into()) | ||
514 | .push_scope(Scope::AdtScope(def)) | ||
515 | } | ||
516 | } | ||
517 | |||
518 | impl HasResolver for Function { | ||
519 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
520 | self.container(db) | ||
521 | .map(|c| c.resolver(db)) | ||
522 | .unwrap_or_else(|| self.module(db).resolver(db)) | ||
523 | .push_generic_params_scope(db, self.into()) | ||
524 | } | ||
525 | } | ||
526 | |||
527 | impl HasResolver for DefWithBody { | ||
528 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
529 | match self { | ||
530 | DefWithBody::Const(c) => c.resolver(db), | ||
531 | DefWithBody::Function(f) => f.resolver(db), | ||
532 | DefWithBody::Static(s) => s.resolver(db), | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | |||
537 | impl HasResolver for Const { | ||
538 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
539 | self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db)) | ||
540 | } | ||
541 | } | ||
542 | |||
543 | impl HasResolver for Static { | ||
544 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
545 | self.module(db).resolver(db) | ||
546 | } | ||
547 | } | ||
548 | |||
549 | impl HasResolver for TypeAlias { | ||
550 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
551 | self.container(db) | ||
552 | .map(|ib| ib.resolver(db)) | ||
553 | .unwrap_or_else(|| self.module(db).resolver(db)) | ||
554 | .push_generic_params_scope(db, self.into()) | ||
555 | } | ||
556 | } | ||
557 | |||
558 | impl HasResolver for Container { | ||
559 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
560 | match self { | ||
561 | Container::Trait(trait_) => trait_.resolver(db), | ||
562 | Container::ImplBlock(impl_block) => impl_block.resolver(db), | ||
563 | } | ||
564 | } | ||
565 | } | ||
566 | |||
567 | impl HasResolver for GenericDef { | ||
568 | fn resolver(self, db: &impl DefDatabase) -> crate::Resolver { | ||
569 | match self { | ||
570 | GenericDef::Function(inner) => inner.resolver(db), | ||
571 | GenericDef::Adt(adt) => adt.resolver(db), | ||
572 | GenericDef::Trait(inner) => inner.resolver(db), | ||
573 | GenericDef::TypeAlias(inner) => inner.resolver(db), | ||
574 | GenericDef::ImplBlock(inner) => inner.resolver(db), | ||
575 | GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), | ||
576 | GenericDef::Const(inner) => inner.resolver(db), | ||
577 | } | ||
578 | } | ||
579 | } | ||
580 | |||
581 | impl HasResolver for ImplBlock { | ||
582 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
583 | self.module(db) | ||
584 | .resolver(db) | ||
585 | .push_generic_params_scope(db, self.into()) | ||
586 | .push_impl_block_scope(self) | ||
587 | } | ||
588 | } | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 5d3196c2a..727310f06 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -23,7 +23,7 @@ use crate::{ | |||
23 | db::HirDatabase, | 23 | db::HirDatabase, |
24 | expr::{self, BodySourceMap, ExprScopes, ScopeId}, | 24 | expr::{self, BodySourceMap, ExprScopes, ScopeId}, |
25 | ids::LocationCtx, | 25 | ids::LocationCtx, |
26 | resolve::{ScopeDef, TypeNs, ValueNs}, | 26 | resolve::{HasResolver, ScopeDef, TypeNs, ValueNs}, |
27 | ty::method_resolution::{self, implements_trait}, | 27 | ty::method_resolution::{self, implements_trait}, |
28 | AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, | 28 | AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, |
29 | HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, | 29 | HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, |
@@ -31,24 +31,24 @@ use crate::{ | |||
31 | 31 | ||
32 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 32 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { |
33 | match_ast! { | 33 | match_ast! { |
34 | match (node.ast) { | 34 | match (node.value) { |
35 | ast::Module(it) => { | 35 | ast::Module(it) => { |
36 | let src = node.with_ast(it); | 36 | let src = node.with_value(it); |
37 | Some(crate::Module::from_declaration(db, src)?.resolver(db)) | 37 | Some(crate::Module::from_declaration(db, src)?.resolver(db)) |
38 | }, | 38 | }, |
39 | ast::SourceFile(it) => { | 39 | ast::SourceFile(it) => { |
40 | let src = node.with_ast(crate::ModuleSource::SourceFile(it)); | 40 | let src = node.with_value(crate::ModuleSource::SourceFile(it)); |
41 | Some(crate::Module::from_definition(db, src)?.resolver(db)) | 41 | Some(crate::Module::from_definition(db, src)?.resolver(db)) |
42 | }, | 42 | }, |
43 | ast::StructDef(it) => { | 43 | ast::StructDef(it) => { |
44 | let src = node.with_ast(it); | 44 | let src = node.with_value(it); |
45 | Some(Struct::from_source(db, src)?.resolver(db)) | 45 | Some(Struct::from_source(db, src)?.resolver(db)) |
46 | }, | 46 | }, |
47 | ast::EnumDef(it) => { | 47 | ast::EnumDef(it) => { |
48 | let src = node.with_ast(it); | 48 | let src = node.with_value(it); |
49 | Some(Enum::from_source(db, src)?.resolver(db)) | 49 | Some(Enum::from_source(db, src)?.resolver(db)) |
50 | }, | 50 | }, |
51 | _ => match node.ast.kind() { | 51 | _ => match node.value.kind() { |
52 | FN_DEF | CONST_DEF | STATIC_DEF => { | 52 | FN_DEF | CONST_DEF | STATIC_DEF => { |
53 | Some(def_with_body_from_child_node(db, node)?.resolver(db)) | 53 | Some(def_with_body_from_child_node(db, node)?.resolver(db)) |
54 | } | 54 | } |
@@ -67,11 +67,11 @@ fn def_with_body_from_child_node( | |||
67 | let module = Module::from_definition(db, Source::new(child.file_id, module_source))?; | 67 | let module = Module::from_definition(db, Source::new(child.file_id, module_source))?; |
68 | let ctx = LocationCtx::new(db, module.id, child.file_id); | 68 | let ctx = LocationCtx::new(db, module.id, child.file_id); |
69 | 69 | ||
70 | child.ast.ancestors().find_map(|node| { | 70 | child.value.ancestors().find_map(|node| { |
71 | match_ast! { | 71 | match_ast! { |
72 | match node { | 72 | match node { |
73 | ast::FnDef(def) => { Some(Function {id: ctx.to_def(&def) }.into()) }, | 73 | ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, |
74 | ast::ConstDef(def) => { Some(Const { id: ctx.to_def(&def) }.into()) }, | 74 | ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, |
75 | ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, | 75 | ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, |
76 | _ => { None }, | 76 | _ => { None }, |
77 | } | 77 | } |
@@ -157,7 +157,7 @@ impl SourceAnalyzer { | |||
157 | let scopes = def.expr_scopes(db); | 157 | let scopes = def.expr_scopes(db); |
158 | let scope = match offset { | 158 | let scope = match offset { |
159 | None => scope_for(&scopes, &source_map, node), | 159 | None => scope_for(&scopes, &source_map, node), |
160 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_ast(offset)), | 160 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), |
161 | }; | 161 | }; |
162 | let resolver = expr::resolver_for_scope(db, def, scope); | 162 | let resolver = expr::resolver_for_scope(db, def, scope); |
163 | SourceAnalyzer { | 163 | SourceAnalyzer { |
@@ -171,9 +171,9 @@ impl SourceAnalyzer { | |||
171 | } else { | 171 | } else { |
172 | SourceAnalyzer { | 172 | SourceAnalyzer { |
173 | resolver: node | 173 | resolver: node |
174 | .ast | 174 | .value |
175 | .ancestors() | 175 | .ancestors() |
176 | .find_map(|it| try_get_resolver_for_node(db, node.with_ast(&it))) | 176 | .find_map(|it| try_get_resolver_for_node(db, node.with_value(&it))) |
177 | .unwrap_or_default(), | 177 | .unwrap_or_default(), |
178 | body_owner: None, | 178 | body_owner: None, |
179 | body_source_map: None, | 179 | body_source_map: None, |
@@ -185,12 +185,12 @@ impl SourceAnalyzer { | |||
185 | } | 185 | } |
186 | 186 | ||
187 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { | 187 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { |
188 | let src = Source { file_id: self.file_id, ast: expr }; | 188 | let src = Source { file_id: self.file_id, value: expr }; |
189 | self.body_source_map.as_ref()?.node_expr(src) | 189 | self.body_source_map.as_ref()?.node_expr(src) |
190 | } | 190 | } |
191 | 191 | ||
192 | fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { | 192 | fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { |
193 | let src = Source { file_id: self.file_id, ast: pat }; | 193 | let src = Source { file_id: self.file_id, value: pat }; |
194 | self.body_source_map.as_ref()?.node_pat(src) | 194 | self.body_source_map.as_ref()?.node_pat(src) |
195 | } | 195 | } |
196 | 196 | ||
@@ -302,7 +302,7 @@ impl SourceAnalyzer { | |||
302 | let entry = scopes.resolve_name_in_scope(scope, &name)?; | 302 | let entry = scopes.resolve_name_in_scope(scope, &name)?; |
303 | Some(ScopeEntryWithSyntax { | 303 | Some(ScopeEntryWithSyntax { |
304 | name: entry.name().clone(), | 304 | name: entry.name().clone(), |
305 | ptr: source_map.pat_syntax(entry.pat())?.ast, | 305 | ptr: source_map.pat_syntax(entry.pat())?.value, |
306 | }) | 306 | }) |
307 | } | 307 | } |
308 | 308 | ||
@@ -405,9 +405,16 @@ impl SourceAnalyzer { | |||
405 | implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) | 405 | implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) |
406 | } | 406 | } |
407 | 407 | ||
408 | pub fn expand(&self, db: &impl HirDatabase, macro_call: &ast::MacroCall) -> Option<Expansion> { | 408 | pub fn expand( |
409 | let def = self.resolve_macro_call(db, macro_call)?.id; | 409 | &self, |
410 | let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(macro_call)); | 410 | db: &impl HirDatabase, |
411 | macro_call: Source<&ast::MacroCall>, | ||
412 | ) -> Option<Expansion> { | ||
413 | let def = self.resolve_macro_call(db, macro_call.value)?.id; | ||
414 | let ast_id = AstId::new( | ||
415 | macro_call.file_id, | ||
416 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | ||
417 | ); | ||
411 | let macro_call_loc = MacroCallLoc { def, ast_id }; | 418 | let macro_call_loc = MacroCallLoc { def, ast_id }; |
412 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) | 419 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) |
413 | } | 420 | } |
@@ -421,6 +428,11 @@ impl SourceAnalyzer { | |||
421 | pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> { | 428 | pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> { |
422 | self.infer.clone().unwrap() | 429 | self.infer.clone().unwrap() |
423 | } | 430 | } |
431 | |||
432 | #[cfg(test)] | ||
433 | pub(crate) fn analyzed_declaration(&self) -> Option<DefWithBody> { | ||
434 | self.body_owner | ||
435 | } | ||
424 | } | 436 | } |
425 | 437 | ||
426 | fn scope_for( | 438 | fn scope_for( |
@@ -428,7 +440,7 @@ fn scope_for( | |||
428 | source_map: &BodySourceMap, | 440 | source_map: &BodySourceMap, |
429 | node: Source<&SyntaxNode>, | 441 | node: Source<&SyntaxNode>, |
430 | ) -> Option<ScopeId> { | 442 | ) -> Option<ScopeId> { |
431 | node.ast | 443 | node.value |
432 | .ancestors() | 444 | .ancestors() |
433 | .filter_map(ast::Expr::cast) | 445 | .filter_map(ast::Expr::cast) |
434 | .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) | 446 | .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) |
@@ -450,18 +462,18 @@ fn scope_for_offset( | |||
450 | return None; | 462 | return None; |
451 | } | 463 | } |
452 | let syntax_node_ptr = | 464 | let syntax_node_ptr = |
453 | source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); | 465 | source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); |
454 | Some((syntax_node_ptr, scope)) | 466 | Some((syntax_node_ptr, scope)) |
455 | }) | 467 | }) |
456 | // find containing scope | 468 | // find containing scope |
457 | .min_by_key(|(ptr, _scope)| { | 469 | .min_by_key(|(ptr, _scope)| { |
458 | ( | 470 | ( |
459 | !(ptr.range().start() <= offset.ast && offset.ast <= ptr.range().end()), | 471 | !(ptr.range().start() <= offset.value && offset.value <= ptr.range().end()), |
460 | ptr.range().len(), | 472 | ptr.range().len(), |
461 | ) | 473 | ) |
462 | }) | 474 | }) |
463 | .map(|(ptr, scope)| { | 475 | .map(|(ptr, scope)| { |
464 | adjust(scopes, source_map, ptr, offset.file_id, offset.ast).unwrap_or(*scope) | 476 | adjust(scopes, source_map, ptr, offset.file_id, offset.value).unwrap_or(*scope) |
465 | }) | 477 | }) |
466 | } | 478 | } |
467 | 479 | ||
@@ -485,7 +497,7 @@ fn adjust( | |||
485 | return None; | 497 | return None; |
486 | } | 498 | } |
487 | let syntax_node_ptr = | 499 | let syntax_node_ptr = |
488 | source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); | 500 | source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); |
489 | Some((syntax_node_ptr, scope)) | 501 | Some((syntax_node_ptr, scope)) |
490 | }) | 502 | }) |
491 | .map(|(ptr, scope)| (ptr.range(), scope)) | 503 | .map(|(ptr, scope)| (ptr.range(), scope)) |
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs deleted file mode 100644 index 1a45dacba..000000000 --- a/crates/ra_hir/src/traits.rs +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | //! HIR for trait definitions. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::name::AsName; | ||
6 | |||
7 | use ra_syntax::ast::{self, NameOwner}; | ||
8 | use rustc_hash::FxHashMap; | ||
9 | |||
10 | use crate::{ | ||
11 | db::{AstDatabase, DefDatabase}, | ||
12 | ids::LocationCtx, | ||
13 | AssocItem, Const, Function, HasSource, Module, Name, Trait, TypeAlias, | ||
14 | }; | ||
15 | |||
16 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
17 | pub struct TraitData { | ||
18 | name: Option<Name>, | ||
19 | items: Vec<AssocItem>, | ||
20 | auto: bool, | ||
21 | } | ||
22 | |||
23 | impl TraitData { | ||
24 | pub(crate) fn trait_data_query( | ||
25 | db: &(impl DefDatabase + AstDatabase), | ||
26 | tr: Trait, | ||
27 | ) -> Arc<TraitData> { | ||
28 | let src = tr.source(db); | ||
29 | let name = src.ast.name().map(|n| n.as_name()); | ||
30 | let module = tr.module(db); | ||
31 | let ctx = LocationCtx::new(db, module.id, src.file_id); | ||
32 | let auto = src.ast.is_auto(); | ||
33 | let items = if let Some(item_list) = src.ast.item_list() { | ||
34 | item_list | ||
35 | .impl_items() | ||
36 | .map(|item_node| match item_node { | ||
37 | ast::ImplItem::FnDef(it) => Function { id: ctx.to_def(&it) }.into(), | ||
38 | ast::ImplItem::ConstDef(it) => Const { id: ctx.to_def(&it) }.into(), | ||
39 | ast::ImplItem::TypeAliasDef(it) => TypeAlias { id: ctx.to_def(&it) }.into(), | ||
40 | }) | ||
41 | .collect() | ||
42 | } else { | ||
43 | Vec::new() | ||
44 | }; | ||
45 | Arc::new(TraitData { name, items, auto }) | ||
46 | } | ||
47 | |||
48 | pub(crate) fn name(&self) -> &Option<Name> { | ||
49 | &self.name | ||
50 | } | ||
51 | |||
52 | pub(crate) fn items(&self) -> &[AssocItem] { | ||
53 | &self.items | ||
54 | } | ||
55 | |||
56 | pub(crate) fn is_auto(&self) -> bool { | ||
57 | self.auto | ||
58 | } | ||
59 | } | ||
60 | |||
61 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
62 | pub struct TraitItemsIndex { | ||
63 | traits_by_def: FxHashMap<AssocItem, Trait>, | ||
64 | } | ||
65 | |||
66 | impl TraitItemsIndex { | ||
67 | pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { | ||
68 | let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; | ||
69 | for decl in module.declarations(db) { | ||
70 | if let crate::ModuleDef::Trait(tr) = decl { | ||
71 | for item in tr.trait_data(db).items() { | ||
72 | index.traits_by_def.insert(*item, tr); | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | index | ||
77 | } | ||
78 | |||
79 | pub(crate) fn get_parent_trait(&self, item: AssocItem) -> Option<Trait> { | ||
80 | self.traits_by_def.get(&item).cloned() | ||
81 | } | ||
82 | } | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index b7f50b714..36ece723f 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -3,8 +3,6 @@ | |||
3 | 3 | ||
4 | mod autoderef; | 4 | mod autoderef; |
5 | pub(crate) mod primitive; | 5 | pub(crate) mod primitive; |
6 | #[cfg(test)] | ||
7 | mod tests; | ||
8 | pub(crate) mod traits; | 6 | pub(crate) mod traits; |
9 | pub(crate) mod method_resolution; | 7 | pub(crate) mod method_resolution; |
10 | mod op; | 8 | mod op; |
@@ -12,6 +10,9 @@ mod lower; | |||
12 | mod infer; | 10 | mod infer; |
13 | pub(crate) mod display; | 11 | pub(crate) mod display; |
14 | 12 | ||
13 | #[cfg(test)] | ||
14 | mod tests; | ||
15 | |||
15 | use std::ops::Deref; | 16 | use std::ops::Deref; |
16 | use std::sync::Arc; | 17 | use std::sync::Arc; |
17 | use std::{fmt, iter, mem}; | 18 | use std::{fmt, iter, mem}; |
@@ -800,6 +801,10 @@ impl HirDisplay for &Ty { | |||
800 | 801 | ||
801 | impl HirDisplay for ApplicationTy { | 802 | impl HirDisplay for ApplicationTy { |
802 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | 803 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { |
804 | if f.should_truncate() { | ||
805 | return write!(f, "…"); | ||
806 | } | ||
807 | |||
803 | match self.ctor { | 808 | match self.ctor { |
804 | TypeCtor::Bool => write!(f, "bool")?, | 809 | TypeCtor::Bool => write!(f, "bool")?, |
805 | TypeCtor::Char => write!(f, "char")?, | 810 | TypeCtor::Char => write!(f, "char")?, |
@@ -901,6 +906,10 @@ impl HirDisplay for ApplicationTy { | |||
901 | 906 | ||
902 | impl HirDisplay for ProjectionTy { | 907 | impl HirDisplay for ProjectionTy { |
903 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | 908 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { |
909 | if f.should_truncate() { | ||
910 | return write!(f, "…"); | ||
911 | } | ||
912 | |||
904 | let trait_name = self | 913 | let trait_name = self |
905 | .associated_ty | 914 | .associated_ty |
906 | .parent_trait(f.db) | 915 | .parent_trait(f.db) |
@@ -919,6 +928,10 @@ impl HirDisplay for ProjectionTy { | |||
919 | 928 | ||
920 | impl HirDisplay for Ty { | 929 | impl HirDisplay for Ty { |
921 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | 930 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { |
931 | if f.should_truncate() { | ||
932 | return write!(f, "…"); | ||
933 | } | ||
934 | |||
922 | match self { | 935 | match self { |
923 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, | 936 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, |
924 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, | 937 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, |
@@ -1001,6 +1014,10 @@ impl HirDisplay for Ty { | |||
1001 | 1014 | ||
1002 | impl TraitRef { | 1015 | impl TraitRef { |
1003 | fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result { | 1016 | fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result { |
1017 | if f.should_truncate() { | ||
1018 | return write!(f, "…"); | ||
1019 | } | ||
1020 | |||
1004 | self.substs[0].hir_fmt(f)?; | 1021 | self.substs[0].hir_fmt(f)?; |
1005 | if use_as { | 1022 | if use_as { |
1006 | write!(f, " as ")?; | 1023 | write!(f, " as ")?; |
@@ -1031,6 +1048,10 @@ impl HirDisplay for &GenericPredicate { | |||
1031 | 1048 | ||
1032 | impl HirDisplay for GenericPredicate { | 1049 | impl HirDisplay for GenericPredicate { |
1033 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | 1050 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { |
1051 | if f.should_truncate() { | ||
1052 | return write!(f, "…"); | ||
1053 | } | ||
1054 | |||
1034 | match self { | 1055 | match self { |
1035 | GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, | 1056 | GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, |
1036 | GenericPredicate::Projection(projection_pred) => { | 1057 | GenericPredicate::Projection(projection_pred) => { |
diff --git a/crates/ra_hir/src/ty/display.rs b/crates/ra_hir/src/ty/display.rs index 7910429d7..9bb3ece6c 100644 --- a/crates/ra_hir/src/ty/display.rs +++ b/crates/ra_hir/src/ty/display.rs | |||
@@ -7,15 +7,30 @@ use crate::db::HirDatabase; | |||
7 | pub struct HirFormatter<'a, 'b, DB> { | 7 | pub struct HirFormatter<'a, 'b, DB> { |
8 | pub db: &'a DB, | 8 | pub db: &'a DB, |
9 | fmt: &'a mut fmt::Formatter<'b>, | 9 | fmt: &'a mut fmt::Formatter<'b>, |
10 | buf: String, | ||
11 | curr_size: usize, | ||
12 | max_size: Option<usize>, | ||
10 | } | 13 | } |
11 | 14 | ||
12 | pub trait HirDisplay { | 15 | pub trait HirDisplay { |
13 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result; | 16 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result; |
17 | |||
14 | fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self> | 18 | fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self> |
15 | where | 19 | where |
16 | Self: Sized, | 20 | Self: Sized, |
17 | { | 21 | { |
18 | HirDisplayWrapper(db, self) | 22 | HirDisplayWrapper(db, self, None) |
23 | } | ||
24 | |||
25 | fn display_truncated<'a, DB>( | ||
26 | &'a self, | ||
27 | db: &'a DB, | ||
28 | max_size: Option<usize>, | ||
29 | ) -> HirDisplayWrapper<'a, DB, Self> | ||
30 | where | ||
31 | Self: Sized, | ||
32 | { | ||
33 | HirDisplayWrapper(db, self, max_size) | ||
19 | } | 34 | } |
20 | } | 35 | } |
21 | 36 | ||
@@ -41,11 +56,25 @@ where | |||
41 | 56 | ||
42 | /// This allows using the `write!` macro directly with a `HirFormatter`. | 57 | /// This allows using the `write!` macro directly with a `HirFormatter`. |
43 | pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { | 58 | pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { |
44 | fmt::write(self.fmt, args) | 59 | // We write to a buffer first to track output size |
60 | self.buf.clear(); | ||
61 | fmt::write(&mut self.buf, args)?; | ||
62 | self.curr_size += self.buf.len(); | ||
63 | |||
64 | // Then we write to the internal formatter from the buffer | ||
65 | self.fmt.write_str(&self.buf) | ||
66 | } | ||
67 | |||
68 | pub fn should_truncate(&self) -> bool { | ||
69 | if let Some(max_size) = self.max_size { | ||
70 | self.curr_size >= max_size | ||
71 | } else { | ||
72 | false | ||
73 | } | ||
45 | } | 74 | } |
46 | } | 75 | } |
47 | 76 | ||
48 | pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T); | 77 | pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>); |
49 | 78 | ||
50 | impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> | 79 | impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> |
51 | where | 80 | where |
@@ -53,6 +82,12 @@ where | |||
53 | T: HirDisplay, | 82 | T: HirDisplay, |
54 | { | 83 | { |
55 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 84 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
56 | self.1.hir_fmt(&mut HirFormatter { db: self.0, fmt: f }) | 85 | self.1.hir_fmt(&mut HirFormatter { |
86 | db: self.0, | ||
87 | fmt: f, | ||
88 | buf: String::with_capacity(20), | ||
89 | curr_size: 0, | ||
90 | max_size: self.2, | ||
91 | }) | ||
57 | } | 92 | } |
58 | } | 93 | } |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c35378cc4..7f9e81d64 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -37,14 +37,13 @@ use super::{ | |||
37 | TypeCtor, TypeWalk, Uncertain, | 37 | TypeCtor, TypeWalk, Uncertain, |
38 | }; | 38 | }; |
39 | use crate::{ | 39 | use crate::{ |
40 | adt::VariantDef, | ||
41 | code_model::TypeAlias, | 40 | code_model::TypeAlias, |
42 | db::HirDatabase, | 41 | db::HirDatabase, |
43 | expr::{BindingAnnotation, Body, ExprId, PatId}, | 42 | expr::{BindingAnnotation, Body, ExprId, PatId}, |
44 | resolve::{Resolver, TypeNs}, | 43 | resolve::{HasResolver, Resolver, TypeNs}, |
45 | ty::infer::diagnostics::InferenceDiagnostic, | 44 | ty::infer::diagnostics::InferenceDiagnostic, |
46 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, | 45 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, |
47 | StructField, | 46 | StructField, VariantDef, |
48 | }; | 47 | }; |
49 | 48 | ||
50 | macro_rules! ty_app { | 49 | macro_rules! ty_app { |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index de3c56097..397ee7d5f 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -19,18 +19,17 @@ use super::{ | |||
19 | TypeWalk, | 19 | TypeWalk, |
20 | }; | 20 | }; |
21 | use crate::{ | 21 | use crate::{ |
22 | adt::VariantDef, | ||
23 | db::HirDatabase, | 22 | db::HirDatabase, |
24 | generics::HasGenericParams, | 23 | generics::HasGenericParams, |
25 | generics::{GenericDef, WherePredicate}, | 24 | generics::{GenericDef, WherePredicate}, |
26 | resolve::{Resolver, TypeNs}, | 25 | resolve::{HasResolver, Resolver, TypeNs}, |
27 | ty::{ | 26 | ty::{ |
28 | primitive::{FloatTy, IntTy, Uncertain}, | 27 | primitive::{FloatTy, IntTy, Uncertain}, |
29 | Adt, | 28 | Adt, |
30 | }, | 29 | }, |
31 | util::make_mut_slice, | 30 | util::make_mut_slice, |
32 | Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, | 31 | Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, |
33 | TypeAlias, Union, | 32 | TypeAlias, Union, VariantDef, |
34 | }; | 33 | }; |
35 | 34 | ||
36 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of | 35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of |
@@ -611,9 +610,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> | |||
611 | let defaults = generic_params | 610 | let defaults = generic_params |
612 | .params_including_parent() | 611 | .params_including_parent() |
613 | .into_iter() | 612 | .into_iter() |
614 | .map(|p| { | 613 | .map(|p| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) |
615 | p.default.as_ref().map_or(Ty::Unknown, |path| Ty::from_hir_path(db, &resolver, path)) | ||
616 | }) | ||
617 | .collect(); | 614 | .collect(); |
618 | 615 | ||
619 | Substs(defaults) | 616 | Substs(defaults) |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index d20aeaacf..f377fca48 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -232,8 +232,8 @@ fn iterate_trait_method_candidates<T>( | |||
232 | // trait, but if we find out it doesn't, we'll skip the rest of the | 232 | // trait, but if we find out it doesn't, we'll skip the rest of the |
233 | // iteration | 233 | // iteration |
234 | let mut known_implemented = false; | 234 | let mut known_implemented = false; |
235 | for &item in data.items() { | 235 | for &item in data.items.iter() { |
236 | if !is_valid_candidate(db, name, mode, item) { | 236 | if !is_valid_candidate(db, name, mode, item.into()) { |
237 | continue; | 237 | continue; |
238 | } | 238 | } |
239 | if !known_implemented { | 239 | if !known_implemented { |
@@ -243,7 +243,7 @@ fn iterate_trait_method_candidates<T>( | |||
243 | } | 243 | } |
244 | } | 244 | } |
245 | known_implemented = true; | 245 | known_implemented = true; |
246 | if let Some(result) = callback(&ty.value, item) { | 246 | if let Some(result) = callback(&ty.value, item.into()) { |
247 | return Some(result); | 247 | return Some(result); |
248 | } | 248 | } |
249 | } | 249 | } |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index ca1693679..74c12a0a2 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -11,6 +11,7 @@ use ra_syntax::{ | |||
11 | ast::{self, AstNode}, | 11 | ast::{self, AstNode}, |
12 | SyntaxKind::*, | 12 | SyntaxKind::*, |
13 | }; | 13 | }; |
14 | use rustc_hash::FxHashSet; | ||
14 | use test_utils::covers; | 15 | use test_utils::covers; |
15 | 16 | ||
16 | use crate::{ | 17 | use crate::{ |
@@ -1980,6 +1981,30 @@ fn test() { | |||
1980 | } | 1981 | } |
1981 | 1982 | ||
1982 | #[test] | 1983 | #[test] |
1984 | fn infer_associated_method_generics_with_default_tuple_param() { | ||
1985 | let t = type_at( | ||
1986 | r#" | ||
1987 | //- /main.rs | ||
1988 | struct Gen<T=()> { | ||
1989 | val: T | ||
1990 | } | ||
1991 | |||
1992 | impl<T> Gen<T> { | ||
1993 | pub fn make() -> Gen<T> { | ||
1994 | loop { } | ||
1995 | } | ||
1996 | } | ||
1997 | |||
1998 | fn test() { | ||
1999 | let a = Gen::make(); | ||
2000 | a.val<|>; | ||
2001 | } | ||
2002 | "#, | ||
2003 | ); | ||
2004 | assert_eq!(t, "()"); | ||
2005 | } | ||
2006 | |||
2007 | #[test] | ||
1983 | fn infer_associated_method_generics_without_args() { | 2008 | fn infer_associated_method_generics_without_args() { |
1984 | assert_snapshot!( | 2009 | assert_snapshot!( |
1985 | infer(r#" | 2010 | infer(r#" |
@@ -2494,7 +2519,6 @@ fn test() { | |||
2494 | [167; 179) 'GLOBAL_CONST': u32 | 2519 | [167; 179) 'GLOBAL_CONST': u32 |
2495 | [189; 191) 'id': u32 | 2520 | [189; 191) 'id': u32 |
2496 | [194; 210) 'Foo::A..._CONST': u32 | 2521 | [194; 210) 'Foo::A..._CONST': u32 |
2497 | [126; 128) '99': u32 | ||
2498 | "### | 2522 | "### |
2499 | ); | 2523 | ); |
2500 | } | 2524 | } |
@@ -4694,14 +4718,16 @@ fn infer(content: &str) -> String { | |||
4694 | } | 4718 | } |
4695 | 4719 | ||
4696 | // sort ranges for consistency | 4720 | // sort ranges for consistency |
4697 | types.sort_by_key(|(src_ptr, _)| (src_ptr.ast.range().start(), src_ptr.ast.range().end())); | 4721 | types.sort_by_key(|(src_ptr, _)| { |
4722 | (src_ptr.value.range().start(), src_ptr.value.range().end()) | ||
4723 | }); | ||
4698 | for (src_ptr, ty) in &types { | 4724 | for (src_ptr, ty) in &types { |
4699 | let node = src_ptr.ast.to_node(&src_ptr.file_syntax(&db)); | 4725 | let node = src_ptr.value.to_node(&src_ptr.file_syntax(&db)); |
4700 | 4726 | ||
4701 | let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) { | 4727 | let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) { |
4702 | (self_param.self_kw_token().text_range(), "self".to_string()) | 4728 | (self_param.self_kw_token().text_range(), "self".to_string()) |
4703 | } else { | 4729 | } else { |
4704 | (src_ptr.ast.range(), node.text().to_string().replace("\n", " ")) | 4730 | (src_ptr.value.range(), node.text().to_string().replace("\n", " ")) |
4705 | }; | 4731 | }; |
4706 | let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; | 4732 | let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; |
4707 | write!( | 4733 | write!( |
@@ -4716,10 +4742,13 @@ fn infer(content: &str) -> String { | |||
4716 | } | 4742 | } |
4717 | }; | 4743 | }; |
4718 | 4744 | ||
4745 | let mut analyzed = FxHashSet::default(); | ||
4719 | for node in source_file.syntax().descendants() { | 4746 | for node in source_file.syntax().descendants() { |
4720 | if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { | 4747 | if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { |
4721 | let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); | 4748 | let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); |
4722 | infer_def(analyzer.inference_result(), analyzer.body_source_map()); | 4749 | if analyzed.insert(analyzer.analyzed_declaration()) { |
4750 | infer_def(analyzer.inference_result(), analyzer.body_source_map()); | ||
4751 | } | ||
4723 | } | 4752 | } |
4724 | } | 4753 | } |
4725 | 4754 | ||
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs index 078e6295e..392f244cf 100644 --- a/crates/ra_hir/src/type_alias.rs +++ b/crates/ra_hir/src/type_alias.rs | |||
@@ -23,7 +23,7 @@ impl TypeAliasData { | |||
23 | db: &(impl DefDatabase + AstDatabase), | 23 | db: &(impl DefDatabase + AstDatabase), |
24 | typ: TypeAlias, | 24 | typ: TypeAlias, |
25 | ) -> Arc<TypeAliasData> { | 25 | ) -> Arc<TypeAliasData> { |
26 | let node = typ.source(db).ast; | 26 | let node = typ.source(db).value; |
27 | let name = node.name().map_or_else(Name::missing, |n| n.as_name()); | 27 | let name = node.name().map_or_else(Name::missing, |n| n.as_name()); |
28 | let type_ref = node.type_ref().map(TypeRef::from_ast); | 28 | let type_ref = node.type_ref().map(TypeRef::from_ast); |
29 | Arc::new(TypeAliasData { name, type_ref }) | 29 | Arc::new(TypeAliasData { name, type_ref }) |
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index a29c4d41e..d04f54e15 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -54,8 +54,8 @@ impl StructData { | |||
54 | id: StructOrUnionId, | 54 | id: StructOrUnionId, |
55 | ) -> Arc<StructData> { | 55 | ) -> Arc<StructData> { |
56 | let src = id.source(db); | 56 | let src = id.source(db); |
57 | let name = src.ast.name().map(|n| n.as_name()); | 57 | let name = src.value.name().map(|n| n.as_name()); |
58 | let variant_data = VariantData::new(src.ast.kind()); | 58 | let variant_data = VariantData::new(src.value.kind()); |
59 | let variant_data = Arc::new(variant_data); | 59 | let variant_data = Arc::new(variant_data); |
60 | Arc::new(StructData { name, variant_data }) | 60 | Arc::new(StructData { name, variant_data }) |
61 | } | 61 | } |
@@ -64,9 +64,9 @@ impl StructData { | |||
64 | impl EnumData { | 64 | impl EnumData { |
65 | pub(crate) fn enum_data_query(db: &impl DefDatabase2, e: EnumId) -> Arc<EnumData> { | 65 | pub(crate) fn enum_data_query(db: &impl DefDatabase2, e: EnumId) -> Arc<EnumData> { |
66 | let src = e.source(db); | 66 | let src = e.source(db); |
67 | let name = src.ast.name().map(|n| n.as_name()); | 67 | let name = src.value.name().map(|n| n.as_name()); |
68 | let variants = src | 68 | let variants = src |
69 | .ast | 69 | .value |
70 | .variant_list() | 70 | .variant_list() |
71 | .into_iter() | 71 | .into_iter() |
72 | .flat_map(|it| it.variants()) | 72 | .flat_map(|it| it.variants()) |
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 85dc4feb0..dfb79a30a 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | expr::{Expr, ExprId, Pat, PatId}, | 17 | expr::{Expr, ExprId, Pat, PatId}, |
18 | nameres::CrateDefMap, | 18 | nameres::CrateDefMap, |
19 | path::Path, | 19 | path::Path, |
20 | AstItemDef, DefWithBodyId, ModuleId, | 20 | AstItemDef, DefWithBodyId, HasModule, HasSource, Lookup, ModuleId, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | pub struct Expander { | 23 | pub struct Expander { |
@@ -73,8 +73,8 @@ impl Expander { | |||
73 | std::mem::forget(mark); | 73 | std::mem::forget(mark); |
74 | } | 74 | } |
75 | 75 | ||
76 | fn to_source<T>(&self, ast: T) -> Source<T> { | 76 | fn to_source<T>(&self, value: T) -> Source<T> { |
77 | Source { file_id: self.current_file_id, ast } | 77 | Source { file_id: self.current_file_id, value } |
78 | } | 78 | } |
79 | 79 | ||
80 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { | 80 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { |
@@ -149,17 +149,19 @@ impl Body { | |||
149 | 149 | ||
150 | let (file_id, module, body) = match def { | 150 | let (file_id, module, body) = match def { |
151 | DefWithBodyId::FunctionId(f) => { | 151 | DefWithBodyId::FunctionId(f) => { |
152 | let f = f.lookup(db); | ||
152 | let src = f.source(db); | 153 | let src = f.source(db); |
153 | params = src.ast.param_list(); | 154 | params = src.value.param_list(); |
154 | (src.file_id, f.module(db), src.ast.body().map(ast::Expr::from)) | 155 | (src.file_id, f.module(db), src.value.body().map(ast::Expr::from)) |
155 | } | 156 | } |
156 | DefWithBodyId::ConstId(c) => { | 157 | DefWithBodyId::ConstId(c) => { |
158 | let c = c.lookup(db); | ||
157 | let src = c.source(db); | 159 | let src = c.source(db); |
158 | (src.file_id, c.module(db), src.ast.body()) | 160 | (src.file_id, c.module(db), src.value.body()) |
159 | } | 161 | } |
160 | DefWithBodyId::StaticId(s) => { | 162 | DefWithBodyId::StaticId(s) => { |
161 | let src = s.source(db); | 163 | let src = s.source(db); |
162 | (src.file_id, s.module(db), src.ast.body()) | 164 | (src.file_id, s.module(db), src.value.body()) |
163 | } | 165 | } |
164 | }; | 166 | }; |
165 | let expander = Expander::new(db, file_id, module); | 167 | let expander = Expander::new(db, file_id, module); |
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 10cb87d37..aeb71ff22 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -210,8 +210,9 @@ mod tests { | |||
210 | let scopes = db.expr_scopes(function.into()); | 210 | let scopes = db.expr_scopes(function.into()); |
211 | let (_body, source_map) = db.body_with_source_map(function.into()); | 211 | let (_body, source_map) = db.body_with_source_map(function.into()); |
212 | 212 | ||
213 | let expr_id = | 213 | let expr_id = source_map |
214 | source_map.node_expr(Source { file_id: file_id.into(), ast: &marker.into() }).unwrap(); | 214 | .node_expr(Source { file_id: file_id.into(), value: &marker.into() }) |
215 | .unwrap(); | ||
215 | let scope = scopes.scope_for(expr_id); | 216 | let scope = scopes.scope_for(expr_id); |
216 | 217 | ||
217 | let actual = scopes | 218 | let actual = scopes |
@@ -317,14 +318,14 @@ mod tests { | |||
317 | let expr_scope = { | 318 | let expr_scope = { |
318 | let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); | 319 | let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); |
319 | let expr_id = | 320 | let expr_id = |
320 | source_map.node_expr(Source { file_id: file_id.into(), ast: &expr_ast }).unwrap(); | 321 | source_map.node_expr(Source { file_id: file_id.into(), value: &expr_ast }).unwrap(); |
321 | scopes.scope_for(expr_id).unwrap() | 322 | scopes.scope_for(expr_id).unwrap() |
322 | }; | 323 | }; |
323 | 324 | ||
324 | let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap(); | 325 | let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap(); |
325 | let pat_src = source_map.pat_syntax(resolved.pat()).unwrap(); | 326 | let pat_src = source_map.pat_syntax(resolved.pat()).unwrap(); |
326 | 327 | ||
327 | let local_name = pat_src.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); | 328 | let local_name = pat_src.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); |
328 | assert_eq!(local_name.range(), expected_name.syntax().text_range()); | 329 | assert_eq!(local_name.range(), expected_name.syntax().text_range()); |
329 | } | 330 | } |
330 | 331 | ||
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 348aca07f..844f8bbe8 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -8,30 +8,32 @@ use ra_syntax::ast; | |||
8 | use crate::{ | 8 | use crate::{ |
9 | adt::{EnumData, StructData}, | 9 | adt::{EnumData, StructData}, |
10 | body::{scope::ExprScopes, Body, BodySourceMap}, | 10 | body::{scope::ExprScopes, Body, BodySourceMap}, |
11 | imp::ImplData, | 11 | generics::GenericParams, |
12 | impls::ImplData, | ||
12 | nameres::{ | 13 | nameres::{ |
13 | raw::{ImportSourceMap, RawItems}, | 14 | raw::{ImportSourceMap, RawItems}, |
14 | CrateDefMap, | 15 | CrateDefMap, |
15 | }, | 16 | }, |
16 | DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, | 17 | traits::TraitData, |
18 | DefWithBodyId, EnumId, GenericDefId, ImplId, ItemLoc, StructOrUnionId, TraitId, | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | #[salsa::query_group(InternDatabaseStorage)] | 21 | #[salsa::query_group(InternDatabaseStorage)] |
20 | pub trait InternDatabase: SourceDatabase { | 22 | pub trait InternDatabase: SourceDatabase { |
21 | #[salsa::interned] | 23 | #[salsa::interned] |
22 | fn intern_function(&self, loc: ItemLoc<ast::FnDef>) -> crate::FunctionId; | 24 | fn intern_function(&self, loc: crate::FunctionLoc) -> crate::FunctionId; |
23 | #[salsa::interned] | 25 | #[salsa::interned] |
24 | fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId; | 26 | fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId; |
25 | #[salsa::interned] | 27 | #[salsa::interned] |
26 | fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId; | 28 | fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId; |
27 | #[salsa::interned] | 29 | #[salsa::interned] |
28 | fn intern_const(&self, loc: ItemLoc<ast::ConstDef>) -> crate::ConstId; | 30 | fn intern_const(&self, loc: crate::ConstLoc) -> crate::ConstId; |
29 | #[salsa::interned] | 31 | #[salsa::interned] |
30 | fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId; | 32 | fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId; |
31 | #[salsa::interned] | 33 | #[salsa::interned] |
32 | fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId; | 34 | fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId; |
33 | #[salsa::interned] | 35 | #[salsa::interned] |
34 | fn intern_type_alias(&self, loc: ItemLoc<ast::TypeAliasDef>) -> crate::TypeAliasId; | 36 | fn intern_type_alias(&self, loc: crate::TypeAliasLoc) -> crate::TypeAliasId; |
35 | #[salsa::interned] | 37 | #[salsa::interned] |
36 | fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId; | 38 | fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId; |
37 | } | 39 | } |
@@ -59,6 +61,9 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
59 | #[salsa::invoke(ImplData::impl_data_query)] | 61 | #[salsa::invoke(ImplData::impl_data_query)] |
60 | fn impl_data(&self, e: ImplId) -> Arc<ImplData>; | 62 | fn impl_data(&self, e: ImplId) -> Arc<ImplData>; |
61 | 63 | ||
64 | #[salsa::invoke(TraitData::trait_data_query)] | ||
65 | fn trait_data(&self, e: TraitId) -> Arc<TraitData>; | ||
66 | |||
62 | #[salsa::invoke(Body::body_with_source_map_query)] | 67 | #[salsa::invoke(Body::body_with_source_map_query)] |
63 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); | 68 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); |
64 | 69 | ||
@@ -67,4 +72,7 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
67 | 72 | ||
68 | #[salsa::invoke(ExprScopes::expr_scopes_query)] | 73 | #[salsa::invoke(ExprScopes::expr_scopes_query)] |
69 | fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>; | 74 | fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>; |
75 | |||
76 | #[salsa::invoke(GenericParams::generic_params_query)] | ||
77 | fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; | ||
70 | } | 78 | } |
diff --git a/crates/ra_hir_def/src/diagnostics.rs b/crates/ra_hir_def/src/diagnostics.rs index 9843009a5..eda9b2269 100644 --- a/crates/ra_hir_def/src/diagnostics.rs +++ b/crates/ra_hir_def/src/diagnostics.rs | |||
@@ -20,7 +20,7 @@ impl Diagnostic for UnresolvedModule { | |||
20 | "unresolved module".to_string() | 20 | "unresolved module".to_string() |
21 | } | 21 | } |
22 | fn source(&self) -> Source<SyntaxNodePtr> { | 22 | fn source(&self) -> Source<SyntaxNodePtr> { |
23 | Source { file_id: self.file, ast: self.decl.into() } | 23 | Source { file_id: self.file, value: self.decl.into() } |
24 | } | 24 | } |
25 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 25 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
26 | self | 26 | self |
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs new file mode 100644 index 000000000..9e2e4c3cc --- /dev/null +++ b/crates/ra_hir_def/src/generics.rs | |||
@@ -0,0 +1,185 @@ | |||
1 | //! Many kinds of items or constructs can have generic parameters: functions, | ||
2 | //! structs, impls, traits, etc. This module provides a common HIR for these | ||
3 | //! generic parameters. See also the `Generics` type and the `generics_of` query | ||
4 | //! in rustc. | ||
5 | use std::sync::Arc; | ||
6 | |||
7 | use hir_expand::name::{self, AsName, Name}; | ||
8 | use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; | ||
9 | |||
10 | use crate::{ | ||
11 | db::DefDatabase2, | ||
12 | type_ref::{TypeBound, TypeRef}, | ||
13 | AdtId, AstItemDef, ContainerId, GenericDefId, HasSource, Lookup, | ||
14 | }; | ||
15 | |||
16 | /// Data about a generic parameter (to a function, struct, impl, ...). | ||
17 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
18 | pub struct GenericParam { | ||
19 | // FIXME: give generic params proper IDs | ||
20 | pub idx: u32, | ||
21 | pub name: Name, | ||
22 | pub default: Option<TypeRef>, | ||
23 | } | ||
24 | |||
25 | /// Data about the generic parameters of a function, struct, impl, etc. | ||
26 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
27 | pub struct GenericParams { | ||
28 | pub parent_params: Option<Arc<GenericParams>>, | ||
29 | pub params: Vec<GenericParam>, | ||
30 | pub where_predicates: Vec<WherePredicate>, | ||
31 | } | ||
32 | |||
33 | /// A single predicate from a where clause, i.e. `where Type: Trait`. Combined | ||
34 | /// where clauses like `where T: Foo + Bar` are turned into multiple of these. | ||
35 | /// It might still result in multiple actual predicates though, because of | ||
36 | /// associated type bindings like `Iterator<Item = u32>`. | ||
37 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
38 | pub struct WherePredicate { | ||
39 | pub type_ref: TypeRef, | ||
40 | pub bound: TypeBound, | ||
41 | } | ||
42 | |||
43 | impl GenericParams { | ||
44 | pub(crate) fn generic_params_query( | ||
45 | db: &impl DefDatabase2, | ||
46 | def: GenericDefId, | ||
47 | ) -> Arc<GenericParams> { | ||
48 | let parent_generics = parent_generic_def(db, def).map(|it| db.generic_params(it)); | ||
49 | Arc::new(GenericParams::new(db, def.into(), parent_generics)) | ||
50 | } | ||
51 | |||
52 | fn new( | ||
53 | db: &impl DefDatabase2, | ||
54 | def: GenericDefId, | ||
55 | parent_params: Option<Arc<GenericParams>>, | ||
56 | ) -> GenericParams { | ||
57 | let mut generics = | ||
58 | GenericParams { params: Vec::new(), parent_params, where_predicates: Vec::new() }; | ||
59 | let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; | ||
60 | // FIXME: add `: Sized` bound for everything except for `Self` in traits | ||
61 | match def { | ||
62 | GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), | ||
63 | GenericDefId::AdtId(AdtId::StructId(it)) => { | ||
64 | generics.fill(&it.0.source(db).value, start) | ||
65 | } | ||
66 | GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.0.source(db).value, start), | ||
67 | GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), | ||
68 | GenericDefId::TraitId(it) => { | ||
69 | // traits get the Self type as an implicit first type parameter | ||
70 | generics.params.push(GenericParam { | ||
71 | idx: start, | ||
72 | name: name::SELF_TYPE, | ||
73 | default: None, | ||
74 | }); | ||
75 | generics.fill(&it.source(db).value, start + 1); | ||
76 | // add super traits as bounds on Self | ||
77 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar | ||
78 | let self_param = TypeRef::Path(name::SELF_TYPE.into()); | ||
79 | generics.fill_bounds(&it.source(db).value, self_param); | ||
80 | } | ||
81 | GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start), | ||
82 | // Note that we don't add `Self` here: in `impl`s, `Self` is not a | ||
83 | // type-parameter, but rather is a type-alias for impl's target | ||
84 | // type, so this is handled by the resolver. | ||
85 | GenericDefId::ImplId(it) => generics.fill(&it.source(db).value, start), | ||
86 | GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} | ||
87 | } | ||
88 | |||
89 | generics | ||
90 | } | ||
91 | |||
92 | fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) { | ||
93 | if let Some(params) = node.type_param_list() { | ||
94 | self.fill_params(params, start) | ||
95 | } | ||
96 | if let Some(where_clause) = node.where_clause() { | ||
97 | self.fill_where_predicates(where_clause); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) { | ||
102 | for bound in | ||
103 | node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) | ||
104 | { | ||
105 | self.add_where_predicate_from_bound(bound, type_ref.clone()); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { | ||
110 | for (idx, type_param) in params.type_params().enumerate() { | ||
111 | let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); | ||
112 | // FIXME: Use `Path::from_src` | ||
113 | let default = type_param.default_type().map(TypeRef::from_ast); | ||
114 | let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; | ||
115 | self.params.push(param); | ||
116 | |||
117 | let type_ref = TypeRef::Path(name.into()); | ||
118 | self.fill_bounds(&type_param, type_ref); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) { | ||
123 | for pred in where_clause.predicates() { | ||
124 | let type_ref = match pred.type_ref() { | ||
125 | Some(type_ref) => type_ref, | ||
126 | None => continue, | ||
127 | }; | ||
128 | let type_ref = TypeRef::from_ast(type_ref); | ||
129 | for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { | ||
130 | self.add_where_predicate_from_bound(bound, type_ref.clone()); | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { | ||
136 | if bound.has_question_mark() { | ||
137 | // FIXME: remove this bound | ||
138 | return; | ||
139 | } | ||
140 | let bound = TypeBound::from_ast(bound); | ||
141 | self.where_predicates.push(WherePredicate { type_ref, bound }); | ||
142 | } | ||
143 | |||
144 | pub fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { | ||
145 | self.params.iter().find(|p| &p.name == name) | ||
146 | } | ||
147 | |||
148 | pub fn count_parent_params(&self) -> usize { | ||
149 | self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0) | ||
150 | } | ||
151 | |||
152 | pub fn count_params_including_parent(&self) -> usize { | ||
153 | let parent_count = self.count_parent_params(); | ||
154 | parent_count + self.params.len() | ||
155 | } | ||
156 | |||
157 | fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) { | ||
158 | if let Some(parent) = &self.parent_params { | ||
159 | parent.for_each_param(f); | ||
160 | } | ||
161 | self.params.iter().for_each(f); | ||
162 | } | ||
163 | |||
164 | pub fn params_including_parent(&self) -> Vec<&GenericParam> { | ||
165 | let mut vec = Vec::with_capacity(self.count_params_including_parent()); | ||
166 | self.for_each_param(&mut |p| vec.push(p)); | ||
167 | vec | ||
168 | } | ||
169 | } | ||
170 | |||
171 | fn parent_generic_def(db: &impl DefDatabase2, def: GenericDefId) -> Option<GenericDefId> { | ||
172 | let container = match def { | ||
173 | GenericDefId::FunctionId(it) => it.lookup(db).container, | ||
174 | GenericDefId::TypeAliasId(it) => it.lookup(db).container, | ||
175 | GenericDefId::ConstId(it) => it.lookup(db).container, | ||
176 | GenericDefId::EnumVariantId(it) => return Some(it.parent.into()), | ||
177 | GenericDefId::AdtId(_) | GenericDefId::TraitId(_) | GenericDefId::ImplId(_) => return None, | ||
178 | }; | ||
179 | |||
180 | match container { | ||
181 | ContainerId::ImplId(it) => Some(it.into()), | ||
182 | ContainerId::TraitId(it) => Some(it.into()), | ||
183 | ContainerId::ModuleId(_) => None, | ||
184 | } | ||
185 | } | ||
diff --git a/crates/ra_hir_def/src/imp.rs b/crates/ra_hir_def/src/impls.rs index 717991c40..750a869f2 100644 --- a/crates/ra_hir_def/src/imp.rs +++ b/crates/ra_hir_def/src/impls.rs | |||
@@ -5,11 +5,12 @@ | |||
5 | 5 | ||
6 | use std::sync::Arc; | 6 | use std::sync::Arc; |
7 | 7 | ||
8 | use hir_expand::AstId; | ||
8 | use ra_syntax::ast; | 9 | use ra_syntax::ast; |
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
11 | db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionId, ImplId, | 12 | db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstLoc, ContainerId, |
12 | LocationCtx, TypeAliasId, | 13 | FunctionLoc, ImplId, Intern, TypeAliasLoc, |
13 | }; | 14 | }; |
14 | 15 | ||
15 | #[derive(Debug, Clone, PartialEq, Eq)] | 16 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -25,23 +26,37 @@ impl ImplData { | |||
25 | let src = id.source(db); | 26 | let src = id.source(db); |
26 | let items = db.ast_id_map(src.file_id); | 27 | let items = db.ast_id_map(src.file_id); |
27 | 28 | ||
28 | let target_trait = src.ast.target_trait().map(TypeRef::from_ast); | 29 | let target_trait = src.value.target_trait().map(TypeRef::from_ast); |
29 | let target_type = TypeRef::from_ast_opt(src.ast.target_type()); | 30 | let target_type = TypeRef::from_ast_opt(src.value.target_type()); |
30 | let negative = src.ast.is_negative(); | 31 | let negative = src.value.is_negative(); |
31 | 32 | ||
32 | let items = if let Some(item_list) = src.ast.item_list() { | 33 | let items = if let Some(item_list) = src.value.item_list() { |
33 | let ctx = LocationCtx::new(db, id.module(db), src.file_id); | ||
34 | item_list | 34 | item_list |
35 | .impl_items() | 35 | .impl_items() |
36 | .map(|item_node| match item_node { | 36 | .map(|item_node| match item_node { |
37 | ast::ImplItem::FnDef(it) => { | 37 | ast::ImplItem::FnDef(it) => { |
38 | FunctionId::from_ast_id(ctx, items.ast_id(&it)).into() | 38 | let def = FunctionLoc { |
39 | container: ContainerId::ImplId(id), | ||
40 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | ||
41 | } | ||
42 | .intern(db); | ||
43 | def.into() | ||
39 | } | 44 | } |
40 | ast::ImplItem::ConstDef(it) => { | 45 | ast::ImplItem::ConstDef(it) => { |
41 | ConstId::from_ast_id(ctx, items.ast_id(&it)).into() | 46 | let def = ConstLoc { |
47 | container: ContainerId::ImplId(id), | ||
48 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | ||
49 | } | ||
50 | .intern(db); | ||
51 | def.into() | ||
42 | } | 52 | } |
43 | ast::ImplItem::TypeAliasDef(it) => { | 53 | ast::ImplItem::TypeAliasDef(it) => { |
44 | TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into() | 54 | let def = TypeAliasLoc { |
55 | container: ContainerId::ImplId(id), | ||
56 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | ||
57 | } | ||
58 | .intern(db); | ||
59 | def.into() | ||
45 | } | 60 | } |
46 | }) | 61 | }) |
47 | .collect() | 62 | .collect() |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index a240a10b8..0af41de87 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -13,10 +13,12 @@ pub mod path; | |||
13 | pub mod type_ref; | 13 | pub mod type_ref; |
14 | pub mod builtin_type; | 14 | pub mod builtin_type; |
15 | pub mod adt; | 15 | pub mod adt; |
16 | pub mod imp; | 16 | pub mod impls; |
17 | pub mod diagnostics; | 17 | pub mod diagnostics; |
18 | pub mod expr; | 18 | pub mod expr; |
19 | pub mod body; | 19 | pub mod body; |
20 | pub mod generics; | ||
21 | pub mod traits; | ||
20 | 22 | ||
21 | #[cfg(test)] | 23 | #[cfg(test)] |
22 | mod test_db; | 24 | mod test_db; |
@@ -80,7 +82,7 @@ impl ModuleSource { | |||
80 | 82 | ||
81 | pub fn from_child_node(db: &impl db::DefDatabase2, child: Source<&SyntaxNode>) -> ModuleSource { | 83 | pub fn from_child_node(db: &impl db::DefDatabase2, child: Source<&SyntaxNode>) -> ModuleSource { |
82 | if let Some(m) = | 84 | if let Some(m) = |
83 | child.ast.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) | 85 | child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) |
84 | { | 86 | { |
85 | ModuleSource::Module(m) | 87 | ModuleSource::Module(m) |
86 | } else { | 88 | } else { |
@@ -184,8 +186,8 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | |||
184 | } | 186 | } |
185 | fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> { | 187 | fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> { |
186 | let loc = self.lookup_intern(db); | 188 | let loc = self.lookup_intern(db); |
187 | let ast = loc.ast_id.to_node(db); | 189 | let value = loc.ast_id.to_node(db); |
188 | Source { file_id: loc.ast_id.file_id(), ast } | 190 | Source { file_id: loc.ast_id.file_id(), value } |
189 | } | 191 | } |
190 | fn module(self, db: &impl InternDatabase) -> ModuleId { | 192 | fn module(self, db: &impl InternDatabase) -> ModuleId { |
191 | let loc = self.lookup_intern(db); | 193 | let loc = self.lookup_intern(db); |
@@ -197,12 +199,23 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | |||
197 | pub struct FunctionId(salsa::InternId); | 199 | pub struct FunctionId(salsa::InternId); |
198 | impl_intern_key!(FunctionId); | 200 | impl_intern_key!(FunctionId); |
199 | 201 | ||
200 | impl AstItemDef<ast::FnDef> for FunctionId { | 202 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
201 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::FnDef>) -> Self { | 203 | pub struct FunctionLoc { |
202 | db.intern_function(loc) | 204 | pub container: ContainerId, |
205 | pub ast_id: AstId<ast::FnDef>, | ||
206 | } | ||
207 | |||
208 | impl Intern for FunctionLoc { | ||
209 | type ID = FunctionId; | ||
210 | fn intern(self, db: &impl db::DefDatabase2) -> FunctionId { | ||
211 | db.intern_function(self) | ||
203 | } | 212 | } |
204 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::FnDef> { | 213 | } |
205 | db.lookup_intern_function(self) | 214 | |
215 | impl Lookup for FunctionId { | ||
216 | type Data = FunctionLoc; | ||
217 | fn lookup(&self, db: &impl db::DefDatabase2) -> FunctionLoc { | ||
218 | db.lookup_intern_function(*self) | ||
206 | } | 219 | } |
207 | } | 220 | } |
208 | 221 | ||
@@ -276,12 +289,23 @@ impl_arena_id!(LocalStructFieldId); | |||
276 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 289 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
277 | pub struct ConstId(salsa::InternId); | 290 | pub struct ConstId(salsa::InternId); |
278 | impl_intern_key!(ConstId); | 291 | impl_intern_key!(ConstId); |
279 | impl AstItemDef<ast::ConstDef> for ConstId { | 292 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
280 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self { | 293 | pub struct ConstLoc { |
281 | db.intern_const(loc) | 294 | pub container: ContainerId, |
295 | pub ast_id: AstId<ast::ConstDef>, | ||
296 | } | ||
297 | |||
298 | impl Intern for ConstLoc { | ||
299 | type ID = ConstId; | ||
300 | fn intern(self, db: &impl db::DefDatabase2) -> ConstId { | ||
301 | db.intern_const(self) | ||
282 | } | 302 | } |
283 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ConstDef> { | 303 | } |
284 | db.lookup_intern_const(self) | 304 | |
305 | impl Lookup for ConstId { | ||
306 | type Data = ConstLoc; | ||
307 | fn lookup(&self, db: &impl db::DefDatabase2) -> ConstLoc { | ||
308 | db.lookup_intern_const(*self) | ||
285 | } | 309 | } |
286 | } | 310 | } |
287 | 311 | ||
@@ -312,12 +336,24 @@ impl AstItemDef<ast::TraitDef> for TraitId { | |||
312 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 336 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
313 | pub struct TypeAliasId(salsa::InternId); | 337 | pub struct TypeAliasId(salsa::InternId); |
314 | impl_intern_key!(TypeAliasId); | 338 | impl_intern_key!(TypeAliasId); |
315 | impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { | 339 | |
316 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self { | 340 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
317 | db.intern_type_alias(loc) | 341 | pub struct TypeAliasLoc { |
342 | pub container: ContainerId, | ||
343 | pub ast_id: AstId<ast::TypeAliasDef>, | ||
344 | } | ||
345 | |||
346 | impl Intern for TypeAliasLoc { | ||
347 | type ID = TypeAliasId; | ||
348 | fn intern(self, db: &impl db::DefDatabase2) -> TypeAliasId { | ||
349 | db.intern_type_alias(self) | ||
318 | } | 350 | } |
319 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TypeAliasDef> { | 351 | } |
320 | db.lookup_intern_type_alias(self) | 352 | |
353 | impl Lookup for TypeAliasId { | ||
354 | type Data = TypeAliasLoc; | ||
355 | fn lookup(&self, db: &impl db::DefDatabase2) -> TypeAliasLoc { | ||
356 | db.lookup_intern_type_alias(*self) | ||
321 | } | 357 | } |
322 | } | 358 | } |
323 | 359 | ||
@@ -352,6 +388,13 @@ macro_rules! impl_froms { | |||
352 | } | 388 | } |
353 | } | 389 | } |
354 | 390 | ||
391 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
392 | pub enum ContainerId { | ||
393 | ModuleId(ModuleId), | ||
394 | ImplId(ImplId), | ||
395 | TraitId(TraitId), | ||
396 | } | ||
397 | |||
355 | /// A Data Type | 398 | /// A Data Type |
356 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 399 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
357 | pub enum AdtId { | 400 | pub enum AdtId { |
@@ -408,3 +451,102 @@ pub enum AssocItemId { | |||
408 | // require not implementing From, and instead having some checked way of | 451 | // require not implementing From, and instead having some checked way of |
409 | // casting them, and somehow making the constructors private, which would be annoying. | 452 | // casting them, and somehow making the constructors private, which would be annoying. |
410 | impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); | 453 | impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); |
454 | |||
455 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
456 | pub enum GenericDefId { | ||
457 | FunctionId(FunctionId), | ||
458 | AdtId(AdtId), | ||
459 | TraitId(TraitId), | ||
460 | TypeAliasId(TypeAliasId), | ||
461 | ImplId(ImplId), | ||
462 | // enum variants cannot have generics themselves, but their parent enums | ||
463 | // can, and this makes some code easier to write | ||
464 | EnumVariantId(EnumVariantId), | ||
465 | // consts can have type parameters from their parents (i.e. associated consts of traits) | ||
466 | ConstId(ConstId), | ||
467 | } | ||
468 | impl_froms!( | ||
469 | GenericDefId: FunctionId, | ||
470 | AdtId(StructId, EnumId, UnionId), | ||
471 | TraitId, | ||
472 | TypeAliasId, | ||
473 | ImplId, | ||
474 | EnumVariantId, | ||
475 | ConstId | ||
476 | ); | ||
477 | |||
478 | trait Intern { | ||
479 | type ID; | ||
480 | fn intern(self, db: &impl db::DefDatabase2) -> Self::ID; | ||
481 | } | ||
482 | |||
483 | pub trait Lookup { | ||
484 | type Data; | ||
485 | fn lookup(&self, db: &impl db::DefDatabase2) -> Self::Data; | ||
486 | } | ||
487 | |||
488 | pub trait HasModule { | ||
489 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId; | ||
490 | } | ||
491 | |||
492 | impl HasModule for FunctionLoc { | ||
493 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
494 | match self.container { | ||
495 | ContainerId::ModuleId(it) => it, | ||
496 | ContainerId::ImplId(it) => it.module(db), | ||
497 | ContainerId::TraitId(it) => it.module(db), | ||
498 | } | ||
499 | } | ||
500 | } | ||
501 | |||
502 | impl HasModule for TypeAliasLoc { | ||
503 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
504 | match self.container { | ||
505 | ContainerId::ModuleId(it) => it, | ||
506 | ContainerId::ImplId(it) => it.module(db), | ||
507 | ContainerId::TraitId(it) => it.module(db), | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | |||
512 | impl HasModule for ConstLoc { | ||
513 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { | ||
514 | match self.container { | ||
515 | ContainerId::ModuleId(it) => it, | ||
516 | ContainerId::ImplId(it) => it.module(db), | ||
517 | ContainerId::TraitId(it) => it.module(db), | ||
518 | } | ||
519 | } | ||
520 | } | ||
521 | |||
522 | pub trait HasSource { | ||
523 | type Value; | ||
524 | fn source(&self, db: &impl db::DefDatabase2) -> Source<Self::Value>; | ||
525 | } | ||
526 | |||
527 | impl HasSource for FunctionLoc { | ||
528 | type Value = ast::FnDef; | ||
529 | |||
530 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::FnDef> { | ||
531 | let node = self.ast_id.to_node(db); | ||
532 | Source::new(self.ast_id.file_id(), node) | ||
533 | } | ||
534 | } | ||
535 | |||
536 | impl HasSource for TypeAliasLoc { | ||
537 | type Value = ast::TypeAliasDef; | ||
538 | |||
539 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::TypeAliasDef> { | ||
540 | let node = self.ast_id.to_node(db); | ||
541 | Source::new(self.ast_id.file_id(), node) | ||
542 | } | ||
543 | } | ||
544 | |||
545 | impl HasSource for ConstLoc { | ||
546 | type Value = ast::ConstDef; | ||
547 | |||
548 | fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::ConstDef> { | ||
549 | let node = self.ast_id.to_node(db); | ||
550 | Source::new(self.ast_id.file_id(), node) | ||
551 | } | ||
552 | } | ||
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index e5b073a0f..c01e020ef 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -165,6 +165,14 @@ impl ModuleScope { | |||
165 | self.items.iter().chain(BUILTIN_SCOPE.iter()) | 165 | self.items.iter().chain(BUILTIN_SCOPE.iter()) |
166 | } | 166 | } |
167 | 167 | ||
168 | pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ { | ||
169 | self.entries() | ||
170 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) | ||
171 | .flat_map(|per_ns| { | ||
172 | per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) | ||
173 | }) | ||
174 | } | ||
175 | |||
168 | /// Iterate over all module scoped macros | 176 | /// Iterate over all module scoped macros |
169 | pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { | 177 | pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { |
170 | self.items | 178 | self.items |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 8f426b097..aae3dcadf 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -19,9 +19,9 @@ use crate::{ | |||
19 | per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode, | 19 | per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode, |
20 | }, | 20 | }, |
21 | path::{Path, PathKind}, | 21 | path::{Path, PathKind}, |
22 | AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId, ImplId, | 22 | AdtId, AstId, AstItemDef, ConstLoc, ContainerId, CrateModuleId, EnumId, EnumVariantId, |
23 | LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, StructOrUnionId, TraitId, TypeAliasId, | 23 | FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, |
24 | UnionId, | 24 | StructOrUnionId, TraitId, TypeAliasLoc, UnionId, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { | 27 | pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { |
@@ -673,8 +673,13 @@ where | |||
673 | let name = def.name.clone(); | 673 | let name = def.name.clone(); |
674 | let def: PerNs = match def.kind { | 674 | let def: PerNs = match def.kind { |
675 | raw::DefKind::Function(ast_id) => { | 675 | raw::DefKind::Function(ast_id) => { |
676 | let f = FunctionId::from_ast_id(ctx, ast_id); | 676 | let def = FunctionLoc { |
677 | PerNs::values(f.into()) | 677 | container: ContainerId::ModuleId(module), |
678 | ast_id: AstId::new(self.file_id, ast_id), | ||
679 | } | ||
680 | .intern(self.def_collector.db); | ||
681 | |||
682 | PerNs::values(def.into()) | ||
678 | } | 683 | } |
679 | raw::DefKind::Struct(ast_id) => { | 684 | raw::DefKind::Struct(ast_id) => { |
680 | let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); | 685 | let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); |
@@ -687,13 +692,27 @@ where | |||
687 | PerNs::both(u, u) | 692 | PerNs::both(u, u) |
688 | } | 693 | } |
689 | raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), | 694 | raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), |
690 | raw::DefKind::Const(ast_id) => PerNs::values(ConstId::from_ast_id(ctx, ast_id).into()), | 695 | raw::DefKind::Const(ast_id) => { |
696 | let def = ConstLoc { | ||
697 | container: ContainerId::ModuleId(module), | ||
698 | ast_id: AstId::new(self.file_id, ast_id), | ||
699 | } | ||
700 | .intern(self.def_collector.db); | ||
701 | |||
702 | PerNs::values(def.into()) | ||
703 | } | ||
691 | raw::DefKind::Static(ast_id) => { | 704 | raw::DefKind::Static(ast_id) => { |
692 | PerNs::values(StaticId::from_ast_id(ctx, ast_id).into()) | 705 | PerNs::values(StaticId::from_ast_id(ctx, ast_id).into()) |
693 | } | 706 | } |
694 | raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), | 707 | raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), |
695 | raw::DefKind::TypeAlias(ast_id) => { | 708 | raw::DefKind::TypeAlias(ast_id) => { |
696 | PerNs::types(TypeAliasId::from_ast_id(ctx, ast_id).into()) | 709 | let def = TypeAliasLoc { |
710 | container: ContainerId::ModuleId(module), | ||
711 | ast_id: AstId::new(self.file_id, ast_id), | ||
712 | } | ||
713 | .intern(self.def_collector.db); | ||
714 | |||
715 | PerNs::types(def.into()) | ||
697 | } | 716 | } |
698 | }; | 717 | }; |
699 | let resolution = Resolution { def, import: None }; | 718 | let resolution = Resolution { def, import: None }; |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index a0a2c7273..7c68fd638 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -327,7 +327,7 @@ impl RawItemsCollector { | |||
327 | 327 | ||
328 | let mut buf = Vec::new(); | 328 | let mut buf = Vec::new(); |
329 | Path::expand_use_item( | 329 | Path::expand_use_item( |
330 | Source { ast: use_item, file_id: self.file_id }, | 330 | Source { value: use_item, file_id: self.file_id }, |
331 | &self.hygiene, | 331 | &self.hygiene, |
332 | |path, use_tree, is_glob, alias| { | 332 | |path, use_tree, is_glob, alias| { |
333 | let import_data = ImportData { | 333 | let import_data = ImportData { |
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 04039376f..626ebffdc 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs | |||
@@ -71,7 +71,7 @@ impl Path { | |||
71 | hygiene: &Hygiene, | 71 | hygiene: &Hygiene, |
72 | mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>), | 72 | mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>), |
73 | ) { | 73 | ) { |
74 | if let Some(tree) = item_src.ast.use_tree() { | 74 | if let Some(tree) = item_src.value.use_tree() { |
75 | expand_use_tree(None, tree, hygiene, &mut cb); | 75 | expand_use_tree(None, tree, hygiene, &mut cb); |
76 | } | 76 | } |
77 | } | 77 | } |
diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs new file mode 100644 index 000000000..877d73d66 --- /dev/null +++ b/crates/ra_hir_def/src/traits.rs | |||
@@ -0,0 +1,59 @@ | |||
1 | //! HIR for trait definitions. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::{ | ||
6 | name::{AsName, Name}, | ||
7 | AstId, | ||
8 | }; | ||
9 | |||
10 | use ra_syntax::ast::{self, NameOwner}; | ||
11 | |||
12 | use crate::{ | ||
13 | db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId, | ||
14 | TypeAliasLoc, | ||
15 | }; | ||
16 | |||
17 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
18 | pub struct TraitData { | ||
19 | pub name: Option<Name>, | ||
20 | pub items: Vec<AssocItemId>, | ||
21 | pub auto: bool, | ||
22 | } | ||
23 | |||
24 | impl TraitData { | ||
25 | pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> { | ||
26 | let src = tr.source(db); | ||
27 | let name = src.value.name().map(|n| n.as_name()); | ||
28 | let auto = src.value.is_auto(); | ||
29 | let ast_id_map = db.ast_id_map(src.file_id); | ||
30 | let items = if let Some(item_list) = src.value.item_list() { | ||
31 | item_list | ||
32 | .impl_items() | ||
33 | .map(|item_node| match item_node { | ||
34 | ast::ImplItem::FnDef(it) => FunctionLoc { | ||
35 | container: ContainerId::TraitId(tr), | ||
36 | ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), | ||
37 | } | ||
38 | .intern(db) | ||
39 | .into(), | ||
40 | ast::ImplItem::ConstDef(it) => ConstLoc { | ||
41 | container: ContainerId::TraitId(tr), | ||
42 | ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), | ||
43 | } | ||
44 | .intern(db) | ||
45 | .into(), | ||
46 | ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc { | ||
47 | container: ContainerId::TraitId(tr), | ||
48 | ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), | ||
49 | } | ||
50 | .intern(db) | ||
51 | .into(), | ||
52 | }) | ||
53 | .collect() | ||
54 | } else { | ||
55 | Vec::new() | ||
56 | }; | ||
57 | Arc::new(TraitData { name, items, auto }) | ||
58 | } | ||
59 | } | ||
diff --git a/crates/ra_hir_expand/src/diagnostics.rs b/crates/ra_hir_expand/src/diagnostics.rs index 201884b95..3d37e9335 100644 --- a/crates/ra_hir_expand/src/diagnostics.rs +++ b/crates/ra_hir_expand/src/diagnostics.rs | |||
@@ -24,7 +24,7 @@ pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static { | |||
24 | fn message(&self) -> String; | 24 | fn message(&self) -> String; |
25 | fn source(&self) -> Source<SyntaxNodePtr>; | 25 | fn source(&self) -> Source<SyntaxNodePtr>; |
26 | fn highlight_range(&self) -> TextRange { | 26 | fn highlight_range(&self) -> TextRange { |
27 | self.source().ast.range() | 27 | self.source().value.range() |
28 | } | 28 | } |
29 | fn as_any(&self) -> &(dyn Any + Send + 'static); | 29 | fn as_any(&self) -> &(dyn Any + Send + 'static); |
30 | } | 30 | } |
@@ -37,7 +37,7 @@ pub trait AstDiagnostic { | |||
37 | impl dyn Diagnostic { | 37 | impl dyn Diagnostic { |
38 | pub fn syntax_node(&self, db: &impl AstDatabase) -> SyntaxNode { | 38 | pub fn syntax_node(&self, db: &impl AstDatabase) -> SyntaxNode { |
39 | let node = db.parse_or_expand(self.source().file_id).unwrap(); | 39 | let node = db.parse_or_expand(self.source().file_id).unwrap(); |
40 | self.source().ast.to_node(&node) | 40 | self.source().value.to_node(&node) |
41 | } | 41 | } |
42 | 42 | ||
43 | pub fn downcast_ref<D: Diagnostic>(&self) -> Option<&D> { | 43 | pub fn downcast_ref<D: Diagnostic>(&self) -> Option<&D> { |
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index cfe7e6d15..1389f64ce 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs | |||
@@ -166,19 +166,19 @@ impl ExpansionInfo { | |||
166 | pub fn map_token_down(&self, token: Source<&SyntaxToken>) -> Option<Source<SyntaxToken>> { | 166 | pub fn map_token_down(&self, token: Source<&SyntaxToken>) -> Option<Source<SyntaxToken>> { |
167 | assert_eq!(token.file_id, self.arg.file_id); | 167 | assert_eq!(token.file_id, self.arg.file_id); |
168 | let range = | 168 | let range = |
169 | token.ast.text_range().checked_sub(self.arg.ast.syntax().text_range().start())?; | 169 | token.value.text_range().checked_sub(self.arg.value.syntax().text_range().start())?; |
170 | let token_id = self.macro_arg.1.token_by_range(range)?; | 170 | let token_id = self.macro_arg.1.token_by_range(range)?; |
171 | let token_id = self.macro_def.0.map_id_down(token_id); | 171 | let token_id = self.macro_def.0.map_id_down(token_id); |
172 | 172 | ||
173 | let range = self.exp_map.range_by_token(token_id)?; | 173 | let range = self.exp_map.range_by_token(token_id)?; |
174 | 174 | ||
175 | let token = algo::find_covering_element(&self.expanded.ast, range).into_token()?; | 175 | let token = algo::find_covering_element(&self.expanded.value, range).into_token()?; |
176 | 176 | ||
177 | Some(self.expanded.with_ast(token)) | 177 | Some(self.expanded.with_value(token)) |
178 | } | 178 | } |
179 | 179 | ||
180 | pub fn map_token_up(&self, token: Source<&SyntaxToken>) -> Option<Source<SyntaxToken>> { | 180 | pub fn map_token_up(&self, token: Source<&SyntaxToken>) -> Option<Source<SyntaxToken>> { |
181 | let token_id = self.exp_map.token_by_range(token.ast.text_range())?; | 181 | let token_id = self.exp_map.token_by_range(token.value.text_range())?; |
182 | 182 | ||
183 | let (token_id, origin) = self.macro_def.0.map_id_up(token_id); | 183 | let (token_id, origin) = self.macro_def.0.map_id_up(token_id); |
184 | let (token_map, tt) = match origin { | 184 | let (token_map, tt) = match origin { |
@@ -188,11 +188,11 @@ impl ExpansionInfo { | |||
188 | 188 | ||
189 | let range = token_map.range_by_token(token_id)?; | 189 | let range = token_map.range_by_token(token_id)?; |
190 | let token = algo::find_covering_element( | 190 | let token = algo::find_covering_element( |
191 | tt.ast.syntax(), | 191 | tt.value.syntax(), |
192 | range + tt.ast.syntax().text_range().start(), | 192 | range + tt.value.syntax().text_range().start(), |
193 | ) | 193 | ) |
194 | .into_token()?; | 194 | .into_token()?; |
195 | Some(tt.with_ast(token)) | 195 | Some(tt.with_value(token)) |
196 | } | 196 | } |
197 | } | 197 | } |
198 | 198 | ||
@@ -240,30 +240,34 @@ impl<N: AstNode> AstId<N> { | |||
240 | } | 240 | } |
241 | } | 241 | } |
242 | 242 | ||
243 | /// FIXME: https://github.com/matklad/with ? | 243 | /// `Source<T>` stores a value of `T` inside a particular file/syntax tree. |
244 | /// | ||
245 | /// Typical usages are: | ||
246 | /// | ||
247 | /// * `Source<SyntaxNode>` -- syntax node in a file | ||
248 | /// * `Source<ast::FnDef>` -- ast node in a file | ||
249 | /// * `Source<TextUnit>` -- offset in a file | ||
244 | #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] | 250 | #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] |
245 | pub struct Source<T> { | 251 | pub struct Source<T> { |
246 | pub file_id: HirFileId, | 252 | pub file_id: HirFileId, |
247 | // FIXME: this stores all kind of things, not only `ast`. | 253 | pub value: T, |
248 | // There should be a better name... | ||
249 | pub ast: T, | ||
250 | } | 254 | } |
251 | 255 | ||
252 | impl<T> Source<T> { | 256 | impl<T> Source<T> { |
253 | pub fn new(file_id: HirFileId, ast: T) -> Source<T> { | 257 | pub fn new(file_id: HirFileId, value: T) -> Source<T> { |
254 | Source { file_id, ast } | 258 | Source { file_id, value } |
255 | } | 259 | } |
256 | 260 | ||
257 | // Similarly, naming here is stupid... | 261 | // Similarly, naming here is stupid... |
258 | pub fn with_ast<U>(&self, ast: U) -> Source<U> { | 262 | pub fn with_value<U>(&self, value: U) -> Source<U> { |
259 | Source::new(self.file_id, ast) | 263 | Source::new(self.file_id, value) |
260 | } | 264 | } |
261 | 265 | ||
262 | pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { | 266 | pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { |
263 | Source::new(self.file_id, f(self.ast)) | 267 | Source::new(self.file_id, f(self.value)) |
264 | } | 268 | } |
265 | pub fn as_ref(&self) -> Source<&T> { | 269 | pub fn as_ref(&self) -> Source<&T> { |
266 | self.with_ast(&self.ast) | 270 | self.with_value(&self.value) |
267 | } | 271 | } |
268 | pub fn file_syntax(&self, db: &impl db::AstDatabase) -> SyntaxNode { | 272 | pub fn file_syntax(&self, db: &impl db::AstDatabase) -> SyntaxNode { |
269 | db.parse_or_expand(self.file_id).expect("source created from invalid file") | 273 | db.parse_or_expand(self.file_id).expect("source created from invalid file") |
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 5c9dec13e..3c607d5b5 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs | |||
@@ -309,7 +309,6 @@ impl RootDatabase { | |||
309 | hir::db::StructDataQuery | 309 | hir::db::StructDataQuery |
310 | hir::db::EnumDataQuery | 310 | hir::db::EnumDataQuery |
311 | hir::db::TraitDataQuery | 311 | hir::db::TraitDataQuery |
312 | hir::db::TraitItemsIndexQuery | ||
313 | hir::db::RawItemsWithSourceMapQuery | 312 | hir::db::RawItemsWithSourceMapQuery |
314 | hir::db::RawItemsQuery | 313 | hir::db::RawItemsQuery |
315 | hir::db::CrateDefMapQuery | 314 | hir::db::CrateDefMapQuery |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 8c57c907d..d5739b58a 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -305,6 +305,13 @@ mod tests { | |||
305 | @r###" | 305 | @r###" |
306 | [ | 306 | [ |
307 | CompletionItem { | 307 | CompletionItem { |
308 | label: "Self", | ||
309 | source_range: [54; 54), | ||
310 | delete: [54; 54), | ||
311 | insert: "Self", | ||
312 | kind: TypeParam, | ||
313 | }, | ||
314 | CompletionItem { | ||
308 | label: "T", | 315 | label: "T", |
309 | source_range: [54; 54), | 316 | source_range: [54; 54), |
310 | delete: [54; 54), | 317 | delete: [54; 54), |
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index 0906a4e1b..b8345c91d 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs | |||
@@ -54,7 +54,7 @@ impl<'a> CompletionContext<'a> { | |||
54 | let src = hir::ModuleSource::from_position(db, position); | 54 | let src = hir::ModuleSource::from_position(db, position); |
55 | let module = hir::Module::from_definition( | 55 | let module = hir::Module::from_definition( |
56 | db, | 56 | db, |
57 | hir::Source { file_id: position.file_id.into(), ast: src }, | 57 | hir::Source { file_id: position.file_id.into(), value: src }, |
58 | ); | 58 | ); |
59 | let token = | 59 | let token = |
60 | original_parse.tree().syntax().token_at_offset(position.offset).left_biased()?; | 60 | original_parse.tree().syntax().token_at_offset(position.offset).left_biased()?; |
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 501b7da4e..b20329459 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs | |||
@@ -169,7 +169,7 @@ impl Completions { | |||
169 | None => return, | 169 | None => return, |
170 | }; | 170 | }; |
171 | 171 | ||
172 | let ast_node = macro_.source(ctx.db).ast; | 172 | let ast_node = macro_.source(ctx.db).value; |
173 | let detail = macro_label(&ast_node); | 173 | let detail = macro_label(&ast_node); |
174 | 174 | ||
175 | let docs = macro_.docs(ctx.db); | 175 | let docs = macro_.docs(ctx.db); |
@@ -201,7 +201,7 @@ impl Completions { | |||
201 | ) { | 201 | ) { |
202 | let data = func.data(ctx.db); | 202 | let data = func.data(ctx.db); |
203 | let name = name.unwrap_or_else(|| data.name().to_string()); | 203 | let name = name.unwrap_or_else(|| data.name().to_string()); |
204 | let ast_node = func.source(ctx.db).ast; | 204 | let ast_node = func.source(ctx.db).value; |
205 | let detail = function_label(&ast_node); | 205 | let detail = function_label(&ast_node); |
206 | 206 | ||
207 | let mut builder = | 207 | let mut builder = |
@@ -234,7 +234,7 @@ impl Completions { | |||
234 | } | 234 | } |
235 | 235 | ||
236 | pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) { | 236 | pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) { |
237 | let ast_node = constant.source(ctx.db).ast; | 237 | let ast_node = constant.source(ctx.db).value; |
238 | let name = match ast_node.name() { | 238 | let name = match ast_node.name() { |
239 | Some(name) => name, | 239 | Some(name) => name, |
240 | _ => return, | 240 | _ => return, |
@@ -250,7 +250,7 @@ impl Completions { | |||
250 | } | 250 | } |
251 | 251 | ||
252 | pub(crate) fn add_type_alias(&mut self, ctx: &CompletionContext, type_alias: hir::TypeAlias) { | 252 | pub(crate) fn add_type_alias(&mut self, ctx: &CompletionContext, type_alias: hir::TypeAlias) { |
253 | let type_def = type_alias.source(ctx.db).ast; | 253 | let type_def = type_alias.source(ctx.db).value; |
254 | let name = match type_def.name() { | 254 | let name = match type_def.name() { |
255 | Some(name) => name, | 255 | Some(name) => name, |
256 | _ => return, | 256 | _ => return, |
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index e52ffefb3..cc1ccab4b 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs | |||
@@ -96,7 +96,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
96 | }); | 96 | }); |
97 | let source_file = db.parse(file_id).tree(); | 97 | let source_file = db.parse(file_id).tree(); |
98 | let src = | 98 | let src = |
99 | hir::Source { file_id: file_id.into(), ast: hir::ModuleSource::SourceFile(source_file) }; | 99 | hir::Source { file_id: file_id.into(), value: hir::ModuleSource::SourceFile(source_file) }; |
100 | if let Some(m) = hir::Module::from_definition(db, src) { | 100 | if let Some(m) = hir::Module::from_definition(db, src) { |
101 | m.diagnostics(db, &mut sink); | 101 | m.diagnostics(db, &mut sink); |
102 | }; | 102 | }; |
diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs index 9075ca443..f42dffc87 100644 --- a/crates/ra_ide_api/src/display/function_signature.rs +++ b/crates/ra_ide_api/src/display/function_signature.rs | |||
@@ -48,12 +48,12 @@ impl FunctionSignature { | |||
48 | 48 | ||
49 | pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self { | 49 | pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self { |
50 | let doc = function.docs(db); | 50 | let doc = function.docs(db); |
51 | let ast_node = function.source(db).ast; | 51 | let ast_node = function.source(db).value; |
52 | FunctionSignature::from(&ast_node).with_doc_opt(doc) | 52 | FunctionSignature::from(&ast_node).with_doc_opt(doc) |
53 | } | 53 | } |
54 | 54 | ||
55 | pub(crate) fn from_struct(db: &db::RootDatabase, st: hir::Struct) -> Option<Self> { | 55 | pub(crate) fn from_struct(db: &db::RootDatabase, st: hir::Struct) -> Option<Self> { |
56 | let node: ast::StructDef = st.source(db).ast; | 56 | let node: ast::StructDef = st.source(db).value; |
57 | match node.kind() { | 57 | match node.kind() { |
58 | ast::StructKind::Named(_) => return None, | 58 | ast::StructKind::Named(_) => return None, |
59 | _ => (), | 59 | _ => (), |
@@ -87,7 +87,7 @@ impl FunctionSignature { | |||
87 | db: &db::RootDatabase, | 87 | db: &db::RootDatabase, |
88 | variant: hir::EnumVariant, | 88 | variant: hir::EnumVariant, |
89 | ) -> Option<Self> { | 89 | ) -> Option<Self> { |
90 | let node: ast::EnumVariant = variant.source(db).ast; | 90 | let node: ast::EnumVariant = variant.source(db).value; |
91 | match node.kind() { | 91 | match node.kind() { |
92 | ast::StructKind::Named(_) | ast::StructKind::Unit => return None, | 92 | ast::StructKind::Named(_) | ast::StructKind::Unit => return None, |
93 | _ => (), | 93 | _ => (), |
@@ -126,7 +126,7 @@ impl FunctionSignature { | |||
126 | } | 126 | } |
127 | 127 | ||
128 | pub(crate) fn from_macro(db: &db::RootDatabase, macro_def: hir::MacroDef) -> Option<Self> { | 128 | pub(crate) fn from_macro(db: &db::RootDatabase, macro_def: hir::MacroDef) -> Option<Self> { |
129 | let node: ast::MacroCall = macro_def.source(db).ast; | 129 | let node: ast::MacroCall = macro_def.source(db).value; |
130 | 130 | ||
131 | let params = vec![]; | 131 | let params = vec![]; |
132 | 132 | ||
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index b30ef8e05..6ac60722b 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs | |||
@@ -86,9 +86,9 @@ impl NavigationTarget { | |||
86 | name, | 86 | name, |
87 | None, | 87 | None, |
88 | frange.range, | 88 | frange.range, |
89 | src.ast.syntax().kind(), | 89 | src.value.syntax().kind(), |
90 | src.ast.doc_comment_text(), | 90 | src.value.doc_comment_text(), |
91 | src.ast.short_label(), | 91 | src.value.short_label(), |
92 | ); | 92 | ); |
93 | } | 93 | } |
94 | module.to_nav(db) | 94 | module.to_nav(db) |
@@ -146,9 +146,9 @@ impl NavigationTarget { | |||
146 | description: Option<String>, | 146 | description: Option<String>, |
147 | ) -> NavigationTarget { | 147 | ) -> NavigationTarget { |
148 | //FIXME: use `_` instead of empty string | 148 | //FIXME: use `_` instead of empty string |
149 | let name = node.ast.name().map(|it| it.text().clone()).unwrap_or_default(); | 149 | let name = node.value.name().map(|it| it.text().clone()).unwrap_or_default(); |
150 | let focus_range = | 150 | let focus_range = |
151 | node.ast.name().map(|it| original_range(db, node.with_ast(it.syntax())).range); | 151 | node.value.name().map(|it| original_range(db, node.with_value(it.syntax())).range); |
152 | let frange = original_range(db, node.map(|it| it.syntax())); | 152 | let frange = original_range(db, node.map(|it| it.syntax())); |
153 | 153 | ||
154 | NavigationTarget::from_syntax( | 154 | NavigationTarget::from_syntax( |
@@ -156,7 +156,7 @@ impl NavigationTarget { | |||
156 | name, | 156 | name, |
157 | focus_range, | 157 | focus_range, |
158 | frange.range, | 158 | frange.range, |
159 | node.ast.syntax().kind(), | 159 | node.value.syntax().kind(), |
160 | docs, | 160 | docs, |
161 | description, | 161 | description, |
162 | ) | 162 | ) |
@@ -220,8 +220,8 @@ where | |||
220 | NavigationTarget::from_named( | 220 | NavigationTarget::from_named( |
221 | db, | 221 | db, |
222 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 222 | src.as_ref().map(|it| it as &dyn ast::NameOwner), |
223 | src.ast.doc_comment_text(), | 223 | src.value.doc_comment_text(), |
224 | src.ast.short_label(), | 224 | src.value.short_label(), |
225 | ) | 225 | ) |
226 | } | 226 | } |
227 | } | 227 | } |
@@ -230,9 +230,9 @@ impl ToNav for hir::Module { | |||
230 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 230 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
231 | let src = self.definition_source(db); | 231 | let src = self.definition_source(db); |
232 | let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 232 | let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
233 | match &src.ast { | 233 | match &src.value { |
234 | ModuleSource::SourceFile(node) => { | 234 | ModuleSource::SourceFile(node) => { |
235 | let frange = original_range(db, src.with_ast(node.syntax())); | 235 | let frange = original_range(db, src.with_value(node.syntax())); |
236 | 236 | ||
237 | NavigationTarget::from_syntax( | 237 | NavigationTarget::from_syntax( |
238 | frange.file_id, | 238 | frange.file_id, |
@@ -245,7 +245,7 @@ impl ToNav for hir::Module { | |||
245 | ) | 245 | ) |
246 | } | 246 | } |
247 | ModuleSource::Module(node) => { | 247 | ModuleSource::Module(node) => { |
248 | let frange = original_range(db, src.with_ast(node.syntax())); | 248 | let frange = original_range(db, src.with_value(node.syntax())); |
249 | 249 | ||
250 | NavigationTarget::from_syntax( | 250 | NavigationTarget::from_syntax( |
251 | frange.file_id, | 251 | frange.file_id, |
@@ -271,7 +271,7 @@ impl ToNav for hir::ImplBlock { | |||
271 | "impl".into(), | 271 | "impl".into(), |
272 | None, | 272 | None, |
273 | frange.range, | 273 | frange.range, |
274 | src.ast.syntax().kind(), | 274 | src.value.syntax().kind(), |
275 | None, | 275 | None, |
276 | None, | 276 | None, |
277 | ) | 277 | ) |
@@ -282,15 +282,15 @@ impl ToNav for hir::StructField { | |||
282 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 282 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
283 | let src = self.source(db); | 283 | let src = self.source(db); |
284 | 284 | ||
285 | match &src.ast { | 285 | match &src.value { |
286 | FieldSource::Named(it) => NavigationTarget::from_named( | 286 | FieldSource::Named(it) => NavigationTarget::from_named( |
287 | db, | 287 | db, |
288 | src.with_ast(it), | 288 | src.with_value(it), |
289 | it.doc_comment_text(), | 289 | it.doc_comment_text(), |
290 | it.short_label(), | 290 | it.short_label(), |
291 | ), | 291 | ), |
292 | FieldSource::Pos(it) => { | 292 | FieldSource::Pos(it) => { |
293 | let frange = original_range(db, src.with_ast(it.syntax())); | 293 | let frange = original_range(db, src.with_value(it.syntax())); |
294 | NavigationTarget::from_syntax( | 294 | NavigationTarget::from_syntax( |
295 | frange.file_id, | 295 | frange.file_id, |
296 | "".into(), | 296 | "".into(), |
@@ -308,11 +308,11 @@ impl ToNav for hir::StructField { | |||
308 | impl ToNav for hir::MacroDef { | 308 | impl ToNav for hir::MacroDef { |
309 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 309 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
310 | let src = self.source(db); | 310 | let src = self.source(db); |
311 | log::debug!("nav target {:#?}", src.ast.syntax()); | 311 | log::debug!("nav target {:#?}", src.value.syntax()); |
312 | NavigationTarget::from_named( | 312 | NavigationTarget::from_named( |
313 | db, | 313 | db, |
314 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 314 | src.as_ref().map(|it| it as &dyn ast::NameOwner), |
315 | src.ast.doc_comment_text(), | 315 | src.value.doc_comment_text(), |
316 | None, | 316 | None, |
317 | ) | 317 | ) |
318 | } | 318 | } |
@@ -341,7 +341,7 @@ impl ToNav for hir::AssocItem { | |||
341 | impl ToNav for hir::Local { | 341 | impl ToNav for hir::Local { |
342 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 342 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
343 | let src = self.source(db); | 343 | let src = self.source(db); |
344 | let (full_range, focus_range) = match src.ast { | 344 | let (full_range, focus_range) = match src.value { |
345 | Either::A(it) => { | 345 | Either::A(it) => { |
346 | (it.syntax().text_range(), it.name().map(|it| it.syntax().text_range())) | 346 | (it.syntax().text_range(), it.name().map(|it| it.syntax().text_range())) |
347 | } | 347 | } |
diff --git a/crates/ra_ide_api/src/expand.rs b/crates/ra_ide_api/src/expand.rs index 7f59e46d2..2f1abf509 100644 --- a/crates/ra_ide_api/src/expand.rs +++ b/crates/ra_ide_api/src/expand.rs | |||
@@ -12,7 +12,7 @@ pub(crate) fn original_range(db: &RootDatabase, node: Source<&SyntaxNode>) -> Fi | |||
12 | None => { | 12 | None => { |
13 | return FileRange { | 13 | return FileRange { |
14 | file_id: node.file_id.original_file(db), | 14 | file_id: node.file_id.original_file(db), |
15 | range: node.ast.text_range(), | 15 | range: node.value.text_range(), |
16 | } | 16 | } |
17 | } | 17 | } |
18 | Some(it) => it, | 18 | Some(it) => it, |
@@ -25,14 +25,18 @@ pub(crate) fn original_range(db: &RootDatabase, node: Source<&SyntaxNode>) -> Fi | |||
25 | // *Second*, we should handle recurside macro expansions | 25 | // *Second*, we should handle recurside macro expansions |
26 | 26 | ||
27 | let token = node | 27 | let token = node |
28 | .ast | 28 | .value |
29 | .descendants_with_tokens() | 29 | .descendants_with_tokens() |
30 | .filter_map(|it| it.into_token()) | 30 | .filter_map(|it| it.into_token()) |
31 | .find_map(|it| expansion.map_token_up(node.with_ast(&it))); | 31 | .find_map(|it| expansion.map_token_up(node.with_value(&it))); |
32 | 32 | ||
33 | match token { | 33 | match token { |
34 | Some(it) => FileRange { file_id: it.file_id.original_file(db), range: it.ast.text_range() }, | 34 | Some(it) => { |
35 | None => FileRange { file_id: node.file_id.original_file(db), range: node.ast.text_range() }, | 35 | FileRange { file_id: it.file_id.original_file(db), range: it.value.text_range() } |
36 | } | ||
37 | None => { | ||
38 | FileRange { file_id: node.file_id.original_file(db), range: node.value.text_range() } | ||
39 | } | ||
36 | } | 40 | } |
37 | } | 41 | } |
38 | 42 | ||
@@ -44,14 +48,14 @@ pub(crate) fn descend_into_macros( | |||
44 | let src = Source::new(file_id.into(), token); | 48 | let src = Source::new(file_id.into(), token); |
45 | 49 | ||
46 | successors(Some(src), |token| { | 50 | successors(Some(src), |token| { |
47 | let macro_call = token.ast.ancestors().find_map(ast::MacroCall::cast)?; | 51 | let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; |
48 | let tt = macro_call.token_tree()?; | 52 | let tt = macro_call.token_tree()?; |
49 | if !token.ast.text_range().is_subrange(&tt.syntax().text_range()) { | 53 | if !token.value.text_range().is_subrange(&tt.syntax().text_range()) { |
50 | return None; | 54 | return None; |
51 | } | 55 | } |
52 | let source_analyzer = | 56 | let source_analyzer = |
53 | hir::SourceAnalyzer::new(db, token.with_ast(token.ast.parent()).as_ref(), None); | 57 | hir::SourceAnalyzer::new(db, token.with_value(token.value.parent()).as_ref(), None); |
54 | let exp = source_analyzer.expand(db, ¯o_call)?; | 58 | let exp = source_analyzer.expand(db, token.with_value(¯o_call))?; |
55 | exp.map_token_down(db, token.as_ref()) | 59 | exp.map_token_down(db, token.as_ref()) |
56 | }) | 60 | }) |
57 | .last() | 61 | .last() |
diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index e9eb2a7fb..7f39262dc 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs | |||
@@ -23,7 +23,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< | |||
23 | let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; | 23 | let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; |
24 | 24 | ||
25 | let source = hir::Source::new(position.file_id.into(), mac.syntax()); | 25 | let source = hir::Source::new(position.file_id.into(), mac.syntax()); |
26 | let expanded = expand_macro_recur(db, source, &mac)?; | 26 | let expanded = expand_macro_recur(db, source, source.with_value(&mac))?; |
27 | 27 | ||
28 | // FIXME: | 28 | // FIXME: |
29 | // macro expansion may lose all white space information | 29 | // macro expansion may lose all white space information |
@@ -35,10 +35,10 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< | |||
35 | fn expand_macro_recur( | 35 | fn expand_macro_recur( |
36 | db: &RootDatabase, | 36 | db: &RootDatabase, |
37 | source: hir::Source<&SyntaxNode>, | 37 | source: hir::Source<&SyntaxNode>, |
38 | macro_call: &ast::MacroCall, | 38 | macro_call: hir::Source<&ast::MacroCall>, |
39 | ) -> Option<SyntaxNode> { | 39 | ) -> Option<SyntaxNode> { |
40 | let analyzer = hir::SourceAnalyzer::new(db, source, None); | 40 | let analyzer = hir::SourceAnalyzer::new(db, source, None); |
41 | let expansion = analyzer.expand(db, ¯o_call)?; | 41 | let expansion = analyzer.expand(db, macro_call)?; |
42 | let macro_file_id = expansion.file_id(); | 42 | let macro_file_id = expansion.file_id(); |
43 | let expanded: SyntaxNode = db.parse_or_expand(macro_file_id)?; | 43 | let expanded: SyntaxNode = db.parse_or_expand(macro_file_id)?; |
44 | 44 | ||
@@ -46,8 +46,8 @@ fn expand_macro_recur( | |||
46 | let mut replaces = FxHashMap::default(); | 46 | let mut replaces = FxHashMap::default(); |
47 | 47 | ||
48 | for child in children.into_iter() { | 48 | for child in children.into_iter() { |
49 | let source = hir::Source::new(macro_file_id, source.ast); | 49 | let node = hir::Source::new(macro_file_id, &child); |
50 | let new_node = expand_macro_recur(db, source, &child)?; | 50 | let new_node = expand_macro_recur(db, source, node)?; |
51 | 51 | ||
52 | replaces.insert(child.syntax().clone().into(), new_node.into()); | 52 | replaces.insert(child.syntax().clone().into(), new_node.into()); |
53 | } | 53 | } |
@@ -139,7 +139,7 @@ mod tests { | |||
139 | } | 139 | } |
140 | macro_rules! baz { | 140 | macro_rules! baz { |
141 | () => { foo!(); } | 141 | () => { foo!(); } |
142 | } | 142 | } |
143 | f<|>oo!(); | 143 | f<|>oo!(); |
144 | "#, | 144 | "#, |
145 | ); | 145 | ); |
@@ -156,7 +156,7 @@ fn b(){} | |||
156 | r#" | 156 | r#" |
157 | //- /lib.rs | 157 | //- /lib.rs |
158 | macro_rules! foo { | 158 | macro_rules! foo { |
159 | () => { | 159 | () => { |
160 | fn some_thing() -> u32 { | 160 | fn some_thing() -> u32 { |
161 | let a = 0; | 161 | let a = 0; |
162 | a + 10 | 162 | a + 10 |
@@ -172,7 +172,7 @@ fn b(){} | |||
172 | fn some_thing() -> u32 { | 172 | fn some_thing() -> u32 { |
173 | let a = 0; | 173 | let a = 0; |
174 | a+10 | 174 | a+10 |
175 | } | 175 | } |
176 | "###); | 176 | "###); |
177 | } | 177 | } |
178 | } | 178 | } |
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 3f16e9566..b6c72efdf 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -23,13 +23,13 @@ pub(crate) fn goto_definition( | |||
23 | let token = descend_into_macros(db, position.file_id, token); | 23 | let token = descend_into_macros(db, position.file_id, token); |
24 | 24 | ||
25 | let res = match_ast! { | 25 | let res = match_ast! { |
26 | match (token.ast.parent()) { | 26 | match (token.value.parent()) { |
27 | ast::NameRef(name_ref) => { | 27 | ast::NameRef(name_ref) => { |
28 | let navs = reference_definition(db, token.with_ast(&name_ref)).to_vec(); | 28 | let navs = reference_definition(db, token.with_value(&name_ref)).to_vec(); |
29 | RangeInfo::new(name_ref.syntax().text_range(), navs.to_vec()) | 29 | RangeInfo::new(name_ref.syntax().text_range(), navs.to_vec()) |
30 | }, | 30 | }, |
31 | ast::Name(name) => { | 31 | ast::Name(name) => { |
32 | let navs = name_definition(db, token.with_ast(&name))?; | 32 | let navs = name_definition(db, token.with_value(&name))?; |
33 | RangeInfo::new(name.syntax().text_range(), navs) | 33 | RangeInfo::new(name.syntax().text_range(), navs) |
34 | 34 | ||
35 | }, | 35 | }, |
@@ -84,7 +84,7 @@ pub(crate) fn reference_definition( | |||
84 | }; | 84 | }; |
85 | 85 | ||
86 | // Fallback index based approach: | 86 | // Fallback index based approach: |
87 | let navs = crate::symbol_index::index_resolve(db, name_ref.ast) | 87 | let navs = crate::symbol_index::index_resolve(db, name_ref.value) |
88 | .into_iter() | 88 | .into_iter() |
89 | .map(|s| s.to_nav(db)) | 89 | .map(|s| s.to_nav(db)) |
90 | .collect(); | 90 | .collect(); |
@@ -95,11 +95,11 @@ pub(crate) fn name_definition( | |||
95 | db: &RootDatabase, | 95 | db: &RootDatabase, |
96 | name: Source<&ast::Name>, | 96 | name: Source<&ast::Name>, |
97 | ) -> Option<Vec<NavigationTarget>> { | 97 | ) -> Option<Vec<NavigationTarget>> { |
98 | let parent = name.ast.syntax().parent()?; | 98 | let parent = name.value.syntax().parent()?; |
99 | 99 | ||
100 | if let Some(module) = ast::Module::cast(parent.clone()) { | 100 | if let Some(module) = ast::Module::cast(parent.clone()) { |
101 | if module.has_semi() { | 101 | if module.has_semi() { |
102 | let src = name.with_ast(module); | 102 | let src = name.with_value(module); |
103 | if let Some(child_module) = hir::Module::from_declaration(db, src) { | 103 | if let Some(child_module) = hir::Module::from_declaration(db, src) { |
104 | let nav = child_module.to_nav(db); | 104 | let nav = child_module.to_nav(db); |
105 | return Some(vec![nav]); | 105 | return Some(vec![nav]); |
@@ -107,7 +107,7 @@ pub(crate) fn name_definition( | |||
107 | } | 107 | } |
108 | } | 108 | } |
109 | 109 | ||
110 | if let Some(nav) = named_target(db, name.with_ast(&parent)) { | 110 | if let Some(nav) = named_target(db, name.with_value(&parent)) { |
111 | return Some(vec![nav]); | 111 | return Some(vec![nav]); |
112 | } | 112 | } |
113 | 113 | ||
@@ -116,11 +116,11 @@ pub(crate) fn name_definition( | |||
116 | 116 | ||
117 | fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<NavigationTarget> { | 117 | fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<NavigationTarget> { |
118 | match_ast! { | 118 | match_ast! { |
119 | match (node.ast) { | 119 | match (node.value) { |
120 | ast::StructDef(it) => { | 120 | ast::StructDef(it) => { |
121 | Some(NavigationTarget::from_named( | 121 | Some(NavigationTarget::from_named( |
122 | db, | 122 | db, |
123 | node.with_ast(&it), | 123 | node.with_value(&it), |
124 | it.doc_comment_text(), | 124 | it.doc_comment_text(), |
125 | it.short_label(), | 125 | it.short_label(), |
126 | )) | 126 | )) |
@@ -128,7 +128,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
128 | ast::EnumDef(it) => { | 128 | ast::EnumDef(it) => { |
129 | Some(NavigationTarget::from_named( | 129 | Some(NavigationTarget::from_named( |
130 | db, | 130 | db, |
131 | node.with_ast(&it), | 131 | node.with_value(&it), |
132 | it.doc_comment_text(), | 132 | it.doc_comment_text(), |
133 | it.short_label(), | 133 | it.short_label(), |
134 | )) | 134 | )) |
@@ -136,7 +136,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
136 | ast::EnumVariant(it) => { | 136 | ast::EnumVariant(it) => { |
137 | Some(NavigationTarget::from_named( | 137 | Some(NavigationTarget::from_named( |
138 | db, | 138 | db, |
139 | node.with_ast(&it), | 139 | node.with_value(&it), |
140 | it.doc_comment_text(), | 140 | it.doc_comment_text(), |
141 | it.short_label(), | 141 | it.short_label(), |
142 | )) | 142 | )) |
@@ -144,7 +144,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
144 | ast::FnDef(it) => { | 144 | ast::FnDef(it) => { |
145 | Some(NavigationTarget::from_named( | 145 | Some(NavigationTarget::from_named( |
146 | db, | 146 | db, |
147 | node.with_ast(&it), | 147 | node.with_value(&it), |
148 | it.doc_comment_text(), | 148 | it.doc_comment_text(), |
149 | it.short_label(), | 149 | it.short_label(), |
150 | )) | 150 | )) |
@@ -152,7 +152,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
152 | ast::TypeAliasDef(it) => { | 152 | ast::TypeAliasDef(it) => { |
153 | Some(NavigationTarget::from_named( | 153 | Some(NavigationTarget::from_named( |
154 | db, | 154 | db, |
155 | node.with_ast(&it), | 155 | node.with_value(&it), |
156 | it.doc_comment_text(), | 156 | it.doc_comment_text(), |
157 | it.short_label(), | 157 | it.short_label(), |
158 | )) | 158 | )) |
@@ -160,7 +160,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
160 | ast::ConstDef(it) => { | 160 | ast::ConstDef(it) => { |
161 | Some(NavigationTarget::from_named( | 161 | Some(NavigationTarget::from_named( |
162 | db, | 162 | db, |
163 | node.with_ast(&it), | 163 | node.with_value(&it), |
164 | it.doc_comment_text(), | 164 | it.doc_comment_text(), |
165 | it.short_label(), | 165 | it.short_label(), |
166 | )) | 166 | )) |
@@ -168,7 +168,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
168 | ast::StaticDef(it) => { | 168 | ast::StaticDef(it) => { |
169 | Some(NavigationTarget::from_named( | 169 | Some(NavigationTarget::from_named( |
170 | db, | 170 | db, |
171 | node.with_ast(&it), | 171 | node.with_value(&it), |
172 | it.doc_comment_text(), | 172 | it.doc_comment_text(), |
173 | it.short_label(), | 173 | it.short_label(), |
174 | )) | 174 | )) |
@@ -176,7 +176,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
176 | ast::TraitDef(it) => { | 176 | ast::TraitDef(it) => { |
177 | Some(NavigationTarget::from_named( | 177 | Some(NavigationTarget::from_named( |
178 | db, | 178 | db, |
179 | node.with_ast(&it), | 179 | node.with_value(&it), |
180 | it.doc_comment_text(), | 180 | it.doc_comment_text(), |
181 | it.short_label(), | 181 | it.short_label(), |
182 | )) | 182 | )) |
@@ -184,7 +184,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
184 | ast::RecordFieldDef(it) => { | 184 | ast::RecordFieldDef(it) => { |
185 | Some(NavigationTarget::from_named( | 185 | Some(NavigationTarget::from_named( |
186 | db, | 186 | db, |
187 | node.with_ast(&it), | 187 | node.with_value(&it), |
188 | it.doc_comment_text(), | 188 | it.doc_comment_text(), |
189 | it.short_label(), | 189 | it.short_label(), |
190 | )) | 190 | )) |
@@ -192,7 +192,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
192 | ast::Module(it) => { | 192 | ast::Module(it) => { |
193 | Some(NavigationTarget::from_named( | 193 | Some(NavigationTarget::from_named( |
194 | db, | 194 | db, |
195 | node.with_ast(&it), | 195 | node.with_value(&it), |
196 | it.doc_comment_text(), | 196 | it.doc_comment_text(), |
197 | it.short_label(), | 197 | it.short_label(), |
198 | )) | 198 | )) |
@@ -200,7 +200,7 @@ fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<Navigati | |||
200 | ast::MacroCall(it) => { | 200 | ast::MacroCall(it) => { |
201 | Some(NavigationTarget::from_named( | 201 | Some(NavigationTarget::from_named( |
202 | db, | 202 | db, |
203 | node.with_ast(&it), | 203 | node.with_value(&it), |
204 | it.doc_comment_text(), | 204 | it.doc_comment_text(), |
205 | None, | 205 | None, |
206 | )) | 206 | )) |
diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide_api/src/goto_type_definition.rs index 7d694e1f6..28a83a3e2 100644 --- a/crates/ra_ide_api/src/goto_type_definition.rs +++ b/crates/ra_ide_api/src/goto_type_definition.rs | |||
@@ -16,13 +16,13 @@ pub(crate) fn goto_type_definition( | |||
16 | let token = file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?; | 16 | let token = file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?; |
17 | let token = descend_into_macros(db, position.file_id, token); | 17 | let token = descend_into_macros(db, position.file_id, token); |
18 | 18 | ||
19 | let node = token.ast.ancestors().find_map(|token| { | 19 | let node = token.value.ancestors().find_map(|token| { |
20 | token | 20 | token |
21 | .ancestors() | 21 | .ancestors() |
22 | .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some()) | 22 | .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some()) |
23 | })?; | 23 | })?; |
24 | 24 | ||
25 | let analyzer = hir::SourceAnalyzer::new(db, token.with_ast(&node), None); | 25 | let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); |
26 | 26 | ||
27 | let ty: hir::Ty = if let Some(ty) = | 27 | let ty: hir::Ty = if let Some(ty) = |
28 | ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) | 28 | ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 787b714b3..9839be985 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -101,11 +101,11 @@ fn hover_text_from_name_kind( | |||
101 | return match name_kind { | 101 | return match name_kind { |
102 | Macro(it) => { | 102 | Macro(it) => { |
103 | let src = it.source(db); | 103 | let src = it.source(db); |
104 | hover_text(src.ast.doc_comment_text(), Some(macro_label(&src.ast))) | 104 | hover_text(src.value.doc_comment_text(), Some(macro_label(&src.value))) |
105 | } | 105 | } |
106 | Field(it) => { | 106 | Field(it) => { |
107 | let src = it.source(db); | 107 | let src = it.source(db); |
108 | match src.ast { | 108 | match src.value { |
109 | hir::FieldSource::Named(it) => hover_text(it.doc_comment_text(), it.short_label()), | 109 | hir::FieldSource::Named(it) => hover_text(it.doc_comment_text(), it.short_label()), |
110 | _ => None, | 110 | _ => None, |
111 | } | 111 | } |
@@ -116,7 +116,7 @@ fn hover_text_from_name_kind( | |||
116 | hir::AssocItem::TypeAlias(it) => from_def_source(db, it), | 116 | hir::AssocItem::TypeAlias(it) => from_def_source(db, it), |
117 | }, | 117 | }, |
118 | Def(it) => match it { | 118 | Def(it) => match it { |
119 | hir::ModuleDef::Module(it) => match it.definition_source(db).ast { | 119 | hir::ModuleDef::Module(it) => match it.definition_source(db).value { |
120 | hir::ModuleSource::Module(it) => { | 120 | hir::ModuleSource::Module(it) => { |
121 | hover_text(it.doc_comment_text(), it.short_label()) | 121 | hover_text(it.doc_comment_text(), it.short_label()) |
122 | } | 122 | } |
@@ -158,7 +158,7 @@ fn hover_text_from_name_kind( | |||
158 | A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel, | 158 | A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel, |
159 | { | 159 | { |
160 | let src = def.source(db); | 160 | let src = def.source(db); |
161 | hover_text(src.ast.doc_comment_text(), src.ast.short_label()) | 161 | hover_text(src.value.doc_comment_text(), src.value.short_label()) |
162 | } | 162 | } |
163 | } | 163 | } |
164 | 164 | ||
@@ -170,11 +170,11 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
170 | let mut res = HoverResult::new(); | 170 | let mut res = HoverResult::new(); |
171 | 171 | ||
172 | let mut range = match_ast! { | 172 | let mut range = match_ast! { |
173 | match (token.ast.parent()) { | 173 | match (token.value.parent()) { |
174 | ast::NameRef(name_ref) => { | 174 | ast::NameRef(name_ref) => { |
175 | let mut no_fallback = false; | 175 | let mut no_fallback = false; |
176 | if let Some(name_kind) = | 176 | if let Some(name_kind) = |
177 | classify_name_ref(db, token.with_ast(&name_ref)).map(|d| d.kind) | 177 | classify_name_ref(db, token.with_value(&name_ref)).map(|d| d.kind) |
178 | { | 178 | { |
179 | res.extend(hover_text_from_name_kind(db, name_kind, &mut no_fallback)) | 179 | res.extend(hover_text_from_name_kind(db, name_kind, &mut no_fallback)) |
180 | } | 180 | } |
@@ -196,7 +196,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
196 | } | 196 | } |
197 | }, | 197 | }, |
198 | ast::Name(name) => { | 198 | ast::Name(name) => { |
199 | if let Some(name_kind) = classify_name(db, token.with_ast(&name)).map(|d| d.kind) { | 199 | if let Some(name_kind) = classify_name(db, token.with_value(&name)).map(|d| d.kind) { |
200 | res.extend(hover_text_from_name_kind(db, name_kind, &mut true)); | 200 | res.extend(hover_text_from_name_kind(db, name_kind, &mut true)); |
201 | } | 201 | } |
202 | 202 | ||
@@ -211,7 +211,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
211 | }; | 211 | }; |
212 | 212 | ||
213 | if range.is_none() { | 213 | if range.is_none() { |
214 | let node = token.ast.ancestors().find(|n| { | 214 | let node = token.value.ancestors().find(|n| { |
215 | ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some() | 215 | ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some() |
216 | })?; | 216 | })?; |
217 | let frange = FileRange { file_id: position.file_id, range: node.text_range() }; | 217 | let frange = FileRange { file_id: position.file_id, range: node.text_range() }; |
@@ -404,9 +404,7 @@ mod tests { | |||
404 | check_hover_result( | 404 | check_hover_result( |
405 | r#" | 405 | r#" |
406 | //- /main.rs | 406 | //- /main.rs |
407 | fn main() { | 407 | const foo<|>: u32 = 0; |
408 | const foo<|>: u32 = 0; | ||
409 | } | ||
410 | "#, | 408 | "#, |
411 | &["const foo: u32"], | 409 | &["const foo: u32"], |
412 | ); | 410 | ); |
@@ -414,9 +412,7 @@ mod tests { | |||
414 | check_hover_result( | 412 | check_hover_result( |
415 | r#" | 413 | r#" |
416 | //- /main.rs | 414 | //- /main.rs |
417 | fn main() { | 415 | static foo<|>: u32 = 0; |
418 | static foo<|>: u32 = 0; | ||
419 | } | ||
420 | "#, | 416 | "#, |
421 | &["static foo: u32"], | 417 | &["static foo: u32"], |
422 | ); | 418 | ); |
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index bc9b66550..3e3012559 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs | |||
@@ -16,7 +16,7 @@ pub(crate) fn goto_implementation( | |||
16 | let src = hir::ModuleSource::from_position(db, position); | 16 | let src = hir::ModuleSource::from_position(db, position); |
17 | let module = hir::Module::from_definition( | 17 | let module = hir::Module::from_definition( |
18 | db, | 18 | db, |
19 | hir::Source { file_id: position.file_id.into(), ast: src }, | 19 | hir::Source { file_id: position.file_id.into(), value: src }, |
20 | )?; | 20 | )?; |
21 | 21 | ||
22 | if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) { | 22 | if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) { |
@@ -42,11 +42,11 @@ fn impls_for_def( | |||
42 | ) -> Option<Vec<NavigationTarget>> { | 42 | ) -> Option<Vec<NavigationTarget>> { |
43 | let ty = match node { | 43 | let ty = match node { |
44 | ast::NominalDef::StructDef(def) => { | 44 | ast::NominalDef::StructDef(def) => { |
45 | let src = hir::Source { file_id: position.file_id.into(), ast: def.clone() }; | 45 | let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; |
46 | hir::Struct::from_source(db, src)?.ty(db) | 46 | hir::Struct::from_source(db, src)?.ty(db) |
47 | } | 47 | } |
48 | ast::NominalDef::EnumDef(def) => { | 48 | ast::NominalDef::EnumDef(def) => { |
49 | let src = hir::Source { file_id: position.file_id.into(), ast: def.clone() }; | 49 | let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; |
50 | hir::Enum::from_source(db, src)?.ty(db) | 50 | hir::Enum::from_source(db, src)?.ty(db) |
51 | } | 51 | } |
52 | }; | 52 | }; |
@@ -69,7 +69,7 @@ fn impls_for_trait( | |||
69 | node: &ast::TraitDef, | 69 | node: &ast::TraitDef, |
70 | module: hir::Module, | 70 | module: hir::Module, |
71 | ) -> Option<Vec<NavigationTarget>> { | 71 | ) -> Option<Vec<NavigationTarget>> { |
72 | let src = hir::Source { file_id: position.file_id.into(), ast: node.clone() }; | 72 | let src = hir::Source { file_id: position.file_id.into(), value: node.clone() }; |
73 | let tr = hir::Trait::from_source(db, src)?; | 73 | let tr = hir::Trait::from_source(db, src)?; |
74 | 74 | ||
75 | let krate = module.krate(); | 75 | let krate = module.krate(); |
diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs index 0cd959848..24a7ca5e7 100644 --- a/crates/ra_ide_api/src/inlay_hints.rs +++ b/crates/ra_ide_api/src/inlay_hints.rs | |||
@@ -19,10 +19,15 @@ pub struct InlayHint { | |||
19 | pub label: SmolStr, | 19 | pub label: SmolStr, |
20 | } | 20 | } |
21 | 21 | ||
22 | pub(crate) fn inlay_hints(db: &RootDatabase, file_id: FileId, file: &SourceFile) -> Vec<InlayHint> { | 22 | pub(crate) fn inlay_hints( |
23 | db: &RootDatabase, | ||
24 | file_id: FileId, | ||
25 | file: &SourceFile, | ||
26 | max_inlay_hint_length: Option<usize>, | ||
27 | ) -> Vec<InlayHint> { | ||
23 | file.syntax() | 28 | file.syntax() |
24 | .descendants() | 29 | .descendants() |
25 | .map(|node| get_inlay_hints(db, file_id, &node).unwrap_or_default()) | 30 | .map(|node| get_inlay_hints(db, file_id, &node, max_inlay_hint_length).unwrap_or_default()) |
26 | .flatten() | 31 | .flatten() |
27 | .collect() | 32 | .collect() |
28 | } | 33 | } |
@@ -31,6 +36,7 @@ fn get_inlay_hints( | |||
31 | db: &RootDatabase, | 36 | db: &RootDatabase, |
32 | file_id: FileId, | 37 | file_id: FileId, |
33 | node: &SyntaxNode, | 38 | node: &SyntaxNode, |
39 | max_inlay_hint_length: Option<usize>, | ||
34 | ) -> Option<Vec<InlayHint>> { | 40 | ) -> Option<Vec<InlayHint>> { |
35 | let analyzer = SourceAnalyzer::new(db, hir::Source::new(file_id.into(), node), None); | 41 | let analyzer = SourceAnalyzer::new(db, hir::Source::new(file_id.into(), node), None); |
36 | match_ast! { | 42 | match_ast! { |
@@ -40,7 +46,7 @@ fn get_inlay_hints( | |||
40 | return None; | 46 | return None; |
41 | } | 47 | } |
42 | let pat = it.pat()?; | 48 | let pat = it.pat()?; |
43 | Some(get_pat_type_hints(db, &analyzer, pat, false)) | 49 | Some(get_pat_type_hints(db, &analyzer, pat, false, max_inlay_hint_length)) |
44 | }, | 50 | }, |
45 | ast::LambdaExpr(it) => { | 51 | ast::LambdaExpr(it) => { |
46 | it.param_list().map(|param_list| { | 52 | it.param_list().map(|param_list| { |
@@ -48,22 +54,22 @@ fn get_inlay_hints( | |||
48 | .params() | 54 | .params() |
49 | .filter(|closure_param| closure_param.ascribed_type().is_none()) | 55 | .filter(|closure_param| closure_param.ascribed_type().is_none()) |
50 | .filter_map(|closure_param| closure_param.pat()) | 56 | .filter_map(|closure_param| closure_param.pat()) |
51 | .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false)) | 57 | .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false, max_inlay_hint_length)) |
52 | .flatten() | 58 | .flatten() |
53 | .collect() | 59 | .collect() |
54 | }) | 60 | }) |
55 | }, | 61 | }, |
56 | ast::ForExpr(it) => { | 62 | ast::ForExpr(it) => { |
57 | let pat = it.pat()?; | 63 | let pat = it.pat()?; |
58 | Some(get_pat_type_hints(db, &analyzer, pat, false)) | 64 | Some(get_pat_type_hints(db, &analyzer, pat, false, max_inlay_hint_length)) |
59 | }, | 65 | }, |
60 | ast::IfExpr(it) => { | 66 | ast::IfExpr(it) => { |
61 | let pat = it.condition()?.pat()?; | 67 | let pat = it.condition()?.pat()?; |
62 | Some(get_pat_type_hints(db, &analyzer, pat, true)) | 68 | Some(get_pat_type_hints(db, &analyzer, pat, true, max_inlay_hint_length)) |
63 | }, | 69 | }, |
64 | ast::WhileExpr(it) => { | 70 | ast::WhileExpr(it) => { |
65 | let pat = it.condition()?.pat()?; | 71 | let pat = it.condition()?.pat()?; |
66 | Some(get_pat_type_hints(db, &analyzer, pat, true)) | 72 | Some(get_pat_type_hints(db, &analyzer, pat, true, max_inlay_hint_length)) |
67 | }, | 73 | }, |
68 | ast::MatchArmList(it) => { | 74 | ast::MatchArmList(it) => { |
69 | Some( | 75 | Some( |
@@ -71,7 +77,7 @@ fn get_inlay_hints( | |||
71 | .arms() | 77 | .arms() |
72 | .map(|match_arm| match_arm.pats()) | 78 | .map(|match_arm| match_arm.pats()) |
73 | .flatten() | 79 | .flatten() |
74 | .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true)) | 80 | .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true, max_inlay_hint_length)) |
75 | .flatten() | 81 | .flatten() |
76 | .collect(), | 82 | .collect(), |
77 | ) | 83 | ) |
@@ -86,6 +92,7 @@ fn get_pat_type_hints( | |||
86 | analyzer: &SourceAnalyzer, | 92 | analyzer: &SourceAnalyzer, |
87 | root_pat: ast::Pat, | 93 | root_pat: ast::Pat, |
88 | skip_root_pat_hint: bool, | 94 | skip_root_pat_hint: bool, |
95 | max_inlay_hint_length: Option<usize>, | ||
89 | ) -> Vec<InlayHint> { | 96 | ) -> Vec<InlayHint> { |
90 | let original_pat = &root_pat.clone(); | 97 | let original_pat = &root_pat.clone(); |
91 | 98 | ||
@@ -99,7 +106,7 @@ fn get_pat_type_hints( | |||
99 | .map(|(range, pat_type)| InlayHint { | 106 | .map(|(range, pat_type)| InlayHint { |
100 | range, | 107 | range, |
101 | kind: InlayKind::TypeHint, | 108 | kind: InlayKind::TypeHint, |
102 | label: pat_type.display(db).to_string().into(), | 109 | label: pat_type.display_truncated(db, max_inlay_hint_length).to_string().into(), |
103 | }) | 110 | }) |
104 | .collect() | 111 | .collect() |
105 | } | 112 | } |
@@ -209,7 +216,7 @@ fn main() { | |||
209 | }"#, | 216 | }"#, |
210 | ); | 217 | ); |
211 | 218 | ||
212 | assert_debug_snapshot!(analysis.inlay_hints(file_id).unwrap(), @r###" | 219 | assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" |
213 | [ | 220 | [ |
214 | InlayHint { | 221 | InlayHint { |
215 | range: [193; 197), | 222 | range: [193; 197), |
@@ -278,7 +285,7 @@ fn main() { | |||
278 | }"#, | 285 | }"#, |
279 | ); | 286 | ); |
280 | 287 | ||
281 | assert_debug_snapshot!(analysis.inlay_hints(file_id).unwrap(), @r###" | 288 | assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" |
282 | [ | 289 | [ |
283 | InlayHint { | 290 | InlayHint { |
284 | range: [21; 30), | 291 | range: [21; 30), |
@@ -307,7 +314,7 @@ fn main() { | |||
307 | }"#, | 314 | }"#, |
308 | ); | 315 | ); |
309 | 316 | ||
310 | assert_debug_snapshot!(analysis.inlay_hints(file_id).unwrap(), @r###" | 317 | assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" |
311 | [ | 318 | [ |
312 | InlayHint { | 319 | InlayHint { |
313 | range: [21; 30), | 320 | range: [21; 30), |
@@ -355,7 +362,7 @@ fn main() { | |||
355 | }"#, | 362 | }"#, |
356 | ); | 363 | ); |
357 | 364 | ||
358 | assert_debug_snapshot!(analysis.inlay_hints(file_id).unwrap(), @r###" | 365 | assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" |
359 | [ | 366 | [ |
360 | InlayHint { | 367 | InlayHint { |
361 | range: [166; 170), | 368 | range: [166; 170), |
@@ -418,7 +425,7 @@ fn main() { | |||
418 | }"#, | 425 | }"#, |
419 | ); | 426 | ); |
420 | 427 | ||
421 | assert_debug_snapshot!(analysis.inlay_hints(file_id).unwrap(), @r###" | 428 | assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" |
422 | [ | 429 | [ |
423 | InlayHint { | 430 | InlayHint { |
424 | range: [166; 170), | 431 | range: [166; 170), |
@@ -481,7 +488,7 @@ fn main() { | |||
481 | }"#, | 488 | }"#, |
482 | ); | 489 | ); |
483 | 490 | ||
484 | assert_debug_snapshot!(analysis.inlay_hints(file_id).unwrap(), @r###" | 491 | assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" |
485 | [ | 492 | [ |
486 | InlayHint { | 493 | InlayHint { |
487 | range: [311; 315), | 494 | range: [311; 315), |
@@ -507,4 +514,41 @@ fn main() { | |||
507 | "### | 514 | "### |
508 | ); | 515 | ); |
509 | } | 516 | } |
517 | |||
518 | #[test] | ||
519 | fn hint_truncation() { | ||
520 | let (analysis, file_id) = single_file( | ||
521 | r#" | ||
522 | struct Smol<T>(T); | ||
523 | |||
524 | struct VeryLongOuterName<T>(T); | ||
525 | |||
526 | fn main() { | ||
527 | let a = Smol(0u32); | ||
528 | let b = VeryLongOuterName(0usize); | ||
529 | let c = Smol(Smol(0u32)) | ||
530 | }"#, | ||
531 | ); | ||
532 | |||
533 | assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" | ||
534 | [ | ||
535 | InlayHint { | ||
536 | range: [74; 75), | ||
537 | kind: TypeHint, | ||
538 | label: "Smol<u32>", | ||
539 | }, | ||
540 | InlayHint { | ||
541 | range: [98; 99), | ||
542 | kind: TypeHint, | ||
543 | label: "VeryLongOuterName<…>", | ||
544 | }, | ||
545 | InlayHint { | ||
546 | range: [137; 138), | ||
547 | kind: TypeHint, | ||
548 | label: "Smol<Smol<…>>", | ||
549 | }, | ||
550 | ] | ||
551 | "### | ||
552 | ); | ||
553 | } | ||
510 | } | 554 | } |
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs index 6f71b27db..7deeb3494 100644 --- a/crates/ra_ide_api/src/join_lines.rs +++ b/crates/ra_ide_api/src/join_lines.rs | |||
@@ -244,6 +244,34 @@ fn foo(e: Result<U, V>) { | |||
244 | } | 244 | } |
245 | 245 | ||
246 | #[test] | 246 | #[test] |
247 | fn join_lines_multiline_in_block() { | ||
248 | check_join_lines( | ||
249 | r" | ||
250 | fn foo() { | ||
251 | match ty { | ||
252 | <|> Some(ty) => { | ||
253 | match ty { | ||
254 | _ => false, | ||
255 | } | ||
256 | } | ||
257 | _ => true, | ||
258 | } | ||
259 | } | ||
260 | ", | ||
261 | r" | ||
262 | fn foo() { | ||
263 | match ty { | ||
264 | <|> Some(ty) => match ty { | ||
265 | _ => false, | ||
266 | }, | ||
267 | _ => true, | ||
268 | } | ||
269 | } | ||
270 | ", | ||
271 | ); | ||
272 | } | ||
273 | |||
274 | #[test] | ||
247 | fn join_lines_keeps_comma_for_block_in_match_arm() { | 275 | fn join_lines_keeps_comma_for_block_in_match_arm() { |
248 | // We already have a comma | 276 | // We already have a comma |
249 | check_join_lines( | 277 | check_join_lines( |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 57ed97147..62ad996bc 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -344,8 +344,14 @@ impl Analysis { | |||
344 | } | 344 | } |
345 | 345 | ||
346 | /// Returns a list of the places in the file where type hints can be displayed. | 346 | /// Returns a list of the places in the file where type hints can be displayed. |
347 | pub fn inlay_hints(&self, file_id: FileId) -> Cancelable<Vec<InlayHint>> { | 347 | pub fn inlay_hints( |
348 | self.with_db(|db| inlay_hints::inlay_hints(db, file_id, &db.parse(file_id).tree())) | 348 | &self, |
349 | file_id: FileId, | ||
350 | max_inlay_hint_length: Option<usize>, | ||
351 | ) -> Cancelable<Vec<InlayHint>> { | ||
352 | self.with_db(|db| { | ||
353 | inlay_hints::inlay_hints(db, file_id, &db.parse(file_id).tree(), max_inlay_hint_length) | ||
354 | }) | ||
349 | } | 355 | } |
350 | 356 | ||
351 | /// Returns the set of folding ranges. | 357 | /// Returns the set of folding ranges. |
diff --git a/crates/ra_ide_api/src/parent_module.rs b/crates/ra_ide_api/src/parent_module.rs index 4c57566e2..fa232a379 100644 --- a/crates/ra_ide_api/src/parent_module.rs +++ b/crates/ra_ide_api/src/parent_module.rs | |||
@@ -10,7 +10,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na | |||
10 | let src = hir::ModuleSource::from_position(db, position); | 10 | let src = hir::ModuleSource::from_position(db, position); |
11 | let module = match hir::Module::from_definition( | 11 | let module = match hir::Module::from_definition( |
12 | db, | 12 | db, |
13 | hir::Source { file_id: position.file_id.into(), ast: src }, | 13 | hir::Source { file_id: position.file_id.into(), value: src }, |
14 | ) { | 14 | ) { |
15 | None => return Vec::new(), | 15 | None => return Vec::new(), |
16 | Some(it) => it, | 16 | Some(it) => it, |
@@ -23,7 +23,8 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na | |||
23 | pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> { | 23 | pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> { |
24 | let src = hir::ModuleSource::from_file_id(db, file_id); | 24 | let src = hir::ModuleSource::from_file_id(db, file_id); |
25 | let module = | 25 | let module = |
26 | match hir::Module::from_definition(db, hir::Source { file_id: file_id.into(), ast: src }) { | 26 | match hir::Module::from_definition(db, hir::Source { file_id: file_id.into(), value: src }) |
27 | { | ||
27 | Some(it) => it, | 28 | Some(it) => it, |
28 | None => return Vec::new(), | 29 | None => return Vec::new(), |
29 | }; | 30 | }; |
diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs index ea9d20e71..4a4b030f8 100644 --- a/crates/ra_ide_api/src/references/classify.rs +++ b/crates/ra_ide_api/src/references/classify.rs | |||
@@ -13,12 +13,12 @@ use crate::db::RootDatabase; | |||
13 | 13 | ||
14 | pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Option<NameDefinition> { | 14 | pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Option<NameDefinition> { |
15 | let _p = profile("classify_name"); | 15 | let _p = profile("classify_name"); |
16 | let parent = name.ast.syntax().parent()?; | 16 | let parent = name.value.syntax().parent()?; |
17 | 17 | ||
18 | match_ast! { | 18 | match_ast! { |
19 | match parent { | 19 | match parent { |
20 | ast::BindPat(it) => { | 20 | ast::BindPat(it) => { |
21 | let src = name.with_ast(it); | 21 | let src = name.with_value(it); |
22 | let local = hir::Local::from_source(db, src)?; | 22 | let local = hir::Local::from_source(db, src)?; |
23 | Some(NameDefinition { | 23 | Some(NameDefinition { |
24 | visibility: None, | 24 | visibility: None, |
@@ -28,7 +28,7 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti | |||
28 | }, | 28 | }, |
29 | ast::RecordFieldDef(it) => { | 29 | ast::RecordFieldDef(it) => { |
30 | let ast = hir::FieldSource::Named(it); | 30 | let ast = hir::FieldSource::Named(it); |
31 | let src = name.with_ast(ast); | 31 | let src = name.with_value(ast); |
32 | let field = hir::StructField::from_source(db, src)?; | 32 | let field = hir::StructField::from_source(db, src)?; |
33 | Some(from_struct_field(db, field)) | 33 | Some(from_struct_field(db, field)) |
34 | }, | 34 | }, |
@@ -36,42 +36,42 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti | |||
36 | let def = { | 36 | let def = { |
37 | if !it.has_semi() { | 37 | if !it.has_semi() { |
38 | let ast = hir::ModuleSource::Module(it); | 38 | let ast = hir::ModuleSource::Module(it); |
39 | let src = name.with_ast(ast); | 39 | let src = name.with_value(ast); |
40 | hir::Module::from_definition(db, src) | 40 | hir::Module::from_definition(db, src) |
41 | } else { | 41 | } else { |
42 | let src = name.with_ast(it); | 42 | let src = name.with_value(it); |
43 | hir::Module::from_declaration(db, src) | 43 | hir::Module::from_declaration(db, src) |
44 | } | 44 | } |
45 | }?; | 45 | }?; |
46 | Some(from_module_def(db, def.into(), None)) | 46 | Some(from_module_def(db, def.into(), None)) |
47 | }, | 47 | }, |
48 | ast::StructDef(it) => { | 48 | ast::StructDef(it) => { |
49 | let src = name.with_ast(it); | 49 | let src = name.with_value(it); |
50 | let def = hir::Struct::from_source(db, src)?; | 50 | let def = hir::Struct::from_source(db, src)?; |
51 | Some(from_module_def(db, def.into(), None)) | 51 | Some(from_module_def(db, def.into(), None)) |
52 | }, | 52 | }, |
53 | ast::EnumDef(it) => { | 53 | ast::EnumDef(it) => { |
54 | let src = name.with_ast(it); | 54 | let src = name.with_value(it); |
55 | let def = hir::Enum::from_source(db, src)?; | 55 | let def = hir::Enum::from_source(db, src)?; |
56 | Some(from_module_def(db, def.into(), None)) | 56 | Some(from_module_def(db, def.into(), None)) |
57 | }, | 57 | }, |
58 | ast::TraitDef(it) => { | 58 | ast::TraitDef(it) => { |
59 | let src = name.with_ast(it); | 59 | let src = name.with_value(it); |
60 | let def = hir::Trait::from_source(db, src)?; | 60 | let def = hir::Trait::from_source(db, src)?; |
61 | Some(from_module_def(db, def.into(), None)) | 61 | Some(from_module_def(db, def.into(), None)) |
62 | }, | 62 | }, |
63 | ast::StaticDef(it) => { | 63 | ast::StaticDef(it) => { |
64 | let src = name.with_ast(it); | 64 | let src = name.with_value(it); |
65 | let def = hir::Static::from_source(db, src)?; | 65 | let def = hir::Static::from_source(db, src)?; |
66 | Some(from_module_def(db, def.into(), None)) | 66 | Some(from_module_def(db, def.into(), None)) |
67 | }, | 67 | }, |
68 | ast::EnumVariant(it) => { | 68 | ast::EnumVariant(it) => { |
69 | let src = name.with_ast(it); | 69 | let src = name.with_value(it); |
70 | let def = hir::EnumVariant::from_source(db, src)?; | 70 | let def = hir::EnumVariant::from_source(db, src)?; |
71 | Some(from_module_def(db, def.into(), None)) | 71 | Some(from_module_def(db, def.into(), None)) |
72 | }, | 72 | }, |
73 | ast::FnDef(it) => { | 73 | ast::FnDef(it) => { |
74 | let src = name.with_ast(it); | 74 | let src = name.with_value(it); |
75 | let def = hir::Function::from_source(db, src)?; | 75 | let def = hir::Function::from_source(db, src)?; |
76 | if parent.parent().and_then(ast::ItemList::cast).is_some() { | 76 | if parent.parent().and_then(ast::ItemList::cast).is_some() { |
77 | Some(from_assoc_item(db, def.into())) | 77 | Some(from_assoc_item(db, def.into())) |
@@ -80,7 +80,7 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti | |||
80 | } | 80 | } |
81 | }, | 81 | }, |
82 | ast::ConstDef(it) => { | 82 | ast::ConstDef(it) => { |
83 | let src = name.with_ast(it); | 83 | let src = name.with_value(it); |
84 | let def = hir::Const::from_source(db, src)?; | 84 | let def = hir::Const::from_source(db, src)?; |
85 | if parent.parent().and_then(ast::ItemList::cast).is_some() { | 85 | if parent.parent().and_then(ast::ItemList::cast).is_some() { |
86 | Some(from_assoc_item(db, def.into())) | 86 | Some(from_assoc_item(db, def.into())) |
@@ -89,7 +89,7 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti | |||
89 | } | 89 | } |
90 | }, | 90 | }, |
91 | ast::TypeAliasDef(it) => { | 91 | ast::TypeAliasDef(it) => { |
92 | let src = name.with_ast(it); | 92 | let src = name.with_value(it); |
93 | let def = hir::TypeAlias::from_source(db, src)?; | 93 | let def = hir::TypeAlias::from_source(db, src)?; |
94 | if parent.parent().and_then(ast::ItemList::cast).is_some() { | 94 | if parent.parent().and_then(ast::ItemList::cast).is_some() { |
95 | Some(from_assoc_item(db, def.into())) | 95 | Some(from_assoc_item(db, def.into())) |
@@ -98,11 +98,11 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti | |||
98 | } | 98 | } |
99 | }, | 99 | }, |
100 | ast::MacroCall(it) => { | 100 | ast::MacroCall(it) => { |
101 | let src = name.with_ast(it); | 101 | let src = name.with_value(it); |
102 | let def = hir::MacroDef::from_source(db, src.clone())?; | 102 | let def = hir::MacroDef::from_source(db, src.clone())?; |
103 | 103 | ||
104 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); | 104 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); |
105 | let module = Module::from_definition(db, src.with_ast(module_src))?; | 105 | let module = Module::from_definition(db, src.with_value(module_src))?; |
106 | 106 | ||
107 | Some(NameDefinition { | 107 | Some(NameDefinition { |
108 | visibility: None, | 108 | visibility: None, |
@@ -121,7 +121,7 @@ pub(crate) fn classify_name_ref( | |||
121 | ) -> Option<NameDefinition> { | 121 | ) -> Option<NameDefinition> { |
122 | let _p = profile("classify_name_ref"); | 122 | let _p = profile("classify_name_ref"); |
123 | 123 | ||
124 | let parent = name_ref.ast.syntax().parent()?; | 124 | let parent = name_ref.value.syntax().parent()?; |
125 | let analyzer = SourceAnalyzer::new(db, name_ref.map(|it| it.syntax()), None); | 125 | let analyzer = SourceAnalyzer::new(db, name_ref.map(|it| it.syntax()), None); |
126 | 126 | ||
127 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { | 127 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { |
@@ -142,16 +142,16 @@ pub(crate) fn classify_name_ref( | |||
142 | tested_by!(goto_definition_works_for_record_fields); | 142 | tested_by!(goto_definition_works_for_record_fields); |
143 | if let Some(record_lit) = record_field.syntax().ancestors().find_map(ast::RecordLit::cast) { | 143 | if let Some(record_lit) = record_field.syntax().ancestors().find_map(ast::RecordLit::cast) { |
144 | let variant_def = analyzer.resolve_record_literal(&record_lit)?; | 144 | let variant_def = analyzer.resolve_record_literal(&record_lit)?; |
145 | let hir_path = Path::from_name_ref(name_ref.ast); | 145 | let hir_path = Path::from_name_ref(name_ref.value); |
146 | let hir_name = hir_path.as_ident()?; | 146 | let hir_name = hir_path.as_ident()?; |
147 | let field = variant_def.field(db, hir_name)?; | 147 | let field = variant_def.field(db, hir_name)?; |
148 | return Some(from_struct_field(db, field)); | 148 | return Some(from_struct_field(db, field)); |
149 | } | 149 | } |
150 | } | 150 | } |
151 | 151 | ||
152 | let ast = ModuleSource::from_child_node(db, name_ref.with_ast(&parent)); | 152 | let ast = ModuleSource::from_child_node(db, name_ref.with_value(&parent)); |
153 | // FIXME: find correct container and visibility for each case | 153 | // FIXME: find correct container and visibility for each case |
154 | let container = Module::from_definition(db, name_ref.with_ast(ast))?; | 154 | let container = Module::from_definition(db, name_ref.with_value(ast))?; |
155 | let visibility = None; | 155 | let visibility = None; |
156 | 156 | ||
157 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { | 157 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { |
@@ -162,7 +162,7 @@ pub(crate) fn classify_name_ref( | |||
162 | } | 162 | } |
163 | } | 163 | } |
164 | 164 | ||
165 | let path = name_ref.ast.syntax().ancestors().find_map(ast::Path::cast)?; | 165 | let path = name_ref.value.syntax().ancestors().find_map(ast::Path::cast)?; |
166 | let resolved = analyzer.resolve_path(db, &path)?; | 166 | let resolved = analyzer.resolve_path(db, &path)?; |
167 | match resolved { | 167 | match resolved { |
168 | PathResolution::Def(def) => Some(from_module_def(db, def, Some(container))), | 168 | PathResolution::Def(def) => Some(from_module_def(db, def, Some(container))), |
diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide_api/src/references/name_definition.rs index ccd75278a..aca23f79e 100644 --- a/crates/ra_ide_api/src/references/name_definition.rs +++ b/crates/ra_ide_api/src/references/name_definition.rs | |||
@@ -32,9 +32,9 @@ pub(crate) struct NameDefinition { | |||
32 | pub(super) fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition { | 32 | pub(super) fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition { |
33 | let container = item.module(db); | 33 | let container = item.module(db); |
34 | let visibility = match item { | 34 | let visibility = match item { |
35 | AssocItem::Function(f) => f.source(db).ast.visibility(), | 35 | AssocItem::Function(f) => f.source(db).value.visibility(), |
36 | AssocItem::Const(c) => c.source(db).ast.visibility(), | 36 | AssocItem::Const(c) => c.source(db).value.visibility(), |
37 | AssocItem::TypeAlias(a) => a.source(db).ast.visibility(), | 37 | AssocItem::TypeAlias(a) => a.source(db).value.visibility(), |
38 | }; | 38 | }; |
39 | let kind = NameKind::AssocItem(item); | 39 | let kind = NameKind::AssocItem(item); |
40 | NameDefinition { kind, container, visibility } | 40 | NameDefinition { kind, container, visibility } |
@@ -45,8 +45,8 @@ pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDe | |||
45 | let parent = field.parent_def(db); | 45 | let parent = field.parent_def(db); |
46 | let container = parent.module(db); | 46 | let container = parent.module(db); |
47 | let visibility = match parent { | 47 | let visibility = match parent { |
48 | VariantDef::Struct(s) => s.source(db).ast.visibility(), | 48 | VariantDef::Struct(s) => s.source(db).value.visibility(), |
49 | VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(), | 49 | VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), |
50 | }; | 50 | }; |
51 | NameDefinition { kind, container, visibility } | 51 | NameDefinition { kind, container, visibility } |
52 | } | 52 | } |
@@ -60,22 +60,22 @@ pub(super) fn from_module_def( | |||
60 | let (container, visibility) = match def { | 60 | let (container, visibility) = match def { |
61 | ModuleDef::Module(it) => { | 61 | ModuleDef::Module(it) => { |
62 | let container = it.parent(db).or_else(|| Some(it)).unwrap(); | 62 | let container = it.parent(db).or_else(|| Some(it)).unwrap(); |
63 | let visibility = it.declaration_source(db).and_then(|s| s.ast.visibility()); | 63 | let visibility = it.declaration_source(db).and_then(|s| s.value.visibility()); |
64 | (container, visibility) | 64 | (container, visibility) |
65 | } | 65 | } |
66 | ModuleDef::EnumVariant(it) => { | 66 | ModuleDef::EnumVariant(it) => { |
67 | let container = it.module(db); | 67 | let container = it.module(db); |
68 | let visibility = it.source(db).ast.parent_enum().visibility(); | 68 | let visibility = it.source(db).value.parent_enum().visibility(); |
69 | (container, visibility) | 69 | (container, visibility) |
70 | } | 70 | } |
71 | ModuleDef::Function(it) => (it.module(db), it.source(db).ast.visibility()), | 71 | ModuleDef::Function(it) => (it.module(db), it.source(db).value.visibility()), |
72 | ModuleDef::Const(it) => (it.module(db), it.source(db).ast.visibility()), | 72 | ModuleDef::Const(it) => (it.module(db), it.source(db).value.visibility()), |
73 | ModuleDef::Static(it) => (it.module(db), it.source(db).ast.visibility()), | 73 | ModuleDef::Static(it) => (it.module(db), it.source(db).value.visibility()), |
74 | ModuleDef::Trait(it) => (it.module(db), it.source(db).ast.visibility()), | 74 | ModuleDef::Trait(it) => (it.module(db), it.source(db).value.visibility()), |
75 | ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).ast.visibility()), | 75 | ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).value.visibility()), |
76 | ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).ast.visibility()), | 76 | ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).value.visibility()), |
77 | ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).ast.visibility()), | 77 | ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).value.visibility()), |
78 | ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).ast.visibility()), | 78 | ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).value.visibility()), |
79 | ModuleDef::BuiltinType(..) => (module.unwrap(), None), | 79 | ModuleDef::BuiltinType(..) => (module.unwrap(), None), |
80 | }; | 80 | }; |
81 | NameDefinition { kind, container, visibility } | 81 | NameDefinition { kind, container, visibility } |
diff --git a/crates/ra_ide_api/src/references/rename.rs b/crates/ra_ide_api/src/references/rename.rs index 11f81cbb3..d58496049 100644 --- a/crates/ra_ide_api/src/references/rename.rs +++ b/crates/ra_ide_api/src/references/rename.rs | |||
@@ -55,11 +55,11 @@ fn rename_mod( | |||
55 | ) -> Option<SourceChange> { | 55 | ) -> Option<SourceChange> { |
56 | let mut source_file_edits = Vec::new(); | 56 | let mut source_file_edits = Vec::new(); |
57 | let mut file_system_edits = Vec::new(); | 57 | let mut file_system_edits = Vec::new(); |
58 | let module_src = hir::Source { file_id: position.file_id.into(), ast: ast_module.clone() }; | 58 | let module_src = hir::Source { file_id: position.file_id.into(), value: ast_module.clone() }; |
59 | if let Some(module) = hir::Module::from_declaration(db, module_src) { | 59 | if let Some(module) = hir::Module::from_declaration(db, module_src) { |
60 | let src = module.definition_source(db); | 60 | let src = module.definition_source(db); |
61 | let file_id = src.file_id.original_file(db); | 61 | let file_id = src.file_id.original_file(db); |
62 | match src.ast { | 62 | match src.value { |
63 | ModuleSource::SourceFile(..) => { | 63 | ModuleSource::SourceFile(..) => { |
64 | let mod_path: RelativePathBuf = db.file_relative_path(file_id); | 64 | let mod_path: RelativePathBuf = db.file_relative_path(file_id); |
65 | // mod is defined in path/to/dir/mod.rs | 65 | // mod is defined in path/to/dir/mod.rs |
@@ -121,141 +121,9 @@ mod tests { | |||
121 | 121 | ||
122 | use crate::{ | 122 | use crate::{ |
123 | mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId, | 123 | mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId, |
124 | ReferenceSearchResult, | ||
125 | }; | 124 | }; |
126 | 125 | ||
127 | #[test] | 126 | #[test] |
128 | fn test_find_all_refs_for_local() { | ||
129 | let code = r#" | ||
130 | fn main() { | ||
131 | let mut i = 1; | ||
132 | let j = 1; | ||
133 | i = i<|> + j; | ||
134 | |||
135 | { | ||
136 | i = 0; | ||
137 | } | ||
138 | |||
139 | i = 5; | ||
140 | }"#; | ||
141 | |||
142 | let refs = get_all_refs(code); | ||
143 | assert_eq!(refs.len(), 5); | ||
144 | } | ||
145 | |||
146 | #[test] | ||
147 | fn test_find_all_refs_for_param_inside() { | ||
148 | let code = r#" | ||
149 | fn foo(i : u32) -> u32 { | ||
150 | i<|> | ||
151 | }"#; | ||
152 | |||
153 | let refs = get_all_refs(code); | ||
154 | assert_eq!(refs.len(), 2); | ||
155 | } | ||
156 | |||
157 | #[test] | ||
158 | fn test_find_all_refs_for_fn_param() { | ||
159 | let code = r#" | ||
160 | fn foo(i<|> : u32) -> u32 { | ||
161 | i | ||
162 | }"#; | ||
163 | |||
164 | let refs = get_all_refs(code); | ||
165 | assert_eq!(refs.len(), 2); | ||
166 | } | ||
167 | |||
168 | #[test] | ||
169 | fn test_find_all_refs_field_name() { | ||
170 | let code = r#" | ||
171 | //- /lib.rs | ||
172 | struct Foo { | ||
173 | pub spam<|>: u32, | ||
174 | } | ||
175 | |||
176 | fn main(s: Foo) { | ||
177 | let f = s.spam; | ||
178 | } | ||
179 | "#; | ||
180 | |||
181 | let refs = get_all_refs(code); | ||
182 | assert_eq!(refs.len(), 2); | ||
183 | } | ||
184 | |||
185 | #[test] | ||
186 | fn test_find_all_refs_impl_item_name() { | ||
187 | let code = r#" | ||
188 | //- /lib.rs | ||
189 | struct Foo; | ||
190 | impl Foo { | ||
191 | fn f<|>(&self) { } | ||
192 | } | ||
193 | "#; | ||
194 | |||
195 | let refs = get_all_refs(code); | ||
196 | assert_eq!(refs.len(), 1); | ||
197 | } | ||
198 | |||
199 | #[test] | ||
200 | fn test_find_all_refs_enum_var_name() { | ||
201 | let code = r#" | ||
202 | //- /lib.rs | ||
203 | enum Foo { | ||
204 | A, | ||
205 | B<|>, | ||
206 | C, | ||
207 | } | ||
208 | "#; | ||
209 | |||
210 | let refs = get_all_refs(code); | ||
211 | assert_eq!(refs.len(), 1); | ||
212 | } | ||
213 | |||
214 | #[test] | ||
215 | fn test_find_all_refs_modules() { | ||
216 | let code = r#" | ||
217 | //- /lib.rs | ||
218 | pub mod foo; | ||
219 | pub mod bar; | ||
220 | |||
221 | fn f() { | ||
222 | let i = foo::Foo { n: 5 }; | ||
223 | } | ||
224 | |||
225 | //- /foo.rs | ||
226 | use crate::bar; | ||
227 | |||
228 | pub struct Foo { | ||
229 | pub n: u32, | ||
230 | } | ||
231 | |||
232 | fn f() { | ||
233 | let i = bar::Bar { n: 5 }; | ||
234 | } | ||
235 | |||
236 | //- /bar.rs | ||
237 | use crate::foo; | ||
238 | |||
239 | pub struct Bar { | ||
240 | pub n: u32, | ||
241 | } | ||
242 | |||
243 | fn f() { | ||
244 | let i = foo::Foo<|> { n: 5 }; | ||
245 | } | ||
246 | "#; | ||
247 | |||
248 | let (analysis, pos) = analysis_and_position(code); | ||
249 | let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); | ||
250 | assert_eq!(refs.len(), 3); | ||
251 | } | ||
252 | |||
253 | fn get_all_refs(text: &str) -> ReferenceSearchResult { | ||
254 | let (analysis, position) = single_file_with_position(text); | ||
255 | analysis.find_all_refs(position, None).unwrap().unwrap() | ||
256 | } | ||
257 | |||
258 | #[test] | ||
259 | fn test_rename_for_local() { | 127 | fn test_rename_for_local() { |
260 | test_rename( | 128 | test_rename( |
261 | r#" | 129 | r#" |
diff --git a/crates/ra_ide_api/src/references/search_scope.rs b/crates/ra_ide_api/src/references/search_scope.rs index 2907787c2..f5c9589f4 100644 --- a/crates/ra_ide_api/src/references/search_scope.rs +++ b/crates/ra_ide_api/src/references/search_scope.rs | |||
@@ -73,9 +73,9 @@ impl NameDefinition { | |||
73 | 73 | ||
74 | if let NameKind::Local(var) = self.kind { | 74 | if let NameKind::Local(var) = self.kind { |
75 | let range = match var.parent(db) { | 75 | let range = match var.parent(db) { |
76 | DefWithBody::Function(f) => f.source(db).ast.syntax().text_range(), | 76 | DefWithBody::Function(f) => f.source(db).value.syntax().text_range(), |
77 | DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(), | 77 | DefWithBody::Const(c) => c.source(db).value.syntax().text_range(), |
78 | DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(), | 78 | DefWithBody::Static(s) => s.source(db).value.syntax().text_range(), |
79 | }; | 79 | }; |
80 | let mut res = FxHashMap::default(); | 80 | let mut res = FxHashMap::default(); |
81 | res.insert(file_id, Some(range)); | 81 | res.insert(file_id, Some(range)); |
@@ -91,7 +91,7 @@ impl NameDefinition { | |||
91 | let parent_src = parent_module.definition_source(db); | 91 | let parent_src = parent_module.definition_source(db); |
92 | let file_id = parent_src.file_id.original_file(db); | 92 | let file_id = parent_src.file_id.original_file(db); |
93 | 93 | ||
94 | match parent_src.ast { | 94 | match parent_src.value { |
95 | ModuleSource::Module(m) => { | 95 | ModuleSource::Module(m) => { |
96 | let range = Some(m.syntax().text_range()); | 96 | let range = Some(m.syntax().text_range()); |
97 | res.insert(file_id, range); | 97 | res.insert(file_id, range); |
@@ -135,7 +135,7 @@ impl NameDefinition { | |||
135 | } | 135 | } |
136 | 136 | ||
137 | let mut res = FxHashMap::default(); | 137 | let mut res = FxHashMap::default(); |
138 | let range = match module_src.ast { | 138 | let range = match module_src.value { |
139 | ModuleSource::Module(m) => Some(m.syntax().text_range()), | 139 | ModuleSource::Module(m) => Some(m.syntax().text_range()), |
140 | ModuleSource::SourceFile(_) => None, | 140 | ModuleSource::SourceFile(_) => None, |
141 | }; | 141 | }; |
diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs index 9871a3b37..8045f3d60 100644 --- a/crates/ra_lsp_server/src/config.rs +++ b/crates/ra_lsp_server/src/config.rs | |||
@@ -29,6 +29,8 @@ pub struct ServerConfig { | |||
29 | 29 | ||
30 | pub lru_capacity: Option<usize>, | 30 | pub lru_capacity: Option<usize>, |
31 | 31 | ||
32 | pub max_inlay_hint_length: Option<usize>, | ||
33 | |||
32 | /// For internal usage to make integrated tests faster. | 34 | /// For internal usage to make integrated tests faster. |
33 | #[serde(deserialize_with = "nullable_bool_true")] | 35 | #[serde(deserialize_with = "nullable_bool_true")] |
34 | pub with_sysroot: bool, | 36 | pub with_sysroot: bool, |
@@ -44,6 +46,7 @@ impl Default for ServerConfig { | |||
44 | exclude_globs: Vec::new(), | 46 | exclude_globs: Vec::new(), |
45 | use_client_watching: false, | 47 | use_client_watching: false, |
46 | lru_capacity: None, | 48 | lru_capacity: None, |
49 | max_inlay_hint_length: None, | ||
47 | with_sysroot: true, | 50 | with_sysroot: true, |
48 | feature_flags: FxHashMap::default(), | 51 | feature_flags: FxHashMap::default(), |
49 | } | 52 | } |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index f828efdee..0dc0aeee8 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -123,6 +123,7 @@ pub fn main_loop( | |||
123 | .and_then(|it| it.folding_range.as_ref()) | 123 | .and_then(|it| it.folding_range.as_ref()) |
124 | .and_then(|it| it.line_folding_only) | 124 | .and_then(|it| it.line_folding_only) |
125 | .unwrap_or(false), | 125 | .unwrap_or(false), |
126 | max_inlay_hint_length: config.max_inlay_hint_length, | ||
126 | } | 127 | } |
127 | }; | 128 | }; |
128 | 129 | ||
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 0461bf385..e552f2106 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -888,7 +888,7 @@ pub fn handle_inlay_hints( | |||
888 | let analysis = world.analysis(); | 888 | let analysis = world.analysis(); |
889 | let line_index = analysis.file_line_index(file_id)?; | 889 | let line_index = analysis.file_line_index(file_id)?; |
890 | Ok(analysis | 890 | Ok(analysis |
891 | .inlay_hints(file_id)? | 891 | .inlay_hints(file_id, world.options.max_inlay_hint_length)? |
892 | .into_iter() | 892 | .into_iter() |
893 | .map(|api_type| InlayHint { | 893 | .map(|api_type| InlayHint { |
894 | label: api_type.label.to_string(), | 894 | label: api_type.label.to_string(), |
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index 51824e7a3..9bdea70c7 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -28,6 +28,7 @@ pub struct Options { | |||
28 | pub publish_decorations: bool, | 28 | pub publish_decorations: bool, |
29 | pub supports_location_link: bool, | 29 | pub supports_location_link: bool, |
30 | pub line_folding_only: bool, | 30 | pub line_folding_only: bool, |
31 | pub max_inlay_hint_length: Option<usize>, | ||
31 | } | 32 | } |
32 | 33 | ||
33 | /// `WorldState` is the primary mutable state of the language server | 34 | /// `WorldState` is the primary mutable state of the language server |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 2b381dcdb..de506d7cd 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -3625,8 +3625,11 @@ impl AstNode for TypeParam { | |||
3625 | impl ast::NameOwner for TypeParam {} | 3625 | impl ast::NameOwner for TypeParam {} |
3626 | impl ast::AttrsOwner for TypeParam {} | 3626 | impl ast::AttrsOwner for TypeParam {} |
3627 | impl ast::TypeBoundsOwner for TypeParam {} | 3627 | impl ast::TypeBoundsOwner for TypeParam {} |
3628 | impl ast::DefaultTypeParamOwner for TypeParam {} | 3628 | impl TypeParam { |
3629 | impl TypeParam {} | 3629 | pub fn default_type(&self) -> Option<TypeRef> { |
3630 | AstChildren::new(&self.syntax).next() | ||
3631 | } | ||
3632 | } | ||
3630 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 3633 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
3631 | pub struct TypeParamList { | 3634 | pub struct TypeParamList { |
3632 | pub(crate) syntax: SyntaxNode, | 3635 | pub(crate) syntax: SyntaxNode, |
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index c2b005886..f99984fe0 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs | |||
@@ -163,9 +163,3 @@ impl Iterator for CommentIter { | |||
163 | self.iter.by_ref().find_map(|el| el.into_token().and_then(ast::Comment::cast)) | 163 | self.iter.by_ref().find_map(|el| el.into_token().and_then(ast::Comment::cast)) |
164 | } | 164 | } |
165 | } | 165 | } |
166 | |||
167 | pub trait DefaultTypeParamOwner: AstNode { | ||
168 | fn default_type(&self) -> Option<ast::PathType> { | ||
169 | child_opt(self) | ||
170 | } | ||
171 | } | ||
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 70d85a8e6..88d1dc109 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -587,7 +587,10 @@ Grammar( | |||
587 | ("lifetime_params", "LifetimeParam" ), | 587 | ("lifetime_params", "LifetimeParam" ), |
588 | ] | 588 | ] |
589 | ), | 589 | ), |
590 | "TypeParam": ( traits: ["NameOwner", "AttrsOwner", "TypeBoundsOwner", "DefaultTypeParamOwner"] ), | 590 | "TypeParam": ( |
591 | options: [("default_type", "TypeRef")], | ||
592 | traits: ["NameOwner", "AttrsOwner", "TypeBoundsOwner"], | ||
593 | ), | ||
591 | "LifetimeParam": ( | 594 | "LifetimeParam": ( |
592 | traits: ["AttrsOwner"], | 595 | traits: ["AttrsOwner"], |
593 | ), | 596 | ), |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs index 31167cada..e049fce61 100644 --- a/crates/ra_syntax/src/ptr.rs +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -43,7 +43,7 @@ impl SyntaxNodePtr { | |||
43 | } | 43 | } |
44 | 44 | ||
45 | /// Like `SyntaxNodePtr`, but remembers the type of node | 45 | /// Like `SyntaxNodePtr`, but remembers the type of node |
46 | #[derive(Debug, PartialEq, Eq, Hash)] | 46 | #[derive(Debug, Hash)] |
47 | pub struct AstPtr<N: AstNode> { | 47 | pub struct AstPtr<N: AstNode> { |
48 | raw: SyntaxNodePtr, | 48 | raw: SyntaxNodePtr, |
49 | _ty: PhantomData<fn() -> N>, | 49 | _ty: PhantomData<fn() -> N>, |
@@ -56,6 +56,14 @@ impl<N: AstNode> Clone for AstPtr<N> { | |||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | impl<N: AstNode> Eq for AstPtr<N> {} | ||
60 | |||
61 | impl<N: AstNode> PartialEq for AstPtr<N> { | ||
62 | fn eq(&self, other: &AstPtr<N>) -> bool { | ||
63 | self.raw == other.raw | ||
64 | } | ||
65 | } | ||
66 | |||
59 | impl<N: AstNode> AstPtr<N> { | 67 | impl<N: AstNode> AstPtr<N> { |
60 | pub fn new(node: &N) -> AstPtr<N> { | 68 | pub fn new(node: &N) -> AstPtr<N> { |
61 | AstPtr { raw: SyntaxNodePtr::new(node.syntax()), _ty: PhantomData } | 69 | AstPtr { raw: SyntaxNodePtr::new(node.syntax()), _ty: PhantomData } |
diff --git a/docs/user/README.md b/docs/user/README.md index eac9c50d2..235676850 100644 --- a/docs/user/README.md +++ b/docs/user/README.md | |||
@@ -136,7 +136,7 @@ Installation: | |||
136 | [ra-emacs-lsp.el](https://github.com/rust-analyzer/rust-analyzer/blob/69ee5c9c5ef212f7911028c9ddf581559e6565c3/editors/emacs/ra-emacs-lsp.el) | 136 | [ra-emacs-lsp.el](https://github.com/rust-analyzer/rust-analyzer/blob/69ee5c9c5ef212f7911028c9ddf581559e6565c3/editors/emacs/ra-emacs-lsp.el) |
137 | to load path and require it in `init.el` | 137 | to load path and require it in `init.el` |
138 | * run `lsp` in a rust buffer | 138 | * run `lsp` in a rust buffer |
139 | * (Optionally) bind commands like `rust-analyzer-join-lines` or `rust-analyzer-extend-selection` to keys, and enable `rust-analyzer-inlay-hints-mode` to get inline type hints | 139 | * (Optionally) bind commands like `rust-analyzer-join-lines`, `rust-analyzer-extend-selection` and `rust-analyzer-expand-macro` to keys, and enable `rust-analyzer-inlay-hints-mode` to get inline type hints |
140 | 140 | ||
141 | 141 | ||
142 | ## Vim and NeoVim | 142 | ## Vim and NeoVim |
diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index ffaaaebcb..0dbdd94fb 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts | |||
@@ -87,7 +87,7 @@ export class HintsUpdater { | |||
87 | range: hint.range, | 87 | range: hint.range, |
88 | renderOptions: { | 88 | renderOptions: { |
89 | after: { | 89 | after: { |
90 | contentText: `: ${this.truncateHint(hint.label)}` | 90 | contentText: `: ${hint.label}` |
91 | } | 91 | } |
92 | } | 92 | } |
93 | })); | 93 | })); |
@@ -98,18 +98,6 @@ export class HintsUpdater { | |||
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | private truncateHint(label: string): string { | ||
102 | if (!Server.config.maxInlayHintLength) { | ||
103 | return label; | ||
104 | } | ||
105 | |||
106 | let newLabel = label.substring(0, Server.config.maxInlayHintLength); | ||
107 | if (label.length > Server.config.maxInlayHintLength) { | ||
108 | newLabel += '…'; | ||
109 | } | ||
110 | return newLabel; | ||
111 | } | ||
112 | |||
113 | private async queryHints(documentUri: string): Promise<InlayHint[] | null> { | 101 | private async queryHints(documentUri: string): Promise<InlayHint[] | null> { |
114 | const request: InlayHintsParams = { | 102 | const request: InlayHintsParams = { |
115 | textDocument: { uri: documentUri } | 103 | textDocument: { uri: documentUri } |
diff --git a/editors/code/src/server.ts b/editors/code/src/server.ts index a3ef21a16..7907b70bc 100644 --- a/editors/code/src/server.ts +++ b/editors/code/src/server.ts | |||
@@ -43,6 +43,7 @@ export class Server { | |||
43 | initializationOptions: { | 43 | initializationOptions: { |
44 | publishDecorations: true, | 44 | publishDecorations: true, |
45 | lruCapacity: Server.config.lruCapacity, | 45 | lruCapacity: Server.config.lruCapacity, |
46 | maxInlayHintLength: Server.config.maxInlayHintLength, | ||
46 | excludeGlobs: Server.config.excludeGlobs, | 47 | excludeGlobs: Server.config.excludeGlobs, |
47 | useClientWatching: Server.config.useClientWatching, | 48 | useClientWatching: Server.config.useClientWatching, |
48 | featureFlags: Server.config.featureFlags | 49 | featureFlags: Server.config.featureFlags |
diff --git a/editors/emacs/ra-emacs-lsp.el b/editors/emacs/ra-emacs-lsp.el index 79822c8ce..fafb9cbe7 100644 --- a/editors/emacs/ra-emacs-lsp.el +++ b/editors/emacs/ra-emacs-lsp.el | |||
@@ -16,6 +16,7 @@ | |||
16 | ;; - implements joinLines (you need to bind rust-analyzer-join-lines to a key) | 16 | ;; - implements joinLines (you need to bind rust-analyzer-join-lines to a key) |
17 | ;; - implements selectionRanges (either bind lsp-extend-selection to a key, or use expand-region) | 17 | ;; - implements selectionRanges (either bind lsp-extend-selection to a key, or use expand-region) |
18 | ;; - provides rust-analyzer-inlay-hints-mode for inline type hints | 18 | ;; - provides rust-analyzer-inlay-hints-mode for inline type hints |
19 | ;; - provides rust-analyzer-expand-macro to expand macros | ||
19 | 20 | ||
20 | ;; What's missing: | 21 | ;; What's missing: |
21 | ;; - file system changes in apply-source-change | 22 | ;; - file system changes in apply-source-change |
@@ -247,5 +248,32 @@ | |||
247 | (remove-hook 'after-change-functions #'rust-analyzer--inlay-hints-change-handler t)))) | 248 | (remove-hook 'after-change-functions #'rust-analyzer--inlay-hints-change-handler t)))) |
248 | 249 | ||
249 | 250 | ||
251 | |||
252 | ;; expand macros | ||
253 | (defun rust-analyzer-expand-macro () | ||
254 | "Expands the macro call at point recursively." | ||
255 | (interactive) | ||
256 | (when (eq 'rust-mode major-mode) | ||
257 | (let* ((workspace (lsp-find-workspace 'rust-analyzer (buffer-file-name))) | ||
258 | (params (list :textDocument (lsp--text-document-identifier) | ||
259 | :position (lsp--cur-position)))) | ||
260 | (when workspace | ||
261 | (let* ((response (with-lsp-workspace workspace | ||
262 | (lsp-send-request (lsp-make-request | ||
263 | "rust-analyzer/expandMacro" | ||
264 | params)))) | ||
265 | (result (when response (ht-get response "expansion")))) | ||
266 | (if result | ||
267 | (let ((buf (get-buffer-create (concat "*rust-analyzer macro expansion " (with-lsp-workspace workspace (lsp-workspace-root)) "*")))) | ||
268 | (with-current-buffer buf | ||
269 | (let ((inhibit-read-only t)) | ||
270 | (erase-buffer) | ||
271 | (insert result) | ||
272 | (setq buffer-read-only t) | ||
273 | (special-mode))) | ||
274 | (pop-to-buffer buf)) | ||
275 | (message "No macro found at point, or it could not be expanded"))))))) | ||
276 | |||
277 | |||
250 | (provide 'ra-emacs-lsp) | 278 | (provide 'ra-emacs-lsp) |
251 | ;;; ra-emacs-lsp.el ends here | 279 | ;;; ra-emacs-lsp.el ends here |
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 77b9ae2b4..65cabf005 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml | |||
@@ -5,6 +5,9 @@ version = "0.1.0" | |||
5 | authors = ["rust-analyzer developers"] | 5 | authors = ["rust-analyzer developers"] |
6 | publish = false | 6 | publish = false |
7 | 7 | ||
8 | [lib] | ||
9 | doctest = false | ||
10 | |||
8 | [dependencies] | 11 | [dependencies] |
9 | walkdir = "2.1.3" | 12 | walkdir = "2.1.3" |
10 | pico-args = "0.3.0" | 13 | pico-args = "0.3.0" |
diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 663e28103..c97bfec97 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs | |||
@@ -9,11 +9,10 @@ | |||
9 | //! `.cargo/config`. | 9 | //! `.cargo/config`. |
10 | mod help; | 10 | mod help; |
11 | 11 | ||
12 | use std::{env, fmt::Write, path::PathBuf, str}; | ||
13 | |||
12 | use anyhow::Context; | 14 | use anyhow::Context; |
13 | use core::fmt::Write; | ||
14 | use core::str; | ||
15 | use pico_args::Arguments; | 15 | use pico_args::Arguments; |
16 | use std::{env, path::PathBuf}; | ||
17 | use xtask::{ | 16 | use xtask::{ |
18 | codegen::{self, Mode}, | 17 | codegen::{self, Mode}, |
19 | install_pre_commit_hook, reformat_staged_files, run, run_clippy, run_fuzzer, run_rustfmt, | 18 | install_pre_commit_hook, reformat_staged_files, run, run_clippy, run_fuzzer, run_rustfmt, |
@@ -37,7 +36,7 @@ struct ServerOpt { | |||
37 | } | 36 | } |
38 | 37 | ||
39 | fn main() -> Result<()> { | 38 | fn main() -> Result<()> { |
40 | if std::env::args().next().map(|it| it.contains("pre-commit")) == Some(true) { | 39 | if env::args().next().map(|it| it.contains("pre-commit")) == Some(true) { |
41 | return reformat_staged_files(); | 40 | return reformat_staged_files(); |
42 | } | 41 | } |
43 | 42 | ||
@@ -174,7 +173,7 @@ fn fix_path_for_mac() -> Result<()> { | |||
174 | fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> { | 173 | fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> { |
175 | let npm_version = Cmd { | 174 | let npm_version = Cmd { |
176 | unix: r"npm --version", | 175 | unix: r"npm --version", |
177 | windows: r"cmd.exe /c npm.cmd --version", | 176 | windows: r"cmd.exe /c npm --version", |
178 | work_dir: "./editors/code", | 177 | work_dir: "./editors/code", |
179 | } | 178 | } |
180 | .run(); | 179 | .run(); |
@@ -183,10 +182,10 @@ fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> { | |||
183 | eprintln!("\nERROR: `npm --version` failed, `npm` is required to build the VS Code plugin") | 182 | eprintln!("\nERROR: `npm --version` failed, `npm` is required to build the VS Code plugin") |
184 | } | 183 | } |
185 | 184 | ||
186 | Cmd { unix: r"npm ci", windows: r"cmd.exe /c npm.cmd ci", work_dir: "./editors/code" }.run()?; | 185 | Cmd { unix: r"npm ci", windows: r"cmd.exe /c npm ci", work_dir: "./editors/code" }.run()?; |
187 | Cmd { | 186 | Cmd { |
188 | unix: r"npm run package --scripts-prepend-node-path", | 187 | unix: r"npm run package --scripts-prepend-node-path", |
189 | windows: r"cmd.exe /c npm.cmd run package", | 188 | windows: r"cmd.exe /c npm run package", |
190 | work_dir: "./editors/code", | 189 | work_dir: "./editors/code", |
191 | } | 190 | } |
192 | .run()?; | 191 | .run()?; |