diff options
Diffstat (limited to 'crates')
97 files changed, 2943 insertions, 2197 deletions
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs index 3ec8d3b60..fc0f7c12f 100644 --- a/crates/ra_arena/src/lib.rs +++ b/crates/ra_arena/src/lib.rs | |||
@@ -37,7 +37,7 @@ impl fmt::Display for RawId { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | #[derive(Clone, PartialEq, Eq)] | 39 | #[derive(Clone, PartialEq, Eq)] |
40 | pub struct Arena<ID: ArenaId, T> { | 40 | pub struct Arena<ID, T> { |
41 | data: Vec<T>, | 41 | data: Vec<T>, |
42 | _ty: PhantomData<ID>, | 42 | _ty: PhantomData<ID>, |
43 | } | 43 | } |
@@ -67,6 +67,12 @@ pub trait ArenaId { | |||
67 | fn into_raw(self) -> RawId; | 67 | fn into_raw(self) -> RawId; |
68 | } | 68 | } |
69 | 69 | ||
70 | impl<ID, T> Arena<ID, T> { | ||
71 | pub const fn new() -> Arena<ID, T> { | ||
72 | Arena { data: Vec::new(), _ty: PhantomData } | ||
73 | } | ||
74 | } | ||
75 | |||
70 | impl<ID: ArenaId, T> Arena<ID, T> { | 76 | impl<ID: ArenaId, T> Arena<ID, T> { |
71 | pub fn len(&self) -> usize { | 77 | pub fn len(&self) -> usize { |
72 | self.data.len() | 78 | self.data.len() |
@@ -79,7 +85,7 @@ impl<ID: ArenaId, T> Arena<ID, T> { | |||
79 | self.data.push(value); | 85 | self.data.push(value); |
80 | ID::from_raw(id) | 86 | ID::from_raw(id) |
81 | } | 87 | } |
82 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> + ExactSizeIterator { | 88 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> + ExactSizeIterator + DoubleEndedIterator { |
83 | self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) | 89 | self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) |
84 | } | 90 | } |
85 | } | 91 | } |
diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs index b5f8afb4e..ee8bff346 100644 --- a/crates/ra_assists/src/assists/add_new.rs +++ b/crates/ra_assists/src/assists/add_new.rs | |||
@@ -36,7 +36,7 @@ pub(crate) fn add_new(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
36 | 36 | ||
37 | // We want to only apply this to non-union structs with named fields | 37 | // We want to only apply this to non-union structs with named fields |
38 | let field_list = match (strukt.kind(), strukt.is_union()) { | 38 | let field_list = match (strukt.kind(), strukt.is_union()) { |
39 | (StructKind::Named(named), false) => named, | 39 | (StructKind::Record(named), false) => named, |
40 | _ => return None, | 40 | _ => return None, |
41 | }; | 41 | }; |
42 | 42 | ||
diff --git a/crates/ra_assists/src/assists/apply_demorgan.rs b/crates/ra_assists/src/assists/apply_demorgan.rs index 068da1774..7c57c0560 100644 --- a/crates/ra_assists/src/assists/apply_demorgan.rs +++ b/crates/ra_assists/src/assists/apply_demorgan.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use super::invert_if::invert_boolean_expression; | ||
1 | use hir::db::HirDatabase; | 2 | use hir::db::HirDatabase; |
2 | use ra_syntax::ast::{self, AstNode}; | 3 | use ra_syntax::ast::{self, AstNode}; |
3 | use ra_syntax::SyntaxNode; | ||
4 | 4 | ||
5 | use crate::{Assist, AssistCtx, AssistId}; | 5 | use crate::{Assist, AssistCtx, AssistId}; |
6 | 6 | ||
@@ -32,18 +32,18 @@ pub(crate) fn apply_demorgan(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> | |||
32 | if !cursor_in_range { | 32 | if !cursor_in_range { |
33 | return None; | 33 | return None; |
34 | } | 34 | } |
35 | let lhs = expr.lhs()?.syntax().clone(); | 35 | let lhs = expr.lhs()?; |
36 | let lhs_range = lhs.text_range(); | 36 | let lhs_range = lhs.syntax().text_range(); |
37 | let rhs = expr.rhs()?.syntax().clone(); | 37 | let rhs = expr.rhs()?; |
38 | let rhs_range = rhs.text_range(); | 38 | let rhs_range = rhs.syntax().text_range(); |
39 | let not_lhs = undo_negation(lhs)?; | 39 | let not_lhs = invert_boolean_expression(&lhs)?; |
40 | let not_rhs = undo_negation(rhs)?; | 40 | let not_rhs = invert_boolean_expression(&rhs)?; |
41 | 41 | ||
42 | ctx.add_assist(AssistId("apply_demorgan"), "apply demorgan's law", |edit| { | 42 | ctx.add_assist(AssistId("apply_demorgan"), "apply demorgan's law", |edit| { |
43 | edit.target(op_range); | 43 | edit.target(op_range); |
44 | edit.replace(op_range, opposite_op); | 44 | edit.replace(op_range, opposite_op); |
45 | edit.replace(lhs_range, format!("!({}", not_lhs)); | 45 | edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text())); |
46 | edit.replace(rhs_range, format!("{})", not_rhs)); | 46 | edit.replace(rhs_range, format!("{})", not_rhs.syntax().text())); |
47 | }) | 47 | }) |
48 | } | 48 | } |
49 | 49 | ||
@@ -56,28 +56,6 @@ fn opposite_logic_op(kind: ast::BinOp) -> Option<&'static str> { | |||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | // This function tries to undo unary negation, or inequality | ||
60 | fn undo_negation(node: SyntaxNode) -> Option<String> { | ||
61 | match ast::Expr::cast(node)? { | ||
62 | ast::Expr::BinExpr(bin) => match bin.op_kind()? { | ||
63 | ast::BinOp::NegatedEqualityTest => { | ||
64 | let lhs = bin.lhs()?.syntax().text(); | ||
65 | let rhs = bin.rhs()?.syntax().text(); | ||
66 | Some(format!("{} == {}", lhs, rhs)) | ||
67 | } | ||
68 | _ => None, | ||
69 | }, | ||
70 | ast::Expr::PrefixExpr(pe) => match pe.op_kind()? { | ||
71 | ast::PrefixOp::Not => { | ||
72 | let child = pe.expr()?.syntax().text(); | ||
73 | Some(String::from(child)) | ||
74 | } | ||
75 | _ => None, | ||
76 | }, | ||
77 | _ => None, | ||
78 | } | ||
79 | } | ||
80 | |||
81 | #[cfg(test)] | 59 | #[cfg(test)] |
82 | mod tests { | 60 | mod tests { |
83 | use super::*; | 61 | use super::*; |
diff --git a/crates/ra_assists/src/assists/fill_match_arms.rs b/crates/ra_assists/src/assists/fill_match_arms.rs index 9354466d9..8482897c5 100644 --- a/crates/ra_assists/src/assists/fill_match_arms.rs +++ b/crates/ra_assists/src/assists/fill_match_arms.rs | |||
@@ -101,7 +101,7 @@ fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> { | |||
101 | iter::repeat(make::placeholder_pat().into()).take(field_list.fields().count()); | 101 | iter::repeat(make::placeholder_pat().into()).take(field_list.fields().count()); |
102 | make::tuple_struct_pat(path, pats).into() | 102 | make::tuple_struct_pat(path, pats).into() |
103 | } | 103 | } |
104 | ast::StructKind::Named(field_list) => { | 104 | ast::StructKind::Record(field_list) => { |
105 | let pats = field_list.fields().map(|f| make::bind_pat(f.name().unwrap()).into()); | 105 | let pats = field_list.fields().map(|f| make::bind_pat(f.name().unwrap()).into()); |
106 | make::record_pat(path, pats).into() | 106 | make::record_pat(path, pats).into() |
107 | } | 107 | } |
diff --git a/crates/ra_assists/src/assists/invert_if.rs b/crates/ra_assists/src/assists/invert_if.rs new file mode 100644 index 000000000..bababa3e2 --- /dev/null +++ b/crates/ra_assists/src/assists/invert_if.rs | |||
@@ -0,0 +1,102 @@ | |||
1 | use hir::db::HirDatabase; | ||
2 | use ra_syntax::ast::{self, AstNode}; | ||
3 | use ra_syntax::T; | ||
4 | |||
5 | use crate::{Assist, AssistCtx, AssistId}; | ||
6 | |||
7 | // Assist: invert_if | ||
8 | // | ||
9 | // Apply invert_if | ||
10 | // This transforms if expressions of the form `if !x {A} else {B}` into `if x {B} else {A}` | ||
11 | // This also works with `!=`. This assist can only be applied with the cursor | ||
12 | // on `if`. | ||
13 | // | ||
14 | // ``` | ||
15 | // fn main() { | ||
16 | // if<|> !y { A } else { B } | ||
17 | // } | ||
18 | // ``` | ||
19 | // -> | ||
20 | // ``` | ||
21 | // fn main() { | ||
22 | // if y { B } else { A } | ||
23 | // } | ||
24 | // ``` | ||
25 | |||
26 | pub(crate) fn invert_if(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | ||
27 | let if_keyword = ctx.find_token_at_offset(T![if])?; | ||
28 | let expr = ast::IfExpr::cast(if_keyword.parent())?; | ||
29 | let if_range = if_keyword.text_range(); | ||
30 | let cursor_in_range = ctx.frange.range.is_subrange(&if_range); | ||
31 | if !cursor_in_range { | ||
32 | return None; | ||
33 | } | ||
34 | |||
35 | let cond = expr.condition()?.expr()?; | ||
36 | let then_node = expr.then_branch()?.syntax().clone(); | ||
37 | |||
38 | if let ast::ElseBranch::Block(else_block) = expr.else_branch()? { | ||
39 | let flip_cond = invert_boolean_expression(&cond)?; | ||
40 | let cond_range = cond.syntax().text_range(); | ||
41 | let else_node = else_block.syntax(); | ||
42 | let else_range = else_node.text_range(); | ||
43 | let then_range = then_node.text_range(); | ||
44 | return ctx.add_assist(AssistId("invert_if"), "invert if branches", |edit| { | ||
45 | edit.target(if_range); | ||
46 | edit.replace(cond_range, flip_cond.syntax().text()); | ||
47 | edit.replace(else_range, then_node.text()); | ||
48 | edit.replace(then_range, else_node.text()); | ||
49 | }); | ||
50 | } | ||
51 | |||
52 | None | ||
53 | } | ||
54 | |||
55 | pub(crate) fn invert_boolean_expression(expr: &ast::Expr) -> Option<ast::Expr> { | ||
56 | match expr { | ||
57 | ast::Expr::BinExpr(bin) => match bin.op_kind()? { | ||
58 | ast::BinOp::NegatedEqualityTest => bin.replace_op(T![==]).map(|it| it.into()), | ||
59 | _ => None, | ||
60 | }, | ||
61 | ast::Expr::PrefixExpr(pe) => match pe.op_kind()? { | ||
62 | ast::PrefixOp::Not => pe.expr(), | ||
63 | _ => None, | ||
64 | }, | ||
65 | _ => None, | ||
66 | } | ||
67 | } | ||
68 | |||
69 | #[cfg(test)] | ||
70 | mod tests { | ||
71 | use super::*; | ||
72 | |||
73 | use crate::helpers::{check_assist, check_assist_not_applicable}; | ||
74 | |||
75 | #[test] | ||
76 | fn invert_if_remove_inequality() { | ||
77 | check_assist( | ||
78 | invert_if, | ||
79 | "fn f() { i<|>f x != 3 { 1 } else { 3 + 2 } }", | ||
80 | "fn f() { i<|>f x == 3 { 3 + 2 } else { 1 } }", | ||
81 | ) | ||
82 | } | ||
83 | |||
84 | #[test] | ||
85 | fn invert_if_remove_not() { | ||
86 | check_assist( | ||
87 | invert_if, | ||
88 | "fn f() { <|>if !cond { 3 * 2 } else { 1 } }", | ||
89 | "fn f() { <|>if cond { 1 } else { 3 * 2 } }", | ||
90 | ) | ||
91 | } | ||
92 | |||
93 | #[test] | ||
94 | fn invert_if_doesnt_apply_with_cursor_not_on_if() { | ||
95 | check_assist_not_applicable(invert_if, "fn f() { if !<|>cond { 3 * 2 } else { 1 } }") | ||
96 | } | ||
97 | |||
98 | #[test] | ||
99 | fn invert_if_doesnt_apply_without_negated() { | ||
100 | check_assist_not_applicable(invert_if, "fn f() { i<|>f cond { 3 * 2 } else { 1 } }") | ||
101 | } | ||
102 | } | ||
diff --git a/crates/ra_assists/src/doc_tests/generated.rs b/crates/ra_assists/src/doc_tests/generated.rs index 176761efb..3c716c2d1 100644 --- a/crates/ra_assists/src/doc_tests/generated.rs +++ b/crates/ra_assists/src/doc_tests/generated.rs | |||
@@ -342,6 +342,23 @@ fn main() { | |||
342 | } | 342 | } |
343 | 343 | ||
344 | #[test] | 344 | #[test] |
345 | fn doctest_invert_if() { | ||
346 | check( | ||
347 | "invert_if", | ||
348 | r#####" | ||
349 | fn main() { | ||
350 | if<|> !y { A } else { B } | ||
351 | } | ||
352 | "#####, | ||
353 | r#####" | ||
354 | fn main() { | ||
355 | if y { B } else { A } | ||
356 | } | ||
357 | "#####, | ||
358 | ) | ||
359 | } | ||
360 | |||
361 | #[test] | ||
345 | fn doctest_make_raw_string() { | 362 | fn doctest_make_raw_string() { |
346 | check( | 363 | check( |
347 | "make_raw_string", | 364 | "make_raw_string", |
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index f2f0dacbf..a372bd8b9 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -97,6 +97,7 @@ mod assists { | |||
97 | mod add_impl; | 97 | mod add_impl; |
98 | mod add_new; | 98 | mod add_new; |
99 | mod apply_demorgan; | 99 | mod apply_demorgan; |
100 | mod invert_if; | ||
100 | mod flip_comma; | 101 | mod flip_comma; |
101 | mod flip_binexpr; | 102 | mod flip_binexpr; |
102 | mod flip_trait_bound; | 103 | mod flip_trait_bound; |
@@ -122,6 +123,7 @@ mod assists { | |||
122 | add_impl::add_impl, | 123 | add_impl::add_impl, |
123 | add_new::add_new, | 124 | add_new::add_new, |
124 | apply_demorgan::apply_demorgan, | 125 | apply_demorgan::apply_demorgan, |
126 | invert_if::invert_if, | ||
125 | change_visibility::change_visibility, | 127 | change_visibility::change_visibility, |
126 | fill_match_arms::fill_match_arms, | 128 | fill_match_arms::fill_match_arms, |
127 | merge_match_arms::merge_match_arms, | 129 | merge_match_arms::merge_match_arms, |
diff --git a/crates/ra_assists/src/test_db.rs b/crates/ra_assists/src/test_db.rs index 5be7383ed..5f96c974b 100644 --- a/crates/ra_assists/src/test_db.rs +++ b/crates/ra_assists/src/test_db.rs | |||
@@ -10,7 +10,6 @@ use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath | |||
10 | hir::db::InternDatabaseStorage, | 10 | hir::db::InternDatabaseStorage, |
11 | hir::db::AstDatabaseStorage, | 11 | hir::db::AstDatabaseStorage, |
12 | hir::db::DefDatabaseStorage, | 12 | hir::db::DefDatabaseStorage, |
13 | hir::db::DefDatabase2Storage, | ||
14 | hir::db::HirDatabaseStorage | 13 | hir::db::HirDatabaseStorage |
15 | )] | 14 | )] |
16 | #[derive(Debug, Default)] | 15 | #[derive(Debug, Default)] |
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index df49eb13d..cb389eb26 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs | |||
@@ -117,9 +117,12 @@ pub fn load( | |||
117 | done = true; | 117 | done = true; |
118 | } | 118 | } |
119 | } | 119 | } |
120 | VfsChange::AddFile { .. } | 120 | VfsChange::AddFile { root, file, path, text } => { |
121 | | VfsChange::RemoveFile { .. } | 121 | let source_root_id = vfs_root_to_id(root); |
122 | | VfsChange::ChangeFile { .. } => { | 122 | let file_id = vfs_file_to_id(file); |
123 | analysis_change.add_file(source_root_id, file_id, path, text); | ||
124 | } | ||
125 | VfsChange::RemoveFile { .. } | VfsChange::ChangeFile { .. } => { | ||
123 | // We just need the first scan, so just ignore these | 126 | // We just need the first scan, so just ignore these |
124 | } | 127 | } |
125 | } | 128 | } |
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 9cd21e4b6..c4eb28245 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; | 3 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; |
4 | 4 | ||
5 | use ra_db::SourceDatabaseExt; | 5 | use ra_db::SourceDatabaseExt; |
6 | use ra_hir::{AssocItem, Crate, HasBodySource, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; | 6 | use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; |
7 | use ra_syntax::AstNode; | 7 | use ra_syntax::AstNode; |
8 | 8 | ||
9 | use crate::{Result, Verbosity}; | 9 | use crate::{Result, Verbosity}; |
@@ -109,7 +109,7 @@ pub fn run( | |||
109 | } | 109 | } |
110 | let body = f.body(db); | 110 | let body = f.body(db); |
111 | let inference_result = f.infer(db); | 111 | let inference_result = f.infer(db); |
112 | for (expr_id, _) in body.exprs() { | 112 | for (expr_id, _) in body.exprs.iter() { |
113 | let ty = &inference_result[expr_id]; | 113 | let ty = &inference_result[expr_id]; |
114 | num_exprs += 1; | 114 | num_exprs += 1; |
115 | if let Ty::Unknown = ty { | 115 | if let Ty::Unknown = ty { |
@@ -128,15 +128,16 @@ pub fn run( | |||
128 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { | 128 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { |
129 | num_type_mismatches += 1; | 129 | num_type_mismatches += 1; |
130 | if verbosity.is_verbose() { | 130 | if verbosity.is_verbose() { |
131 | let src = f.expr_source(db, expr_id); | 131 | let src = f.body_source_map(db).expr_syntax(expr_id); |
132 | if let Some(src) = src { | 132 | if let Some(src) = src { |
133 | // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly | 133 | // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly |
134 | let original_file = src.file_id.original_file(db); | 134 | let original_file = src.file_id.original_file(db); |
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.value.either( |
138 | .value | 138 | |it| it.syntax_node_ptr().range(), |
139 | .either(|it| it.syntax().text_range(), |it| it.syntax().text_range()); | 139 | |it| it.syntax_node_ptr().range(), |
140 | ); | ||
140 | let (start, end) = ( | 141 | let (start, end) = ( |
141 | line_index.line_col(text_range.start()), | 142 | line_index.line_col(text_range.start()), |
142 | line_index.line_col(text_range.end()), | 143 | line_index.line_col(text_range.end()), |
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index ade187629..e8f335e33 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs | |||
@@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; | |||
8 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; | 8 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | CrateGraph, CrateId, Edition, FileId, FilePosition, RelativePathBuf, SourceDatabaseExt, | 11 | CrateGraph, CrateId, Edition, Env, FileId, FilePosition, RelativePathBuf, SourceDatabaseExt, |
12 | SourceRoot, SourceRootId, | 12 | SourceRoot, SourceRootId, |
13 | }; | 13 | }; |
14 | 14 | ||
@@ -53,7 +53,12 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, text: &str) -> FileId { | |||
53 | source_root.insert_file(rel_path.clone(), file_id); | 53 | source_root.insert_file(rel_path.clone(), file_id); |
54 | 54 | ||
55 | let mut crate_graph = CrateGraph::default(); | 55 | let mut crate_graph = CrateGraph::default(); |
56 | crate_graph.add_crate_root(file_id, Edition::Edition2018, CfgOptions::default()); | 56 | crate_graph.add_crate_root( |
57 | file_id, | ||
58 | Edition::Edition2018, | ||
59 | CfgOptions::default(), | ||
60 | Env::default(), | ||
61 | ); | ||
57 | 62 | ||
58 | db.set_file_text(file_id, Arc::new(text.to_string())); | 63 | db.set_file_text(file_id, Arc::new(text.to_string())); |
59 | db.set_file_relative_path(file_id, rel_path); | 64 | db.set_file_relative_path(file_id, rel_path); |
@@ -93,7 +98,8 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
93 | assert!(meta.path.starts_with(&source_root_prefix)); | 98 | assert!(meta.path.starts_with(&source_root_prefix)); |
94 | 99 | ||
95 | if let Some(krate) = meta.krate { | 100 | if let Some(krate) = meta.krate { |
96 | let crate_id = crate_graph.add_crate_root(file_id, meta.edition, meta.cfg); | 101 | let crate_id = |
102 | crate_graph.add_crate_root(file_id, meta.edition, meta.cfg, Env::default()); | ||
97 | let prev = crates.insert(krate.clone(), crate_id); | 103 | let prev = crates.insert(krate.clone(), crate_id); |
98 | assert!(prev.is_none()); | 104 | assert!(prev.is_none()); |
99 | for dep in meta.deps { | 105 | for dep in meta.deps { |
@@ -123,7 +129,12 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
123 | 129 | ||
124 | if crates.is_empty() { | 130 | if crates.is_empty() { |
125 | let crate_root = default_crate_root.unwrap(); | 131 | let crate_root = default_crate_root.unwrap(); |
126 | crate_graph.add_crate_root(crate_root, Edition::Edition2018, CfgOptions::default()); | 132 | crate_graph.add_crate_root( |
133 | crate_root, | ||
134 | Edition::Edition2018, | ||
135 | CfgOptions::default(), | ||
136 | Env::default(), | ||
137 | ); | ||
127 | } else { | 138 | } else { |
128 | for (from, to) in crate_deps { | 139 | for (from, to) in crate_deps { |
129 | let from_id = crates[&from]; | 140 | let from_id = crates[&from]; |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index c0d95a13f..b6d851776 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -6,14 +6,14 @@ | |||
6 | //! actual IO. See `vfs` and `project_model` in the `ra_lsp_server` crate for how | 6 | //! actual IO. See `vfs` and `project_model` in the `ra_lsp_server` crate for how |
7 | //! actual IO is done and lowered to input. | 7 | //! actual IO is done and lowered to input. |
8 | 8 | ||
9 | use rustc_hash::FxHashMap; | 9 | use std::{fmt, str::FromStr}; |
10 | 10 | ||
11 | use ra_cfg::CfgOptions; | 11 | use ra_cfg::CfgOptions; |
12 | use ra_syntax::SmolStr; | 12 | use ra_syntax::SmolStr; |
13 | use rustc_hash::FxHashMap; | ||
13 | use rustc_hash::FxHashSet; | 14 | use rustc_hash::FxHashSet; |
14 | 15 | ||
15 | use crate::{RelativePath, RelativePathBuf}; | 16 | use crate::{RelativePath, RelativePathBuf}; |
16 | use std::str::FromStr; | ||
17 | 17 | ||
18 | /// `FileId` is an integer which uniquely identifies a file. File paths are | 18 | /// `FileId` is an integer which uniquely identifies a file. File paths are |
19 | /// messy and system-dependent, so most of the code should work directly with | 19 | /// messy and system-dependent, so most of the code should work directly with |
@@ -80,56 +80,27 @@ pub struct CrateGraph { | |||
80 | arena: FxHashMap<CrateId, CrateData>, | 80 | arena: FxHashMap<CrateId, CrateData>, |
81 | } | 81 | } |
82 | 82 | ||
83 | #[derive(Debug)] | ||
84 | pub struct CyclicDependencies; | ||
85 | |||
86 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 83 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
87 | pub struct CrateId(pub u32); | 84 | pub struct CrateId(pub u32); |
88 | 85 | ||
89 | impl CrateId { | ||
90 | pub fn shift(self, amount: u32) -> CrateId { | ||
91 | CrateId(self.0 + amount) | ||
92 | } | ||
93 | } | ||
94 | |||
95 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
96 | pub enum Edition { | ||
97 | Edition2018, | ||
98 | Edition2015, | ||
99 | } | ||
100 | |||
101 | #[derive(Debug)] | ||
102 | pub struct ParseEditionError { | ||
103 | pub msg: String, | ||
104 | } | ||
105 | |||
106 | impl FromStr for Edition { | ||
107 | type Err = ParseEditionError; | ||
108 | fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
109 | match s { | ||
110 | "2015" => Ok(Edition::Edition2015), | ||
111 | "2018" => Ok(Edition::Edition2018), | ||
112 | _ => Err(ParseEditionError { msg: format!("unknown edition: {}", s) }), | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | |||
117 | #[derive(Debug, Clone, PartialEq, Eq)] | 86 | #[derive(Debug, Clone, PartialEq, Eq)] |
118 | struct CrateData { | 87 | struct CrateData { |
119 | file_id: FileId, | 88 | file_id: FileId, |
120 | edition: Edition, | 89 | edition: Edition, |
121 | dependencies: Vec<Dependency>, | ||
122 | cfg_options: CfgOptions, | 90 | cfg_options: CfgOptions, |
91 | env: Env, | ||
92 | dependencies: Vec<Dependency>, | ||
123 | } | 93 | } |
124 | 94 | ||
125 | impl CrateData { | 95 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
126 | fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions) -> CrateData { | 96 | pub enum Edition { |
127 | CrateData { file_id, edition, dependencies: Vec::new(), cfg_options } | 97 | Edition2018, |
128 | } | 98 | Edition2015, |
99 | } | ||
129 | 100 | ||
130 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | 101 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
131 | self.dependencies.push(Dependency { name, crate_id }) | 102 | pub struct Env { |
132 | } | 103 | entries: FxHashMap<String, String>, |
133 | } | 104 | } |
134 | 105 | ||
135 | #[derive(Debug, Clone, PartialEq, Eq)] | 106 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -138,21 +109,17 @@ pub struct Dependency { | |||
138 | pub name: SmolStr, | 109 | pub name: SmolStr, |
139 | } | 110 | } |
140 | 111 | ||
141 | impl Dependency { | ||
142 | pub fn crate_id(&self) -> CrateId { | ||
143 | self.crate_id | ||
144 | } | ||
145 | } | ||
146 | |||
147 | impl CrateGraph { | 112 | impl CrateGraph { |
148 | pub fn add_crate_root( | 113 | pub fn add_crate_root( |
149 | &mut self, | 114 | &mut self, |
150 | file_id: FileId, | 115 | file_id: FileId, |
151 | edition: Edition, | 116 | edition: Edition, |
152 | cfg_options: CfgOptions, | 117 | cfg_options: CfgOptions, |
118 | env: Env, | ||
153 | ) -> CrateId { | 119 | ) -> CrateId { |
120 | let data = CrateData::new(file_id, edition, cfg_options, env); | ||
154 | let crate_id = CrateId(self.arena.len() as u32); | 121 | let crate_id = CrateId(self.arena.len() as u32); |
155 | let prev = self.arena.insert(crate_id, CrateData::new(file_id, edition, cfg_options)); | 122 | let prev = self.arena.insert(crate_id, data); |
156 | assert!(prev.is_none()); | 123 | assert!(prev.is_none()); |
157 | crate_id | 124 | crate_id |
158 | } | 125 | } |
@@ -166,9 +133,9 @@ impl CrateGraph { | |||
166 | from: CrateId, | 133 | from: CrateId, |
167 | name: SmolStr, | 134 | name: SmolStr, |
168 | to: CrateId, | 135 | to: CrateId, |
169 | ) -> Result<(), CyclicDependencies> { | 136 | ) -> Result<(), CyclicDependenciesError> { |
170 | if self.dfs_find(from, to, &mut FxHashSet::default()) { | 137 | if self.dfs_find(from, to, &mut FxHashSet::default()) { |
171 | return Err(CyclicDependencies); | 138 | return Err(CyclicDependenciesError); |
172 | } | 139 | } |
173 | self.arena.get_mut(&from).unwrap().add_dep(name, to); | 140 | self.arena.get_mut(&from).unwrap().add_dep(name, to); |
174 | Ok(()) | 141 | Ok(()) |
@@ -239,16 +206,70 @@ impl CrateGraph { | |||
239 | } | 206 | } |
240 | } | 207 | } |
241 | 208 | ||
209 | impl CrateId { | ||
210 | pub fn shift(self, amount: u32) -> CrateId { | ||
211 | CrateId(self.0 + amount) | ||
212 | } | ||
213 | } | ||
214 | |||
215 | impl CrateData { | ||
216 | fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions, env: Env) -> CrateData { | ||
217 | CrateData { file_id, edition, dependencies: Vec::new(), cfg_options, env } | ||
218 | } | ||
219 | |||
220 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | ||
221 | self.dependencies.push(Dependency { name, crate_id }) | ||
222 | } | ||
223 | } | ||
224 | |||
225 | impl FromStr for Edition { | ||
226 | type Err = ParseEditionError; | ||
227 | |||
228 | fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
229 | let res = match s { | ||
230 | "2015" => Edition::Edition2015, | ||
231 | "2018" => Edition::Edition2018, | ||
232 | _ => Err(ParseEditionError { invalid_input: s.to_string() })?, | ||
233 | }; | ||
234 | Ok(res) | ||
235 | } | ||
236 | } | ||
237 | |||
238 | impl Dependency { | ||
239 | pub fn crate_id(&self) -> CrateId { | ||
240 | self.crate_id | ||
241 | } | ||
242 | } | ||
243 | |||
244 | #[derive(Debug)] | ||
245 | pub struct ParseEditionError { | ||
246 | invalid_input: String, | ||
247 | } | ||
248 | |||
249 | impl fmt::Display for ParseEditionError { | ||
250 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
251 | write!(f, "invalid edition: {:?}", self.invalid_input) | ||
252 | } | ||
253 | } | ||
254 | |||
255 | impl std::error::Error for ParseEditionError {} | ||
256 | |||
257 | #[derive(Debug)] | ||
258 | pub struct CyclicDependenciesError; | ||
259 | |||
242 | #[cfg(test)] | 260 | #[cfg(test)] |
243 | mod tests { | 261 | mod tests { |
244 | use super::{CfgOptions, CrateGraph, Edition::Edition2018, FileId, SmolStr}; | 262 | use super::{CfgOptions, CrateGraph, Edition::Edition2018, Env, FileId, SmolStr}; |
245 | 263 | ||
246 | #[test] | 264 | #[test] |
247 | fn it_should_panic_because_of_cycle_dependencies() { | 265 | fn it_should_panic_because_of_cycle_dependencies() { |
248 | let mut graph = CrateGraph::default(); | 266 | let mut graph = CrateGraph::default(); |
249 | let crate1 = graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default()); | 267 | let crate1 = |
250 | let crate2 = graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default()); | 268 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); |
251 | let crate3 = graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default()); | 269 | let crate2 = |
270 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | ||
271 | let crate3 = | ||
272 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | ||
252 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); | 273 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
253 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); | 274 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
254 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); | 275 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); |
@@ -257,9 +278,12 @@ mod tests { | |||
257 | #[test] | 278 | #[test] |
258 | fn it_works() { | 279 | fn it_works() { |
259 | let mut graph = CrateGraph::default(); | 280 | let mut graph = CrateGraph::default(); |
260 | let crate1 = graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default()); | 281 | let crate1 = |
261 | let crate2 = graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default()); | 282 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); |
262 | let crate3 = graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default()); | 283 | let crate2 = |
284 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | ||
285 | let crate3 = | ||
286 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | ||
263 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); | 287 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
264 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); | 288 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
265 | } | 289 | } |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index b6bfd531d..e8852531b 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -10,11 +10,25 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; | |||
10 | 10 | ||
11 | pub use crate::{ | 11 | pub use crate::{ |
12 | cancellation::Canceled, | 12 | cancellation::Canceled, |
13 | input::{CrateGraph, CrateId, Dependency, Edition, FileId, SourceRoot, SourceRootId}, | 13 | input::{CrateGraph, CrateId, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId}, |
14 | }; | 14 | }; |
15 | pub use relative_path::{RelativePath, RelativePathBuf}; | 15 | pub use relative_path::{RelativePath, RelativePathBuf}; |
16 | pub use salsa; | 16 | pub use salsa; |
17 | 17 | ||
18 | #[macro_export] | ||
19 | macro_rules! impl_intern_key { | ||
20 | ($name:ident) => { | ||
21 | impl $crate::salsa::InternKey for $name { | ||
22 | fn from_intern_id(v: $crate::salsa::InternId) -> Self { | ||
23 | $name(v) | ||
24 | } | ||
25 | fn as_intern_id(&self) -> $crate::salsa::InternId { | ||
26 | self.0 | ||
27 | } | ||
28 | } | ||
29 | }; | ||
30 | } | ||
31 | |||
18 | pub trait CheckCanceled { | 32 | pub trait CheckCanceled { |
19 | /// Aborts current query if there are pending changes. | 33 | /// Aborts current query if there are pending changes. |
20 | /// | 34 | /// |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 92860fb59..534f1f8e9 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -1,39 +1,33 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | pub(crate) mod src; | 3 | pub(crate) mod src; |
4 | pub(crate) mod docs; | ||
5 | pub(crate) mod attrs; | ||
6 | 4 | ||
7 | use std::sync::Arc; | 5 | use std::sync::Arc; |
8 | 6 | ||
9 | use hir_def::{ | 7 | use hir_def::{ |
10 | adt::VariantData, | 8 | adt::VariantData, |
11 | body::scope::ExprScopes, | ||
12 | builtin_type::BuiltinType, | 9 | builtin_type::BuiltinType, |
13 | nameres::per_ns::PerNs, | 10 | docs::Documentation, |
11 | per_ns::PerNs, | ||
14 | resolver::{HasResolver, TypeNs}, | 12 | resolver::{HasResolver, TypeNs}, |
15 | traits::TraitData, | 13 | type_ref::TypeRef, |
16 | type_ref::{Mutability, TypeRef}, | 14 | AstItemDef, ConstId, ContainerId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, |
17 | ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, | 15 | LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, |
18 | ModuleId, UnionId, | 16 | StaticId, StructId, TraitId, TypeAliasId, UnionId, |
19 | }; | 17 | }; |
20 | use hir_expand::{ | 18 | use hir_expand::{ |
21 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
22 | name::{self, AsName}, | 20 | name::{self, AsName}, |
21 | AstId, MacroDefId, | ||
23 | }; | 22 | }; |
24 | use ra_db::{CrateId, Edition}; | 23 | use ra_db::{CrateId, Edition, FileId, FilePosition}; |
25 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | 24 | use ra_syntax::{ast, AstNode, SyntaxNode}; |
26 | 25 | ||
27 | use crate::{ | 26 | use crate::{ |
28 | db::{AstDatabase, DefDatabase, HirDatabase}, | 27 | db::{DefDatabase, HirDatabase}, |
29 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, | 28 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, |
30 | generics::{GenericDef, HasGenericParams}, | ||
31 | ids::{ | ||
32 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, | ||
33 | TypeAliasId, | ||
34 | }, | ||
35 | ty::{InferenceResult, Namespace, TraitRef}, | 29 | ty::{InferenceResult, Namespace, TraitRef}, |
36 | Either, HasSource, ImportId, Name, Source, Ty, | 30 | Either, Name, Source, Ty, |
37 | }; | 31 | }; |
38 | 32 | ||
39 | /// hir::Crate describes a single crate. It's the main interface with which | 33 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -67,7 +61,7 @@ impl Crate { | |||
67 | } | 61 | } |
68 | 62 | ||
69 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { | 63 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { |
70 | let module_id = db.crate_def_map(self.crate_id).root(); | 64 | let module_id = db.crate_def_map(self.crate_id).root; |
71 | Some(Module::new(self, module_id)) | 65 | Some(Module::new(self, module_id)) |
72 | } | 66 | } |
73 | 67 | ||
@@ -81,6 +75,64 @@ impl Crate { | |||
81 | } | 75 | } |
82 | } | 76 | } |
83 | 77 | ||
78 | pub enum ModuleSource { | ||
79 | SourceFile(ast::SourceFile), | ||
80 | Module(ast::Module), | ||
81 | } | ||
82 | |||
83 | impl ModuleSource { | ||
84 | pub fn new( | ||
85 | db: &impl DefDatabase, | ||
86 | file_id: Option<FileId>, | ||
87 | decl_id: Option<AstId<ast::Module>>, | ||
88 | ) -> ModuleSource { | ||
89 | match (file_id, decl_id) { | ||
90 | (Some(file_id), _) => { | ||
91 | let source_file = db.parse(file_id).tree(); | ||
92 | ModuleSource::SourceFile(source_file) | ||
93 | } | ||
94 | (None, Some(item_id)) => { | ||
95 | let module = item_id.to_node(db); | ||
96 | assert!(module.item_list().is_some(), "expected inline module"); | ||
97 | ModuleSource::Module(module) | ||
98 | } | ||
99 | (None, None) => panic!(), | ||
100 | } | ||
101 | } | ||
102 | |||
103 | // FIXME: this methods do not belong here | ||
104 | pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource { | ||
105 | let parse = db.parse(position.file_id); | ||
106 | match &ra_syntax::algo::find_node_at_offset::<ast::Module>( | ||
107 | parse.tree().syntax(), | ||
108 | position.offset, | ||
109 | ) { | ||
110 | Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()), | ||
111 | _ => { | ||
112 | let source_file = parse.tree(); | ||
113 | ModuleSource::SourceFile(source_file) | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | |||
118 | pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource { | ||
119 | if let Some(m) = | ||
120 | child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) | ||
121 | { | ||
122 | ModuleSource::Module(m) | ||
123 | } else { | ||
124 | let file_id = child.file_id.original_file(db); | ||
125 | let source_file = db.parse(file_id).tree(); | ||
126 | ModuleSource::SourceFile(source_file) | ||
127 | } | ||
128 | } | ||
129 | |||
130 | pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource { | ||
131 | let source_file = db.parse(file_id).tree(); | ||
132 | ModuleSource::SourceFile(source_file) | ||
133 | } | ||
134 | } | ||
135 | |||
84 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 136 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
85 | pub struct Module { | 137 | pub struct Module { |
86 | pub(crate) id: ModuleId, | 138 | pub(crate) id: ModuleId, |
@@ -112,10 +164,10 @@ impl_froms!( | |||
112 | BuiltinType | 164 | BuiltinType |
113 | ); | 165 | ); |
114 | 166 | ||
115 | pub use hir_def::ModuleSource; | 167 | pub use hir_def::attr::Attrs; |
116 | 168 | ||
117 | impl Module { | 169 | impl Module { |
118 | pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module { | 170 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
119 | Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } | 171 | Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } |
120 | } | 172 | } |
121 | 173 | ||
@@ -132,17 +184,6 @@ impl Module { | |||
132 | }) | 184 | }) |
133 | } | 185 | } |
134 | 186 | ||
135 | /// Returns the syntax of the last path segment corresponding to this import | ||
136 | pub fn import_source( | ||
137 | self, | ||
138 | db: &impl HirDatabase, | ||
139 | import: ImportId, | ||
140 | ) -> Either<ast::UseTree, ast::ExternCrateItem> { | ||
141 | let src = self.definition_source(db); | ||
142 | let (_, source_map) = db.raw_items_with_source_map(src.file_id); | ||
143 | source_map.get(&src.value, import) | ||
144 | } | ||
145 | |||
146 | /// Returns the crate this module is part of. | 187 | /// Returns the crate this module is part of. |
147 | pub fn krate(self) -> Crate { | 188 | pub fn krate(self) -> Crate { |
148 | Crate { crate_id: self.id.krate } | 189 | Crate { crate_id: self.id.krate } |
@@ -153,7 +194,7 @@ impl Module { | |||
153 | /// in the module tree of any target in `Cargo.toml`. | 194 | /// in the module tree of any target in `Cargo.toml`. |
154 | pub fn crate_root(self, db: &impl DefDatabase) -> Module { | 195 | pub fn crate_root(self, db: &impl DefDatabase) -> Module { |
155 | let def_map = db.crate_def_map(self.id.krate); | 196 | let def_map = db.crate_def_map(self.id.krate); |
156 | self.with_module_id(def_map.root()) | 197 | self.with_module_id(def_map.root) |
157 | } | 198 | } |
158 | 199 | ||
159 | /// Finds a child module with the specified name. | 200 | /// Finds a child module with the specified name. |
@@ -192,11 +233,13 @@ impl Module { | |||
192 | } | 233 | } |
193 | 234 | ||
194 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 235 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
195 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<ImportId>)> { | 236 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { |
196 | db.crate_def_map(self.id.krate)[self.id.module_id] | 237 | db.crate_def_map(self.id.krate)[self.id.module_id] |
197 | .scope | 238 | .scope |
198 | .entries() | 239 | .entries() |
199 | .map(|(name, res)| (name.clone(), res.def.into(), res.import)) | 240 | .map(|(name, res)| { |
241 | (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id })) | ||
242 | }) | ||
200 | .collect() | 243 | .collect() |
201 | } | 244 | } |
202 | 245 | ||
@@ -234,11 +277,16 @@ impl Module { | |||
234 | def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() | 277 | def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() |
235 | } | 278 | } |
236 | 279 | ||
237 | fn with_module_id(self, module_id: CrateModuleId) -> Module { | 280 | fn with_module_id(self, module_id: LocalModuleId) -> Module { |
238 | Module::new(self.krate(), module_id) | 281 | Module::new(self.krate(), module_id) |
239 | } | 282 | } |
240 | } | 283 | } |
241 | 284 | ||
285 | pub struct Import { | ||
286 | pub(crate) parent: Module, | ||
287 | pub(crate) id: LocalImportId, | ||
288 | } | ||
289 | |||
242 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 290 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
243 | pub struct StructField { | 291 | pub struct StructField { |
244 | pub(crate) parent: VariantDef, | 292 | pub(crate) parent: VariantDef, |
@@ -253,11 +301,11 @@ pub enum FieldSource { | |||
253 | 301 | ||
254 | impl StructField { | 302 | impl StructField { |
255 | pub fn name(&self, db: &impl HirDatabase) -> Name { | 303 | pub fn name(&self, db: &impl HirDatabase) -> Name { |
256 | self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() | 304 | self.parent.variant_data(db).fields()[self.id].name.clone() |
257 | } | 305 | } |
258 | 306 | ||
259 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { | 307 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { |
260 | db.type_for_field(*self) | 308 | db.field_types(self.parent.into())[self.id].clone() |
261 | } | 309 | } |
262 | 310 | ||
263 | pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { | 311 | pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { |
@@ -287,8 +335,7 @@ impl Struct { | |||
287 | db.struct_data(self.id.into()) | 335 | db.struct_data(self.id.into()) |
288 | .variant_data | 336 | .variant_data |
289 | .fields() | 337 | .fields() |
290 | .into_iter() | 338 | .iter() |
291 | .flat_map(|it| it.iter()) | ||
292 | .map(|(id, _)| StructField { parent: self.into(), id }) | 339 | .map(|(id, _)| StructField { parent: self.into(), id }) |
293 | .collect() | 340 | .collect() |
294 | } | 341 | } |
@@ -297,8 +344,7 @@ impl Struct { | |||
297 | db.struct_data(self.id.into()) | 344 | db.struct_data(self.id.into()) |
298 | .variant_data | 345 | .variant_data |
299 | .fields() | 346 | .fields() |
300 | .into_iter() | 347 | .iter() |
301 | .flat_map(|it| it.iter()) | ||
302 | .find(|(_id, data)| data.name == *name) | 348 | .find(|(_id, data)| data.name == *name) |
303 | .map(|(id, _)| StructField { parent: self.into(), id }) | 349 | .map(|(id, _)| StructField { parent: self.into(), id }) |
304 | } | 350 | } |
@@ -395,8 +441,7 @@ impl EnumVariant { | |||
395 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | 441 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { |
396 | self.variant_data(db) | 442 | self.variant_data(db) |
397 | .fields() | 443 | .fields() |
398 | .into_iter() | 444 | .iter() |
399 | .flat_map(|it| it.iter()) | ||
400 | .map(|(id, _)| StructField { parent: self.into(), id }) | 445 | .map(|(id, _)| StructField { parent: self.into(), id }) |
401 | .collect() | 446 | .collect() |
402 | } | 447 | } |
@@ -404,8 +449,7 @@ impl EnumVariant { | |||
404 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | 449 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { |
405 | self.variant_data(db) | 450 | self.variant_data(db) |
406 | .fields() | 451 | .fields() |
407 | .into_iter() | 452 | .iter() |
408 | .flat_map(|it| it.iter()) | ||
409 | .find(|(_id, data)| data.name == *name) | 453 | .find(|(_id, data)| data.name == *name) |
410 | .map(|(id, _)| StructField { parent: self.into(), id }) | 454 | .map(|(id, _)| StructField { parent: self.into(), id }) |
411 | } | 455 | } |
@@ -461,7 +505,7 @@ impl VariantDef { | |||
461 | } | 505 | } |
462 | } | 506 | } |
463 | 507 | ||
464 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | 508 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { |
465 | match self { | 509 | match self { |
466 | VariantDef::Struct(it) => it.field(db, name), | 510 | VariantDef::Struct(it) => it.field(db, name), |
467 | VariantDef::EnumVariant(it) => it.field(db, name), | 511 | VariantDef::EnumVariant(it) => it.field(db, name), |
@@ -511,128 +555,11 @@ impl DefWithBody { | |||
511 | } | 555 | } |
512 | } | 556 | } |
513 | 557 | ||
514 | pub trait HasBody: Copy { | ||
515 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>; | ||
516 | fn body(self, db: &impl HirDatabase) -> Arc<Body>; | ||
517 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>; | ||
518 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes>; | ||
519 | } | ||
520 | |||
521 | impl<T> HasBody for T | ||
522 | where | ||
523 | T: Into<DefWithBody> + Copy + HasSource, | ||
524 | { | ||
525 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
526 | db.infer(self.into()) | ||
527 | } | ||
528 | |||
529 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
530 | self.into().body(db) | ||
531 | } | ||
532 | |||
533 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
534 | self.into().body_source_map(db) | ||
535 | } | ||
536 | |||
537 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> { | ||
538 | self.into().expr_scopes(db) | ||
539 | } | ||
540 | } | ||
541 | |||
542 | impl HasBody for DefWithBody { | ||
543 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
544 | db.infer(self) | ||
545 | } | ||
546 | |||
547 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
548 | db.body(self.into()) | ||
549 | } | ||
550 | |||
551 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
552 | db.body_with_source_map(self.into()).1 | ||
553 | } | ||
554 | |||
555 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> { | ||
556 | db.expr_scopes(self.into()) | ||
557 | } | ||
558 | } | ||
559 | |||
560 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 558 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
561 | pub struct Function { | 559 | pub struct Function { |
562 | pub(crate) id: FunctionId, | 560 | pub(crate) id: FunctionId, |
563 | } | 561 | } |
564 | 562 | ||
565 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
566 | pub struct FnData { | ||
567 | pub(crate) name: Name, | ||
568 | pub(crate) params: Vec<TypeRef>, | ||
569 | pub(crate) ret_type: TypeRef, | ||
570 | /// True if the first param is `self`. This is relevant to decide whether this | ||
571 | /// can be called as a method. | ||
572 | pub(crate) has_self_param: bool, | ||
573 | } | ||
574 | |||
575 | impl FnData { | ||
576 | pub(crate) fn fn_data_query( | ||
577 | db: &(impl DefDatabase + AstDatabase), | ||
578 | func: Function, | ||
579 | ) -> Arc<FnData> { | ||
580 | let src = func.source(db); | ||
581 | let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); | ||
582 | let mut params = Vec::new(); | ||
583 | let mut has_self_param = false; | ||
584 | if let Some(param_list) = src.value.param_list() { | ||
585 | if let Some(self_param) = param_list.self_param() { | ||
586 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { | ||
587 | TypeRef::from_ast(type_ref) | ||
588 | } else { | ||
589 | let self_type = TypeRef::Path(name::SELF_TYPE.into()); | ||
590 | match self_param.kind() { | ||
591 | ast::SelfParamKind::Owned => self_type, | ||
592 | ast::SelfParamKind::Ref => { | ||
593 | TypeRef::Reference(Box::new(self_type), Mutability::Shared) | ||
594 | } | ||
595 | ast::SelfParamKind::MutRef => { | ||
596 | TypeRef::Reference(Box::new(self_type), Mutability::Mut) | ||
597 | } | ||
598 | } | ||
599 | }; | ||
600 | params.push(self_type); | ||
601 | has_self_param = true; | ||
602 | } | ||
603 | for param in param_list.params() { | ||
604 | let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); | ||
605 | params.push(type_ref); | ||
606 | } | ||
607 | } | ||
608 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { | ||
609 | TypeRef::from_ast(type_ref) | ||
610 | } else { | ||
611 | TypeRef::unit() | ||
612 | }; | ||
613 | |||
614 | let sig = FnData { name, params, ret_type, has_self_param }; | ||
615 | Arc::new(sig) | ||
616 | } | ||
617 | pub fn name(&self) -> &Name { | ||
618 | &self.name | ||
619 | } | ||
620 | |||
621 | pub fn params(&self) -> &[TypeRef] { | ||
622 | &self.params | ||
623 | } | ||
624 | |||
625 | pub fn ret_type(&self) -> &TypeRef { | ||
626 | &self.ret_type | ||
627 | } | ||
628 | |||
629 | /// True if the first arg is `self`. This is relevant to decide whether this | ||
630 | /// can be called as a method. | ||
631 | pub fn has_self_param(&self) -> bool { | ||
632 | self.has_self_param | ||
633 | } | ||
634 | } | ||
635 | |||
636 | impl Function { | 563 | impl Function { |
637 | pub fn module(self, db: &impl DefDatabase) -> Module { | 564 | pub fn module(self, db: &impl DefDatabase) -> Module { |
638 | self.id.lookup(db).module(db).into() | 565 | self.id.lookup(db).module(db).into() |
@@ -643,10 +570,18 @@ impl Function { | |||
643 | } | 570 | } |
644 | 571 | ||
645 | pub fn name(self, db: &impl HirDatabase) -> Name { | 572 | pub fn name(self, db: &impl HirDatabase) -> Name { |
646 | self.data(db).name.clone() | 573 | db.function_data(self.id).name.clone() |
574 | } | ||
575 | |||
576 | pub fn has_self_param(self, db: &impl HirDatabase) -> bool { | ||
577 | db.function_data(self.id).has_self_param | ||
578 | } | ||
579 | |||
580 | pub fn params(self, db: &impl HirDatabase) -> Vec<TypeRef> { | ||
581 | db.function_data(self.id).params.clone() | ||
647 | } | 582 | } |
648 | 583 | ||
649 | pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | 584 | pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { |
650 | db.body_with_source_map(self.id.into()).1 | 585 | db.body_with_source_map(self.id.into()).1 |
651 | } | 586 | } |
652 | 587 | ||
@@ -658,10 +593,6 @@ impl Function { | |||
658 | db.type_for_def(self.into(), Namespace::Values) | 593 | db.type_for_def(self.into(), Namespace::Values) |
659 | } | 594 | } |
660 | 595 | ||
661 | pub fn data(self, db: &impl HirDatabase) -> Arc<FnData> { | ||
662 | db.fn_data(self) | ||
663 | } | ||
664 | |||
665 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 596 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
666 | db.infer(self.into()) | 597 | db.infer(self.into()) |
667 | } | 598 | } |
@@ -712,12 +643,8 @@ impl Const { | |||
712 | Some(self.module(db).krate()) | 643 | Some(self.module(db).krate()) |
713 | } | 644 | } |
714 | 645 | ||
715 | pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { | ||
716 | db.const_data(self) | ||
717 | } | ||
718 | |||
719 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { | 646 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { |
720 | self.data(db).name().cloned() | 647 | db.const_data(self.id).name.clone() |
721 | } | 648 | } |
722 | 649 | ||
723 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 650 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
@@ -749,45 +676,6 @@ impl Const { | |||
749 | } | 676 | } |
750 | } | 677 | } |
751 | 678 | ||
752 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
753 | pub struct ConstData { | ||
754 | pub(crate) name: Option<Name>, | ||
755 | pub(crate) type_ref: TypeRef, | ||
756 | } | ||
757 | |||
758 | impl ConstData { | ||
759 | pub fn name(&self) -> Option<&Name> { | ||
760 | self.name.as_ref() | ||
761 | } | ||
762 | |||
763 | pub fn type_ref(&self) -> &TypeRef { | ||
764 | &self.type_ref | ||
765 | } | ||
766 | |||
767 | pub(crate) fn const_data_query( | ||
768 | db: &(impl DefDatabase + AstDatabase), | ||
769 | konst: Const, | ||
770 | ) -> Arc<ConstData> { | ||
771 | let node = konst.source(db).value; | ||
772 | const_data_for(&node) | ||
773 | } | ||
774 | |||
775 | pub(crate) fn static_data_query( | ||
776 | db: &(impl DefDatabase + AstDatabase), | ||
777 | konst: Static, | ||
778 | ) -> Arc<ConstData> { | ||
779 | let node = konst.source(db).value; | ||
780 | const_data_for(&node) | ||
781 | } | ||
782 | } | ||
783 | |||
784 | fn const_data_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstData> { | ||
785 | let name = node.name().map(|n| n.as_name()); | ||
786 | let type_ref = TypeRef::from_ast_opt(node.ascribed_type()); | ||
787 | let sig = ConstData { name, type_ref }; | ||
788 | Arc::new(sig) | ||
789 | } | ||
790 | |||
791 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 679 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
792 | pub struct Static { | 680 | pub struct Static { |
793 | pub(crate) id: StaticId, | 681 | pub(crate) id: StaticId, |
@@ -795,17 +683,13 @@ pub struct Static { | |||
795 | 683 | ||
796 | impl Static { | 684 | impl Static { |
797 | pub fn module(self, db: &impl DefDatabase) -> Module { | 685 | pub fn module(self, db: &impl DefDatabase) -> Module { |
798 | Module { id: self.id.module(db) } | 686 | Module { id: self.id.lookup(db).module(db) } |
799 | } | 687 | } |
800 | 688 | ||
801 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 689 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
802 | Some(self.module(db).krate()) | 690 | Some(self.module(db).krate()) |
803 | } | 691 | } |
804 | 692 | ||
805 | pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { | ||
806 | db.static_data(self) | ||
807 | } | ||
808 | |||
809 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 693 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
810 | db.infer(self.into()) | 694 | db.infer(self.into()) |
811 | } | 695 | } |
@@ -822,11 +706,11 @@ impl Trait { | |||
822 | } | 706 | } |
823 | 707 | ||
824 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 708 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
825 | self.trait_data(db).name.clone() | 709 | db.trait_data(self.id).name.clone() |
826 | } | 710 | } |
827 | 711 | ||
828 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { | 712 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { |
829 | self.trait_data(db).items.iter().map(|it| (*it).into()).collect() | 713 | db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect() |
830 | } | 714 | } |
831 | 715 | ||
832 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | 716 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { |
@@ -835,7 +719,7 @@ impl Trait { | |||
835 | // lifetime problems, but since there usually shouldn't be more than a | 719 | // lifetime problems, but since there usually shouldn't be more than a |
836 | // few direct traits this should be fine (we could even use some kind of | 720 | // few direct traits this should be fine (we could even use some kind of |
837 | // SmallVec if performance is a concern) | 721 | // SmallVec if performance is a concern) |
838 | self.generic_params(db) | 722 | db.generic_params(self.id.into()) |
839 | .where_predicates | 723 | .where_predicates |
840 | .iter() | 724 | .iter() |
841 | .filter_map(|pred| match &pred.type_ref { | 725 | .filter_map(|pred| match &pred.type_ref { |
@@ -872,7 +756,7 @@ impl Trait { | |||
872 | } | 756 | } |
873 | 757 | ||
874 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { | 758 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { |
875 | let trait_data = self.trait_data(db); | 759 | let trait_data = db.trait_data(self.id); |
876 | let res = | 760 | let res = |
877 | trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; | 761 | trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; |
878 | Some(res) | 762 | Some(res) |
@@ -886,16 +770,12 @@ impl Trait { | |||
886 | self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) | 770 | self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) |
887 | } | 771 | } |
888 | 772 | ||
889 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { | ||
890 | db.trait_data(self.id) | ||
891 | } | ||
892 | |||
893 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { | 773 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { |
894 | TraitRef::for_trait(db, self) | 774 | TraitRef::for_trait(db, self) |
895 | } | 775 | } |
896 | 776 | ||
897 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { | 777 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { |
898 | self.trait_data(db).auto | 778 | db.trait_data(self.id).auto |
899 | } | 779 | } |
900 | } | 780 | } |
901 | 781 | ||
@@ -938,7 +818,7 @@ impl TypeAlias { | |||
938 | } | 818 | } |
939 | 819 | ||
940 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { | 820 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { |
941 | db.type_alias_data(self).type_ref.clone() | 821 | db.type_alias_data(self.id).type_ref.clone() |
942 | } | 822 | } |
943 | 823 | ||
944 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 824 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
@@ -946,7 +826,7 @@ impl TypeAlias { | |||
946 | } | 826 | } |
947 | 827 | ||
948 | pub fn name(self, db: &impl DefDatabase) -> Name { | 828 | pub fn name(self, db: &impl DefDatabase) -> Name { |
949 | db.type_alias_data(self).name.clone() | 829 | db.type_alias_data(self.id).name.clone() |
950 | } | 830 | } |
951 | } | 831 | } |
952 | 832 | ||
@@ -975,16 +855,6 @@ pub enum AssocItem { | |||
975 | // casting them, and somehow making the constructors private, which would be annoying. | 855 | // casting them, and somehow making the constructors private, which would be annoying. |
976 | impl_froms!(AssocItem: Function, Const, TypeAlias); | 856 | impl_froms!(AssocItem: Function, Const, TypeAlias); |
977 | 857 | ||
978 | impl From<AssocItem> for crate::generics::GenericDef { | ||
979 | fn from(item: AssocItem) -> Self { | ||
980 | match item { | ||
981 | AssocItem::Function(f) => f.into(), | ||
982 | AssocItem::Const(c) => c.into(), | ||
983 | AssocItem::TypeAlias(t) => t.into(), | ||
984 | } | ||
985 | } | ||
986 | } | ||
987 | |||
988 | impl AssocItem { | 858 | impl AssocItem { |
989 | pub fn module(self, db: &impl DefDatabase) -> Module { | 859 | pub fn module(self, db: &impl DefDatabase) -> Module { |
990 | match self { | 860 | match self { |
@@ -1004,6 +874,29 @@ impl AssocItem { | |||
1004 | } | 874 | } |
1005 | } | 875 | } |
1006 | 876 | ||
877 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
878 | pub enum GenericDef { | ||
879 | Function(Function), | ||
880 | Adt(Adt), | ||
881 | Trait(Trait), | ||
882 | TypeAlias(TypeAlias), | ||
883 | ImplBlock(ImplBlock), | ||
884 | // enum variants cannot have generics themselves, but their parent enums | ||
885 | // can, and this makes some code easier to write | ||
886 | EnumVariant(EnumVariant), | ||
887 | // consts can have type parameters from their parents (i.e. associated consts of traits) | ||
888 | Const(Const), | ||
889 | } | ||
890 | impl_froms!( | ||
891 | GenericDef: Function, | ||
892 | Adt(Struct, Enum, Union), | ||
893 | Trait, | ||
894 | TypeAlias, | ||
895 | ImplBlock, | ||
896 | EnumVariant, | ||
897 | Const | ||
898 | ); | ||
899 | |||
1007 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 900 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1008 | pub struct Local { | 901 | pub struct Local { |
1009 | pub(crate) parent: DefWithBody, | 902 | pub(crate) parent: DefWithBody, |
@@ -1012,7 +905,7 @@ pub struct Local { | |||
1012 | 905 | ||
1013 | impl Local { | 906 | impl Local { |
1014 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { | 907 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { |
1015 | let body = self.parent.body(db); | 908 | let body = db.body(self.parent.into()); |
1016 | match &body[self.pat_id] { | 909 | match &body[self.pat_id] { |
1017 | Pat::Bind { name, .. } => Some(name.clone()), | 910 | Pat::Bind { name, .. } => Some(name.clone()), |
1018 | _ => None, | 911 | _ => None, |
@@ -1024,7 +917,7 @@ impl Local { | |||
1024 | } | 917 | } |
1025 | 918 | ||
1026 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { | 919 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { |
1027 | let body = self.parent.body(db); | 920 | let body = db.body(self.parent.into()); |
1028 | match &body[self.pat_id] { | 921 | match &body[self.pat_id] { |
1029 | Pat::Bind { mode, .. } => match mode { | 922 | Pat::Bind { mode, .. } => match mode { |
1030 | BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, | 923 | BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, |
@@ -1048,7 +941,7 @@ impl Local { | |||
1048 | } | 941 | } |
1049 | 942 | ||
1050 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | 943 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { |
1051 | let source_map = self.parent.body_source_map(db); | 944 | let (_body, source_map) = db.body_with_source_map(self.parent.into()); |
1052 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... | 945 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... |
1053 | let root = src.file_syntax(db); | 946 | let root = src.file_syntax(db); |
1054 | src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) | 947 | src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) |
@@ -1057,7 +950,7 @@ impl Local { | |||
1057 | 950 | ||
1058 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 951 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1059 | pub struct GenericParam { | 952 | pub struct GenericParam { |
1060 | pub(crate) parent: GenericDef, | 953 | pub(crate) parent: GenericDefId, |
1061 | pub(crate) idx: u32, | 954 | pub(crate) idx: u32, |
1062 | } | 955 | } |
1063 | 956 | ||
@@ -1066,6 +959,41 @@ pub struct ImplBlock { | |||
1066 | pub(crate) id: ImplId, | 959 | pub(crate) id: ImplId, |
1067 | } | 960 | } |
1068 | 961 | ||
962 | impl ImplBlock { | ||
963 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | ||
964 | db.impl_data(self.id).target_trait.clone() | ||
965 | } | ||
966 | |||
967 | pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { | ||
968 | db.impl_data(self.id).target_type.clone() | ||
969 | } | ||
970 | |||
971 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | ||
972 | Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) | ||
973 | } | ||
974 | |||
975 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { | ||
976 | let target_ty = self.target_ty(db); | ||
977 | TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) | ||
978 | } | ||
979 | |||
980 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | ||
981 | db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect() | ||
982 | } | ||
983 | |||
984 | pub fn is_negative(&self, db: &impl DefDatabase) -> bool { | ||
985 | db.impl_data(self.id).is_negative | ||
986 | } | ||
987 | |||
988 | pub fn module(&self, db: &impl DefDatabase) -> Module { | ||
989 | self.id.module(db).into() | ||
990 | } | ||
991 | |||
992 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | ||
993 | Crate { crate_id: self.module(db).id.krate } | ||
994 | } | ||
995 | } | ||
996 | |||
1069 | /// For IDE only | 997 | /// For IDE only |
1070 | pub enum ScopeDef { | 998 | pub enum ScopeDef { |
1071 | ModuleDef(ModuleDef), | 999 | ModuleDef(ModuleDef), |
@@ -1083,8 +1011,56 @@ impl From<PerNs> for ScopeDef { | |||
1083 | .or_else(|| def.take_values()) | 1011 | .or_else(|| def.take_values()) |
1084 | .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) | 1012 | .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) |
1085 | .or_else(|| { | 1013 | .or_else(|| { |
1086 | def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) | 1014 | def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) |
1087 | }) | 1015 | }) |
1088 | .unwrap_or(ScopeDef::Unknown) | 1016 | .unwrap_or(ScopeDef::Unknown) |
1089 | } | 1017 | } |
1090 | } | 1018 | } |
1019 | |||
1020 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
1021 | pub enum AttrDef { | ||
1022 | Module(Module), | ||
1023 | StructField(StructField), | ||
1024 | Adt(Adt), | ||
1025 | Function(Function), | ||
1026 | EnumVariant(EnumVariant), | ||
1027 | Static(Static), | ||
1028 | Const(Const), | ||
1029 | Trait(Trait), | ||
1030 | TypeAlias(TypeAlias), | ||
1031 | MacroDef(MacroDef), | ||
1032 | } | ||
1033 | |||
1034 | impl_froms!( | ||
1035 | AttrDef: Module, | ||
1036 | StructField, | ||
1037 | Adt(Struct, Enum, Union), | ||
1038 | EnumVariant, | ||
1039 | Static, | ||
1040 | Const, | ||
1041 | Function, | ||
1042 | Trait, | ||
1043 | TypeAlias, | ||
1044 | MacroDef | ||
1045 | ); | ||
1046 | |||
1047 | pub trait HasAttrs { | ||
1048 | fn attrs(self, db: &impl DefDatabase) -> Attrs; | ||
1049 | } | ||
1050 | |||
1051 | impl<T: Into<AttrDef>> HasAttrs for T { | ||
1052 | fn attrs(self, db: &impl DefDatabase) -> Attrs { | ||
1053 | let def: AttrDef = self.into(); | ||
1054 | db.attrs(def.into()) | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | pub trait Docs { | ||
1059 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>; | ||
1060 | } | ||
1061 | impl<T: Into<AttrDef> + Copy> Docs for T { | ||
1062 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> { | ||
1063 | let def: AttrDef = (*self).into(); | ||
1064 | db.documentation(def.into()) | ||
1065 | } | ||
1066 | } | ||
diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs deleted file mode 100644 index 9e304217c..000000000 --- a/crates/ra_hir/src/code_model/attrs.rs +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use crate::{ | ||
4 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
5 | Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static, | ||
6 | Struct, StructField, Trait, TypeAlias, Union, | ||
7 | }; | ||
8 | use hir_def::attr::Attr; | ||
9 | use hir_expand::hygiene::Hygiene; | ||
10 | use ra_syntax::ast; | ||
11 | use std::sync::Arc; | ||
12 | |||
13 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
14 | pub enum AttrDef { | ||
15 | Module(Module), | ||
16 | StructField(StructField), | ||
17 | Adt(Adt), | ||
18 | Function(Function), | ||
19 | EnumVariant(EnumVariant), | ||
20 | Static(Static), | ||
21 | Const(Const), | ||
22 | Trait(Trait), | ||
23 | TypeAlias(TypeAlias), | ||
24 | MacroDef(MacroDef), | ||
25 | } | ||
26 | |||
27 | impl_froms!( | ||
28 | AttrDef: Module, | ||
29 | StructField, | ||
30 | Adt(Struct, Enum, Union), | ||
31 | EnumVariant, | ||
32 | Static, | ||
33 | Const, | ||
34 | Function, | ||
35 | Trait, | ||
36 | TypeAlias, | ||
37 | MacroDef | ||
38 | ); | ||
39 | |||
40 | pub trait Attrs { | ||
41 | fn attrs(&self, db: &impl HirDatabase) -> Option<Arc<[Attr]>>; | ||
42 | } | ||
43 | |||
44 | pub(crate) fn attributes_query( | ||
45 | db: &(impl DefDatabase + AstDatabase), | ||
46 | def: AttrDef, | ||
47 | ) -> Option<Arc<[Attr]>> { | ||
48 | match def { | ||
49 | AttrDef::Module(it) => { | ||
50 | let src = it.declaration_source(db)?; | ||
51 | let hygiene = Hygiene::new(db, src.file_id); | ||
52 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
53 | } | ||
54 | AttrDef::StructField(it) => match it.source(db).value { | ||
55 | FieldSource::Named(named) => { | ||
56 | let src = it.source(db); | ||
57 | let hygiene = Hygiene::new(db, src.file_id); | ||
58 | Attr::from_attrs_owner(&named, &hygiene) | ||
59 | } | ||
60 | FieldSource::Pos(..) => None, | ||
61 | }, | ||
62 | AttrDef::Adt(it) => match it { | ||
63 | Adt::Struct(it) => attrs_from_ast(it, db), | ||
64 | Adt::Enum(it) => attrs_from_ast(it, db), | ||
65 | Adt::Union(it) => attrs_from_ast(it, db), | ||
66 | }, | ||
67 | AttrDef::EnumVariant(it) => attrs_from_ast(it, db), | ||
68 | AttrDef::Static(it) => attrs_from_ast(it, db), | ||
69 | AttrDef::Const(it) => attrs_from_ast(it, db), | ||
70 | AttrDef::Function(it) => attrs_from_ast(it, db), | ||
71 | AttrDef::Trait(it) => attrs_from_ast(it, db), | ||
72 | AttrDef::TypeAlias(it) => attrs_from_ast(it, db), | ||
73 | AttrDef::MacroDef(it) => attrs_from_ast(it, db), | ||
74 | } | ||
75 | } | ||
76 | |||
77 | fn attrs_from_ast<T, D>(node: T, db: &D) -> Option<Arc<[Attr]>> | ||
78 | where | ||
79 | T: HasSource, | ||
80 | T::Ast: ast::AttrsOwner, | ||
81 | D: DefDatabase + AstDatabase, | ||
82 | { | ||
83 | let src = node.source(db); | ||
84 | let hygiene = Hygiene::new(db, src.file_id); | ||
85 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
86 | } | ||
87 | |||
88 | impl<T: Into<AttrDef> + Copy> Attrs for T { | ||
89 | fn attrs(&self, db: &impl HirDatabase) -> Option<Arc<[Attr]>> { | ||
90 | db.attrs((*self).into()) | ||
91 | } | ||
92 | } | ||
diff --git a/crates/ra_hir/src/code_model/docs.rs b/crates/ra_hir/src/code_model/docs.rs deleted file mode 100644 index e40efef34..000000000 --- a/crates/ra_hir/src/code_model/docs.rs +++ /dev/null | |||
@@ -1,97 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use ra_syntax::ast; | ||
6 | |||
7 | use crate::{ | ||
8 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
9 | Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static, | ||
10 | Struct, StructField, Trait, TypeAlias, Union, | ||
11 | }; | ||
12 | |||
13 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
14 | pub enum DocDef { | ||
15 | Module(Module), | ||
16 | StructField(StructField), | ||
17 | Adt(Adt), | ||
18 | EnumVariant(EnumVariant), | ||
19 | Static(Static), | ||
20 | Const(Const), | ||
21 | Function(Function), | ||
22 | Trait(Trait), | ||
23 | TypeAlias(TypeAlias), | ||
24 | MacroDef(MacroDef), | ||
25 | } | ||
26 | |||
27 | impl_froms!( | ||
28 | DocDef: Module, | ||
29 | StructField, | ||
30 | Adt(Struct, Enum, Union), | ||
31 | EnumVariant, | ||
32 | Static, | ||
33 | Const, | ||
34 | Function, | ||
35 | Trait, | ||
36 | TypeAlias, | ||
37 | MacroDef | ||
38 | ); | ||
39 | |||
40 | /// Holds documentation | ||
41 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
42 | pub struct Documentation(Arc<str>); | ||
43 | |||
44 | impl Documentation { | ||
45 | fn new(s: &str) -> Documentation { | ||
46 | Documentation(s.into()) | ||
47 | } | ||
48 | |||
49 | pub fn as_str(&self) -> &str { | ||
50 | &*self.0 | ||
51 | } | ||
52 | } | ||
53 | |||
54 | impl Into<String> for Documentation { | ||
55 | fn into(self) -> String { | ||
56 | self.as_str().to_owned() | ||
57 | } | ||
58 | } | ||
59 | |||
60 | pub trait Docs { | ||
61 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>; | ||
62 | } | ||
63 | |||
64 | pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> { | ||
65 | node.doc_comment_text().map(|it| Documentation::new(&it)) | ||
66 | } | ||
67 | |||
68 | pub(crate) fn documentation_query( | ||
69 | db: &(impl DefDatabase + AstDatabase), | ||
70 | def: DocDef, | ||
71 | ) -> Option<Documentation> { | ||
72 | match def { | ||
73 | DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.value), | ||
74 | DocDef::StructField(it) => match it.source(db).value { | ||
75 | FieldSource::Named(named) => docs_from_ast(&named), | ||
76 | FieldSource::Pos(..) => None, | ||
77 | }, | ||
78 | DocDef::Adt(it) => match it { | ||
79 | Adt::Struct(it) => docs_from_ast(&it.source(db).value), | ||
80 | Adt::Enum(it) => docs_from_ast(&it.source(db).value), | ||
81 | Adt::Union(it) => docs_from_ast(&it.source(db).value), | ||
82 | }, | ||
83 | DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).value), | ||
84 | DocDef::Static(it) => docs_from_ast(&it.source(db).value), | ||
85 | DocDef::Const(it) => docs_from_ast(&it.source(db).value), | ||
86 | DocDef::Function(it) => docs_from_ast(&it.source(db).value), | ||
87 | DocDef::Trait(it) => docs_from_ast(&it.source(db).value), | ||
88 | DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).value), | ||
89 | DocDef::MacroDef(it) => docs_from_ast(&it.source(db).value), | ||
90 | } | ||
91 | } | ||
92 | |||
93 | impl<T: Into<DocDef> + Copy> Docs for T { | ||
94 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> { | ||
95 | db.documentation((*self).into()) | ||
96 | } | ||
97 | } | ||
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 4aa427de4..a4e317c20 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,172 +1,128 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{HasSource as _, Lookup}; | 3 | use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId}; |
4 | use ra_syntax::ast::{self, AstNode}; | 4 | use hir_expand::either::Either; |
5 | use ra_syntax::ast; | ||
5 | 6 | ||
6 | use crate::{ | 7 | use crate::{ |
7 | db::{AstDatabase, DefDatabase, HirDatabase}, | 8 | db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef, |
8 | ids::AstItemDef, | 9 | Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, |
9 | Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module, | ||
10 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, | ||
11 | }; | 10 | }; |
12 | 11 | ||
13 | pub use hir_expand::Source; | 12 | pub use hir_expand::Source; |
14 | 13 | ||
15 | pub trait HasSource { | 14 | pub trait HasSource { |
16 | type Ast; | 15 | type Ast; |
17 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; | 16 | fn source(self, db: &impl DefDatabase) -> Source<Self::Ast>; |
18 | } | 17 | } |
19 | 18 | ||
20 | /// NB: Module is !HasSource, because it has two source nodes at the same time: | 19 | /// NB: Module is !HasSource, because it has two source nodes at the same time: |
21 | /// definition and declaration. | 20 | /// definition and declaration. |
22 | impl Module { | 21 | impl Module { |
23 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | 22 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. |
24 | pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { | 23 | pub fn definition_source(self, db: &impl DefDatabase) -> Source<ModuleSource> { |
25 | let def_map = db.crate_def_map(self.id.krate); | 24 | let def_map = db.crate_def_map(self.id.krate); |
26 | let decl_id = def_map[self.id.module_id].declaration; | 25 | let src = def_map[self.id.module_id].definition_source(db); |
27 | let file_id = def_map[self.id.module_id].definition; | 26 | src.map(|it| match it { |
28 | let value = ModuleSource::new(db, file_id, decl_id); | 27 | Either::A(it) => ModuleSource::SourceFile(it), |
29 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); | 28 | Either::B(it) => ModuleSource::Module(it), |
30 | Source { file_id, value } | 29 | }) |
31 | } | 30 | } |
32 | 31 | ||
33 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | 32 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. |
34 | /// `None` for the crate root. | 33 | /// `None` for the crate root. |
35 | pub fn declaration_source( | 34 | pub fn declaration_source(self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { |
36 | self, | ||
37 | db: &(impl DefDatabase + AstDatabase), | ||
38 | ) -> Option<Source<ast::Module>> { | ||
39 | let def_map = db.crate_def_map(self.id.krate); | 35 | let def_map = db.crate_def_map(self.id.krate); |
40 | let decl = def_map[self.id.module_id].declaration?; | 36 | def_map[self.id.module_id].declaration_source(db) |
41 | let value = decl.to_node(db); | ||
42 | Some(Source { file_id: decl.file_id(), value }) | ||
43 | } | 37 | } |
44 | } | 38 | } |
45 | 39 | ||
46 | impl HasSource for StructField { | 40 | impl HasSource for StructField { |
47 | type Ast = FieldSource; | 41 | type Ast = FieldSource; |
48 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<FieldSource> { | 42 | fn source(self, db: &impl DefDatabase) -> Source<FieldSource> { |
49 | let var_data = self.parent.variant_data(db); | 43 | let var = VariantId::from(self.parent); |
50 | let fields = var_data.fields().unwrap(); | 44 | let src = var.child_source(db); |
51 | let ss; | 45 | src.map(|it| match it[self.id].clone() { |
52 | let es; | 46 | Either::A(it) => FieldSource::Pos(it), |
53 | let (file_id, struct_kind) = match self.parent { | 47 | Either::B(it) => FieldSource::Named(it), |
54 | VariantDef::Struct(s) => { | 48 | }) |
55 | ss = s.source(db); | ||
56 | (ss.file_id, ss.value.kind()) | ||
57 | } | ||
58 | VariantDef::EnumVariant(e) => { | ||
59 | es = e.source(db); | ||
60 | (es.file_id, es.value.kind()) | ||
61 | } | ||
62 | }; | ||
63 | |||
64 | let field_sources = match struct_kind { | ||
65 | ast::StructKind::Tuple(fl) => fl.fields().map(|it| FieldSource::Pos(it)).collect(), | ||
66 | ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(), | ||
67 | ast::StructKind::Unit => Vec::new(), | ||
68 | }; | ||
69 | let value = field_sources | ||
70 | .into_iter() | ||
71 | .zip(fields.iter()) | ||
72 | .find(|(_syntax, (id, _))| *id == self.id) | ||
73 | .unwrap() | ||
74 | .0; | ||
75 | Source { file_id, value } | ||
76 | } | 49 | } |
77 | } | 50 | } |
78 | impl HasSource for Struct { | 51 | impl HasSource for Struct { |
79 | type Ast = ast::StructDef; | 52 | type Ast = ast::StructDef; |
80 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StructDef> { | 53 | fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { |
81 | self.id.0.source(db) | 54 | self.id.0.source(db) |
82 | } | 55 | } |
83 | } | 56 | } |
84 | impl HasSource for Union { | 57 | impl HasSource for Union { |
85 | type Ast = ast::StructDef; | 58 | type Ast = ast::StructDef; |
86 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StructDef> { | 59 | fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { |
87 | self.id.0.source(db) | 60 | self.id.0.source(db) |
88 | } | 61 | } |
89 | } | 62 | } |
90 | impl HasSource for Enum { | 63 | impl HasSource for Enum { |
91 | type Ast = ast::EnumDef; | 64 | type Ast = ast::EnumDef; |
92 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumDef> { | 65 | fn source(self, db: &impl DefDatabase) -> Source<ast::EnumDef> { |
93 | self.id.source(db) | 66 | self.id.source(db) |
94 | } | 67 | } |
95 | } | 68 | } |
96 | impl HasSource for EnumVariant { | 69 | impl HasSource for EnumVariant { |
97 | type Ast = ast::EnumVariant; | 70 | type Ast = ast::EnumVariant; |
98 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> { | 71 | fn source(self, db: &impl DefDatabase) -> Source<ast::EnumVariant> { |
99 | let enum_data = db.enum_data(self.parent.id); | 72 | self.parent.id.child_source(db).map(|map| map[self.id].clone()) |
100 | let src = self.parent.id.source(db); | ||
101 | let value = src | ||
102 | .value | ||
103 | .variant_list() | ||
104 | .into_iter() | ||
105 | .flat_map(|it| it.variants()) | ||
106 | .zip(enum_data.variants.iter()) | ||
107 | .find(|(_syntax, (id, _))| *id == self.id) | ||
108 | .unwrap() | ||
109 | .0; | ||
110 | Source { file_id: src.file_id, value } | ||
111 | } | 73 | } |
112 | } | 74 | } |
113 | impl HasSource for Function { | 75 | impl HasSource for Function { |
114 | type Ast = ast::FnDef; | 76 | type Ast = ast::FnDef; |
115 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { | 77 | fn source(self, db: &impl DefDatabase) -> Source<ast::FnDef> { |
116 | self.id.lookup(db).source(db) | 78 | self.id.lookup(db).source(db) |
117 | } | 79 | } |
118 | } | 80 | } |
119 | impl HasSource for Const { | 81 | impl HasSource for Const { |
120 | type Ast = ast::ConstDef; | 82 | type Ast = ast::ConstDef; |
121 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> { | 83 | fn source(self, db: &impl DefDatabase) -> Source<ast::ConstDef> { |
122 | self.id.lookup(db).source(db) | 84 | self.id.lookup(db).source(db) |
123 | } | 85 | } |
124 | } | 86 | } |
125 | impl HasSource for Static { | 87 | impl HasSource for Static { |
126 | type Ast = ast::StaticDef; | 88 | type Ast = ast::StaticDef; |
127 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StaticDef> { | 89 | fn source(self, db: &impl DefDatabase) -> Source<ast::StaticDef> { |
128 | self.id.source(db) | 90 | self.id.lookup(db).source(db) |
129 | } | 91 | } |
130 | } | 92 | } |
131 | impl HasSource for Trait { | 93 | impl HasSource for Trait { |
132 | type Ast = ast::TraitDef; | 94 | type Ast = ast::TraitDef; |
133 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TraitDef> { | 95 | fn source(self, db: &impl DefDatabase) -> Source<ast::TraitDef> { |
134 | self.id.source(db) | 96 | self.id.source(db) |
135 | } | 97 | } |
136 | } | 98 | } |
137 | impl HasSource for TypeAlias { | 99 | impl HasSource for TypeAlias { |
138 | type Ast = ast::TypeAliasDef; | 100 | type Ast = ast::TypeAliasDef; |
139 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { | 101 | fn source(self, db: &impl DefDatabase) -> Source<ast::TypeAliasDef> { |
140 | self.id.lookup(db).source(db) | 102 | self.id.lookup(db).source(db) |
141 | } | 103 | } |
142 | } | 104 | } |
143 | impl HasSource for MacroDef { | 105 | impl HasSource for MacroDef { |
144 | type Ast = ast::MacroCall; | 106 | type Ast = ast::MacroCall; |
145 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::MacroCall> { | 107 | fn source(self, db: &impl DefDatabase) -> Source<ast::MacroCall> { |
146 | Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } | 108 | Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } |
147 | } | 109 | } |
148 | } | 110 | } |
149 | 111 | impl HasSource for ImplBlock { | |
150 | pub trait HasBodySource: HasBody + HasSource | 112 | type Ast = ast::ImplBlock; |
151 | where | 113 | fn source(self, db: &impl DefDatabase) -> Source<ast::ImplBlock> { |
152 | Self::Ast: AstNode, | 114 | self.id.source(db) |
153 | { | ||
154 | fn expr_source( | ||
155 | self, | ||
156 | db: &impl HirDatabase, | ||
157 | expr_id: crate::expr::ExprId, | ||
158 | ) -> Option<Source<Either<ast::Expr, ast::RecordField>>> { | ||
159 | let source_map = self.body_source_map(db); | ||
160 | let source_ptr = source_map.expr_syntax(expr_id)?; | ||
161 | let root = source_ptr.file_syntax(db); | ||
162 | let source = source_ptr.map(|ast| ast.map(|it| it.to_node(&root), |it| it.to_node(&root))); | ||
163 | Some(source) | ||
164 | } | 115 | } |
165 | } | 116 | } |
117 | impl HasSource for Import { | ||
118 | type Ast = Either<ast::UseTree, ast::ExternCrateItem>; | ||
166 | 119 | ||
167 | impl<T> HasBodySource for T | 120 | /// Returns the syntax of the last path segment corresponding to this import |
168 | where | 121 | fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> { |
169 | T: HasBody + HasSource, | 122 | let src = self.parent.definition_source(db); |
170 | T::Ast: AstNode, | 123 | let (_, source_map) = db.raw_items_with_source_map(src.file_id); |
171 | { | 124 | let root = db.parse_or_expand(src.file_id).unwrap(); |
125 | let ptr = source_map.get(self.id); | ||
126 | src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root))) | ||
127 | } | ||
172 | } | 128 | } |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index a9982a70f..b034d4e44 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -2,80 +2,46 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::attr::Attr; | 5 | use ra_arena::map::ArenaMap; |
6 | use ra_db::salsa; | 6 | use ra_db::salsa; |
7 | use ra_syntax::SmolStr; | ||
8 | 7 | ||
9 | use crate::{ | 8 | use crate::{ |
10 | debug::HirDebugDatabase, | ||
11 | generics::GenericDef, | ||
12 | ids, | ||
13 | lang_item::{LangItemTarget, LangItems}, | ||
14 | ty::{ | 9 | ty::{ |
15 | method_resolution::CrateImplBlocks, | 10 | method_resolution::CrateImplBlocks, |
16 | traits::{AssocTyValue, Impl}, | 11 | traits::{AssocTyValue, Impl}, |
17 | CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, | 12 | CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, |
18 | TypeCtor, | 13 | TypeCtor, |
19 | }, | 14 | }, |
20 | type_alias::TypeAliasData, | 15 | Crate, DefWithBody, ImplBlock, Trait, |
21 | Const, ConstData, Crate, DefWithBody, FnData, Function, ImplBlock, Module, Static, StructField, | ||
22 | Trait, TypeAlias, | ||
23 | }; | 16 | }; |
24 | 17 | ||
25 | pub use hir_def::db::{ | 18 | pub use hir_def::{ |
26 | BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, | 19 | db::{ |
27 | EnumDataQuery, ExprScopesQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, | 20 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, |
28 | InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, | 21 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, |
29 | TraitDataQuery, | 22 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, |
23 | InternDatabaseStorage, LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, | ||
24 | RawItemsWithSourceMapQuery, StaticDataQuery, StructDataQuery, TraitDataQuery, | ||
25 | TypeAliasDataQuery, | ||
26 | }, | ||
27 | GenericDefId, LocalStructFieldId, VariantId, | ||
30 | }; | 28 | }; |
31 | pub use hir_expand::db::{ | 29 | pub use hir_expand::db::{ |
32 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 30 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
33 | ParseMacroQuery, | 31 | ParseMacroQuery, |
34 | }; | 32 | }; |
35 | 33 | ||
36 | // This database uses `AstDatabase` internally, | ||
37 | #[salsa::query_group(DefDatabaseStorage)] | ||
38 | #[salsa::requires(AstDatabase)] | ||
39 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { | ||
40 | #[salsa::invoke(FnData::fn_data_query)] | ||
41 | fn fn_data(&self, func: Function) -> Arc<FnData>; | ||
42 | |||
43 | #[salsa::invoke(TypeAliasData::type_alias_data_query)] | ||
44 | fn type_alias_data(&self, typ: TypeAlias) -> Arc<TypeAliasData>; | ||
45 | |||
46 | #[salsa::invoke(ConstData::const_data_query)] | ||
47 | fn const_data(&self, konst: Const) -> Arc<ConstData>; | ||
48 | |||
49 | #[salsa::invoke(ConstData::static_data_query)] | ||
50 | fn static_data(&self, konst: Static) -> Arc<ConstData>; | ||
51 | |||
52 | #[salsa::invoke(LangItems::module_lang_items_query)] | ||
53 | fn module_lang_items(&self, module: Module) -> Option<Arc<LangItems>>; | ||
54 | |||
55 | #[salsa::invoke(LangItems::crate_lang_items_query)] | ||
56 | fn crate_lang_items(&self, krate: Crate) -> Arc<LangItems>; | ||
57 | |||
58 | #[salsa::invoke(LangItems::lang_item_query)] | ||
59 | fn lang_item(&self, start_crate: Crate, item: SmolStr) -> Option<LangItemTarget>; | ||
60 | |||
61 | #[salsa::invoke(crate::code_model::docs::documentation_query)] | ||
62 | fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>; | ||
63 | |||
64 | #[salsa::invoke(crate::code_model::attrs::attributes_query)] | ||
65 | fn attrs(&self, def: crate::AttrDef) -> Option<Arc<[Attr]>>; | ||
66 | } | ||
67 | |||
68 | #[salsa::query_group(HirDatabaseStorage)] | 34 | #[salsa::query_group(HirDatabaseStorage)] |
69 | #[salsa::requires(salsa::Database)] | 35 | #[salsa::requires(salsa::Database)] |
70 | pub trait HirDatabase: DefDatabase + AstDatabase { | 36 | pub trait HirDatabase: DefDatabase { |
71 | #[salsa::invoke(crate::ty::infer_query)] | 37 | #[salsa::invoke(crate::ty::infer_query)] |
72 | fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; | 38 | fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; |
73 | 39 | ||
74 | #[salsa::invoke(crate::ty::type_for_def)] | 40 | #[salsa::invoke(crate::ty::type_for_def)] |
75 | fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; | 41 | fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; |
76 | 42 | ||
77 | #[salsa::invoke(crate::ty::type_for_field)] | 43 | #[salsa::invoke(crate::ty::field_types_query)] |
78 | fn type_for_field(&self, field: StructField) -> Ty; | 44 | fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; |
79 | 45 | ||
80 | #[salsa::invoke(crate::ty::callable_item_sig)] | 46 | #[salsa::invoke(crate::ty::callable_item_sig)] |
81 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; | 47 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; |
@@ -83,15 +49,15 @@ pub trait HirDatabase: DefDatabase + AstDatabase { | |||
83 | #[salsa::invoke(crate::ty::generic_predicates_for_param_query)] | 49 | #[salsa::invoke(crate::ty::generic_predicates_for_param_query)] |
84 | fn generic_predicates_for_param( | 50 | fn generic_predicates_for_param( |
85 | &self, | 51 | &self, |
86 | def: GenericDef, | 52 | def: GenericDefId, |
87 | param_idx: u32, | 53 | param_idx: u32, |
88 | ) -> Arc<[GenericPredicate]>; | 54 | ) -> Arc<[GenericPredicate]>; |
89 | 55 | ||
90 | #[salsa::invoke(crate::ty::generic_predicates_query)] | 56 | #[salsa::invoke(crate::ty::generic_predicates_query)] |
91 | fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; | 57 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>; |
92 | 58 | ||
93 | #[salsa::invoke(crate::ty::generic_defaults_query)] | 59 | #[salsa::invoke(crate::ty::generic_defaults_query)] |
94 | fn generic_defaults(&self, def: GenericDef) -> Substs; | 60 | fn generic_defaults(&self, def: GenericDefId) -> Substs; |
95 | 61 | ||
96 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | 62 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] |
97 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | 63 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; |
@@ -109,11 +75,14 @@ pub trait HirDatabase: DefDatabase + AstDatabase { | |||
109 | 75 | ||
110 | // Interned IDs for Chalk integration | 76 | // Interned IDs for Chalk integration |
111 | #[salsa::interned] | 77 | #[salsa::interned] |
112 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId; | 78 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::ty::TypeCtorId; |
113 | #[salsa::interned] | 79 | #[salsa::interned] |
114 | fn intern_chalk_impl(&self, impl_: Impl) -> ids::GlobalImplId; | 80 | fn intern_chalk_impl(&self, impl_: Impl) -> crate::ty::traits::GlobalImplId; |
115 | #[salsa::interned] | 81 | #[salsa::interned] |
116 | fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> ids::AssocTyValueId; | 82 | fn intern_assoc_ty_value( |
83 | &self, | ||
84 | assoc_ty_value: AssocTyValue, | ||
85 | ) -> crate::ty::traits::AssocTyValueId; | ||
117 | 86 | ||
118 | #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] | 87 | #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] |
119 | fn associated_ty_data( | 88 | fn associated_ty_data( |
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs index 4f3e922c3..7a2810f71 100644 --- a/crates/ra_hir/src/debug.rs +++ b/crates/ra_hir/src/debug.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | //! XXX: This does not work at the moment. | ||
2 | //! | ||
1 | //! printf debugging infrastructure for rust-analyzer. | 3 | //! printf debugging infrastructure for rust-analyzer. |
2 | //! | 4 | //! |
3 | //! When you print a hir type, like a module, using `eprintln!("{:?}", module)`, | 5 | //! When you print a hir type, like a module, using `eprintln!("{:?}", module)`, |
@@ -20,9 +22,10 @@ | |||
20 | 22 | ||
21 | use std::fmt; | 23 | use std::fmt; |
22 | 24 | ||
25 | use hir_expand::HirFileId; | ||
23 | use ra_db::{CrateId, FileId}; | 26 | use ra_db::{CrateId, FileId}; |
24 | 27 | ||
25 | use crate::{db::HirDatabase, Crate, HirFileId, Module, Name}; | 28 | use crate::{db::HirDatabase, Crate, Module, Name}; |
26 | 29 | ||
27 | impl Crate { | 30 | impl Crate { |
28 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { | 31 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { |
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs index 7d1b64858..dafacba70 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs | |||
@@ -2,9 +2,10 @@ | |||
2 | 2 | ||
3 | use std::any::Any; | 3 | use std::any::Any; |
4 | 4 | ||
5 | use hir_expand::HirFileId; | ||
5 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; | 6 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; |
6 | 7 | ||
7 | use crate::{db::AstDatabase, HirFileId, Name, Source}; | 8 | use crate::{db::AstDatabase, Name, Source}; |
8 | 9 | ||
9 | pub use hir_def::diagnostics::UnresolvedModule; | 10 | pub use hir_def::diagnostics::UnresolvedModule; |
10 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; | 11 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 6b703d8b4..43fedde7a 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -44,15 +44,15 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
44 | pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { | 44 | pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { |
45 | let body = self.func.body(db); | 45 | let body = self.func.body(db); |
46 | 46 | ||
47 | for e in body.exprs() { | 47 | for e in body.exprs.iter() { |
48 | if let (id, Expr::RecordLit { path, fields, spread }) = e { | 48 | if let (id, Expr::RecordLit { path, fields, spread }) = e { |
49 | self.validate_record_literal(id, path, fields, *spread, db); | 49 | self.validate_record_literal(id, path, fields, *spread, db); |
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | let body_expr = &body[body.body_expr()]; | 53 | let body_expr = &body[body.body_expr]; |
54 | if let Expr::Block { statements: _, tail: Some(t) } = body_expr { | 54 | if let Expr::Block { statements: _, tail: Some(t) } = body_expr { |
55 | self.validate_results_in_tail_expr(body.body_expr(), *t, db); | 55 | self.validate_results_in_tail_expr(body.body_expr, *t, db); |
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index a3e9d8525..619f6055e 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -4,13 +4,13 @@ | |||
4 | //! are splitting the hir. | 4 | //! are splitting the hir. |
5 | 5 | ||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, | 7 | AdtId, AssocItemId, AttrDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, |
8 | ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, | 8 | GenericDefId, ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | ty::TypableDef, Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, | 12 | ty::TypableDef, Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function, |
13 | ModuleDef, Static, TypeAlias, | 13 | GenericDef, ModuleDef, Static, StructField, TypeAlias, VariantDef, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | impl From<ra_db::CrateId> for Crate { | 16 | impl From<ra_db::CrateId> for Crate { |
@@ -69,6 +69,12 @@ impl From<EnumVariantId> for EnumVariant { | |||
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | impl From<EnumVariant> for EnumVariantId { | ||
73 | fn from(def: EnumVariant) -> Self { | ||
74 | EnumVariantId { parent: def.parent.id, local_id: def.id } | ||
75 | } | ||
76 | } | ||
77 | |||
72 | impl From<ModuleDefId> for ModuleDef { | 78 | impl From<ModuleDefId> for ModuleDef { |
73 | fn from(id: ModuleDefId) -> Self { | 79 | fn from(id: ModuleDefId) -> Self { |
74 | match id { | 80 | match id { |
@@ -131,20 +137,6 @@ impl From<GenericDef> for GenericDefId { | |||
131 | } | 137 | } |
132 | } | 138 | } |
133 | 139 | ||
134 | impl From<GenericDefId> for GenericDef { | ||
135 | fn from(def: GenericDefId) -> Self { | ||
136 | match def { | ||
137 | GenericDefId::FunctionId(it) => GenericDef::Function(it.into()), | ||
138 | GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), | ||
139 | GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), | ||
140 | GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), | ||
141 | GenericDefId::ImplId(it) => GenericDef::ImplBlock(it.into()), | ||
142 | GenericDefId::EnumVariantId(it) => GenericDef::EnumVariant(it.into()), | ||
143 | GenericDefId::ConstId(it) => GenericDef::Const(it.into()), | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | |||
148 | impl From<AdtId> for TypableDef { | 140 | impl From<AdtId> for TypableDef { |
149 | fn from(id: AdtId) -> Self { | 141 | fn from(id: AdtId) -> Self { |
150 | Adt::from(id).into() | 142 | Adt::from(id).into() |
@@ -206,3 +198,45 @@ impl From<Adt> for GenericDefId { | |||
206 | } | 198 | } |
207 | } | 199 | } |
208 | } | 200 | } |
201 | |||
202 | impl From<VariantDef> for VariantId { | ||
203 | fn from(def: VariantDef) -> Self { | ||
204 | match def { | ||
205 | VariantDef::Struct(it) => VariantId::StructId(it.id), | ||
206 | VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
211 | impl From<StructField> for StructFieldId { | ||
212 | fn from(def: StructField) -> Self { | ||
213 | StructFieldId { parent: def.parent.into(), local_id: def.id } | ||
214 | } | ||
215 | } | ||
216 | |||
217 | impl From<AttrDef> for AttrDefId { | ||
218 | fn from(def: AttrDef) -> Self { | ||
219 | match def { | ||
220 | AttrDef::Module(it) => AttrDefId::ModuleId(it.id), | ||
221 | AttrDef::StructField(it) => AttrDefId::StructFieldId(it.into()), | ||
222 | AttrDef::Adt(it) => AttrDefId::AdtId(it.into()), | ||
223 | AttrDef::Function(it) => AttrDefId::FunctionId(it.id), | ||
224 | AttrDef::EnumVariant(it) => AttrDefId::EnumVariantId(it.into()), | ||
225 | AttrDef::Static(it) => AttrDefId::StaticId(it.id), | ||
226 | AttrDef::Const(it) => AttrDefId::ConstId(it.id), | ||
227 | AttrDef::Trait(it) => AttrDefId::TraitId(it.id), | ||
228 | AttrDef::TypeAlias(it) => AttrDefId::TypeAliasId(it.id), | ||
229 | AttrDef::MacroDef(it) => AttrDefId::MacroDefId(it.id), | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | |||
234 | impl From<AssocItem> for GenericDefId { | ||
235 | fn from(item: AssocItem) -> Self { | ||
236 | match item { | ||
237 | AssocItem::Function(f) => f.id.into(), | ||
238 | AssocItem::Const(c) => c.id.into(), | ||
239 | AssocItem::TypeAlias(t) => t.id.into(), | ||
240 | } | ||
241 | } | ||
242 | } | ||
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index b86307c58..1e7c22774 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId}; | 3 | use hir_def::{AstItemDef, LocationCtx, 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}, |
@@ -9,10 +9,9 @@ use ra_syntax::{ | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 11 | db::{AstDatabase, DefDatabase, HirDatabase}, |
12 | ids::{AstItemDef, LocationCtx}, | 12 | AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock, |
13 | AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, | 13 | Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, StructField, Trait, |
14 | ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, | 14 | TypeAlias, Union, VariantDef, |
15 | StructField, Trait, TypeAlias, Union, VariantDef, | ||
16 | }; | 15 | }; |
17 | 16 | ||
18 | pub trait FromSource: Sized { | 17 | pub trait FromSource: Sized { |
@@ -105,10 +104,21 @@ impl FromSource for Const { | |||
105 | impl FromSource for Static { | 104 | impl FromSource for Static { |
106 | type Ast = ast::StaticDef; | 105 | type Ast = ast::StaticDef; |
107 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 106 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
108 | let id = from_source(db, src)?; | 107 | let module = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { |
109 | Some(Static { id }) | 108 | Container::Module(it) => it, |
109 | Container::Trait(_) | Container::ImplBlock(_) => return None, | ||
110 | }; | ||
111 | module | ||
112 | .declarations(db) | ||
113 | .into_iter() | ||
114 | .filter_map(|it| match it { | ||
115 | ModuleDef::Static(it) => Some(it), | ||
116 | _ => None, | ||
117 | }) | ||
118 | .find(|it| same_source(&it.source(db), &src)) | ||
110 | } | 119 | } |
111 | } | 120 | } |
121 | |||
112 | impl FromSource for TypeAlias { | 122 | impl FromSource for TypeAlias { |
113 | type Ast = ast::TypeAliasDef; | 123 | type Ast = ast::TypeAliasDef; |
114 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 124 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
@@ -190,8 +200,7 @@ impl FromSource for StructField { | |||
190 | variant_def | 200 | variant_def |
191 | .variant_data(db) | 201 | .variant_data(db) |
192 | .fields() | 202 | .fields() |
193 | .into_iter() | 203 | .iter() |
194 | .flat_map(|it| it.iter()) | ||
195 | .map(|(id, _)| StructField { parent: variant_def, id }) | 204 | .map(|(id, _)| StructField { parent: variant_def, id }) |
196 | .find(|f| f.source(db) == src) | 205 | .find(|f| f.source(db) == src) |
197 | } | 206 | } |
@@ -211,7 +220,7 @@ impl Local { | |||
211 | }; | 220 | }; |
212 | Some(res) | 221 | Some(res) |
213 | })?; | 222 | })?; |
214 | let source_map = parent.body_source_map(db); | 223 | let (_body, source_map) = db.body_with_source_map(parent.into()); |
215 | let src = src.map(ast::Pat::from); | 224 | let src = src.map(ast::Pat::from); |
216 | let pat_id = source_map.node_pat(src.as_ref())?; | 225 | let pat_id = source_map.node_pat(src.as_ref())?; |
217 | Some(Local { parent, pat_id }) | 226 | Some(Local { parent, pat_id }) |
@@ -272,7 +281,9 @@ where | |||
272 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); | 281 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); |
273 | let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; | 282 | let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; |
274 | let ctx = LocationCtx::new(db, module.id, src.file_id); | 283 | let ctx = LocationCtx::new(db, module.id, src.file_id); |
275 | Some(DEF::from_ast(ctx, &src.value)) | 284 | let items = db.ast_id_map(src.file_id); |
285 | let item_id = items.ast_id(&src.value); | ||
286 | Some(DEF::from_ast_id(ctx, item_id)) | ||
276 | } | 287 | } |
277 | 288 | ||
278 | enum Container { | 289 | enum Container { |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs deleted file mode 100644 index f1bf2ee9d..000000000 --- a/crates/ra_hir/src/generics.rs +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | //! Temp module to wrap hir_def::generics | ||
2 | use std::sync::Arc; | ||
3 | |||
4 | use crate::{ | ||
5 | db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, | ||
6 | TypeAlias, Union, | ||
7 | }; | ||
8 | |||
9 | pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate}; | ||
10 | |||
11 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
12 | pub enum GenericDef { | ||
13 | Function(Function), | ||
14 | Adt(Adt), | ||
15 | Trait(Trait), | ||
16 | TypeAlias(TypeAlias), | ||
17 | ImplBlock(ImplBlock), | ||
18 | // enum variants cannot have generics themselves, but their parent enums | ||
19 | // can, and this makes some code easier to write | ||
20 | EnumVariant(EnumVariant), | ||
21 | // consts can have type parameters from their parents (i.e. associated consts of traits) | ||
22 | Const(Const), | ||
23 | } | ||
24 | impl_froms!( | ||
25 | GenericDef: Function, | ||
26 | Adt(Struct, Enum, Union), | ||
27 | Trait, | ||
28 | TypeAlias, | ||
29 | ImplBlock, | ||
30 | EnumVariant, | ||
31 | Const | ||
32 | ); | ||
33 | |||
34 | impl From<Container> for GenericDef { | ||
35 | fn from(c: Container) -> Self { | ||
36 | match c { | ||
37 | Container::Trait(trait_) => trait_.into(), | ||
38 | Container::ImplBlock(impl_block) => impl_block.into(), | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | |||
43 | pub trait HasGenericParams: Copy { | ||
44 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>; | ||
45 | } | ||
46 | |||
47 | impl<T> HasGenericParams for T | ||
48 | where | ||
49 | T: Into<GenericDef> + Copy, | ||
50 | { | ||
51 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> { | ||
52 | db.generic_params(self.into().into()) | ||
53 | } | ||
54 | } | ||
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs deleted file mode 100644 index 2b59365fb..000000000 --- a/crates/ra_hir/src/ids.rs +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | //! hir makes heavy use of ids: integer (u32) handlers to various things. You | ||
2 | //! can think of id as a pointer (but without a lifetime) or a file descriptor | ||
3 | //! (but for hir objects). | ||
4 | //! | ||
5 | //! This module defines a bunch of ids we are using. The most important ones are | ||
6 | //! probably `HirFileId` and `DefId`. | ||
7 | |||
8 | use ra_db::salsa; | ||
9 | |||
10 | pub use hir_def::{ | ||
11 | AstItemDef, ConstId, EnumId, FunctionId, ItemLoc, LocationCtx, StaticId, StructId, TraitId, | ||
12 | TypeAliasId, | ||
13 | }; | ||
14 | pub use hir_expand::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, MacroFileKind}; | ||
15 | |||
16 | macro_rules! impl_intern_key { | ||
17 | ($name:ident) => { | ||
18 | impl salsa::InternKey for $name { | ||
19 | fn from_intern_id(v: salsa::InternId) -> Self { | ||
20 | $name(v) | ||
21 | } | ||
22 | fn as_intern_id(&self) -> salsa::InternId { | ||
23 | self.0 | ||
24 | } | ||
25 | } | ||
26 | }; | ||
27 | } | ||
28 | |||
29 | /// This exists just for Chalk, because Chalk just has a single `StructId` where | ||
30 | /// we have different kinds of ADTs, primitive types and special type | ||
31 | /// constructors like tuples and function pointers. | ||
32 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
33 | pub struct TypeCtorId(salsa::InternId); | ||
34 | impl_intern_key!(TypeCtorId); | ||
35 | |||
36 | /// This exists just for Chalk, because our ImplIds are only unique per module. | ||
37 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
38 | pub struct GlobalImplId(salsa::InternId); | ||
39 | impl_intern_key!(GlobalImplId); | ||
40 | |||
41 | /// This exists just for Chalk, because it needs a unique ID for each associated | ||
42 | /// type value in an impl (even synthetic ones). | ||
43 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
44 | pub struct AssocTyValueId(salsa::InternId); | ||
45 | impl_intern_key!(AssocTyValueId); | ||
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs deleted file mode 100644 index 774fa1d96..000000000 --- a/crates/ra_hir/src/impl_block.rs +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use hir_def::{resolver::HasResolver, type_ref::TypeRef, AstItemDef}; | ||
4 | use ra_syntax::ast; | ||
5 | |||
6 | use crate::{ | ||
7 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
8 | ty::Ty, | ||
9 | AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, | ||
10 | }; | ||
11 | |||
12 | impl HasSource for ImplBlock { | ||
13 | type Ast = ast::ImplBlock; | ||
14 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ImplBlock> { | ||
15 | self.id.source(db) | ||
16 | } | ||
17 | } | ||
18 | |||
19 | impl ImplBlock { | ||
20 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | ||
21 | db.impl_data(self.id).target_trait().cloned() | ||
22 | } | ||
23 | |||
24 | pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { | ||
25 | db.impl_data(self.id).target_type().clone() | ||
26 | } | ||
27 | |||
28 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | ||
29 | Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) | ||
30 | } | ||
31 | |||
32 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { | ||
33 | let target_ty = self.target_ty(db); | ||
34 | TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) | ||
35 | } | ||
36 | |||
37 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | ||
38 | db.impl_data(self.id).items().iter().map(|it| (*it).into()).collect() | ||
39 | } | ||
40 | |||
41 | pub fn is_negative(&self, db: &impl DefDatabase) -> bool { | ||
42 | db.impl_data(self.id).is_negative() | ||
43 | } | ||
44 | |||
45 | pub fn module(&self, db: &impl DefDatabase) -> Module { | ||
46 | self.id.module(db).into() | ||
47 | } | ||
48 | |||
49 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | ||
50 | Crate { crate_id: self.module(db).id.krate } | ||
51 | } | ||
52 | } | ||
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs deleted file mode 100644 index 89fd85f59..000000000 --- a/crates/ra_hir/src/lang_item.rs +++ /dev/null | |||
@@ -1,160 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use rustc_hash::FxHashMap; | ||
4 | use std::sync::Arc; | ||
5 | |||
6 | use ra_syntax::{ast::AttrsOwner, SmolStr}; | ||
7 | |||
8 | use crate::{ | ||
9 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
10 | Adt, Crate, Enum, Function, HasSource, ImplBlock, Module, ModuleDef, Static, Struct, Trait, | ||
11 | }; | ||
12 | |||
13 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
14 | pub enum LangItemTarget { | ||
15 | Enum(Enum), | ||
16 | Function(Function), | ||
17 | ImplBlock(ImplBlock), | ||
18 | Static(Static), | ||
19 | Struct(Struct), | ||
20 | Trait(Trait), | ||
21 | } | ||
22 | |||
23 | impl LangItemTarget { | ||
24 | pub(crate) fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { | ||
25 | Some(match self { | ||
26 | LangItemTarget::Enum(e) => e.module(db).krate(), | ||
27 | LangItemTarget::Function(f) => f.module(db).krate(), | ||
28 | LangItemTarget::ImplBlock(i) => i.krate(db), | ||
29 | LangItemTarget::Static(s) => s.module(db).krate(), | ||
30 | LangItemTarget::Struct(s) => s.module(db).krate(), | ||
31 | LangItemTarget::Trait(t) => t.module(db).krate(), | ||
32 | }) | ||
33 | } | ||
34 | } | ||
35 | |||
36 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | ||
37 | pub struct LangItems { | ||
38 | items: FxHashMap<SmolStr, LangItemTarget>, | ||
39 | } | ||
40 | |||
41 | impl LangItems { | ||
42 | pub fn target<'a>(&'a self, item: &str) -> Option<&'a LangItemTarget> { | ||
43 | self.items.get(item) | ||
44 | } | ||
45 | |||
46 | /// Salsa query. This will look for lang items in a specific crate. | ||
47 | pub(crate) fn crate_lang_items_query( | ||
48 | db: &(impl DefDatabase + AstDatabase), | ||
49 | krate: Crate, | ||
50 | ) -> Arc<LangItems> { | ||
51 | let mut lang_items = LangItems::default(); | ||
52 | |||
53 | if let Some(module) = krate.root_module(db) { | ||
54 | lang_items.collect_lang_items_recursive(db, module); | ||
55 | } | ||
56 | |||
57 | Arc::new(lang_items) | ||
58 | } | ||
59 | |||
60 | pub(crate) fn module_lang_items_query( | ||
61 | db: &(impl DefDatabase + AstDatabase), | ||
62 | module: Module, | ||
63 | ) -> Option<Arc<LangItems>> { | ||
64 | let mut lang_items = LangItems::default(); | ||
65 | lang_items.collect_lang_items(db, module); | ||
66 | if lang_items.items.is_empty() { | ||
67 | None | ||
68 | } else { | ||
69 | Some(Arc::new(lang_items)) | ||
70 | } | ||
71 | } | ||
72 | |||
73 | /// Salsa query. Look for a lang item, starting from the specified crate and recursively | ||
74 | /// traversing its dependencies. | ||
75 | pub(crate) fn lang_item_query( | ||
76 | db: &impl DefDatabase, | ||
77 | start_crate: Crate, | ||
78 | item: SmolStr, | ||
79 | ) -> Option<LangItemTarget> { | ||
80 | let lang_items = db.crate_lang_items(start_crate); | ||
81 | let start_crate_target = lang_items.items.get(&item); | ||
82 | if let Some(target) = start_crate_target { | ||
83 | Some(*target) | ||
84 | } else { | ||
85 | for dep in start_crate.dependencies(db) { | ||
86 | let dep_crate = dep.krate; | ||
87 | let dep_target = db.lang_item(dep_crate, item.clone()); | ||
88 | if dep_target.is_some() { | ||
89 | return dep_target; | ||
90 | } | ||
91 | } | ||
92 | None | ||
93 | } | ||
94 | } | ||
95 | |||
96 | fn collect_lang_items(&mut self, db: &(impl DefDatabase + AstDatabase), module: Module) { | ||
97 | // Look for impl targets | ||
98 | for impl_block in module.impl_blocks(db) { | ||
99 | let src = impl_block.source(db); | ||
100 | if let Some(lang_item_name) = lang_item_name(&src.value) { | ||
101 | self.items | ||
102 | .entry(lang_item_name) | ||
103 | .or_insert_with(|| LangItemTarget::ImplBlock(impl_block)); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | for def in module.declarations(db) { | ||
108 | match def { | ||
109 | ModuleDef::Trait(trait_) => { | ||
110 | self.collect_lang_item(db, trait_, LangItemTarget::Trait) | ||
111 | } | ||
112 | ModuleDef::Adt(Adt::Enum(e)) => self.collect_lang_item(db, e, LangItemTarget::Enum), | ||
113 | ModuleDef::Adt(Adt::Struct(s)) => { | ||
114 | self.collect_lang_item(db, s, LangItemTarget::Struct) | ||
115 | } | ||
116 | ModuleDef::Function(f) => self.collect_lang_item(db, f, LangItemTarget::Function), | ||
117 | ModuleDef::Static(s) => self.collect_lang_item(db, s, LangItemTarget::Static), | ||
118 | _ => {} | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | |||
123 | fn collect_lang_items_recursive( | ||
124 | &mut self, | ||
125 | db: &(impl DefDatabase + AstDatabase), | ||
126 | module: Module, | ||
127 | ) { | ||
128 | if let Some(module_lang_items) = db.module_lang_items(module) { | ||
129 | self.items.extend(module_lang_items.items.iter().map(|(k, v)| (k.clone(), *v))) | ||
130 | } | ||
131 | |||
132 | // Look for lang items in the children | ||
133 | for child in module.children(db) { | ||
134 | self.collect_lang_items_recursive(db, child); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | fn collect_lang_item<T, N>( | ||
139 | &mut self, | ||
140 | db: &(impl DefDatabase + AstDatabase), | ||
141 | item: T, | ||
142 | constructor: fn(T) -> LangItemTarget, | ||
143 | ) where | ||
144 | T: Copy + HasSource<Ast = N>, | ||
145 | N: AttrsOwner, | ||
146 | { | ||
147 | let node = item.source(db).value; | ||
148 | if let Some(lang_item_name) = lang_item_name(&node) { | ||
149 | self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | fn lang_item_name<T: AttrsOwner>(node: &T) -> Option<SmolStr> { | ||
155 | node.attrs() | ||
156 | .filter_map(|a| a.as_simple_key_value()) | ||
157 | .filter(|(key, _)| key == "lang") | ||
158 | .map(|(_, val)| val) | ||
159 | .nth(0) | ||
160 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 76c96bdcf..843ce6a88 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -31,13 +31,8 @@ pub mod debug; | |||
31 | pub mod db; | 31 | pub mod db; |
32 | pub mod source_binder; | 32 | pub mod source_binder; |
33 | 33 | ||
34 | mod ids; | ||
35 | mod type_alias; | ||
36 | mod ty; | 34 | mod ty; |
37 | mod impl_block; | ||
38 | mod expr; | 35 | mod expr; |
39 | mod lang_item; | ||
40 | pub mod generics; | ||
41 | pub mod diagnostics; | 36 | pub mod diagnostics; |
42 | mod util; | 37 | mod util; |
43 | 38 | ||
@@ -53,18 +48,13 @@ mod marks; | |||
53 | 48 | ||
54 | pub use crate::{ | 49 | pub use crate::{ |
55 | code_model::{ | 50 | code_model::{ |
56 | attrs::{AttrDef, Attrs}, | 51 | src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, |
57 | docs::{DocDef, Docs, Documentation}, | 52 | DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam, |
58 | src::{HasBodySource, HasSource}, | 53 | HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, |
59 | Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, | 54 | Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, |
60 | EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, | ||
61 | MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait, | ||
62 | TypeAlias, Union, VariantDef, | ||
63 | }, | 55 | }, |
64 | expr::ExprScopes, | 56 | expr::ExprScopes, |
65 | from_source::FromSource, | 57 | from_source::FromSource, |
66 | generics::GenericDef, | ||
67 | ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, | ||
68 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 58 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
69 | ty::{ | 59 | ty::{ |
70 | display::HirDisplay, | 60 | display::HirDisplay, |
@@ -75,8 +65,10 @@ pub use crate::{ | |||
75 | 65 | ||
76 | pub use hir_def::{ | 66 | pub use hir_def::{ |
77 | builtin_type::BuiltinType, | 67 | builtin_type::BuiltinType, |
78 | nameres::{per_ns::PerNs, raw::ImportId}, | 68 | docs::Documentation, |
79 | path::{Path, PathKind}, | 69 | path::{Path, PathKind}, |
80 | type_ref::Mutability, | 70 | type_ref::Mutability, |
81 | }; | 71 | }; |
82 | pub use hir_expand::{either::Either, name::Name, Source}; | 72 | pub use hir_expand::{ |
73 | either::Either, name::Name, HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Source, | ||
74 | }; | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index c42ceabdf..cbfeca3ab 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -13,7 +13,9 @@ use hir_def::{ | |||
13 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, | 13 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, |
14 | DefWithBodyId, | 14 | DefWithBodyId, |
15 | }; | 15 | }; |
16 | use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; | 16 | use hir_expand::{ |
17 | name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source, | ||
18 | }; | ||
17 | use ra_syntax::{ | 19 | use ra_syntax::{ |
18 | ast::{self, AstNode}, | 20 | ast::{self, AstNode}, |
19 | match_ast, AstPtr, | 21 | match_ast, AstPtr, |
@@ -24,11 +26,12 @@ use ra_syntax::{ | |||
24 | use crate::{ | 26 | use crate::{ |
25 | db::HirDatabase, | 27 | db::HirDatabase, |
26 | expr::{BodySourceMap, ExprScopes, ScopeId}, | 28 | expr::{BodySourceMap, ExprScopes, ScopeId}, |
27 | ids::LocationCtx, | 29 | ty::{ |
28 | ty::method_resolution::{self, implements_trait}, | 30 | method_resolution::{self, implements_trait}, |
31 | TraitEnvironment, | ||
32 | }, | ||
29 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, | 33 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, |
30 | GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, ScopeDef, Static, | 34 | GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias, |
31 | Struct, Trait, Ty, TypeAlias, | ||
32 | }; | 35 | }; |
33 | 36 | ||
34 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 37 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { |
@@ -67,16 +70,12 @@ fn def_with_body_from_child_node( | |||
67 | db: &impl HirDatabase, | 70 | db: &impl HirDatabase, |
68 | child: Source<&SyntaxNode>, | 71 | child: Source<&SyntaxNode>, |
69 | ) -> Option<DefWithBody> { | 72 | ) -> Option<DefWithBody> { |
70 | let module_source = crate::ModuleSource::from_child_node(db, child); | ||
71 | let module = Module::from_definition(db, Source::new(child.file_id, module_source))?; | ||
72 | let ctx = LocationCtx::new(db, module.id, child.file_id); | ||
73 | |||
74 | child.value.ancestors().find_map(|node| { | 73 | child.value.ancestors().find_map(|node| { |
75 | match_ast! { | 74 | match_ast! { |
76 | match node { | 75 | match node { |
77 | ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, | 76 | ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, |
78 | ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, | 77 | ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, |
79 | ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, | 78 | ast::StaticDef(def) => { return Static::from_source(db, child.with_value(def)).map(DefWithBody::from); }, |
80 | _ => { None }, | 79 | _ => { None }, |
81 | } | 80 | } |
82 | } | 81 | } |
@@ -131,6 +130,7 @@ pub struct ReferenceDescriptor { | |||
131 | } | 130 | } |
132 | 131 | ||
133 | pub struct Expansion { | 132 | pub struct Expansion { |
133 | macro_file_kind: MacroFileKind, | ||
134 | macro_call_id: MacroCallId, | 134 | macro_call_id: MacroCallId, |
135 | } | 135 | } |
136 | 136 | ||
@@ -145,7 +145,7 @@ impl Expansion { | |||
145 | } | 145 | } |
146 | 146 | ||
147 | pub fn file_id(&self) -> HirFileId { | 147 | pub fn file_id(&self) -> HirFileId { |
148 | self.macro_call_id.as_file(MacroFileKind::Items) | 148 | self.macro_call_id.as_file(self.macro_file_kind) |
149 | } | 149 | } |
150 | } | 150 | } |
151 | 151 | ||
@@ -157,8 +157,8 @@ impl SourceAnalyzer { | |||
157 | ) -> SourceAnalyzer { | 157 | ) -> SourceAnalyzer { |
158 | let def_with_body = def_with_body_from_child_node(db, node); | 158 | let def_with_body = def_with_body_from_child_node(db, node); |
159 | if let Some(def) = def_with_body { | 159 | if let Some(def) = def_with_body { |
160 | let source_map = def.body_source_map(db); | 160 | let (_body, source_map) = db.body_with_source_map(def.into()); |
161 | let scopes = def.expr_scopes(db); | 161 | let scopes = db.expr_scopes(def.into()); |
162 | let scope = match offset { | 162 | let scope = match offset { |
163 | None => scope_for(&scopes, &source_map, node), | 163 | None => scope_for(&scopes, &source_map, node), |
164 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), | 164 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), |
@@ -168,7 +168,7 @@ impl SourceAnalyzer { | |||
168 | resolver, | 168 | resolver, |
169 | body_owner: Some(def), | 169 | body_owner: Some(def), |
170 | body_source_map: Some(source_map), | 170 | body_source_map: Some(source_map), |
171 | infer: Some(def.infer(db)), | 171 | infer: Some(db.infer(def)), |
172 | scopes: Some(scopes), | 172 | scopes: Some(scopes), |
173 | file_id: node.file_id, | 173 | file_id: node.file_id, |
174 | } | 174 | } |
@@ -218,6 +218,11 @@ impl SourceAnalyzer { | |||
218 | self.infer.as_ref()?.field_resolution(expr_id) | 218 | self.infer.as_ref()?.field_resolution(expr_id) |
219 | } | 219 | } |
220 | 220 | ||
221 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { | ||
222 | let expr_id = self.expr_id(&field.expr()?)?; | ||
223 | self.infer.as_ref()?.record_field_resolution(expr_id) | ||
224 | } | ||
225 | |||
221 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { | 226 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { |
222 | let expr_id = self.expr_id(&record_lit.clone().into())?; | 227 | let expr_id = self.expr_id(&record_lit.clone().into())?; |
223 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | 228 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) |
@@ -246,7 +251,7 @@ impl SourceAnalyzer { | |||
246 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { | 251 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { |
247 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 252 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
248 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { | 253 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { |
249 | parent: self.resolver.generic_def().unwrap().into(), | 254 | parent: self.resolver.generic_def().unwrap(), |
250 | idx, | 255 | idx, |
251 | }), | 256 | }), |
252 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | 257 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
@@ -321,7 +326,7 @@ impl SourceAnalyzer { | |||
321 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), | 326 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), |
322 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), | 327 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), |
323 | resolver::ScopeDef::GenericParam(idx) => { | 328 | resolver::ScopeDef::GenericParam(idx) => { |
324 | let parent = self.resolver.generic_def().unwrap().into(); | 329 | let parent = self.resolver.generic_def().unwrap(); |
325 | ScopeDef::GenericParam(GenericParam { parent, idx }) | 330 | ScopeDef::GenericParam(GenericParam { parent, idx }) |
326 | } | 331 | } |
327 | resolver::ScopeDef::Local(pat_id) => { | 332 | resolver::ScopeDef::Local(pat_id) => { |
@@ -406,7 +411,10 @@ impl SourceAnalyzer { | |||
406 | // There should be no inference vars in types passed here | 411 | // There should be no inference vars in types passed here |
407 | // FIXME check that? | 412 | // FIXME check that? |
408 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | 413 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; |
409 | crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) | 414 | let krate = self.resolver.krate(); |
415 | let environment = TraitEnvironment::lower(db, &self.resolver); | ||
416 | let ty = crate::ty::InEnvironment { value: canonical, environment }; | ||
417 | crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) | ||
410 | } | 418 | } |
411 | 419 | ||
412 | /// Checks that particular type `ty` implements `std::future::Future`. | 420 | /// Checks that particular type `ty` implements `std::future::Future`. |
@@ -439,7 +447,10 @@ impl SourceAnalyzer { | |||
439 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | 447 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), |
440 | ); | 448 | ); |
441 | let macro_call_loc = MacroCallLoc { def, ast_id }; | 449 | let macro_call_loc = MacroCallLoc { def, ast_id }; |
442 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) | 450 | Some(Expansion { |
451 | macro_call_id: db.intern_macro(macro_call_loc), | ||
452 | macro_file_kind: to_macro_file_kind(macro_call.value), | ||
453 | }) | ||
443 | } | 454 | } |
444 | 455 | ||
445 | #[cfg(test)] | 456 | #[cfg(test)] |
@@ -538,3 +549,35 @@ fn adjust( | |||
538 | }) | 549 | }) |
539 | .map(|(_ptr, scope)| *scope) | 550 | .map(|(_ptr, scope)| *scope) |
540 | } | 551 | } |
552 | |||
553 | /// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to. | ||
554 | /// FIXME: Not completed | ||
555 | fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind { | ||
556 | let syn = macro_call.syntax(); | ||
557 | let parent = match syn.parent() { | ||
558 | Some(it) => it, | ||
559 | None => { | ||
560 | // FIXME: | ||
561 | // If it is root, which means the parent HirFile | ||
562 | // MacroKindFile must be non-items | ||
563 | // return expr now. | ||
564 | return MacroFileKind::Expr; | ||
565 | } | ||
566 | }; | ||
567 | |||
568 | match parent.kind() { | ||
569 | MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items, | ||
570 | LET_STMT => { | ||
571 | // FIXME: Handle Pattern | ||
572 | MacroFileKind::Expr | ||
573 | } | ||
574 | EXPR_STMT => MacroFileKind::Statements, | ||
575 | BLOCK => MacroFileKind::Statements, | ||
576 | ARG_LIST => MacroFileKind::Expr, | ||
577 | TRY_EXPR => MacroFileKind::Expr, | ||
578 | _ => { | ||
579 | // Unknown , Just guess it is `Items` | ||
580 | MacroFileKind::Items | ||
581 | } | ||
582 | } | ||
583 | } | ||
diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir/src/test_db.rs index 1caa2e875..efee2f658 100644 --- a/crates/ra_hir/src/test_db.rs +++ b/crates/ra_hir/src/test_db.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::{panic, sync::Arc}; | 3 | use std::{panic, sync::Arc}; |
4 | 4 | ||
5 | use hir_def::{db::DefDatabase2, ModuleId}; | 5 | use hir_def::{db::DefDatabase, ModuleId}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use parking_lot::Mutex; | 7 | use parking_lot::Mutex; |
8 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase}; | 8 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase}; |
@@ -15,7 +15,6 @@ use crate::{db, debug::HirDebugHelper}; | |||
15 | db::InternDatabaseStorage, | 15 | db::InternDatabaseStorage, |
16 | db::AstDatabaseStorage, | 16 | db::AstDatabaseStorage, |
17 | db::DefDatabaseStorage, | 17 | db::DefDatabaseStorage, |
18 | db::DefDatabase2Storage, | ||
19 | db::HirDatabaseStorage | 18 | db::HirDatabaseStorage |
20 | )] | 19 | )] |
21 | #[derive(Debug, Default)] | 20 | #[derive(Debug, Default)] |
@@ -81,7 +80,7 @@ impl TestDB { | |||
81 | let crate_graph = self.crate_graph(); | 80 | let crate_graph = self.crate_graph(); |
82 | for krate in crate_graph.iter().next() { | 81 | for krate in crate_graph.iter().next() { |
83 | let crate_def_map = self.crate_def_map(krate); | 82 | let crate_def_map = self.crate_def_map(krate); |
84 | for module_id in crate_def_map.modules() { | 83 | for (module_id, _) in crate_def_map.modules.iter() { |
85 | let module_id = ModuleId { krate, module_id }; | 84 | let module_id = ModuleId { krate, module_id }; |
86 | let module = crate::Module::from(module_id); | 85 | let module = crate::Module::from(module_id); |
87 | module.diagnostics( | 86 | module.diagnostics( |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 36ece723f..1e05ac3f2 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -17,12 +17,12 @@ use std::ops::Deref; | |||
17 | use std::sync::Arc; | 17 | use std::sync::Arc; |
18 | use std::{fmt, iter, mem}; | 18 | use std::{fmt, iter, mem}; |
19 | 19 | ||
20 | use hir_def::{generics::GenericParams, AdtId, GenericDefId}; | ||
21 | use ra_db::{impl_intern_key, salsa}; | ||
22 | |||
20 | use crate::{ | 23 | use crate::{ |
21 | db::HirDatabase, | 24 | db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, IntTy, |
22 | expr::ExprId, | 25 | Mutability, Name, Trait, TypeAlias, Uncertain, |
23 | generics::{GenericParams, HasGenericParams}, | ||
24 | util::make_mut_slice, | ||
25 | Adt, Crate, DefWithBody, FloatTy, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, | ||
26 | }; | 26 | }; |
27 | use display::{HirDisplay, HirFormatter}; | 27 | use display::{HirDisplay, HirFormatter}; |
28 | 28 | ||
@@ -30,8 +30,9 @@ pub(crate) use autoderef::autoderef; | |||
30 | pub(crate) use infer::{infer_query, InferTy, InferenceResult}; | 30 | pub(crate) use infer::{infer_query, InferTy, InferenceResult}; |
31 | pub use lower::CallableDef; | 31 | pub use lower::CallableDef; |
32 | pub(crate) use lower::{ | 32 | pub(crate) use lower::{ |
33 | callable_item_sig, generic_defaults_query, generic_predicates_for_param_query, | 33 | callable_item_sig, field_types_query, generic_defaults_query, |
34 | generic_predicates_query, type_for_def, type_for_field, Namespace, TypableDef, | 34 | generic_predicates_for_param_query, generic_predicates_query, type_for_def, Namespace, |
35 | TypableDef, | ||
35 | }; | 36 | }; |
36 | pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 37 | pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
37 | 38 | ||
@@ -115,6 +116,13 @@ pub enum TypeCtor { | |||
115 | Closure { def: DefWithBody, expr: ExprId }, | 116 | Closure { def: DefWithBody, expr: ExprId }, |
116 | } | 117 | } |
117 | 118 | ||
119 | /// This exists just for Chalk, because Chalk just has a single `StructId` where | ||
120 | /// we have different kinds of ADTs, primitive types and special type | ||
121 | /// constructors like tuples and function pointers. | ||
122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
123 | pub struct TypeCtorId(salsa::InternId); | ||
124 | impl_intern_key!(TypeCtorId); | ||
125 | |||
118 | impl TypeCtor { | 126 | impl TypeCtor { |
119 | pub fn num_ty_params(self, db: &impl HirDatabase) -> usize { | 127 | pub fn num_ty_params(self, db: &impl HirDatabase) -> usize { |
120 | match self { | 128 | match self { |
@@ -131,15 +139,15 @@ impl TypeCtor { | |||
131 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure | 139 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure |
132 | => 1, | 140 | => 1, |
133 | TypeCtor::Adt(adt) => { | 141 | TypeCtor::Adt(adt) => { |
134 | let generic_params = adt.generic_params(db); | 142 | let generic_params = db.generic_params(AdtId::from(adt).into()); |
135 | generic_params.count_params_including_parent() | 143 | generic_params.count_params_including_parent() |
136 | } | 144 | } |
137 | TypeCtor::FnDef(callable) => { | 145 | TypeCtor::FnDef(callable) => { |
138 | let generic_params = callable.generic_params(db); | 146 | let generic_params = db.generic_params(callable.into()); |
139 | generic_params.count_params_including_parent() | 147 | generic_params.count_params_including_parent() |
140 | } | 148 | } |
141 | TypeCtor::AssociatedType(type_alias) => { | 149 | TypeCtor::AssociatedType(type_alias) => { |
142 | let generic_params = type_alias.generic_params(db); | 150 | let generic_params = db.generic_params(type_alias.id.into()); |
143 | generic_params.count_params_including_parent() | 151 | generic_params.count_params_including_parent() |
144 | } | 152 | } |
145 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, | 153 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, |
@@ -168,7 +176,7 @@ impl TypeCtor { | |||
168 | } | 176 | } |
169 | } | 177 | } |
170 | 178 | ||
171 | pub fn as_generic_def(self) -> Option<crate::generics::GenericDef> { | 179 | pub fn as_generic_def(self) -> Option<GenericDefId> { |
172 | match self { | 180 | match self { |
173 | TypeCtor::Bool | 181 | TypeCtor::Bool |
174 | | TypeCtor::Char | 182 | | TypeCtor::Char |
@@ -185,7 +193,7 @@ impl TypeCtor { | |||
185 | | TypeCtor::Closure { .. } => None, | 193 | | TypeCtor::Closure { .. } => None, |
186 | TypeCtor::Adt(adt) => Some(adt.into()), | 194 | TypeCtor::Adt(adt) => Some(adt.into()), |
187 | TypeCtor::FnDef(callable) => Some(callable.into()), | 195 | TypeCtor::FnDef(callable) => Some(callable.into()), |
188 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), | 196 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.id.into()), |
189 | } | 197 | } |
190 | } | 198 | } |
191 | } | 199 | } |
@@ -348,8 +356,9 @@ impl Substs { | |||
348 | ) | 356 | ) |
349 | } | 357 | } |
350 | 358 | ||
351 | pub fn build_for_def(db: &impl HirDatabase, def: impl HasGenericParams) -> SubstsBuilder { | 359 | pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { |
352 | let params = def.generic_params(db); | <