diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/assists/add_explicit_type.rs | 13 | ||||
-rw-r--r-- | crates/ra_assists/src/assists/add_new.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/assists/fill_match_arms.rs | 7 | ||||
-rw-r--r-- | crates/ra_assists/src/test_db.rs | 3 | ||||
-rw-r--r-- | crates/ra_batch/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_batch/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_cli/Cargo.toml | 3 | ||||
-rw-r--r-- | crates/ra_cli/src/analysis_bench.rs | 6 | ||||
-rw-r--r-- | crates/ra_cli/src/analysis_stats.rs | 14 | ||||
-rw-r--r-- | crates/ra_cli/src/main.rs | 3 | ||||
-rw-r--r-- | crates/ra_cli/src/progress_report.rs | 120 | ||||
-rw-r--r-- | crates/ra_db/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/Cargo.toml | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 449 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 132 | ||||
-rw-r--r-- | crates/ra_hir/src/diagnostics.rs | 86 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 104 | ||||
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 26 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 113 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 1092 | ||||
-rw-r--r-- | crates/ra_hir/src/util.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 43 | ||||
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 60 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/docs.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/generics.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lang_item.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 57 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 36 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/path_resolution.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/test_db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/lib.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/test_db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/Cargo.toml | 32 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/autoderef.rs (renamed from crates/ra_hir/src/ty/autoderef.rs) | 55 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/db.rs | 119 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics.rs | 91 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/display.rs (renamed from crates/ra_hir/src/ty/display.rs) | 0 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs (renamed from crates/ra_hir/src/expr.rs) | 43 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs (renamed from crates/ra_hir/src/ty/infer.rs) | 161 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs (renamed from crates/ra_hir/src/ty/infer/coerce.rs) | 37 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs (renamed from crates/ra_hir/src/ty/infer/expr.rs) | 117 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/pat.rs (renamed from crates/ra_hir/src/ty/infer/pat.rs) | 31 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/path.rs (renamed from crates/ra_hir/src/ty/infer/path.rs) | 98 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/unify.rs (renamed from crates/ra_hir/src/ty/infer/unify.rs) | 8 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 1138 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs (renamed from crates/ra_hir/src/ty/lower.rs) | 444 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/marks.rs (renamed from crates/ra_hir/src/marks.rs) | 0 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs (renamed from crates/ra_hir/src/ty/method_resolution.rs) | 246 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/op.rs (renamed from crates/ra_hir/src/ty/op.rs) | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/primitive.rs (renamed from crates/ra_hir/src/ty/primitive.rs) | 41 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/test_db.rs (renamed from crates/ra_hir/src/test_db.rs) | 85 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs (renamed from crates/ra_hir/src/ty/tests.rs) | 113 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs (renamed from crates/ra_hir/src/ty/tests/coercion.rs) | 0 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/never_type.rs (renamed from crates/ra_hir/src/ty/tests/never_type.rs) | 0 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits.rs (renamed from crates/ra_hir/src/ty/traits.rs) | 30 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs (renamed from crates/ra_hir/src/ty/traits/chalk.rs) | 202 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/utils.rs | 84 | ||||
-rw-r--r-- | crates/ra_ide/Cargo.toml (renamed from crates/ra_ide_api/Cargo.toml) | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/assists.rs (renamed from crates/ra_ide_api/src/assists.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/call_info.rs (renamed from crates/ra_ide_api/src/call_info.rs) | 24 | ||||
-rw-r--r-- | crates/ra_ide/src/change.rs (renamed from crates/ra_ide_api/src/change.rs) | 5 | ||||
-rw-r--r-- | crates/ra_ide/src/completion.rs (renamed from crates/ra_ide_api/src/completion.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_dot.rs (renamed from crates/ra_ide_api/src/completion/complete_dot.rs) | 36 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_fn_param.rs (renamed from crates/ra_ide_api/src/completion/complete_fn_param.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_keyword.rs (renamed from crates/ra_ide_api/src/completion/complete_keyword.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_macro_in_item_position.rs (renamed from crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_path.rs (renamed from crates/ra_ide_api/src/completion/complete_path.rs) | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_pattern.rs (renamed from crates/ra_ide_api/src/completion/complete_pattern.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_postfix.rs (renamed from crates/ra_ide_api/src/completion/complete_postfix.rs) | 16 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_record_literal.rs (renamed from crates/ra_ide_api/src/completion/complete_record_literal.rs) | 7 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_record_pattern.rs (renamed from crates/ra_ide_api/src/completion/complete_record_pattern.rs) | 7 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_scope.rs (renamed from crates/ra_ide_api/src/completion/complete_scope.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_snippet.rs (renamed from crates/ra_ide_api/src/completion/complete_snippet.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/completion_context.rs (renamed from crates/ra_ide_api/src/completion/completion_context.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/completion_item.rs (renamed from crates/ra_ide_api/src/completion/completion_item.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs (renamed from crates/ra_ide_api/src/completion/presentation.rs) | 44 | ||||
-rw-r--r-- | crates/ra_ide/src/db.rs (renamed from crates/ra_ide_api/src/db.rs) | 3 | ||||
-rw-r--r-- | crates/ra_ide/src/diagnostics.rs (renamed from crates/ra_ide_api/src/diagnostics.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/display.rs (renamed from crates/ra_ide_api/src/display.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/display/function_signature.rs (renamed from crates/ra_ide_api/src/display/function_signature.rs) | 7 | ||||
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs (renamed from crates/ra_ide_api/src/display/navigation_target.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/display/short_label.rs (renamed from crates/ra_ide_api/src/display/short_label.rs) | 6 | ||||
-rw-r--r-- | crates/ra_ide/src/display/structure.rs (renamed from crates/ra_ide_api/src/display/structure.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/expand.rs (renamed from crates/ra_ide_api/src/expand.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/expand_macro.rs (renamed from crates/ra_ide_api/src/expand_macro.rs) | 23 | ||||
-rw-r--r-- | crates/ra_ide/src/extend_selection.rs (renamed from crates/ra_ide_api/src/extend_selection.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/feature_flags.rs (renamed from crates/ra_ide_api/src/feature_flags.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/folding_ranges.rs (renamed from crates/ra_ide_api/src/folding_ranges.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs (renamed from crates/ra_ide_api/src/goto_definition.rs) | 23 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_type_definition.rs (renamed from crates/ra_ide_api/src/goto_type_definition.rs) | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs (renamed from crates/ra_ide_api/src/hover.rs) | 95 | ||||
-rw-r--r-- | crates/ra_ide/src/impls.rs (renamed from crates/ra_ide_api/src/impls.rs) | 29 | ||||
-rw-r--r-- | crates/ra_ide/src/inlay_hints.rs (renamed from crates/ra_ide_api/src/inlay_hints.rs) | 23 | ||||
-rw-r--r-- | crates/ra_ide/src/join_lines.rs (renamed from crates/ra_ide_api/src/join_lines.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/lib.rs (renamed from crates/ra_ide_api/src/lib.rs) | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/line_index.rs (renamed from crates/ra_ide_api/src/line_index.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/line_index_utils.rs (renamed from crates/ra_ide_api/src/line_index_utils.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/marks.rs (renamed from crates/ra_ide_api/src/marks.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/matching_brace.rs (renamed from crates/ra_ide_api/src/matching_brace.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/mock_analysis.rs (renamed from crates/ra_ide_api/src/mock_analysis.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/parent_module.rs (renamed from crates/ra_ide_api/src/parent_module.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/references.rs (renamed from crates/ra_ide_api/src/references.rs) | 5 | ||||
-rw-r--r-- | crates/ra_ide/src/references/classify.rs (renamed from crates/ra_ide_api/src/references/classify.rs) | 5 | ||||
-rw-r--r-- | crates/ra_ide/src/references/name_definition.rs (renamed from crates/ra_ide_api/src/references/name_definition.rs) | 7 | ||||
-rw-r--r-- | crates/ra_ide/src/references/rename.rs (renamed from crates/ra_ide_api/src/references/rename.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/references/search_scope.rs (renamed from crates/ra_ide_api/src/references/search_scope.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/runnables.rs (renamed from crates/ra_ide_api/src/runnables.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlighting.html (renamed from crates/ra_ide_api/src/snapshots/highlighting.html) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/rainbow_highlighting.html (renamed from crates/ra_ide_api/src/snapshots/rainbow_highlighting.html) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/source_change.rs (renamed from crates/ra_ide_api/src/source_change.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/status.rs (renamed from crates/ra_ide_api/src/status.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/symbol_index.rs (renamed from crates/ra_ide_api/src/symbol_index.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs (renamed from crates/ra_ide_api/src/syntax_highlighting.rs) | 14 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_tree.rs (renamed from crates/ra_ide_api/src/syntax_tree.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/test_utils.rs (renamed from crates/ra_ide_api/src/test_utils.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/typing.rs (renamed from crates/ra_ide_api/src/typing.rs) | 0 | ||||
-rw-r--r-- | crates/ra_ide/src/wasm_shims.rs (renamed from crates/ra_ide_api/src/wasm_shims.rs) | 0 | ||||
-rw-r--r-- | crates/ra_lsp_server/Cargo.toml | 4 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/cargo_target_spec.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/subscriptions.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/world.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items.rs | 10 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/adt.rs (renamed from crates/ra_parser/src/grammar/items/nominal.rs) | 23 | ||||
-rw-r--r-- | crates/ra_parser/src/syntax_kind/generated.rs | 1 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/extensions.rs | 11 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 54 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 17 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt | 4 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt | 2 |
143 files changed, 3393 insertions, 2873 deletions
diff --git a/crates/ra_assists/src/assists/add_explicit_type.rs b/crates/ra_assists/src/assists/add_explicit_type.rs index 562a09685..eeb4ff39f 100644 --- a/crates/ra_assists/src/assists/add_explicit_type.rs +++ b/crates/ra_assists/src/assists/add_explicit_type.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use hir::{db::HirDatabase, HirDisplay, Ty}; | 1 | use hir::{db::HirDatabase, HirDisplay}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | ast::{self, AstNode, LetStmt, NameOwner}, | 3 | ast::{self, AstNode, LetStmt, NameOwner}, |
4 | T, | 4 | T, |
@@ -43,7 +43,7 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx<impl HirDatabase>) -> Option<Assi | |||
43 | let analyzer = ctx.source_analyzer(stmt.syntax(), None); | 43 | let analyzer = ctx.source_analyzer(stmt.syntax(), None); |
44 | let ty = analyzer.type_of(db, &expr)?; | 44 | let ty = analyzer.type_of(db, &expr)?; |
45 | // Assist not applicable if the type is unknown | 45 | // Assist not applicable if the type is unknown |
46 | if is_unknown(&ty) { | 46 | if ty.contains_unknown() { |
47 | return None; | 47 | return None; |
48 | } | 48 | } |
49 | 49 | ||
@@ -53,15 +53,6 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx<impl HirDatabase>) -> Option<Assi | |||
53 | }) | 53 | }) |
54 | } | 54 | } |
55 | 55 | ||
56 | /// Returns true if any type parameter is unknown | ||
57 | fn is_unknown(ty: &Ty) -> bool { | ||
58 | match ty { | ||
59 | Ty::Unknown => true, | ||
60 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(is_unknown), | ||
61 | _ => false, | ||
62 | } | ||
63 | } | ||
64 | |||
65 | #[cfg(test)] | 56 | #[cfg(test)] |
66 | mod tests { | 57 | mod tests { |
67 | use super::*; | 58 | use super::*; |
diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs index ee8bff346..8f68bd5fb 100644 --- a/crates/ra_assists/src/assists/add_new.rs +++ b/crates/ra_assists/src/assists/add_new.rs | |||
@@ -35,8 +35,8 @@ pub(crate) fn add_new(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
35 | let strukt = ctx.find_node_at_offset::<ast::StructDef>()?; | 35 | let strukt = ctx.find_node_at_offset::<ast::StructDef>()?; |
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() { |
39 | (StructKind::Record(named), false) => named, | 39 | StructKind::Record(named) => named, |
40 | _ => return None, | 40 | _ => return None, |
41 | }; | 41 | }; |
42 | 42 | ||
diff --git a/crates/ra_assists/src/assists/fill_match_arms.rs b/crates/ra_assists/src/assists/fill_match_arms.rs index 8482897c5..b75bd44eb 100644 --- a/crates/ra_assists/src/assists/fill_match_arms.rs +++ b/crates/ra_assists/src/assists/fill_match_arms.rs | |||
@@ -83,10 +83,11 @@ fn resolve_enum_def( | |||
83 | ) -> Option<ast::EnumDef> { | 83 | ) -> Option<ast::EnumDef> { |
84 | let expr_ty = analyzer.type_of(db, &expr)?; | 84 | let expr_ty = analyzer.type_of(db, &expr)?; |
85 | 85 | ||
86 | analyzer.autoderef(db, expr_ty).find_map(|ty| match ty.as_adt() { | 86 | let res = expr_ty.autoderef(db).find_map(|ty| match ty.as_adt() { |
87 | Some((Adt::Enum(e), _)) => Some(e.source(db).value), | 87 | Some(Adt::Enum(e)) => Some(e.source(db).value), |
88 | _ => None, | 88 | _ => None, |
89 | }) | 89 | }); |
90 | res | ||
90 | } | 91 | } |
91 | 92 | ||
92 | fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> { | 93 | fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> { |
diff --git a/crates/ra_assists/src/test_db.rs b/crates/ra_assists/src/test_db.rs index 5f96c974b..523259fd4 100644 --- a/crates/ra_assists/src/test_db.rs +++ b/crates/ra_assists/src/test_db.rs | |||
@@ -21,6 +21,9 @@ impl salsa::Database for TestDB { | |||
21 | fn salsa_runtime(&self) -> &salsa::Runtime<Self> { | 21 | fn salsa_runtime(&self) -> &salsa::Runtime<Self> { |
22 | &self.runtime | 22 | &self.runtime |
23 | } | 23 | } |
24 | fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> { | ||
25 | &mut self.runtime | ||
26 | } | ||
24 | } | 27 | } |
25 | 28 | ||
26 | impl std::panic::RefUnwindSafe for TestDB {} | 29 | impl std::panic::RefUnwindSafe for TestDB {} |
diff --git a/crates/ra_batch/Cargo.toml b/crates/ra_batch/Cargo.toml index 35626d77d..3bf351fe3 100644 --- a/crates/ra_batch/Cargo.toml +++ b/crates/ra_batch/Cargo.toml | |||
@@ -15,6 +15,6 @@ crossbeam-channel = "0.4.0" | |||
15 | ra_vfs = "0.5.0" | 15 | ra_vfs = "0.5.0" |
16 | ra_vfs_glob = { path = "../ra_vfs_glob" } | 16 | ra_vfs_glob = { path = "../ra_vfs_glob" } |
17 | ra_db = { path = "../ra_db" } | 17 | ra_db = { path = "../ra_db" } |
18 | ra_ide_api = { path = "../ra_ide_api" } | 18 | ra_ide = { path = "../ra_ide" } |
19 | ra_hir = { path = "../ra_hir" } | 19 | ra_hir = { path = "../ra_hir" } |
20 | ra_project_model = { path = "../ra_project_model" } | 20 | ra_project_model = { path = "../ra_project_model" } |
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index cb389eb26..2c9645c00 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs | |||
@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap; | |||
6 | 6 | ||
7 | use crossbeam_channel::{unbounded, Receiver}; | 7 | use crossbeam_channel::{unbounded, Receiver}; |
8 | use ra_db::{CrateGraph, FileId, SourceRootId}; | 8 | use ra_db::{CrateGraph, FileId, SourceRootId}; |
9 | use ra_ide_api::{AnalysisChange, AnalysisHost, FeatureFlags}; | 9 | use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags}; |
10 | use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; | 10 | use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; |
11 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; | 11 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; |
12 | use ra_vfs_glob::RustPackageFilterBuilder; | 12 | use ra_vfs_glob::RustPackageFilterBuilder; |
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml index c9d3bdb77..c7e0d0f0f 100644 --- a/crates/ra_cli/Cargo.toml +++ b/crates/ra_cli/Cargo.toml | |||
@@ -8,10 +8,9 @@ publish = false | |||
8 | [dependencies] | 8 | [dependencies] |
9 | pico-args = "0.3.0" | 9 | pico-args = "0.3.0" |
10 | flexi_logger = "0.14.0" | 10 | flexi_logger = "0.14.0" |
11 | indicatif = "0.13.0" | ||
12 | 11 | ||
13 | ra_syntax = { path = "../ra_syntax" } | 12 | ra_syntax = { path = "../ra_syntax" } |
14 | ra_ide_api = { path = "../ra_ide_api" } | 13 | ra_ide = { path = "../ra_ide" } |
15 | ra_batch = { path = "../ra_batch" } | 14 | ra_batch = { path = "../ra_batch" } |
16 | ra_hir = { path = "../ra_hir" } | 15 | ra_hir = { path = "../ra_hir" } |
17 | ra_db = { path = "../ra_db" } | 16 | ra_db = { path = "../ra_db" } |
diff --git a/crates/ra_cli/src/analysis_bench.rs b/crates/ra_cli/src/analysis_bench.rs index 8bbe5d9e8..5485a38ff 100644 --- a/crates/ra_cli/src/analysis_bench.rs +++ b/crates/ra_cli/src/analysis_bench.rs | |||
@@ -10,7 +10,7 @@ use ra_db::{ | |||
10 | salsa::{Database, Durability}, | 10 | salsa::{Database, Durability}, |
11 | FileId, SourceDatabaseExt, | 11 | FileId, SourceDatabaseExt, |
12 | }; | 12 | }; |
13 | use ra_ide_api::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol}; | 13 | use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol}; |
14 | 14 | ||
15 | use crate::Result; | 15 | use crate::Result; |
16 | 16 | ||
@@ -91,7 +91,7 @@ fn do_work<F: Fn(&Analysis) -> T, T>(host: &mut AnalysisHost, file_id: FileId, w | |||
91 | { | 91 | { |
92 | let start = Instant::now(); | 92 | let start = Instant::now(); |
93 | eprint!("trivial change: "); | 93 | eprint!("trivial change: "); |
94 | host.raw_database().salsa_runtime().synthetic_write(Durability::LOW); | 94 | host.raw_database_mut().salsa_runtime_mut().synthetic_write(Durability::LOW); |
95 | work(&host.analysis()); | 95 | work(&host.analysis()); |
96 | eprintln!("{:?}", start.elapsed()); | 96 | eprintln!("{:?}", start.elapsed()); |
97 | } | 97 | } |
@@ -111,7 +111,7 @@ fn do_work<F: Fn(&Analysis) -> T, T>(host: &mut AnalysisHost, file_id: FileId, w | |||
111 | { | 111 | { |
112 | let start = Instant::now(); | 112 | let start = Instant::now(); |
113 | eprint!("const change: "); | 113 | eprint!("const change: "); |
114 | host.raw_database().salsa_runtime().synthetic_write(Durability::HIGH); | 114 | host.raw_database_mut().salsa_runtime_mut().synthetic_write(Durability::HIGH); |
115 | let res = work(&host.analysis()); | 115 | let res = work(&host.analysis()); |
116 | eprintln!("{:?}", start.elapsed()); | 116 | eprintln!("{:?}", start.elapsed()); |
117 | res | 117 | res |
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index c4eb28245..9b1802a5f 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -6,7 +6,7 @@ use ra_db::SourceDatabaseExt; | |||
6 | use ra_hir::{AssocItem, Crate, 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::{progress_report::ProgressReport, Result, Verbosity}; |
10 | 10 | ||
11 | pub fn run( | 11 | pub fn run( |
12 | verbosity: Verbosity, | 12 | verbosity: Verbosity, |
@@ -75,17 +75,11 @@ pub fn run( | |||
75 | println!("Item Collection: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); | 75 | println!("Item Collection: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); |
76 | 76 | ||
77 | let inference_time = Instant::now(); | 77 | let inference_time = Instant::now(); |
78 | let bar = match verbosity { | 78 | let mut bar = match verbosity { |
79 | Verbosity::Verbose | Verbosity::Normal => indicatif::ProgressBar::with_draw_target( | 79 | Verbosity::Verbose | Verbosity::Normal => ProgressReport::new(funcs.len() as u64), |
80 | funcs.len() as u64, | 80 | Verbosity::Quiet => ProgressReport::hidden(), |
81 | indicatif::ProgressDrawTarget::stderr_nohz(), | ||
82 | ), | ||
83 | Verbosity::Quiet => indicatif::ProgressBar::hidden(), | ||
84 | }; | 81 | }; |
85 | 82 | ||
86 | bar.set_style( | ||
87 | indicatif::ProgressStyle::default_bar().template("{wide_bar} {pos}/{len}\n{msg}"), | ||
88 | ); | ||
89 | bar.tick(); | 83 | bar.tick(); |
90 | let mut num_exprs = 0; | 84 | let mut num_exprs = 0; |
91 | let mut num_exprs_unknown = 0; | 85 | let mut num_exprs_unknown = 0; |
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index a31fd5d6a..fe847e611 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs | |||
@@ -3,12 +3,13 @@ | |||
3 | mod analysis_stats; | 3 | mod analysis_stats; |
4 | mod analysis_bench; | 4 | mod analysis_bench; |
5 | mod help; | 5 | mod help; |
6 | mod progress_report; | ||
6 | 7 | ||
7 | use std::{error::Error, fmt::Write, io::Read}; | 8 | use std::{error::Error, fmt::Write, io::Read}; |
8 | 9 | ||
9 | use flexi_logger::Logger; | 10 | use flexi_logger::Logger; |
10 | use pico_args::Arguments; | 11 | use pico_args::Arguments; |
11 | use ra_ide_api::{file_structure, Analysis}; | 12 | use ra_ide::{file_structure, Analysis}; |
12 | use ra_prof::profile; | 13 | use ra_prof::profile; |
13 | use ra_syntax::{AstNode, SourceFile}; | 14 | use ra_syntax::{AstNode, SourceFile}; |
14 | 15 | ||
diff --git a/crates/ra_cli/src/progress_report.rs b/crates/ra_cli/src/progress_report.rs new file mode 100644 index 000000000..31867a1e9 --- /dev/null +++ b/crates/ra_cli/src/progress_report.rs | |||
@@ -0,0 +1,120 @@ | |||
1 | //! A simple progress bar | ||
2 | //! | ||
3 | //! A single thread non-optimized progress bar | ||
4 | use std::io::Write; | ||
5 | |||
6 | /// A Simple ASCII Progress Bar | ||
7 | pub struct ProgressReport { | ||
8 | curr: f32, | ||
9 | text: String, | ||
10 | hidden: bool, | ||
11 | |||
12 | len: u64, | ||
13 | pos: u64, | ||
14 | msg: String, | ||
15 | } | ||
16 | |||
17 | impl ProgressReport { | ||
18 | pub fn new(len: u64) -> ProgressReport { | ||
19 | ProgressReport { | ||
20 | curr: 0.0, | ||
21 | text: String::new(), | ||
22 | hidden: false, | ||
23 | len, | ||
24 | pos: 0, | ||
25 | msg: String::new(), | ||
26 | } | ||
27 | } | ||
28 | |||
29 | pub fn hidden() -> ProgressReport { | ||
30 | ProgressReport { | ||
31 | curr: 0.0, | ||
32 | text: String::new(), | ||
33 | hidden: true, | ||
34 | len: 0, | ||
35 | pos: 0, | ||
36 | msg: String::new(), | ||
37 | } | ||
38 | } | ||
39 | |||
40 | pub fn set_message(&mut self, msg: &str) { | ||
41 | self.msg = msg.to_string(); | ||
42 | self.tick(); | ||
43 | } | ||
44 | |||
45 | pub fn println<I: Into<String>>(&mut self, msg: I) { | ||
46 | self.clear(); | ||
47 | println!("{}", msg.into()); | ||
48 | self.tick(); | ||
49 | } | ||
50 | |||
51 | pub fn inc(&mut self, delta: u64) { | ||
52 | self.pos += delta; | ||
53 | if self.len == 0 { | ||
54 | self.set_value(0.0) | ||
55 | } else { | ||
56 | self.set_value((self.pos as f32) / (self.len as f32)) | ||
57 | } | ||
58 | self.tick(); | ||
59 | } | ||
60 | |||
61 | pub fn finish_and_clear(&mut self) { | ||
62 | self.clear(); | ||
63 | } | ||
64 | |||
65 | pub fn tick(&mut self) { | ||
66 | if self.hidden { | ||
67 | return; | ||
68 | } | ||
69 | let percent = (self.curr * 100.0) as u32; | ||
70 | let text = format!("{}/{} {:3>}% {}", self.pos, self.len, percent, self.msg); | ||
71 | self.update_text(&text); | ||
72 | } | ||
73 | |||
74 | fn update_text(&mut self, text: &str) { | ||
75 | // Get length of common portion | ||
76 | let mut common_prefix_length = 0; | ||
77 | let common_length = usize::min(self.text.len(), text.len()); | ||
78 | |||
79 | while common_prefix_length < common_length | ||
80 | && text.chars().nth(common_prefix_length).unwrap() | ||
81 | == self.text.chars().nth(common_prefix_length).unwrap() | ||
82 | { | ||
83 | common_prefix_length += 1; | ||
84 | } | ||
85 | |||
86 | // Backtrack to the first differing character | ||
87 | let mut output = String::new(); | ||
88 | output += &'\x08'.to_string().repeat(self.text.len() - common_prefix_length); | ||
89 | // Output new suffix | ||
90 | output += &text[common_prefix_length..text.len()]; | ||
91 | |||
92 | // If the new text is shorter than the old one: delete overlapping characters | ||
93 | if let Some(overlap_count) = self.text.len().checked_sub(text.len()) { | ||
94 | if overlap_count > 0 { | ||
95 | output += &" ".repeat(overlap_count); | ||
96 | output += &"\x08".repeat(overlap_count); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | let _ = std::io::stdout().write(output.as_bytes()); | ||
101 | let _ = std::io::stdout().flush(); | ||
102 | self.text = text.to_string(); | ||
103 | } | ||
104 | |||
105 | fn set_value(&mut self, value: f32) { | ||
106 | self.curr = f32::max(0.0, f32::min(1.0, value)); | ||
107 | } | ||
108 | |||
109 | fn clear(&mut self) { | ||
110 | if self.hidden { | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | // Fill all last text to space and return the cursor | ||
115 | let spaces = " ".repeat(self.text.len()); | ||
116 | let backspaces = "\x08".repeat(self.text.len()); | ||
117 | print!("{}{}{}", backspaces, spaces, backspaces); | ||
118 | self.text = String::new(); | ||
119 | } | ||
120 | } | ||
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml index 4ec09b6d9..7afa5d8fc 100644 --- a/crates/ra_db/Cargo.toml +++ b/crates/ra_db/Cargo.toml | |||
@@ -8,7 +8,7 @@ authors = ["rust-analyzer developers"] | |||
8 | doctest = false | 8 | doctest = false |
9 | 9 | ||
10 | [dependencies] | 10 | [dependencies] |
11 | salsa = "0.13.0" | 11 | salsa = "0.14.1" |
12 | relative-path = "1.0.0" | 12 | relative-path = "1.0.0" |
13 | rustc-hash = "1.0" | 13 | rustc-hash = "1.0" |
14 | 14 | ||
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index e8852531b..21341b769 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api. | 1 | //! ra_db defines basic database traits. The concrete DB is defined by ra_ide. |
2 | mod cancellation; | 2 | mod cancellation; |
3 | mod input; | 3 | mod input; |
4 | pub mod fixture; | 4 | pub mod fixture; |
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 42ddfecc9..e79361e7c 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml | |||
@@ -8,28 +8,11 @@ authors = ["rust-analyzer developers"] | |||
8 | doctest = false | 8 | doctest = false |
9 | 9 | ||
10 | [dependencies] | 10 | [dependencies] |
11 | arrayvec = "0.5.1" | ||
12 | log = "0.4.5" | 11 | log = "0.4.5" |
13 | rustc-hash = "1.0" | 12 | rustc-hash = "1.0" |
14 | parking_lot = "0.9.0" | ||
15 | ena = "0.13" | ||
16 | once_cell = "1.0.1" | ||
17 | 13 | ||
18 | ra_syntax = { path = "../ra_syntax" } | 14 | ra_syntax = { path = "../ra_syntax" } |
19 | ra_arena = { path = "../ra_arena" } | ||
20 | ra_cfg = { path = "../ra_cfg" } | ||
21 | ra_db = { path = "../ra_db" } | 15 | ra_db = { path = "../ra_db" } |
22 | mbe = { path = "../ra_mbe", package = "ra_mbe" } | ||
23 | tt = { path = "../ra_tt", package = "ra_tt" } | ||
24 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } | 16 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } |
25 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | 17 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } |
26 | test_utils = { path = "../test_utils" } | 18 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } |
27 | ra_prof = { path = "../ra_prof" } | ||
28 | |||
29 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } | ||
30 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } | ||
31 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } | ||
32 | lalrpop-intern = "0.15.1" | ||
33 | |||
34 | [dev-dependencies] | ||
35 | insta = "0.12.0" | ||
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 3f44a50c4..38d66c2a7 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -6,28 +6,31 @@ use std::sync::Arc; | |||
6 | 6 | ||
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | adt::VariantData, | 8 | adt::VariantData, |
9 | body::{Body, BodySourceMap}, | ||
9 | builtin_type::BuiltinType, | 10 | builtin_type::BuiltinType, |
10 | docs::Documentation, | 11 | docs::Documentation, |
12 | expr::{BindingAnnotation, Pat, PatId}, | ||
11 | per_ns::PerNs, | 13 | per_ns::PerNs, |
12 | resolver::{HasResolver, TypeNs}, | 14 | resolver::HasResolver, |
13 | type_ref::TypeRef, | 15 | type_ref::{Mutability, TypeRef}, |
14 | AstItemDef, ConstId, ContainerId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, | 16 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, |
15 | LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, | 17 | HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, |
16 | TraitId, TypeAliasId, UnionId, | 18 | Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, |
17 | }; | 19 | }; |
18 | use hir_expand::{ | 20 | use hir_expand::{ |
19 | diagnostics::DiagnosticSink, | 21 | diagnostics::DiagnosticSink, |
20 | name::{self, AsName}, | 22 | name::{self, AsName}, |
21 | AstId, MacroDefId, | 23 | AstId, MacroDefId, |
22 | }; | 24 | }; |
25 | use hir_ty::expr::ExprValidator; | ||
23 | use ra_db::{CrateId, Edition, FileId, FilePosition}; | 26 | use ra_db::{CrateId, Edition, FileId, FilePosition}; |
24 | use ra_syntax::{ast, AstNode, SyntaxNode}; | 27 | use ra_syntax::{ast, AstNode, SyntaxNode}; |
25 | 28 | ||
26 | use crate::{ | 29 | use crate::{ |
27 | db::{DefDatabase, HirDatabase}, | 30 | db::{DefDatabase, HirDatabase}, |
28 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, | 31 | ty::display::HirFormatter, |
29 | ty::{InferenceResult, Namespace, TraitRef}, | 32 | ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk}, |
30 | Either, Name, Source, Ty, | 33 | CallableDef, Either, HirDisplay, Name, Source, |
31 | }; | 34 | }; |
32 | 35 | ||
33 | /// hir::Crate describes a single crate. It's the main interface with which | 36 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -168,15 +171,15 @@ pub use hir_def::attr::Attrs; | |||
168 | 171 | ||
169 | impl Module { | 172 | impl Module { |
170 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 173 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
171 | Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } | 174 | Module { id: ModuleId { krate: krate.crate_id, local_id: crate_module_id } } |
172 | } | 175 | } |
173 | 176 | ||
174 | /// Name of this module. | 177 | /// Name of this module. |
175 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 178 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
176 | let def_map = db.crate_def_map(self.id.krate); | 179 | let def_map = db.crate_def_map(self.id.krate); |
177 | let parent = def_map[self.id.module_id].parent?; | 180 | let parent = def_map[self.id.local_id].parent?; |
178 | def_map[parent].children.iter().find_map(|(name, module_id)| { | 181 | def_map[parent].children.iter().find_map(|(name, module_id)| { |
179 | if *module_id == self.id.module_id { | 182 | if *module_id == self.id.local_id { |
180 | Some(name.clone()) | 183 | Some(name.clone()) |
181 | } else { | 184 | } else { |
182 | None | 185 | None |
@@ -200,14 +203,14 @@ impl Module { | |||
200 | /// Finds a child module with the specified name. | 203 | /// Finds a child module with the specified name. |
201 | pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> { | 204 | pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> { |
202 | let def_map = db.crate_def_map(self.id.krate); | 205 | let def_map = db.crate_def_map(self.id.krate); |
203 | let child_id = def_map[self.id.module_id].children.get(name)?; | 206 | let child_id = def_map[self.id.local_id].children.get(name)?; |
204 | Some(self.with_module_id(*child_id)) | 207 | Some(self.with_module_id(*child_id)) |
205 | } | 208 | } |
206 | 209 | ||
207 | /// Iterates over all child modules. | 210 | /// Iterates over all child modules. |
208 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { | 211 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { |
209 | let def_map = db.crate_def_map(self.id.krate); | 212 | let def_map = db.crate_def_map(self.id.krate); |
210 | let children = def_map[self.id.module_id] | 213 | let children = def_map[self.id.local_id] |
211 | .children | 214 | .children |
212 | .iter() | 215 | .iter() |
213 | .map(|(_, module_id)| self.with_module_id(*module_id)) | 216 | .map(|(_, module_id)| self.with_module_id(*module_id)) |
@@ -218,7 +221,7 @@ impl Module { | |||
218 | /// Finds a parent module. | 221 | /// Finds a parent module. |
219 | pub fn parent(self, db: &impl DefDatabase) -> Option<Module> { | 222 | pub fn parent(self, db: &impl DefDatabase) -> Option<Module> { |
220 | let def_map = db.crate_def_map(self.id.krate); | 223 | let def_map = db.crate_def_map(self.id.krate); |
221 | let parent_id = def_map[self.id.module_id].parent?; | 224 | let parent_id = def_map[self.id.local_id].parent?; |
222 | Some(self.with_module_id(parent_id)) | 225 | Some(self.with_module_id(parent_id)) |
223 | } | 226 | } |
224 | 227 | ||
@@ -234,7 +237,7 @@ impl Module { | |||
234 | 237 | ||
235 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 238 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
236 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { | 239 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { |
237 | db.crate_def_map(self.id.krate)[self.id.module_id] | 240 | db.crate_def_map(self.id.krate)[self.id.local_id] |
238 | .scope | 241 | .scope |
239 | .entries() | 242 | .entries() |
240 | .map(|(name, res)| { | 243 | .map(|(name, res)| { |
@@ -244,7 +247,7 @@ impl Module { | |||
244 | } | 247 | } |
245 | 248 | ||
246 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 249 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
247 | db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.module_id, sink); | 250 | db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.local_id, sink); |
248 | for decl in self.declarations(db) { | 251 | for decl in self.declarations(db) { |
249 | match decl { | 252 | match decl { |
250 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), | 253 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), |
@@ -269,12 +272,12 @@ impl Module { | |||
269 | 272 | ||
270 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { | 273 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { |
271 | let def_map = db.crate_def_map(self.id.krate); | 274 | let def_map = db.crate_def_map(self.id.krate); |
272 | def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect() | 275 | def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect() |
273 | } | 276 | } |
274 | 277 | ||
275 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { | 278 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { |
276 | let def_map = db.crate_def_map(self.id.krate); | 279 | let def_map = db.crate_def_map(self.id.krate); |
277 | def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() | 280 | def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() |
278 | } | 281 | } |
279 | 282 | ||
280 | fn with_module_id(self, module_id: LocalModuleId) -> Module { | 283 | fn with_module_id(self, module_id: LocalModuleId) -> Module { |
@@ -320,14 +323,14 @@ pub struct Struct { | |||
320 | 323 | ||
321 | impl Struct { | 324 | impl Struct { |
322 | pub fn module(self, db: &impl DefDatabase) -> Module { | 325 | pub fn module(self, db: &impl DefDatabase) -> Module { |
323 | Module { id: self.id.0.module(db) } | 326 | Module { id: self.id.module(db) } |
324 | } | 327 | } |
325 | 328 | ||
326 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 329 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
327 | Some(self.module(db).krate()) | 330 | Some(self.module(db).krate()) |
328 | } | 331 | } |
329 | 332 | ||
330 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 333 | pub fn name(self, db: &impl DefDatabase) -> Name { |
331 | db.struct_data(self.id.into()).name.clone() | 334 | db.struct_data(self.id.into()).name.clone() |
332 | } | 335 | } |
333 | 336 | ||
@@ -349,12 +352,12 @@ impl Struct { | |||
349 | .map(|(id, _)| StructField { parent: self.into(), id }) | 352 | .map(|(id, _)| StructField { parent: self.into(), id }) |
350 | } | 353 | } |
351 | 354 | ||
352 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 355 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
353 | db.type_for_def(self.into(), Namespace::Types) | 356 | Type::from_def(db, self.id.module(db).krate, self.id) |
354 | } | 357 | } |
355 | 358 | ||
356 | pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { | 359 | pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { |
357 | db.type_for_def(self.into(), Namespace::Values) | 360 | db.value_ty(self.id.into()) |
358 | } | 361 | } |
359 | 362 | ||
360 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 363 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
@@ -368,16 +371,38 @@ pub struct Union { | |||
368 | } | 371 | } |
369 | 372 | ||
370 | impl Union { | 373 | impl Union { |
371 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 374 | pub fn name(self, db: &impl DefDatabase) -> Name { |
372 | db.struct_data(self.id.into()).name.clone() | 375 | db.union_data(self.id).name.clone() |
373 | } | 376 | } |
374 | 377 | ||
375 | pub fn module(self, db: &impl DefDatabase) -> Module { | 378 | pub fn module(self, db: &impl DefDatabase) -> Module { |
376 | Module { id: self.id.0.module(db) } | 379 | Module { id: self.id.module(db) } |
377 | } | 380 | } |
378 | 381 | ||
379 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 382 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
380 | db.type_for_def(self.into(), Namespace::Types) | 383 | Type::from_def(db, self.id.module(db).krate, self.id) |
384 | } | ||
385 | |||
386 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | ||
387 | db.union_data(self.id) | ||
388 | .variant_data | ||
389 | .fields() | ||
390 | .iter() | ||
391 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
392 | .collect() | ||
393 | } | ||
394 | |||
395 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
396 | db.union_data(self.id) | ||
397 | .variant_data | ||
398 | .fields() | ||
399 | .iter() | ||
400 | .find(|(_id, data)| data.name == *name) | ||
401 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
402 | } | ||
403 | |||
404 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | ||
405 | db.union_data(self.id).variant_data.clone() | ||
381 | } | 406 | } |
382 | } | 407 | } |
383 | 408 | ||
@@ -395,7 +420,7 @@ impl Enum { | |||
395 | Some(self.module(db).krate()) | 420 | Some(self.module(db).krate()) |
396 | } | 421 | } |
397 | 422 | ||
398 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 423 | pub fn name(self, db: &impl DefDatabase) -> Name { |
399 | db.enum_data(self.id).name.clone() | 424 | db.enum_data(self.id).name.clone() |
400 | } | 425 | } |
401 | 426 | ||
@@ -408,15 +433,12 @@ impl Enum { | |||
408 | } | 433 | } |
409 | 434 | ||
410 | pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> { | 435 | pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> { |
411 | db.enum_data(self.id) | 436 | let id = db.enum_data(self.id).variant(name)?; |
412 | .variants | 437 | Some(EnumVariant { parent: self, id }) |
413 | .iter() | ||
414 | .find(|(_id, data)| data.name.as_ref() == Some(name)) | ||
415 | .map(|(id, _)| EnumVariant { parent: self, id }) | ||
416 | } | 438 | } |
417 | 439 | ||
418 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 440 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
419 | db.type_for_def(self.into(), Namespace::Types) | 441 | Type::from_def(db, self.id.module(db).krate, self.id) |
420 | } | 442 | } |
421 | } | 443 | } |
422 | 444 | ||
@@ -434,7 +456,7 @@ impl EnumVariant { | |||
434 | self.parent | 456 | self.parent |
435 | } | 457 | } |
436 | 458 | ||
437 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 459 | pub fn name(self, db: &impl DefDatabase) -> Name { |
438 | db.enum_data(self.parent.id).variants[self.id].name.clone() | 460 | db.enum_data(self.parent.id).variants[self.id].name.clone() |
439 | } | 461 | } |
440 | 462 | ||
@@ -469,12 +491,13 @@ pub enum Adt { | |||
469 | impl_froms!(Adt: Struct, Union, Enum); | 491 | impl_froms!(Adt: Struct, Union, Enum); |
470 | 492 | ||
471 | impl Adt { | 493 | impl Adt { |
472 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 494 | pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool { |
473 | match self { | 495 | let subst = db.generic_defaults(self.into()); |
474 | Adt::Struct(it) => it.ty(db), | 496 | subst.iter().any(|ty| ty == &Ty::Unknown) |
475 | Adt::Union(it) => it.ty(db), | 497 | } |
476 | Adt::Enum(it) => it.ty(db), | 498 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
477 | } | 499 | let id = AdtId::from(self); |
500 | Type::from_def(db, id.module(db).krate, id) | ||
478 | } | 501 | } |
479 | 502 | ||
480 | pub fn module(self, db: &impl DefDatabase) -> Module { | 503 | pub fn module(self, db: &impl DefDatabase) -> Module { |
@@ -493,28 +516,24 @@ impl Adt { | |||
493 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 516 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
494 | pub enum VariantDef { | 517 | pub enum VariantDef { |
495 | Struct(Struct), | 518 | Struct(Struct), |
519 | Union(Union), | ||
496 | EnumVariant(EnumVariant), | 520 | EnumVariant(EnumVariant), |
497 | } | 521 | } |
498 | impl_froms!(VariantDef: Struct, EnumVariant); | 522 | impl_froms!(VariantDef: Struct, Union, EnumVariant); |
499 | 523 | ||
500 | impl VariantDef { | 524 | impl VariantDef { |
501 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | 525 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { |
502 | match self { | 526 | match self { |
503 | VariantDef::Struct(it) => it.fields(db), | 527 | VariantDef::Struct(it) => it.fields(db), |
528 | VariantDef::Union(it) => it.fields(db), | ||
504 | VariantDef::EnumVariant(it) => it.fields(db), | 529 | VariantDef::EnumVariant(it) => it.fields(db), |
505 | } | 530 | } |
506 | } | 531 | } |
507 | 532 | ||
508 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
509 | match self { | ||
510 | VariantDef::Struct(it) => it.field(db, name), | ||
511 | VariantDef::EnumVariant(it) => it.field(db, name), | ||
512 | } | ||
513 | } | ||
514 | |||
515 | pub fn module(self, db: &impl HirDatabase) -> Module { | 533 | pub fn module(self, db: &impl HirDatabase) -> Module { |
516 | match self { | 534 | match self { |
517 | VariantDef::Struct(it) => it.module(db), | 535 | VariantDef::Struct(it) => it.module(db), |
536 | VariantDef::Union(it) => it.module(db), | ||
518 | VariantDef::EnumVariant(it) => it.module(db), | 537 | VariantDef::EnumVariant(it) => it.module(db), |
519 | } | 538 | } |
520 | } | 539 | } |
@@ -522,6 +541,7 @@ impl VariantDef { | |||
522 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 541 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
523 | match self { | 542 | match self { |
524 | VariantDef::Struct(it) => it.variant_data(db), | 543 | VariantDef::Struct(it) => it.variant_data(db), |
544 | VariantDef::Union(it) => it.variant_data(db), | ||
525 | VariantDef::EnumVariant(it) => it.variant_data(db), | 545 | VariantDef::EnumVariant(it) => it.variant_data(db), |
526 | } | 546 | } |
527 | } | 547 | } |
@@ -538,14 +558,6 @@ pub enum DefWithBody { | |||
538 | impl_froms!(DefWithBody: Function, Const, Static); | 558 | impl_froms!(DefWithBody: Function, Const, Static); |
539 | 559 | ||
540 | impl DefWithBody { | 560 | impl DefWithBody { |
541 | pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> { | ||
542 | match self { | ||
543 | DefWithBody::Const(c) => c.krate(db), | ||
544 | DefWithBody::Function(f) => f.krate(db), | ||
545 | DefWithBody::Static(s) => s.krate(db), | ||
546 | } | ||
547 | } | ||
548 | |||
549 | pub fn module(self, db: &impl HirDatabase) -> Module { | 561 | pub fn module(self, db: &impl HirDatabase) -> Module { |
550 | match self { | 562 | match self { |
551 | DefWithBody::Const(c) => c.module(db), | 563 | DefWithBody::Const(c) => c.module(db), |
@@ -590,11 +602,11 @@ impl Function { | |||
590 | } | 602 | } |
591 | 603 | ||
592 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 604 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
593 | db.type_for_def(self.into(), Namespace::Values) | 605 | db.value_ty(self.id.into()) |
594 | } | 606 | } |
595 | 607 | ||
596 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 608 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
597 | db.infer(self.into()) | 609 | db.infer(self.id.into()) |
598 | } | 610 | } |
599 | 611 | ||
600 | /// The containing impl block, if this is a method. | 612 | /// The containing impl block, if this is a method. |
@@ -623,8 +635,8 @@ impl Function { | |||
623 | 635 | ||
624 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 636 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
625 | let infer = self.infer(db); | 637 | let infer = self.infer(db); |
626 | infer.add_diagnostics(db, self, sink); | 638 | infer.add_diagnostics(db, self.id, sink); |
627 | let mut validator = ExprValidator::new(self, infer, sink); | 639 | let mut validator = ExprValidator::new(self.id, infer, sink); |
628 | validator.validate_body(db); | 640 | validator.validate_body(db); |
629 | } | 641 | } |
630 | } | 642 | } |
@@ -648,7 +660,7 @@ impl Const { | |||
648 | } | 660 | } |
649 | 661 | ||
650 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 662 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
651 | db.infer(self.into()) | 663 | db.infer(self.id.into()) |
652 | } | 664 | } |
653 | 665 | ||
654 | /// The containing impl block, if this is a type alias. | 666 | /// The containing impl block, if this is a type alias. |
@@ -691,7 +703,7 @@ impl Static { | |||
691 | } | 703 | } |
692 | 704 | ||
693 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 705 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
694 | db.infer(self.into()) | 706 | db.infer(self.id.into()) |
695 | } | 707 | } |
696 | } | 708 | } |
697 | 709 | ||
@@ -705,73 +717,12 @@ impl Trait { | |||
705 | Module { id: self.id.module(db) } | 717 | Module { id: self.id.module(db) } |
706 | } | 718 | } |
707 | 719 | ||
708 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 720 | pub fn name(self, db: &impl DefDatabase) -> Name { |
709 | db.trait_data(self.id).name.clone() | 721 | db.trait_data(self.id).name.clone() |
710 | } | 722 | } |
711 | 723 | ||
712 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { | 724 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { |
713 | db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect() | 725 | db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() |
714 | } | ||
715 | |||
716 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | ||
717 | let resolver = self.id.resolver(db); | ||
718 | // returning the iterator directly doesn't easily work because of | ||
719 | // lifetime problems, but since there usually shouldn't be more than a | ||
720 | // few direct traits this should be fine (we could even use some kind of | ||
721 | // SmallVec if performance is a concern) | ||
722 | db.generic_params(self.id.into()) | ||
723 | .where_predicates | ||
724 | .iter() | ||
725 | .filter_map(|pred| match &pred.type_ref { | ||
726 | TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(), | ||
727 | _ => None, | ||
728 | }) | ||
729 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { | ||
730 | Some(TypeNs::TraitId(t)) => Some(t), | ||
731 | _ => None, | ||
732 | }) | ||
733 | .map(Trait::from) | ||
734 | .collect() | ||
735 | } | ||
736 | |||
737 | /// Returns an iterator over the whole super trait hierarchy (including the | ||
738 | /// trait itself). | ||
739 | pub fn all_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | ||
740 | // we need to take care a bit here to avoid infinite loops in case of cycles | ||
741 | // (i.e. if we have `trait A: B; trait B: A;`) | ||
742 | let mut result = vec![self]; | ||
743 | let mut i = 0; | ||
744 | while i < result.len() { | ||
745 | let t = result[i]; | ||
746 | // yeah this is quadratic, but trait hierarchies should be flat | ||
747 | // enough that this doesn't matter | ||
748 | for tt in t.direct_super_traits(db) { | ||
749 | if !result.contains(&tt) { | ||
750 | result.push(tt); | ||
751 | } | ||
752 | } | ||
753 | i += 1; | ||
754 | } | ||
755 | result | ||
756 | } | ||
757 | |||
758 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { | ||
759 | let trait_data = db.trait_data(self.id); | ||
760 | let res = | ||
761 | trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; | ||
762 | Some(res) | ||
763 | } | ||
764 | |||
765 | pub fn associated_type_by_name_including_super_traits( | ||
766 | self, | ||
767 | db: &impl HirDatabase, | ||
768 | name: &Name, | ||
769 | ) -> Option<TypeAlias> { | ||
770 | self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) | ||
771 | } | ||
772 | |||
773 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { | ||
774 | TraitRef::for_trait(db, self) | ||
775 | } | 726 | } |
776 | 727 | ||
777 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { | 728 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { |
@@ -785,6 +736,11 @@ pub struct TypeAlias { | |||
785 | } | 736 | } |
786 | 737 | ||
787 | impl TypeAlias { | 738 | impl TypeAlias { |
739 | pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool { | ||
740 | let subst = db.generic_defaults(self.id.into()); | ||
741 | subst.iter().any(|ty| ty == &Ty::Unknown) | ||
742 | } | ||
743 | |||
788 | pub fn module(self, db: &impl DefDatabase) -> Module { | 744 | pub fn module(self, db: &impl DefDatabase) -> Module { |
789 | Module { id: self.id.lookup(db).module(db) } | 745 | Module { id: self.id.lookup(db).module(db) } |
790 | } | 746 | } |
@@ -821,8 +777,8 @@ impl TypeAlias { | |||
821 | db.type_alias_data(self.id).type_ref.clone() | 777 | db.type_alias_data(self.id).type_ref.clone() |
822 | } | 778 | } |
823 | 779 | ||
824 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 780 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
825 | db.type_for_def(self.into(), Namespace::Types) | 781 | Type::from_def(db, self.id.lookup(db).module(db).krate, self.id) |
826 | } | 782 | } |
827 | 783 | ||
828 | pub fn name(self, db: &impl DefDatabase) -> Name { | 784 | pub fn name(self, db: &impl DefDatabase) -> Name { |
@@ -897,16 +853,6 @@ impl_froms!( | |||
897 | Const | 853 | Const |
898 | ); | 854 | ); |
899 | 855 | ||
900 | impl From<AssocItem> for GenericDef { | ||
901 | fn from(item: AssocItem) -> Self { | ||
902 | match item { | ||
903 | AssocItem::Function(f) => f.into(), | ||
904 | AssocItem::Const(c) => c.into(), | ||
905 | AssocItem::TypeAlias(t) => t.into(), | ||
906 | } | ||
907 | } | ||
908 | } | ||
909 | |||
910 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 856 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
911 | pub struct Local { | 857 | pub struct Local { |
912 | pub(crate) parent: DefWithBody, | 858 | pub(crate) parent: DefWithBody, |
@@ -945,9 +891,14 @@ impl Local { | |||
945 | self.parent.module(db) | 891 | self.parent.module(db) |
946 | } | 892 | } |
947 | 893 | ||
948 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 894 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
949 | let infer = db.infer(self.parent); | 895 | let def = DefWithBodyId::from(self.parent); |
950 | infer[self.pat_id].clone() | 896 | let infer = db.infer(def); |
897 | let ty = infer[self.pat_id].clone(); | ||
898 | let resolver = def.resolver(db); | ||
899 | let krate = def.module(db).krate; | ||
900 | let environment = TraitEnvironment::lower(db, &resolver); | ||
901 | Type { krate, ty: InEnvironment { value: ty, environment } } | ||
951 | } | 902 | } |
952 | 903 | ||
953 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | 904 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { |
@@ -960,7 +911,7 @@ impl Local { | |||
960 | 911 | ||
961 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 912 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
962 | pub struct GenericParam { | 913 | pub struct GenericParam { |
963 | pub(crate) parent: GenericDef, | 914 | pub(crate) parent: GenericDefId, |
964 | pub(crate) idx: u32, | 915 | pub(crate) idx: u32, |
965 | } | 916 | } |
966 | 917 | ||
@@ -970,6 +921,15 @@ pub struct ImplBlock { | |||
970 | } | 921 | } |
971 | 922 | ||
972 | impl ImplBlock { | 923 | impl ImplBlock { |
924 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { | ||
925 | let impls = db.impls_in_crate(krate.crate_id); | ||
926 | impls.all_impls().map(Self::from).collect() | ||
927 | } | ||
928 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { | ||
929 | let impls = db.impls_in_crate(krate.crate_id); | ||
930 | impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() | ||
931 | } | ||
932 | |||
973 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | 933 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
974 | db.impl_data(self.id).target_trait.clone() | 934 | db.impl_data(self.id).target_trait.clone() |
975 | } | 935 | } |
@@ -978,13 +938,12 @@ impl ImplBlock { | |||
978 | db.impl_data(self.id).target_type.clone() | 938 | db.impl_data(self.id).target_type.clone() |
979 | } | 939 | } |
980 | 940 | ||
981 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | 941 | pub fn target_ty(&self, db: &impl HirDatabase) -> Type { |
982 | Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) | 942 | let impl_data = db.impl_data(self.id); |
983 | } | 943 | let resolver = self.id.resolver(db); |
984 | 944 | let environment = TraitEnvironment::lower(db, &resolver); | |
985 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { | 945 | let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); |
986 | let target_ty = self.target_ty(db); | 946 | Type { krate: self.id.module(db).krate, ty: InEnvironment { value: ty, environment } } |
987 | TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) | ||
988 | } | 947 | } |
989 | 948 | ||
990 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | 949 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { |
@@ -1004,6 +963,194 @@ impl ImplBlock { | |||
1004 | } | 963 | } |
1005 | } | 964 | } |
1006 | 965 | ||
966 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
967 | pub struct Type { | ||
968 | pub(crate) krate: CrateId, | ||
969 | pub(crate) ty: InEnvironment<Ty>, | ||
970 | } | ||
971 | |||
972 | impl Type { | ||
973 | fn from_def( | ||
974 | db: &impl HirDatabase, | ||
975 | krate: CrateId, | ||
976 | def: impl HasResolver + Into<TyDefId>, | ||
977 | ) -> Type { | ||
978 | let resolver = def.resolver(db); | ||
979 | let environment = TraitEnvironment::lower(db, &resolver); | ||
980 | let ty = db.ty(def.into()); | ||
981 | Type { krate, ty: InEnvironment { value: ty, environment } } | ||
982 | } | ||
983 | |||
984 | pub fn is_bool(&self) -> bool { | ||
985 | match &self.ty.value { | ||
986 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
987 | TypeCtor::Bool => true, | ||
988 | _ => false, | ||
989 | }, | ||
990 | _ => false, | ||
991 | } | ||
992 | } | ||
993 | |||
994 | pub fn is_mutable_reference(&self) -> bool { | ||
995 | match &self.ty.value { | ||
996 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
997 | TypeCtor::Ref(Mutability::Mut) => true, | ||
998 | _ => false, | ||
999 | }, | ||
1000 | _ => false, | ||
1001 | } | ||
1002 | } | ||
1003 | |||
1004 | pub fn is_unknown(&self) -> bool { | ||
1005 | match &self.ty.value { | ||
1006 | Ty::Unknown => true, | ||
1007 | _ => false, | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | // FIXME: this method is broken, as it doesn't take closures into account. | ||
1012 | pub fn as_callable(&self) -> Option<CallableDef> { | ||
1013 | Some(self.ty.value.as_callable()?.0) | ||
1014 | } | ||
1015 | |||
1016 | pub fn contains_unknown(&self) -> bool { | ||
1017 | return go(&self.ty.value); | ||
1018 | |||
1019 | fn go(ty: &Ty) -> bool { | ||
1020 | match ty { | ||
1021 | Ty::Unknown => true, | ||
1022 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), | ||
1023 | _ => false, | ||
1024 | } | ||
1025 | } | ||
1026 | } | ||
1027 | |||
1028 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { | ||
1029 | if let Ty::Apply(a_ty) = &self.ty.value { | ||
1030 | match a_ty.ctor { | ||
1031 | ty::TypeCtor::Adt(AdtId::StructId(s)) => { | ||
1032 | let var_def = s.into(); | ||
1033 | return db | ||
1034 | .field_types(var_def) | ||
1035 | .iter() | ||
1036 | .map(|(local_id, ty)| { | ||
1037 | let def = StructField { parent: var_def.into(), id: local_id }; | ||
1038 | let ty = ty.clone().subst(&a_ty.parameters); | ||
1039 | (def, self.derived(ty)) | ||
1040 | }) | ||
1041 | .collect(); | ||
1042 | } | ||
1043 | _ => {} | ||
1044 | } | ||
1045 | }; | ||
1046 | Vec::new() | ||
1047 | } | ||
1048 | |||
1049 | pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> { | ||
1050 | let mut res = Vec::new(); | ||
1051 | if let Ty::Apply(a_ty) = &self.ty.value { | ||
1052 | match a_ty.ctor { | ||
1053 | ty::TypeCtor::Tuple { .. } => { | ||
1054 | for ty in a_ty.parameters.iter() { | ||
1055 | let ty = ty.clone().subst(&a_ty.parameters); | ||
1056 | res.push(self.derived(ty)); | ||
1057 | } | ||
1058 | } | ||
1059 | _ => {} | ||
1060 | } | ||
1061 | }; | ||
1062 | res | ||
1063 | } | ||
1064 | |||
1065 | pub fn variant_fields( | ||
1066 | &self, | ||
1067 | db: &impl HirDatabase, | ||
1068 | def: VariantDef, | ||
1069 | ) -> Vec<(StructField, Type)> { | ||
1070 | // FIXME: check that ty and def match | ||
1071 | match &self.ty.value { | ||
1072 | Ty::Apply(a_ty) => def | ||
1073 | .fields(db) | ||
1074 | .into_iter() | ||
1075 | .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters)))) | ||
1076 | .collect(), | ||
1077 | _ => Vec::new(), | ||
1078 | } | ||
1079 | } | ||
1080 | |||
1081 | pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { | ||
1082 | // There should be no inference vars in types passed here | ||
1083 | // FIXME check that? | ||
1084 | let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
1085 | let environment = self.ty.environment.clone(); | ||
1086 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; | ||
1087 | ty::autoderef(db, Some(self.krate), ty) | ||
1088 | .map(|canonical| canonical.value) | ||
1089 | .map(move |ty| self.derived(ty)) | ||
1090 | } | ||
1091 | |||
1092 | // This would be nicer if it just returned an iterator, but that runs into | ||
1093 | // lifetime problems, because we need to borrow temp `CrateImplBlocks`. | ||
1094 | pub fn iterate_impl_items<T>( | ||
1095 | self, | ||
1096 | db: &impl HirDatabase, | ||
1097 | krate: Crate, | ||
1098 | mut callback: impl FnMut(AssocItem) -> Option<T>, | ||
1099 | ) -> Option<T> { | ||
1100 | for krate in self.ty.value.def_crates(db, krate.crate_id)? { | ||
1101 | let impls = db.impls_in_crate(krate); | ||
1102 | |||
1103 | for impl_block in impls.lookup_impl_blocks(&self.ty.value) { | ||
1104 | for &item in db.impl_data(impl_block).items.iter() { | ||
1105 | if let Some(result) = callback(item.into()) { | ||
1106 | return Some(result); | ||
1107 | } | ||
1108 | } | ||
1109 | } | ||
1110 | } | ||
1111 | None | ||
1112 | } | ||
1113 | |||
1114 | // FIXME: remove | ||
1115 | pub fn into_ty(self) -> Ty { | ||
1116 | self.ty.value | ||
1117 | } | ||
1118 | |||
1119 | pub fn as_adt(&self) -> Option<Adt> { | ||
1120 | let (adt, _subst) = self.ty.value.as_adt()?; | ||
1121 | Some(adt.into()) | ||
1122 | } | ||
1123 | |||
1124 | // FIXME: provide required accessors such that it becomes implementable from outside. | ||
1125 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | ||
1126 | match (&self.ty.value, &other.ty.value) { | ||
1127 | (Ty::Apply(a_original_ty), Ty::Apply(ty::ApplicationTy { ctor, parameters })) => { | ||
1128 | match ctor { | ||
1129 | TypeCtor::Ref(..) => match parameters.as_single() { | ||
1130 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, | ||
1131 | _ => false, | ||
1132 | }, | ||
1133 | _ => a_original_ty.ctor == *ctor, | ||
1134 | } | ||
1135 | } | ||
1136 | _ => false, | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | fn derived(&self, ty: Ty) -> Type { | ||
1141 | Type { | ||
1142 | krate: self.krate, | ||
1143 | ty: InEnvironment { value: ty, environment: self.ty.environment.clone() }, | ||
1144 | } | ||
1145 | } | ||
1146 | } | ||
1147 | |||
1148 | impl HirDisplay for Type { | ||
1149 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> std::fmt::Result { | ||
1150 | self.ty.value.hir_fmt(f) | ||
1151 | } | ||
1152 | } | ||
1153 | |||
1007 | /// For IDE only | 1154 | /// For IDE only |
1008 | pub enum ScopeDef { | 1155 | pub enum ScopeDef { |
1009 | ModuleDef(ModuleDef), | 1156 | ModuleDef(ModuleDef), |
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index a4e317c20..bf3ee0834 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -22,7 +22,7 @@ impl Module { | |||
22 | /// 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. |
23 | pub fn definition_source(self, db: &impl DefDatabase) -> Source<ModuleSource> { | 23 | pub fn definition_source(self, db: &impl DefDatabase) -> Source<ModuleSource> { |
24 | let def_map = db.crate_def_map(self.id.krate); | 24 | let def_map = db.crate_def_map(self.id.krate); |
25 | let src = def_map[self.id.module_id].definition_source(db); | 25 | let src = def_map[self.id.local_id].definition_source(db); |
26 | src.map(|it| match it { | 26 | src.map(|it| match it { |
27 | Either::A(it) => ModuleSource::SourceFile(it), | 27 | Either::A(it) => ModuleSource::SourceFile(it), |
28 | Either::B(it) => ModuleSource::Module(it), | 28 | Either::B(it) => ModuleSource::Module(it), |
@@ -33,7 +33,7 @@ impl Module { | |||
33 | /// `None` for the crate root. | 33 | /// `None` for the crate root. |
34 | pub fn declaration_source(self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { | 34 | pub fn declaration_source(self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { |
35 | let def_map = db.crate_def_map(self.id.krate); | 35 | let def_map = db.crate_def_map(self.id.krate); |
36 | def_map[self.id.module_id].declaration_source(db) | 36 | def_map[self.id.local_id].declaration_source(db) |
37 | } | 37 | } |
38 | } | 38 | } |
39 | 39 | ||
@@ -51,13 +51,13 @@ impl HasSource for StructField { | |||
51 | impl HasSource for Struct { | 51 | impl HasSource for Struct { |
52 | type Ast = ast::StructDef; | 52 | type Ast = ast::StructDef; |
53 | fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { | 53 | fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { |
54 | self.id.0.source(db) | 54 | self.id.source(db) |
55 | } | 55 | } |
56 | } | 56 | } |
57 | impl HasSource for Union { | 57 | impl HasSource for Union { |
58 | type Ast = ast::StructDef; | 58 | type Ast = ast::UnionDef; |
59 | fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { | 59 | fn source(self, db: &impl DefDatabase) -> Source<ast::UnionDef> { |
60 | self.id.0.source(db) | 60 | self.id.source(db) |
61 | } | 61 | } |
62 | } | 62 | } |
63 | impl HasSource for Enum { | 63 | impl HasSource for Enum { |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 5084bbacf..bfae3660b 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,130 +1,22 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use std::sync::Arc; | 3 | pub use hir_def::db::{ |
4 | 4 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, | |
5 | use ra_arena::map::ArenaMap; | 5 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, |
6 | use ra_db::salsa; | 6 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, |
7 | 7 | LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery, | |
8 | use crate::{ | 8 | StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, |
9 | ty::{ | ||
10 | method_resolution::CrateImplBlocks, | ||
11 | traits::{AssocTyValue, Impl}, | ||
12 | CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, | ||
13 | TypeCtor, | ||
14 | }, | ||
15 | Crate, DefWithBody, GenericDef, ImplBlock, Trait, | ||
16 | }; | ||
17 | |||
18 | pub use hir_def::{ | ||
19 | db::{ | ||
20 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, | ||
21 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, | ||
22 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, | ||
23 | InternDatabaseStorage, LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, | ||
24 | RawItemsWithSourceMapQuery, StaticDataQuery, StructDataQuery, TraitDataQuery, | ||
25 | TypeAliasDataQuery, | ||
26 | }, | ||
27 | LocalStructFieldId, VariantId, | ||
28 | }; | 9 | }; |
29 | pub use hir_expand::db::{ | 10 | pub use hir_expand::db::{ |
30 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 11 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
31 | ParseMacroQuery, | 12 | ParseMacroQuery, |
32 | }; | 13 | }; |
33 | 14 | pub use hir_ty::db::{ | |
34 | #[salsa::query_group(HirDatabaseStorage)] | 15 | AssociatedTyDataQuery, CallableItemSignatureQuery, FieldTypesQuery, GenericDefaultsQuery, |
35 | #[salsa::requires(salsa::Database)] | 16 | GenericPredicatesQuery, HirDatabase, HirDatabaseStorage, ImplDatumQuery, ImplsForTraitQuery, |
36 | pub trait HirDatabase: DefDatabase { | 17 | ImplsInCrateQuery, InferQuery, StructDatumQuery, TraitDatumQuery, TraitSolveQuery, TyQuery, |
37 | #[salsa::invoke(crate::ty::infer_query)] | 18 | ValueTyQuery, |
38 | fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; | 19 | }; |
39 | |||
40 | #[salsa::invoke(crate::ty::type_for_def)] | ||
41 | fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; | ||
42 | |||
43 | #[salsa::invoke(crate::ty::field_types_query)] | ||
44 | fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; | ||
45 | |||
46 | #[salsa::invoke(crate::ty::callable_item_sig)] | ||
47 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; | ||
48 | |||
49 | #[salsa::invoke(crate::ty::generic_predicates_for_param_query)] | ||
50 | fn generic_predicates_for_param( | ||
51 | &self, | ||
52 | def: GenericDef, | ||
53 | param_idx: u32, | ||
54 | ) -> Arc<[GenericPredicate]>; | ||
55 | |||
56 | #[salsa::invoke(crate::ty::generic_predicates_query)] | ||
57 | fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; | ||
58 | |||
59 | #[salsa::invoke(crate::ty::generic_defaults_query)] | ||
60 | fn generic_defaults(&self, def: GenericDef) -> Substs; | ||
61 | |||
62 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | ||
63 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | ||
64 | |||
65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] | ||
66 | fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; | ||
67 | |||
68 | /// This provides the Chalk trait solver instance. Because Chalk always | ||
69 | /// works from a specific crate, this query is keyed on the crate; and | ||
70 | /// because Chalk does its own internal caching, the solver is wrapped in a | ||
71 | /// Mutex and the query does an untracked read internally, to make sure the | ||
72 | /// cached state is thrown away when input facts change. | ||
73 | #[salsa::invoke(crate::ty::traits::trait_solver_query)] | ||
74 | fn trait_solver(&self, krate: Crate) -> crate::ty::traits::TraitSolver; | ||
75 | |||
76 | // Interned IDs for Chalk integration | ||
77 | #[salsa::interned] | ||
78 | fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::ty::TypeCtorId; | ||
79 | #[salsa::interned] | ||
80 | fn intern_chalk_impl(&self, impl_: Impl) -> crate::ty::traits::GlobalImplId; | ||
81 | #[salsa::interned] | ||
82 | fn intern_assoc_ty_value( | ||
83 | &self, | ||
84 | assoc_ty_value: AssocTyValue, | ||
85 | ) -> crate::ty::traits::AssocTyValueId; | ||
86 | |||
87 | #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] | ||
88 | fn associated_ty_data( | ||
89 | &self, | ||
90 | id: chalk_ir::TypeId, | ||
91 | ) -> Arc<chalk_rust_ir::AssociatedTyDatum<chalk_ir::family::ChalkIr>>; | ||
92 | |||
93 | #[salsa::invoke(crate::ty::traits::chalk::trait_datum_query)] | ||
94 | fn trait_datum( | ||
95 | &self, | ||
96 | krate: Crate, | ||
97 | trait_id: chalk_ir::TraitId, | ||
98 | ) -> Arc<chalk_rust_ir::TraitDatum<chalk_ir::family::ChalkIr>>; | ||
99 | |||
100 | #[salsa::invoke(crate::ty::traits::chalk::struct_datum_query)] | ||
101 | fn struct_datum( | ||
102 | &self, | ||
103 | krate: Crate, | ||
104 | struct_id: chalk_ir::StructId, | ||
105 | ) -> Arc<chalk_rust_ir::StructDatum<chalk_ir::family::ChalkIr>>; | ||
106 | |||
107 | #[salsa::invoke(crate::ty::traits::chalk::impl_datum_query)] | ||
108 | fn impl_datum( | ||
109 | &self, | ||
110 | krate: Crate, | ||
111 | impl_id: chalk_ir::ImplId, | ||
112 | ) -> Arc<chalk_rust_ir::ImplDatum<chalk_ir::family::ChalkIr>>; | ||
113 | |||
114 | #[salsa::invoke(crate::ty::traits::chalk::associated_ty_value_query)] | ||
115 | fn associated_ty_value( | ||
116 | &self, | ||
117 | krate: Crate, | ||
118 | id: chalk_rust_ir::AssociatedTyValueId, | ||
119 | ) -> Arc<chalk_rust_ir::AssociatedTyValue<chalk_ir::family::ChalkIr>>; | ||
120 | |||
121 | #[salsa::invoke(crate::ty::traits::trait_solve_query)] | ||
122 | fn trait_solve( | ||
123 | &self, | ||
124 | krate: Crate, | ||
125 | goal: crate::ty::Canonical<crate::ty::InEnvironment<crate::ty::Obligation>>, | ||
126 | ) -> Option<crate::ty::traits::Solution>; | ||
127 | } | ||
128 | 20 | ||
129 | #[test] | 21 | #[test] |
130 | fn hir_database_is_object_safe() { | 22 | fn hir_database_is_object_safe() { |
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs index dafacba70..a9040ea3d 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs | |||
@@ -1,88 +1,4 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | |||
3 | use std::any::Any; | ||
4 | |||
5 | use hir_expand::HirFileId; | ||
6 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; | ||
7 | |||
8 | use crate::{db::AstDatabase, Name, Source}; | ||
9 | |||
10 | pub use hir_def::diagnostics::UnresolvedModule; | 2 | pub use hir_def::diagnostics::UnresolvedModule; |
11 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; | 3 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; |
12 | 4 | pub use hir_ty::diagnostics::{MissingFields, MissingOkInTailExpr, NoSuchField}; | |
13 | #[derive(Debug)] | ||
14 | pub struct NoSuchField { | ||
15 | pub file: HirFileId, | ||
16 | pub field: AstPtr<ast::RecordField>, | ||
17 | } | ||
18 | |||
19 | impl Diagnostic for NoSuchField { | ||
20 | fn message(&self) -> String { | ||
21 | "no such field".to_string() | ||
22 | } | ||
23 | |||
24 | fn source(&self) -> Source<SyntaxNodePtr> { | ||
25 | Source { file_id: self.file, value: self.field.into() } | ||
26 | } | ||
27 | |||
28 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
29 | self | ||
30 | } | ||
31 | } | ||
32 | |||
33 | #[derive(Debug)] | ||
34 | pub struct MissingFields { | ||
35 | pub file: HirFileId, | ||
36 | pub field_list: AstPtr<ast::RecordFieldList>, | ||
37 | pub missed_fields: Vec<Name>, | ||
38 | } | ||
39 | |||
40 | impl Diagnostic for MissingFields { | ||
41 | fn message(&self) -> String { | ||
42 | "fill structure fields".to_string() | ||
43 | } | ||
44 | fn source(&self) -> Source<SyntaxNodePtr> { | ||
45 | Source { file_id: self.file, value: self.field_list.into() } | ||
46 | } | ||
47 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
48 | self | ||
49 | } | ||
50 | } | ||
51 | |||
52 | impl AstDiagnostic for MissingFields { | ||
53 | type AST = ast::RecordFieldList; | ||
54 | |||
55 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { | ||
56 | let root = db.parse_or_expand(self.source().file_id).unwrap(); | ||
57 | let node = self.source().value.to_node(&root); | ||
58 | ast::RecordFieldList::cast(node).unwrap() | ||
59 | } | ||
60 | } | ||
61 | |||
62 | #[derive(Debug)] | ||
63 | pub struct MissingOkInTailExpr { | ||
64 | pub file: HirFileId, | ||
65 | pub expr: AstPtr<ast::Expr>, | ||
66 | } | ||
67 | |||
68 | impl Diagnostic for MissingOkInTailExpr { | ||
69 | fn message(&self) -> String { | ||
70 | "wrap return expression in Ok".to_string() | ||
71 | } | ||
72 | fn source(&self) -> Source<SyntaxNodePtr> { | ||
73 | Source { file_id: self.file, value: self.expr.into() } | ||
74 | } | ||
75 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
76 | self | ||
77 | } | ||
78 | } | ||
79 | |||
80 | impl AstDiagnostic for MissingOkInTailExpr { | ||
81 | type AST = ast::Expr; | ||
82 | |||
83 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { | ||
84 | let root = db.parse_or_expand(self.file).unwrap(); | ||
85 | let node = self.source().value.to_node(&root); | ||
86 | ast::Expr::cast(node).unwrap() | ||
87 | } | ||
88 | } | ||
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 529ac8251..e96a18d12 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -4,14 +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, AttrDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, | 7 | AdtId, AssocItemId, AttrDefId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId, |
8 | GenericDefId, ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId, | 8 | StructFieldId, VariantId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | ty::{CallableDef, TypableDef}, | 12 | Adt, AssocItem, AttrDef, Crate, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField, |
13 | Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, | 13 | VariantDef, |
14 | ModuleDef, Static, StructField, TypeAlias, VariantDef, | ||
15 | }; | 14 | }; |
16 | 15 | ||
17 | impl From<ra_db::CrateId> for Crate { | 16 | impl From<ra_db::CrateId> for Crate { |
@@ -138,72 +137,6 @@ impl From<GenericDef> for GenericDefId { | |||
138 | } | 137 | } |
139 | } | 138 | } |
140 | 139 | ||
141 | impl From<GenericDefId> for GenericDef { | ||
142 | fn from(def: GenericDefId) -> Self { | ||
143 | match def { | ||
144 | GenericDefId::FunctionId(it) => GenericDef::Function(it.into()), | ||
145 | GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), | ||
146 | GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), | ||
147 | GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), | ||
148 | GenericDefId::ImplId(it) => GenericDef::ImplBlock(it.into()), | ||
149 | GenericDefId::EnumVariantId(it) => GenericDef::EnumVariant(it.into()), | ||
150 | GenericDefId::ConstId(it) => GenericDef::Const(it.into()), | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | |||
155 | impl From<AdtId> for TypableDef { | ||
156 | fn from(id: AdtId) -> Self { | ||
157 | Adt::from(id).into() | ||
158 | } | ||
159 | } | ||
160 | |||
161 | impl From<StructId> for TypableDef { | ||
162 | fn from(id: StructId) -> Self { | ||
163 | AdtId::StructId(id).into() | ||
164 | } | ||
165 | } | ||
166 | |||
167 | impl From<UnionId> for TypableDef { | ||
168 | fn from(id: UnionId) -> Self { | ||
169 | AdtId::UnionId(id).into() | ||
170 | } | ||
171 | } | ||
172 | |||
173 | impl From<EnumId> for TypableDef { | ||
174 | fn from(id: EnumId) -> Self { | ||
175 | AdtId::EnumId(id).into() | ||
176 | } | ||
177 | } | ||
178 | |||
179 | impl From<EnumVariantId> for TypableDef { | ||
180 | fn from(id: EnumVariantId) -> Self { | ||
181 | EnumVariant::from(id).into() | ||
182 | } | ||
183 | } | ||
184 | |||
185 | impl From<TypeAliasId> for TypableDef { | ||
186 | fn from(id: TypeAliasId) -> Self { | ||
187 | TypeAlias::from(id).into() | ||
188 | } | ||
189 | } | ||
190 | |||
191 | impl From<FunctionId> for TypableDef { | ||
192 | fn from(id: FunctionId) -> Self { | ||
193 | Function::from(id).into() | ||
194 | } | ||
195 | } | ||
196 | impl From<ConstId> for TypableDef { | ||
197 | fn from(id: ConstId) -> Self { | ||
198 | Const::from(id).into() | ||
199 | } | ||
200 | } | ||
201 | impl From<StaticId> for TypableDef { | ||
202 | fn from(id: StaticId) -> Self { | ||
203 | Static::from(id).into() | ||
204 | } | ||
205 | } | ||
206 | |||
207 | impl From<Adt> for GenericDefId { | 140 | impl From<Adt> for GenericDefId { |
208 | fn from(id: Adt) -> Self { | 141 | fn from(id: Adt) -> Self { |
209 | match id { | 142 | match id { |
@@ -214,14 +147,12 @@ impl From<Adt> for GenericDefId { | |||
214 | } | 147 | } |
215 | } | 148 | } |
216 | 149 | ||
217 | impl From<CallableDef> for GenericDefId { | 150 | impl From<VariantId> for VariantDef { |
218 | fn from(def: CallableDef) -> Self { | 151 | fn from(def: VariantId) -> Self { |
219 | match def { | 152 | match def { |
220 | CallableDef::Function(it) => it.id.into(), | 153 | VariantId::StructId(it) => VariantDef::Struct(it.into()), |
221 | CallableDef::Struct(it) => it.id.into(), | 154 | VariantId::EnumVariantId(it) => VariantDef::EnumVariant(it.into()), |
222 | CallableDef::EnumVariant(it) => { | 155 | VariantId::UnionId(it) => VariantDef::Union(it.into()), |
223 | EnumVariantId { parent: it.parent.id, local_id: it.id }.into() | ||
224 | } | ||
225 | } | 156 | } |
226 | } | 157 | } |
227 | } | 158 | } |
@@ -231,6 +162,7 @@ impl From<VariantDef> for VariantId { | |||
231 | match def { | 162 | match def { |
232 | VariantDef::Struct(it) => VariantId::StructId(it.id), | 163 | VariantDef::Struct(it) => VariantId::StructId(it.id), |
233 | VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), | 164 | VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), |
165 | VariantDef::Union(it) => VariantId::UnionId(it.id), | ||
234 | } | 166 | } |
235 | } | 167 | } |
236 | } | 168 | } |
@@ -241,6 +173,12 @@ impl From<StructField> for StructFieldId { | |||
241 | } | 173 | } |
242 | } | 174 | } |
243 | 175 | ||
176 | impl From<StructFieldId> for StructField { | ||
177 | fn from(def: StructFieldId) -> Self { | ||
178 | StructField { parent: def.parent.into(), id: def.local_id } | ||
179 | } | ||
180 | } | ||
181 | |||
244 | impl From<AttrDef> for AttrDefId { | 182 | impl From<AttrDef> for AttrDefId { |
245 | fn from(def: AttrDef) -> Self { | 183 | fn from(def: AttrDef) -> Self { |
246 | match def { | 184 | match def { |
@@ -257,3 +195,13 @@ impl From<AttrDef> for AttrDefId { | |||
257 | } | 195 | } |
258 | } | 196 | } |
259 | } | 197 | } |
198 | |||
199 | impl From<AssocItem> for GenericDefId { | ||
200 | fn from(item: AssocItem) -> Self { | ||
201 | match item { | ||
202 | AssocItem::Function(f) => f.id.into(), | ||
203 | AssocItem::Const(c) => c.id.into(), | ||
204 | AssocItem::TypeAlias(t) => t.id.into(), | ||
205 | } | ||
206 | } | ||
207 | } | ||
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 1e7c22774..9f7c22b21 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::{AstItemDef, LocationCtx, ModuleId, StructId, StructOrUnionId, UnionId}; | 3 | use hir_def::{AstItemDef, LocationCtx, ModuleId}; |
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}, |
@@ -19,19 +19,18 @@ pub trait FromSource: Sized { | |||
19 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>; | 19 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>; |
20 | } | 20 | } |
21 | 21 | ||
22 | // FIXIME: these two impls are wrong, `ast::StructDef` might produce either a struct or a union | ||
23 | impl FromSource for Struct { | 22 | impl FromSource for Struct { |
24 | type Ast = ast::StructDef; | 23 | type Ast = ast::StructDef; |
25 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 24 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
26 | let id: StructOrUnionId = from_source(db, src)?; | 25 | let id = from_source(db, src)?; |
27 | Some(Struct { id: StructId(id) }) | 26 | Some(Struct { id }) |
28 | } | 27 | } |
29 | } | 28 | } |
30 | impl FromSource for Union { | 29 | impl FromSource for Union { |
31 | type Ast = ast::StructDef; | 30 | type Ast = ast::UnionDef; |
32 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 31 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
33 | let id: StructOrUnionId = from_source(db, src)?; | 32 | let id = from_source(db, src)?; |
34 | Some(Union { id: UnionId(id) }) | 33 | Some(Union { id }) |
35 | } | 34 | } |
36 | } | 35 | } |
37 | impl FromSource for Enum { | 36 | impl FromSource for Enum { |
@@ -263,13 +262,12 @@ impl Module { | |||
263 | 262 | ||
264 | let original_file = src.file_id.original_file(db); | 263 | let original_file = src.file_id.original_file(db); |
265 | 264 | ||
266 | let (krate, module_id) = | 265 | let (krate, local_id) = db.relevant_crates(original_file).iter().find_map(|&crate_id| { |
267 | db.relevant_crates(original_file).iter().find_map(|&crate_id| { | 266 | let crate_def_map = db.crate_def_map(crate_id); |
268 | let crate_def_map = db.crate_def_map(crate_id); | 267 | let local_id = crate_def_map.modules_for_file(original_file).next()?; |
269 | let local_module_id = crate_def_map.modules_for_file(original_file).next()?; | 268 | Some((crate_id, local_id)) |
270 | Some((crate_id, local_module_id)) | 269 | })?; |
271 | })?; | 270 | Some(Module { id: ModuleId { krate, local_id } }) |
272 | Some(Module { id: ModuleId { krate, module_id } }) | ||
273 | } | 271 | } |
274 | } | 272 | } |
275 | 273 | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 843ce6a88..3c12c61f0 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -32,28 +32,20 @@ pub mod db; | |||
32 | pub mod source_binder; | 32 | pub mod source_binder; |
33 | 33 | ||
34 | mod ty; | 34 | mod ty; |
35 | mod expr; | ||
36 | pub mod diagnostics; | 35 | pub mod diagnostics; |
37 | mod util; | ||
38 | 36 | ||
39 | mod from_id; | 37 | mod from_id; |
40 | mod code_model; | 38 | mod code_model; |
41 | 39 | ||
42 | pub mod from_source; | 40 | pub mod from_source; |
43 | 41 | ||
44 | #[cfg(test)] | ||
45 | mod test_db; | ||
46 | #[cfg(test)] | ||
47 | mod marks; | ||
48 | |||
49 | pub use crate::{ | 42 | pub use crate::{ |
50 | code_model::{ | 43 | code_model::{ |
51 | src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, | 44 | src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, |
52 | DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam, | 45 | DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam, |
53 | HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, | 46 | HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, |
54 | Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, | 47 | Static, Struct, StructField, Trait, Type, TypeAlias, Union, VariantDef, |
55 | }, | 48 | }, |
56 | expr::ExprScopes, | ||
57 | from_source::FromSource, | 49 | from_source::FromSource, |
58 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 50 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
59 | ty::{ | 51 | ty::{ |
@@ -64,6 +56,7 @@ pub use crate::{ | |||
64 | }; | 56 | }; |
65 | 57 | ||
66 | pub use hir_def::{ | 58 | pub use hir_def::{ |
59 | body::scope::ExprScopes, | ||
67 | builtin_type::BuiltinType, | 60 | builtin_type::BuiltinType, |
68 | docs::Documentation, | 61 | docs::Documentation, |
69 | path::{Path, PathKind}, | 62 | path::{Path, PathKind}, |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 31390bb7f..76c493f1a 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -8,13 +8,17 @@ | |||
8 | use std::sync::Arc; | 8 | use std::sync::Arc; |
9 | 9 | ||
10 | use hir_def::{ | 10 | use hir_def::{ |
11 | body::{ | ||
12 | scope::{ExprScopes, ScopeId}, | ||
13 | BodySourceMap, | ||
14 | }, | ||
11 | expr::{ExprId, PatId}, | 15 | expr::{ExprId, PatId}, |
12 | path::known, | 16 | path::known, |
13 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, | 17 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, |
14 | DefWithBodyId, | 18 | AssocItemId, DefWithBodyId, |
15 | }; | 19 | }; |
16 | use hir_expand::{ | 20 | use hir_expand::{ |
17 | name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source, | 21 | hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, |
18 | }; | 22 | }; |
19 | use ra_syntax::{ | 23 | use ra_syntax::{ |
20 | ast::{self, AstNode}, | 24 | ast::{self, AstNode}, |
@@ -25,10 +29,12 @@ use ra_syntax::{ | |||
25 | 29 | ||
26 | use crate::{ | 30 | use crate::{ |
27 | db::HirDatabase, | 31 | db::HirDatabase, |
28 | expr::{BodySourceMap, ExprScopes, ScopeId}, | 32 | ty::{ |
29 | ty::method_resolution::{self, implements_trait}, | 33 | method_resolution::{self, implements_trait}, |
34 | InEnvironment, TraitEnvironment, Ty, | ||
35 | }, | ||
30 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, | 36 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, |
31 | GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias, | 37 | GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, |
32 | }; | 38 | }; |
33 | 39 | ||
34 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 40 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { |
@@ -88,7 +94,7 @@ pub struct SourceAnalyzer { | |||
88 | body_owner: Option<DefWithBody>, | 94 | body_owner: Option<DefWithBody>, |
89 | body_source_map: Option<Arc<BodySourceMap>>, | 95 | body_source_map: Option<Arc<BodySourceMap>>, |
90 | infer: Option<Arc<crate::ty::InferenceResult>>, | 96 | infer: Option<Arc<crate::ty::InferenceResult>>, |
91 | scopes: Option<Arc<crate::expr::ExprScopes>>, | 97 | scopes: Option<Arc<ExprScopes>>, |
92 | } | 98 | } |
93 | 99 | ||
94 | #[derive(Debug, Clone, PartialEq, Eq)] | 100 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -165,7 +171,7 @@ impl SourceAnalyzer { | |||
165 | resolver, | 171 | resolver, |
166 | body_owner: Some(def), | 172 | body_owner: Some(def), |
167 | body_source_map: Some(source_map), | 173 | body_source_map: Some(source_map), |
168 | infer: Some(db.infer(def)), | 174 | infer: Some(db.infer(def.into())), |
169 | scopes: Some(scopes), | 175 | scopes: Some(scopes), |
170 | file_id: node.file_id, | 176 | file_id: node.file_id, |
171 | } | 177 | } |
@@ -195,48 +201,52 @@ impl SourceAnalyzer { | |||
195 | self.body_source_map.as_ref()?.node_pat(src) | 201 | self.body_source_map.as_ref()?.node_pat(src) |
196 | } | 202 | } |
197 | 203 | ||
198 | pub fn type_of(&self, _db: &impl HirDatabase, expr: &ast::Expr) -> Option<crate::Ty> { | 204 | pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { |
199 | let expr_id = self.expr_id(expr)?; | 205 | let expr_id = self.expr_id(expr)?; |
200 | Some(self.infer.as_ref()?[expr_id].clone()) | 206 | let ty = self.infer.as_ref()?[expr_id].clone(); |
207 | let environment = TraitEnvironment::lower(db, &self.resolver); | ||
208 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) | ||
201 | } | 209 | } |
202 | 210 | ||
203 | pub fn type_of_pat(&self, _db: &impl HirDatabase, pat: &ast::Pat) -> Option<crate::Ty> { | 211 | pub fn type_of_pat(&self, db: &impl HirDatabase, pat: &ast::Pat) -> Option<Type> { |
204 | let pat_id = self.pat_id(pat)?; | 212 | let pat_id = self.pat_id(pat)?; |
205 | Some(self.infer.as_ref()?[pat_id].clone()) | 213 | let ty = self.infer.as_ref()?[pat_id].clone(); |
214 | let environment = TraitEnvironment::lower(db, &self.resolver); | ||
215 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) | ||
206 | } | 216 | } |
207 | 217 | ||
208 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { | 218 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { |
209 | let expr_id = self.expr_id(&call.clone().into())?; | 219 | let expr_id = self.expr_id(&call.clone().into())?; |
210 | self.infer.as_ref()?.method_resolution(expr_id) | 220 | self.infer.as_ref()?.method_resolution(expr_id).map(Function::from) |
211 | } | 221 | } |
212 | 222 | ||
213 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> { | 223 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> { |
214 | let expr_id = self.expr_id(&field.clone().into())?; | 224 | let expr_id = self.expr_id(&field.clone().into())?; |
215 | self.infer.as_ref()?.field_resolution(expr_id) | 225 | self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into()) |
216 | } | 226 | } |
217 | 227 | ||
218 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { | 228 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { |
219 | let expr_id = self.expr_id(&field.expr()?)?; | 229 | let expr_id = self.expr_id(&field.expr()?)?; |
220 | self.infer.as_ref()?.record_field_resolution(expr_id) | 230 | self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) |
221 | } | 231 | } |
222 | 232 | ||
223 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { | 233 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { |
224 | let expr_id = self.expr_id(&record_lit.clone().into())?; | 234 | let expr_id = self.expr_id(&record_lit.clone().into())?; |
225 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | 235 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id).map(|it| it.into()) |
226 | } | 236 | } |
227 | 237 | ||
228 | pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option<crate::VariantDef> { | 238 | pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option<crate::VariantDef> { |
229 | let pat_id = self.pat_id(&record_pat.clone().into())?; | 239 | let pat_id = self.pat_id(&record_pat.clone().into())?; |
230 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) | 240 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id).map(|it| it.into()) |
231 | } | 241 | } |
232 | 242 | ||
233 | pub fn resolve_macro_call( | 243 | pub fn resolve_macro_call( |
234 | &self, | 244 | &self, |
235 | db: &impl HirDatabase, | 245 | db: &impl HirDatabase, |
236 | macro_call: &ast::MacroCall, | 246 | macro_call: Source<&ast::MacroCall>, |
237 | ) -> Option<MacroDef> { | 247 | ) -> Option<MacroDef> { |
238 | // This must be a normal source file rather than macro file. | 248 | let hygiene = Hygiene::new(db, macro_call.file_id); |
239 | let path = macro_call.path().and_then(Path::from_ast)?; | 249 | let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; |
240 | self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) | 250 | self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) |
241 | } | 251 | } |
242 | 252 | ||
@@ -248,7 +258,7 @@ impl SourceAnalyzer { | |||
248 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { | 258 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { |
249 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 259 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
250 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { | 260 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { |
251 | parent: self.resolver.generic_def().unwrap().into(), | 261 | parent: self.resolver.generic_def().unwrap(), |
252 | idx, | 262 | idx, |
253 | }), | 263 | }), |
254 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | 264 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
@@ -290,13 +300,13 @@ impl SourceAnalyzer { | |||
290 | if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { | 300 | if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { |
291 | let expr_id = self.expr_id(&path_expr.into())?; | 301 | let expr_id = self.expr_id(&path_expr.into())?; |
292 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { | 302 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { |
293 | return Some(PathResolution::AssocItem(assoc)); | 303 | return Some(PathResolution::AssocItem(assoc.into())); |
294 | } | 304 | } |
295 | } | 305 | } |
296 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { | 306 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { |
297 | let pat_id = self.pat_id(&path_pat.into())?; | 307 | let pat_id = self.pat_id(&path_pat.into())?; |
298 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { | 308 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { |
299 | return Some(PathResolution::AssocItem(assoc)); | 309 | return Some(PathResolution::AssocItem(assoc.into())); |
300 | } | 310 | } |
301 | } | 311 | } |
302 | // This must be a normal source file rather than macro file. | 312 | // This must be a normal source file rather than macro file. |
@@ -323,7 +333,7 @@ impl SourceAnalyzer { | |||
323 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), | 333 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), |
324 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), | 334 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), |
325 | resolver::ScopeDef::GenericParam(idx) => { | 335 | resolver::ScopeDef::GenericParam(idx) => { |
326 | let parent = self.resolver.generic_def().unwrap().into(); | 336 | let parent = self.resolver.generic_def().unwrap(); |
327 | ScopeDef::GenericParam(GenericParam { parent, idx }) | 337 | ScopeDef::GenericParam(GenericParam { parent, idx }) |
328 | } | 338 | } |
329 | resolver::ScopeDef::Local(pat_id) => { | 339 | resolver::ScopeDef::Local(pat_id) => { |
@@ -358,14 +368,14 @@ impl SourceAnalyzer { | |||
358 | pub fn iterate_method_candidates<T>( | 368 | pub fn iterate_method_candidates<T>( |
359 | &self, | 369 | &self, |
360 | db: &impl HirDatabase, | 370 | db: &impl HirDatabase, |
361 | ty: Ty, | 371 | ty: &Type, |
362 | name: Option<&Name>, | 372 | name: Option<&Name>, |
363 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, | 373 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, |
364 | ) -> Option<T> { | 374 | ) -> Option<T> { |
365 | // There should be no inference vars in types passed here | 375 | // There should be no inference vars in types passed here |
366 | // FIXME check that? | 376 | // FIXME check that? |
367 | // FIXME replace Unknown by bound vars here | 377 | // FIXME replace Unknown by bound vars here |
368 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | 378 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
369 | method_resolution::iterate_method_candidates( | 379 | method_resolution::iterate_method_candidates( |
370 | &canonical, | 380 | &canonical, |
371 | db, | 381 | db, |
@@ -373,7 +383,7 @@ impl SourceAnalyzer { | |||
373 | name, | 383 | name, |
374 | method_resolution::LookupMode::MethodCall, | 384 | method_resolution::LookupMode::MethodCall, |
375 | |ty, it| match it { | 385 | |ty, it| match it { |
376 | AssocItem::Function(f) => callback(ty, f), | 386 | AssocItemId::FunctionId(f) => callback(ty, f.into()), |
377 | _ => None, | 387 | _ => None, |
378 | }, | 388 | }, |
379 | ) | 389 | ) |
@@ -382,34 +392,37 @@ impl SourceAnalyzer { | |||
382 | pub fn iterate_path_candidates<T>( | 392 | pub fn iterate_path_candidates<T>( |
383 | &self, | 393 | &self, |
384 | db: &impl HirDatabase, | 394 | db: &impl HirDatabase, |
385 | ty: Ty, | 395 | ty: &Type, |
386 | name: Option<&Name>, | 396 | name: Option<&Name>, |
387 | callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | 397 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, |
388 | ) -> Option<T> { | 398 | ) -> Option<T> { |
389 | // There should be no inference vars in types passed here | 399 | // There should be no inference vars in types passed here |
390 | // FIXME check that? | 400 | // FIXME check that? |
391 | // FIXME replace Unknown by bound vars here | 401 | // FIXME replace Unknown by bound vars here |
392 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | 402 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
393 | method_resolution::iterate_method_candidates( | 403 | method_resolution::iterate_method_candidates( |
394 | &canonical, | 404 | &canonical, |
395 | db, | 405 | db, |
396 | &self.resolver, | 406 | &self.resolver, |
397 | name, | 407 | name, |
398 | method_resolution::LookupMode::Path, | 408 | method_resolution::LookupMode::Path, |
399 | callback, | 409 | |ty, it| callback(ty, it.into()), |
400 | ) | 410 | ) |
401 | } | 411 | } |
402 | 412 | ||
403 | pub fn autoderef<'a>( | 413 | // pub fn autoderef<'a>( |
404 | &'a self, | 414 | // &'a self, |
405 | db: &'a impl HirDatabase, | 415 | // db: &'a impl HirDatabase, |
406 | ty: Ty, | 416 | // ty: Ty, |
407 | ) -> impl Iterator<Item = Ty> + 'a { | 417 | // ) -> impl Iterator<Item = Ty> + 'a { |
408 | // There should be no inference vars in types passed here | 418 | // // There should be no inference vars in types passed here |
409 | // FIXME check that? | 419 | // // FIXME check that? |
410 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | 420 | // let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; |
411 | crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) | 421 | // let krate = self.resolver.krate(); |
412 | } | 422 | // let environment = TraitEnvironment::lower(db, &self.resolver); |
423 | // let ty = crate::ty::InEnvironment { value: canonical, environment }; | ||
424 | // crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) | ||
425 | // } | ||
413 | 426 | ||
414 | /// Checks that particular type `ty` implements `std::future::Future`. | 427 | /// Checks that particular type `ty` implements `std::future::Future`. |
415 | /// This function is used in `.await` syntax completion. | 428 | /// This function is used in `.await` syntax completion. |
@@ -435,32 +448,16 @@ impl SourceAnalyzer { | |||
435 | db: &impl HirDatabase, | 448 | db: &impl HirDatabase, |
436 | macro_call: Source<&ast::MacroCall>, | 449 | macro_call: Source<&ast::MacroCall>, |
437 | ) -> Option<Expansion> { | 450 | ) -> Option<Expansion> { |
438 | let def = self.resolve_macro_call(db, macro_call.value)?.id; | 451 | let def = self.resolve_macro_call(db, macro_call)?.id; |
439 | let ast_id = AstId::new( | 452 | let ast_id = AstId::new( |
440 | macro_call.file_id, | 453 | macro_call.file_id, |
441 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | 454 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), |
442 | ); | 455 | ); |
443 | let macro_call_loc = MacroCallLoc { def, ast_id }; | ||
444 | Some(Expansion { | 456 | Some(Expansion { |
445 | macro_call_id: db.intern_macro(macro_call_loc), | 457 | macro_call_id: def.as_call_id(db, ast_id), |
446 | macro_file_kind: to_macro_file_kind(macro_call.value), | 458 | macro_file_kind: to_macro_file_kind(macro_call.value), |
447 | }) | 459 | }) |
448 | } | 460 | } |
449 | |||
450 | #[cfg(test)] | ||
451 | pub(crate) fn body_source_map(&self) -> Arc<BodySourceMap> { | ||
452 | self.body_source_map.clone().unwrap() | ||
453 | } | ||
454 | |||
455 | #[cfg(test)] | ||
456 | pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> { | ||
457 | self.infer.clone().unwrap() | ||
458 | } | ||
459 | |||
460 | #[cfg(test)] | ||
461 | pub(crate) fn analyzed_declaration(&self) -> Option<DefWithBody> { | ||
462 | self.body_owner | ||
463 | } | ||
464 | } | 461 | } |
465 | 462 | ||
466 | fn scope_for( | 463 | fn scope_for( |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index f62316c1f..4ed69c00d 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -1,1094 +1,4 @@ | |||
1 | //! The type system. We currently use this to infer types for completion, hover | 1 | //! The type system. We currently use this to infer types for completion, hover |
2 | //! information and various assists. | 2 | //! information and various assists. |
3 | 3 | ||
4 | mod autoderef; | 4 | pub use hir_ty::*; |
5 | pub(crate) mod primitive; | ||
6 | pub(crate) mod traits; | ||
7 | pub(crate) mod method_resolution; | ||
8 | mod op; | ||
9 | mod lower; | ||
10 | mod infer; | ||
11 | pub(crate) mod display; | ||
12 | |||
13 | #[cfg(test)] | ||
14 | mod tests; | ||
15 | |||
16 | use std::ops::Deref; | ||
17 | use std::sync::Arc; | ||
18 | use std::{fmt, iter, mem}; | ||
19 | |||
20 | use hir_def::{generics::GenericParams, AdtId}; | ||
21 | use ra_db::{impl_intern_key, salsa}; | ||
22 | |||
23 | use crate::{ | ||
24 | db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, | ||
25 | GenericDef, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, | ||
26 | }; | ||
27 | use display::{HirDisplay, HirFormatter}; | ||
28 | |||
29 | pub(crate) use autoderef::autoderef; | ||
30 | pub(crate) use infer::{infer_query, InferTy, InferenceResult}; | ||
31 | pub use lower::CallableDef; | ||
32 | pub(crate) use lower::{ | ||
33 | callable_item_sig, field_types_query, generic_defaults_query, | ||
34 | generic_predicates_for_param_query, generic_predicates_query, type_for_def, Namespace, | ||
35 | TypableDef, | ||
36 | }; | ||
37 | pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | ||
38 | |||
39 | /// A type constructor or type name: this might be something like the primitive | ||
40 | /// type `bool`, a struct like `Vec`, or things like function pointers or | ||
41 | /// tuples. | ||
42 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | ||
43 | pub enum TypeCtor { | ||
44 | /// The primitive boolean type. Written as `bool`. | ||
45 | Bool, | ||
46 | |||
47 | /// The primitive character type; holds a Unicode scalar value | ||
48 | /// (a non-surrogate code point). Written as `char`. | ||
49 | Char, | ||
50 | |||
51 | /// A primitive integer type. For example, `i32`. | ||
52 | Int(Uncertain<IntTy>), | ||
53 | |||
54 | /// A primitive floating-point type. For example, `f64`. | ||
55 | Float(Uncertain<FloatTy>), | ||
56 | |||
57 | /// Structures, enumerations and unions. | ||
58 | Adt(Adt), | ||
59 | |||
60 | /// The pointee of a string slice. Written as `str`. | ||
61 | Str, | ||
62 | |||
63 | /// The pointee of an array slice. Written as `[T]`. | ||
64 | Slice, | ||
65 | |||
66 | /// An array with the given length. Written as `[T; n]`. | ||
67 | Array, | ||
68 | |||
69 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
70 | RawPtr(Mutability), | ||
71 | |||
72 | /// A reference; a pointer with an associated lifetime. Written as | ||
73 | /// `&'a mut T` or `&'a T`. | ||
74 | Ref(Mutability), | ||
75 | |||
76 | /// The anonymous type of a function declaration/definition. Each | ||
77 | /// function has a unique type, which is output (for a function | ||
78 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
79 | /// | ||
80 | /// This includes tuple struct / enum variant constructors as well. | ||
81 | /// | ||
82 | /// For example the type of `bar` here: | ||
83 | /// | ||
84 | /// ``` | ||
85 | /// fn foo() -> i32 { 1 } | ||
86 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
87 | /// ``` | ||
88 | FnDef(CallableDef), | ||
89 | |||
90 | /// A pointer to a function. Written as `fn() -> i32`. | ||
91 | /// | ||
92 | /// For example the type of `bar` here: | ||
93 | /// | ||
94 | /// ``` | ||
95 | /// fn foo() -> i32 { 1 } | ||
96 | /// let bar: fn() -> i32 = foo; | ||
97 | /// ``` | ||
98 | FnPtr { num_args: u16 }, | ||
99 | |||
100 | /// The never type `!`. | ||
101 | Never, | ||
102 | |||
103 | /// A tuple type. For example, `(i32, bool)`. | ||
104 | Tuple { cardinality: u16 }, | ||
105 | |||
106 | /// Represents an associated item like `Iterator::Item`. This is used | ||
107 | /// when we have tried to normalize a projection like `T::Item` but | ||
108 | /// couldn't find a better representation. In that case, we generate | ||
109 | /// an **application type** like `(Iterator::Item)<T>`. | ||
110 | AssociatedType(TypeAlias), | ||
111 | |||
112 | /// The type of a specific closure. | ||
113 | /// | ||
114 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
115 | /// parameter. | ||
116 | Closure { def: DefWithBody, expr: ExprId }, | ||
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 | |||
126 | impl TypeCtor { | ||
127 | pub fn num_ty_params(self, db: &impl HirDatabase) -> usize { | ||
128 | match self { | ||
129 | TypeCtor::Bool | ||
130 | | TypeCtor::Char | ||
131 | | TypeCtor::Int(_) | ||
132 | | TypeCtor::Float(_) | ||
133 | | TypeCtor::Str | ||
134 | | TypeCtor::Never => 0, | ||
135 | TypeCtor::Slice | ||
136 | | TypeCtor::Array | ||
137 | | TypeCtor::RawPtr(_) | ||
138 | | TypeCtor::Ref(_) | ||
139 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure | ||
140 | => 1, | ||
141 | TypeCtor::Adt(adt) => { | ||
142 | let generic_params = db.generic_params(AdtId::from(adt).into()); | ||
143 | generic_params.count_params_including_parent() | ||
144 | } | ||
145 | TypeCtor::FnDef(callable) => { | ||
146 | let generic_params = db.generic_params(callable.into()); | ||
147 | generic_params.count_params_including_parent() | ||
148 | } | ||
149 | TypeCtor::AssociatedType(type_alias) => { | ||
150 | let generic_params = db.generic_params(type_alias.id.into()); | ||
151 | generic_params.count_params_including_parent() | ||
152 | } | ||
153 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, | ||
154 | TypeCtor::Tuple { cardinality } => cardinality as usize, | ||
155 | } | ||
156 | } | ||
157 | |||
158 | pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> { | ||
159 | match self { | ||
160 | TypeCtor::Bool | ||
161 | | TypeCtor::Char | ||
162 | | TypeCtor::Int(_) | ||
163 | | TypeCtor::Float(_) | ||
164 | | TypeCtor::Str | ||
165 | | TypeCtor::Never | ||
166 | | TypeCtor::Slice | ||
167 | | TypeCtor::Array | ||
168 | | TypeCtor::RawPtr(_) | ||
169 | | TypeCtor::Ref(_) | ||
170 | | TypeCtor::FnPtr { .. } | ||
171 | | TypeCtor::Tuple { .. } => None, | ||
172 | TypeCtor::Closure { def, .. } => def.krate(db), | ||
173 | TypeCtor::Adt(adt) => adt.krate(db), | ||
174 | TypeCtor::FnDef(callable) => callable.krate(db), | ||
175 | TypeCtor::AssociatedType(type_alias) => type_alias.krate(db), | ||
176 | } | ||
177 | } | ||
178 | |||
179 | pub fn as_generic_def(self) -> Option<crate::GenericDef> { | ||
180 | match self { | ||
181 | TypeCtor::Bool | ||
182 | | TypeCtor::Char | ||
183 | | TypeCtor::Int(_) | ||
184 | | TypeCtor::Float(_) | ||
185 | | TypeCtor::Str | ||
186 | | TypeCtor::Never | ||
187 | | TypeCtor::Slice | ||
188 | | TypeCtor::Array | ||
189 | | TypeCtor::RawPtr(_) | ||
190 | | TypeCtor::Ref(_) | ||
191 | | TypeCtor::FnPtr { .. } | ||
192 | | TypeCtor::Tuple { .. } | ||
193 | | TypeCtor::Closure { .. } => None, | ||
194 | TypeCtor::Adt(adt) => Some(adt.into()), | ||
195 | TypeCtor::FnDef(callable) => Some(callable.into()), | ||
196 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | ||
202 | /// type like `bool`, a struct, tuple, function pointer, reference or | ||
203 | /// several other things. | ||
204 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
205 | pub struct ApplicationTy { | ||
206 | pub ctor: TypeCtor, | ||
207 | pub parameters: Substs, | ||
208 | } | ||
209 | |||
210 | /// A "projection" type corresponds to an (unnormalized) | ||
211 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | ||
212 | /// trait and all its parameters are fully known. | ||
213 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
214 | pub struct ProjectionTy { | ||
215 | pub associated_ty: TypeAlias, | ||
216 | pub parameters: Substs, | ||
217 | } | ||
218 | |||
219 | impl ProjectionTy { | ||
220 | pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef { | ||
221 | TraitRef { | ||
222 | trait_: self | ||
223 | .associated_ty | ||
224 | .parent_trait(db) | ||
225 | .expect("projection ty without parent trait"), | ||
226 | substs: self.parameters.clone(), | ||
227 | } | ||
228 | } | ||
229 | } | ||
230 | |||
231 | impl TypeWalk for ProjectionTy { | ||
232 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
233 | self.parameters.walk(f); | ||
234 | } | ||
235 | |||
236 | fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { | ||
237 | self.parameters.walk_mut_binders(f, binders); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /// A type. | ||
242 | /// | ||
243 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | ||
244 | /// the same thing (but in a different way). | ||
245 | /// | ||
246 | /// This should be cheap to clone. | ||
247 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
248 | pub enum Ty { | ||
249 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | ||
250 | /// type like `bool`, a struct, tuple, function pointer, reference or | ||
251 | /// several other things. | ||
252 | Apply(ApplicationTy), | ||
253 | |||
254 | /// A "projection" type corresponds to an (unnormalized) | ||
255 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | ||
256 | /// trait and all its parameters are fully known. | ||
257 | Projection(ProjectionTy), | ||
258 | |||
259 | /// A type parameter; for example, `T` in `fn f<T>(x: T) {} | ||
260 | Param { | ||
261 | /// The index of the parameter (starting with parameters from the | ||
262 | /// surrounding impl, then the current function). | ||
263 | idx: u32, | ||
264 | /// The name of the parameter, for displaying. | ||
265 | // FIXME get rid of this | ||
266 | name: Name, | ||
267 | }, | ||
268 | |||
269 | /// A bound type variable. Used during trait resolution to represent Chalk | ||
270 | /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. | ||
271 | Bound(u32), | ||
272 | |||
273 | /// A type variable used during type checking. Not to be confused with a | ||
274 | /// type parameter. | ||
275 | Infer(InferTy), | ||
276 | |||
277 | /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). | ||
278 | /// | ||
279 | /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)` | ||
280 | /// represents the `Self` type inside the bounds. This is currently | ||
281 | /// implicit; Chalk has the `Binders` struct to make it explicit, but it | ||
282 | /// didn't seem worth the overhead yet. | ||
283 | Dyn(Arc<[GenericPredicate]>), | ||
284 | |||
285 | /// An opaque type (`impl Trait`). | ||
286 | /// | ||
287 | /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for | ||
288 | /// more. | ||
289 | Opaque(Arc<[GenericPredicate]>), | ||
290 | |||
291 | /// A placeholder for a type which could not be computed; this is propagated | ||
292 | /// to avoid useless error messages. Doubles as a placeholder where type | ||
293 | /// variables are inserted before type checking, since we want to try to | ||
294 | /// infer a better type here anyway -- for the IDE use case, we want to try | ||
295 | /// to infer as much as possible even in the presence of type errors. | ||
296 | Unknown, | ||
297 | } | ||
298 | |||
299 | /// A list of substitutions for generic parameters. | ||
300 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
301 | pub struct Substs(Arc<[Ty]>); | ||
302 | |||
303 | impl TypeWalk for Substs { | ||
304 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
305 | for t in self.0.iter() { | ||
306 | t.walk(f); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { | ||
311 | for t in make_mut_slice(&mut self.0) { | ||
312 | t.walk_mut_binders(f, binders); | ||
313 | } | ||
314 | } | ||
315 | } | ||
316 | |||
317 | impl Substs { | ||
318 | pub fn empty() -> Substs { | ||
319 | Substs(Arc::new([])) | ||
320 | } | ||
321 | |||
322 | pub fn single(ty: Ty) -> Substs { | ||
323 | Substs(Arc::new([ty])) | ||
324 | } | ||
325 | |||
326 | pub fn prefix(&self, n: usize) -> Substs { | ||
327 | Substs(self.0[..std::cmp::min(self.0.len(), n)].into()) | ||
328 | } | ||
329 | |||
330 | pub fn as_single(&self) -> &Ty { | ||
331 | if self.0.len() != 1 { | ||
332 | panic!("expected substs of len 1, got {:?}", self); | ||
333 | } | ||
334 | &self.0[0] | ||
335 | } | ||
336 | |||
337 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | ||
338 | pub fn identity(generic_params: &GenericParams) -> Substs { | ||
339 | Substs( | ||
340 | generic_params | ||
341 | .params_including_parent() | ||
342 | .into_iter() | ||
343 | .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() }) | ||
344 | .collect(), | ||
345 | ) | ||
346 | } | ||
347 | |||
348 | /// Return Substs that replace each parameter by a bound variable. | ||
349 | pub fn bound_vars(generic_params: &GenericParams) -> Substs { | ||
350 | Substs( | ||
351 | generic_params | ||
352 | .params_including_parent() | ||
353 | .into_iter() | ||
354 | .map(|p| Ty::Bound(p.idx)) | ||
355 | .collect(), | ||
356 | ) | ||
357 | } | ||
358 | |||
359 | pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDef>) -> SubstsBuilder { | ||
360 | let def = def.into(); | ||
361 | let params = db.generic_params(def.into()); | ||
362 | let param_count = params.count_params_including_parent(); | ||
363 | Substs::builder(param_count) | ||
364 | } | ||
365 | |||
366 | pub fn build_for_generics(generic_params: &GenericParams) -> SubstsBuilder { | ||
367 | Substs::builder(generic_params.count_params_including_parent()) | ||
368 | } | ||
369 | |||
370 | pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { | ||
371 | Substs::builder(type_ctor.num_ty_params(db)) | ||
372 | } | ||
373 | |||
374 | fn builder(param_count: usize) -> SubstsBuilder { | ||
375 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } | ||
376 | } | ||
377 | } | ||
378 | |||
379 | #[derive(Debug, Clone)] | ||
380 | pub struct SubstsBuilder { | ||
381 | vec: Vec<Ty>, | ||
382 | param_count: usize, | ||
383 | } | ||
384 | |||
385 | impl SubstsBuilder { | ||
386 | pub fn build(self) -> Substs { | ||
387 | assert_eq!(self.vec.len(), self.param_count); | ||
388 | Substs(self.vec.into()) | ||
389 | } | ||
390 | |||
391 | pub fn push(mut self, ty: Ty) -> Self { | ||
392 | self.vec.push(ty); | ||
393 | self | ||
394 | } | ||
395 | |||
396 | fn remaining(&self) -> usize { | ||
397 | self.param_count - self.vec.len() | ||
398 | } | ||
399 | |||
400 | pub fn fill_with_bound_vars(self, starting_from: u32) -> Self { | ||
401 | self.fill((starting_from..).map(Ty::Bound)) | ||
402 | } | ||
403 | |||
404 | pub fn fill_with_params(self) -> Self { | ||
405 | let start = self.vec.len() as u32; | ||
406 | self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() })) | ||
407 | } | ||
408 | |||
409 | pub fn fill_with_unknown(self) -> Self { | ||
410 | self.fill(iter::repeat(Ty::Unknown)) | ||
411 | } | ||
412 | |||
413 | pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { | ||
414 | self.vec.extend(filler.take(self.remaining())); | ||
415 | assert_eq!(self.remaining(), 0); | ||
416 | self | ||
417 | } | ||
418 | |||
419 | pub fn use_parent_substs(mut self, parent_substs: &Substs) -> Self { | ||
420 | assert!(self.vec.is_empty()); | ||
421 | assert!(parent_substs.len() <= self.param_count); | ||
422 | self.vec.extend(parent_substs.iter().cloned()); | ||
423 | self | ||
424 | } | ||
425 | } | ||
426 | |||
427 | impl Deref for Substs { | ||
428 | type Target = [Ty]; | ||
429 | |||
430 | fn deref(&self) -> &[Ty] { | ||
431 | &self.0 | ||
432 | } | ||
433 | } | ||
434 | |||
435 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. | ||
436 | /// Name to be bikeshedded: TraitBound? TraitImplements? | ||
437 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
438 | pub struct TraitRef { | ||
439 | /// FIXME name? | ||
440 | pub trait_: Trait, | ||
441 | pub substs: Substs, | ||
442 | } | ||
443 | |||
444 | impl TraitRef { | ||
445 | pub fn self_ty(&self) -> &Ty { | ||
446 | &self.substs[0] | ||
447 | } | ||
448 | } | ||
449 | |||
450 | impl TypeWalk for TraitRef { | ||
451 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
452 | self.substs.walk(f); | ||
453 | } | ||
454 | |||
455 | fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { | ||
456 | self.substs.walk_mut_binders(f, binders); | ||
457 | } | ||
458 | } | ||
459 | |||
460 | /// Like `generics::WherePredicate`, but with resolved types: A condition on the | ||
461 | /// parameters of a generic item. | ||
462 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
463 | pub enum GenericPredicate { | ||
464 | /// The given trait needs to be implemented for its type parameters. | ||
465 | Implemented(TraitRef), | ||
466 | /// An associated type bindings like in `Iterator<Item = T>`. | ||
467 | Projection(ProjectionPredicate), | ||
468 | /// We couldn't resolve the trait reference. (If some type parameters can't | ||
469 | /// be resolved, they will just be Unknown). | ||
470 | Error, | ||
471 | } | ||
472 | |||
473 | impl GenericPredicate { | ||
474 | pub fn is_error(&self) -> bool { | ||
475 | match self { | ||
476 | GenericPredicate::Error => true, | ||
477 | _ => false, | ||
478 | } | ||
479 | } | ||
480 | |||
481 | pub fn is_implemented(&self) -> bool { | ||
482 | match self { | ||
483 | GenericPredicate::Implemented(_) => true, | ||
484 | _ => false, | ||
485 | } | ||
486 | } | ||
487 | |||
488 | pub fn trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { | ||
489 | match self { | ||
490 | GenericPredicate::Implemented(tr) => Some(tr.clone()), | ||
491 | GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)), | ||
492 | GenericPredicate::Error => None, | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | |||
497 | impl TypeWalk for GenericPredicate { | ||
498 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
499 | match self { | ||
500 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), | ||
501 | GenericPredicate::Projection(projection_pred) => projection_pred.walk(f), | ||
502 | GenericPredicate::Error => {} | ||
503 | } | ||
504 | } | ||
505 | |||
506 | fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { | ||
507 | match self { | ||
508 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), | ||
509 | GenericPredicate::Projection(projection_pred) => { | ||
510 | projection_pred.walk_mut_binders(f, binders) | ||
511 | } | ||
512 | GenericPredicate::Error => {} | ||
513 | } | ||
514 | } | ||
515 | } | ||
516 | |||
517 | /// Basically a claim (currently not validated / checked) that the contained | ||
518 | /// type / trait ref contains no inference variables; any inference variables it | ||
519 | /// contained have been replaced by bound variables, and `num_vars` tells us how | ||
520 | /// many there are. This is used to erase irrelevant differences between types | ||
521 | /// before using them in queries. | ||
522 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
523 | pub struct Canonical<T> { | ||
524 | pub value: T, | ||
525 | pub num_vars: usize, | ||
526 | } | ||
527 | |||
528 | /// A function signature as seen by type inference: Several parameter types and | ||
529 | /// one return type. | ||
530 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
531 | pub struct FnSig { | ||
532 | params_and_return: Arc<[Ty]>, | ||
533 | } | ||
534 | |||
535 | impl FnSig { | ||
536 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig { | ||
537 | params.push(ret); | ||
538 | FnSig { params_and_return: params.into() } | ||
539 | } | ||
540 | |||
541 | pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig { | ||
542 | FnSig { params_and_return: Arc::clone(&substs.0) } | ||
543 | } | ||
544 | |||
545 | pub fn params(&self) -> &[Ty] { | ||
546 | &self.params_and_return[0..self.params_and_return.len() - 1] | ||
547 | } | ||
548 | |||
549 | pub fn ret(&self) -> &Ty { | ||
550 | &self.params_and_return[self.params_and_return.len() - 1] | ||
551 | } | ||
552 | } | ||
553 | |||
554 | impl TypeWalk for FnSig { | ||
555 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
556 | for t in self.params_and_return.iter() { | ||
557 | t.walk(f); | ||
558 | } | ||
559 | } | ||
560 | |||
561 | fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { | ||
562 | for t in make_mut_slice(&mut self.params_and_return) { | ||
563 | t.walk_mut_binders(f, binders); | ||
564 | } | ||
565 | } | ||
566 | } | ||
567 | |||
568 | impl Ty { | ||
569 | pub fn simple(ctor: TypeCtor) -> Ty { | ||
570 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() }) | ||
571 | } | ||
572 | pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty { | ||
573 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) }) | ||
574 | } | ||
575 | pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty { | ||
576 | Ty::Apply(ApplicationTy { ctor, parameters }) | ||
577 | } | ||
578 | pub fn unit() -> Self { | ||
579 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) | ||
580 | } | ||
581 | |||
582 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | ||
583 | match self { | ||
584 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | ||
585 | Some((parameters.as_single(), *mutability)) | ||
586 | } | ||
587 | _ => None, | ||
588 | } | ||
589 | } | ||
590 | |||
591 | pub fn as_adt(&self) -> Option<(Adt, &Substs)> { | ||
592 | match self { | ||
593 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { | ||
594 | Some((*adt_def, parameters)) | ||
595 | } | ||
596 | _ => None, | ||
597 | } | ||
598 | } | ||
599 | |||
600 | pub fn as_tuple(&self) -> Option<&Substs> { | ||
601 | match self { | ||
602 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { | ||
603 | Some(parameters) | ||
604 | } | ||
605 | _ => None, | ||
606 | } | ||
607 | } | ||
608 | |||
609 | pub fn as_callable(&self) -> Option<(CallableDef, &Substs)> { | ||
610 | match self { | ||
611 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => { | ||
612 | Some((*callable_def, parameters)) | ||
613 | } | ||
614 | _ => None, | ||
615 | } | ||
616 | } | ||
617 | |||
618 | fn builtin_deref(&self) -> Option<Ty> { | ||
619 | match self { | ||
620 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
621 | TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), | ||
622 | TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), | ||
623 | _ => None, | ||
624 | }, | ||
625 | _ => None, | ||
626 | } | ||
627 | } | ||
628 | |||
629 | fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> { | ||
630 | match self { | ||
631 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
632 | TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)), | ||
633 | TypeCtor::FnDef(def) => { | ||
634 | let sig = db.callable_item_signature(def); | ||
635 | Some(sig.subst(&a_ty.parameters)) | ||
636 | } | ||
637 | TypeCtor::Closure { .. } => { | ||
638 | let sig_param = &a_ty.parameters[0]; | ||
639 | sig_param.callable_sig(db) | ||
640 | } | ||
641 | _ => None, | ||
642 | }, | ||
643 | _ => None, | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /// If this is a type with type parameters (an ADT or function), replaces | ||
648 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | ||
649 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | ||
650 | /// `Option<u32>` afterwards.) | ||
651 | pub fn apply_substs(self, substs: Substs) -> Ty { | ||
652 | match self { | ||
653 | Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { | ||
654 | assert_eq!(previous_substs.len(), substs.len()); | ||
655 | Ty::Apply(ApplicationTy { ctor, parameters: substs }) | ||
656 | } | ||
657 | _ => self, | ||
658 | } | ||
659 | } | ||
660 | |||
661 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | ||
662 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | ||
663 | pub fn substs(&self) -> Option<Substs> { | ||
664 | match self { | ||
665 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | ||
666 | _ => None, | ||
667 | } | ||
668 | } | ||
669 | |||
670 | /// If this is an `impl Trait` or `dyn Trait`, returns that trait. | ||
671 | pub fn inherent_trait(&self) -> Option<Trait> { | ||
672 | match self { | ||
673 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | ||
674 | predicates.iter().find_map(|pred| match pred { | ||
675 | GenericPredicate::Implemented(tr) => Some(tr.trait_), | ||
676 | _ => None, | ||
677 | }) | ||
678 | } | ||
679 | _ => None, | ||
680 | } | ||
681 | } | ||
682 | } | ||
683 | |||
684 | /// This allows walking structures that contain types to do something with those | ||
685 | /// types, similar to Chalk's `Fold` trait. | ||
686 | pub trait TypeWalk { | ||
687 | fn walk(&self, f: &mut impl FnMut(&Ty)); | ||
688 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | ||
689 | self.walk_mut_binders(&mut |ty, _binders| f(ty), 0); | ||
690 | } | ||
691 | /// Walk the type, counting entered binders. | ||
692 | /// | ||
693 | /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers | ||
694 | /// to the innermost binder, 1 to the next, etc.. So when we want to | ||
695 | /// substitute a certain bound variable, we can't just walk the whole type | ||
696 | /// and blindly replace each instance of a certain index; when we 'enter' | ||
697 | /// things that introduce new bound variables, we have to keep track of | ||
698 | /// that. Currently, the only thing that introduces bound variables on our | ||
699 | /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound | ||
700 | /// variable for the self type. | ||
701 | fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize); | ||
702 | |||
703 | fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self | ||
704 | where | ||
705 | Self: Sized, | ||
706 | { | ||
707 | self.walk_mut(&mut |ty_mut| { | ||
708 | let ty = mem::replace(ty_mut, Ty::Unknown); | ||
709 | *ty_mut = f(ty); | ||
710 | }); | ||
711 | self | ||
712 | } | ||
713 | |||
714 | /// Replaces type parameters in this type using the given `Substs`. (So e.g. | ||
715 | /// if `self` is `&[T]`, where type parameter T has index 0, and the | ||
716 | /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) | ||
717 | fn subst(self, substs: &Substs) -> Self | ||
718 | where | ||
719 | Self: Sized, | ||
720 | { | ||
721 | self.fold(&mut |ty| match ty { | ||
722 | Ty::Param { idx, name } => { | ||
723 | substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name }) | ||
724 | } | ||
725 | ty => ty, | ||
726 | }) | ||
727 | } | ||
728 | |||
729 | /// Substitutes `Ty::Bound` vars (as opposed to type parameters). | ||
730 | fn subst_bound_vars(mut self, substs: &Substs) -> Self | ||
731 | where | ||
732 | Self: Sized, | ||
733 | { | ||
734 | self.walk_mut_binders( | ||
735 | &mut |ty, binders| match ty { | ||
736 | &mut Ty::Bound(idx) => { | ||
737 | if idx as usize >= binders && (idx as usize - binders) < substs.len() { | ||
738 | *ty = substs.0[idx as usize - binders].clone(); | ||
739 | } | ||
740 | } | ||
741 | _ => {} | ||
742 | }, | ||
743 | 0, | ||
744 | ); | ||
745 | self | ||
746 | } | ||
747 | |||
748 | /// Shifts up `Ty::Bound` vars by `n`. | ||
749 | fn shift_bound_vars(self, n: i32) -> Self | ||
750 | where | ||
751 | Self: Sized, | ||
752 | { | ||
753 | self.fold(&mut |ty| match ty { | ||
754 | Ty::Bound(idx) => { | ||
755 | assert!(idx as i32 >= -n); | ||
756 | Ty::Bound((idx as i32 + n) as u32) | ||
757 | } | ||
758 | ty => ty, | ||
759 | }) | ||
760 | } | ||
761 | } | ||
762 | |||
763 | impl TypeWalk for Ty { | ||
764 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
765 | match self { | ||
766 | Ty::Apply(a_ty) => { | ||
767 | for t in a_ty.parameters.iter() { | ||
768 | t.walk(f); | ||
769 | } | ||
770 | } | ||
771 | Ty::Projection(p_ty) => { | ||
772 | for t in p_ty.parameters.iter() { | ||
773 | t.walk(f); | ||
774 | } | ||
775 | } | ||
776 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | ||
777 | for p in predicates.iter() { | ||
778 | p.walk(f); | ||
779 | } | ||
780 | } | ||
781 | Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | ||
782 | } | ||
783 | f(self); | ||
784 | } | ||
785 | |||
786 | fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) { | ||
787 | match self { | ||
788 | Ty::Apply(a_ty) => { | ||
789 | a_ty.parameters.walk_mut_binders(f, binders); | ||
790 | } | ||
791 | Ty::Projection(p_ty) => { | ||
792 | p_ty.parameters.walk_mut_binders(f, binders); | ||
793 | } | ||
794 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | ||
795 | for p in make_mut_slice(predicates) { | ||
796 | p.walk_mut_binders(f, binders + 1); | ||
797 | } | ||
798 | } | ||
799 | Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | ||
800 | } | ||
801 | f(self, binders); | ||
802 | } | ||
803 | } | ||
804 | |||
805 | impl HirDisplay for &Ty { | ||
806 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | ||
807 | HirDisplay::hir_fmt(*self, f) | ||
808 | } | ||
809 | } | ||
810 | |||
811 | impl HirDisplay for ApplicationTy { | ||
812 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | ||
813 | if f.should_truncate() { | ||
814 | return write!(f, "…"); | ||
815 | } | ||
816 | |||
817 | match self.ctor { | ||
818 | TypeCtor::Bool => write!(f, "bool")?, | ||
819 | TypeCtor::Char => write!(f, "char")?, | ||
820 | TypeCtor::Int(t) => write!(f, "{}", t)?, | ||
821 | TypeCtor::Float(t) => write!(f, "{}", t)?, | ||
822 | TypeCtor::Str => write!(f, "str")?, | ||
823 | TypeCtor::Slice => { | ||
824 | let t = self.parameters.as_single(); | ||
825 | write!(f, "[{}]", t.display(f.db))?; | ||
826 | } | ||
827 | TypeCtor::Array => { | ||
828 | let t = self.parameters.as_single(); | ||
829 | write!(f, "[{};_]", t.display(f.db))?; | ||
830 | } | ||
831 | TypeCtor::RawPtr(m) => { | ||
832 | let t = self.parameters.as_single(); | ||
833 | write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?; | ||
834 | } | ||
835 | TypeCtor::Ref(m) => { | ||
836 | let t = self.parameters.as_single(); | ||
837 | write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?; | ||
838 | } | ||
839 | TypeCtor::Never => write!(f, "!")?, | ||
840 | TypeCtor::Tuple { .. } => { | ||
841 | let ts = &self.parameters; | ||
842 | if ts.len() == 1 { | ||
843 | write!(f, "({},)", ts[0].display(f.db))?; | ||
844 | } else { | ||
845 | write!(f, "(")?; | ||
846 | f.write_joined(&*ts.0, ", ")?; | ||
847 | write!(f, ")")?; | ||
848 | } | ||
849 | } | ||
850 | TypeCtor::FnPtr { .. } => { | ||
851 | let sig = FnSig::from_fn_ptr_substs(&self.parameters); | ||
852 | write!(f, "fn(")?; | ||
853 | f.write_joined(sig.params(), ", ")?; | ||
854 | write!(f, ") -> {}", sig.ret().display(f.db))?; | ||
855 | } | ||
856 | TypeCtor::FnDef(def) => { | ||
857 | let sig = f.db.callable_item_signature(def); | ||
858 | let name = match def { | ||
859 | CallableDef::Function(ff) => ff.name(f.db), | ||
860 | CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing), | ||
861 | CallableDef::EnumVariant(e) => e.name(f.db).unwrap_or_else(Name::missing), | ||
862 | }; | ||
863 | match def { | ||
864 | CallableDef::Function(_) => write!(f, "fn {}", name)?, | ||
865 | CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?, | ||
866 | } | ||
867 | if self.parameters.len() > 0 { | ||
868 | write!(f, "<")?; | ||
869 | f.write_joined(&*self.parameters.0, ", ")?; | ||
870 | write!(f, ">")?; | ||
871 | } | ||
872 | write!(f, "(")?; | ||
873 | f.write_joined(sig.params(), ", ")?; | ||
874 | write!(f, ") -> {}", sig.ret().display(f.db))?; | ||
875 | } | ||
876 | TypeCtor::Adt(def_id) => { | ||
877 | let name = match def_id { | ||
878 | Adt::Struct(s) => s.name(f.db), | ||
879 | Adt::Union(u) => u.name(f.db), | ||
880 | Adt::Enum(e) => e.name(f.db), | ||
881 | } | ||
882 | .unwrap_or_else(Name::missing); | ||
883 | write!(f, "{}", name)?; | ||
884 | if self.parameters.len() > 0 { | ||
885 | write!(f, "<")?; | ||
886 | f.write_joined(&*self.parameters.0, ", ")?; | ||
887 | write!(f, ">")?; | ||
888 | } | ||
889 | } | ||
890 | TypeCtor::AssociatedType(type_alias) => { | ||
891 | let trait_name = type_alias | ||
892 | .parent_trait(f.db) | ||
893 | .and_then(|t| t.name(f.db)) | ||
894 | .unwrap_or_else(Name::missing); | ||
895 | let name = type_alias.name(f.db); | ||
896 | write!(f, "{}::{}", trait_name, name)?; | ||
897 | if self.parameters.len() > 0 { | ||
898 | write!(f, "<")?; | ||
899 | f.write_joined(&*self.parameters.0, ", ")?; | ||
900 | write!(f, ">")?; | ||
901 | } | ||
902 | } | ||
903 | TypeCtor::Closure { .. } => { | ||
904 | let sig = self.parameters[0] | ||
905 | .callable_sig(f.db) | ||
906 | .expect("first closure parameter should contain signature"); | ||
907 | write!(f, "|")?; | ||
908 | f.write_joined(sig.params(), ", ")?; | ||
909 | write!(f, "| -> {}", sig.ret().display(f.db))?; | ||
910 | } | ||
911 | } | ||
912 | Ok(()) | ||
913 | } | ||
914 | } | ||
915 | |||
916 | impl HirDisplay for ProjectionTy { | ||
917 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | ||
918 | if f.should_truncate() { | ||
919 | return write!(f, "…"); | ||
920 | } | ||
921 | |||
922 | let trait_name = self | ||
923 | .associated_ty | ||
924 | .parent_trait(f.db) | ||
925 | .and_then(|t| t.name(f.db)) | ||
926 | .unwrap_or_else(Name::missing); | ||
927 | write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; | ||
928 | if self.parameters.len() > 1 { | ||
929 | write!(f, "<")?; | ||
930 | f.write_joined(&self.parameters[1..], ", ")?; | ||
931 | write!(f, ">")?; | ||
932 | } | ||
933 | write!(f, ">::{}", self.associated_ty.name(f.db))?; | ||
934 | Ok(()) | ||
935 | } | ||
936 | } | ||
937 | |||
938 | impl HirDisplay for Ty { | ||
939 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | ||
940 | if f.should_truncate() { | ||
941 | return write!(f, "…"); | ||
942 | } | ||
943 | |||
944 | match self { | ||
945 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, | ||
946 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, | ||
947 | Ty::Param { name, .. } => write!(f, "{}", name)?, | ||
948 | Ty::Bound(idx) => write!(f, "?{}", idx)?, | ||
949 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | ||
950 | match self { | ||
951 | Ty::Dyn(_) => write!(f, "dyn ")?, | ||
952 | Ty::Opaque(_) => write!(f, "impl ")?, | ||
953 | _ => unreachable!(), | ||
954 | }; | ||
955 | // Note: This code is written to produce nice results (i.e. | ||
956 | // corresponding to surface Rust) for types that can occur in | ||
957 | // actual Rust. It will have weird results if the predicates | ||
958 | // aren't as expected (i.e. self types = $0, projection | ||
959 | // predicates for a certain trait come after the Implemented | ||
960 | // predicate for that trait). | ||
961 | let mut first = true; | ||
962 | let mut angle_open = false; | ||
963 | for p in predicates.iter() { | ||
964 | match p { | ||
965 | GenericPredicate::Implemented(trait_ref) => { | ||
966 | if angle_open { | ||
967 | write!(f, ">")?; | ||
968 | } | ||
969 | if !first { | ||
970 | write!(f, " + ")?; | ||
971 | } | ||
972 | // We assume that the self type is $0 (i.e. the | ||
973 | // existential) here, which is the only thing that's | ||
974 | // possible in actual Rust, and hence don't print it | ||
975 | write!( | ||
976 | f, | ||
977 | "{}", | ||
978 | trait_ref.trait_.name(f.db).unwrap_or_else(Name::missing) | ||
979 | )?; | ||
980 | if trait_ref.substs.len() > 1 { | ||
981 | write!(f, "<")?; | ||
982 | f.write_joined(&trait_ref.substs[1..], ", ")?; | ||
983 | // there might be assoc type bindings, so we leave the angle brackets open | ||
984 | angle_open = true; | ||
985 | } | ||
986 | } | ||
987 | GenericPredicate::Projection(projection_pred) => { | ||
988 | // in types in actual Rust, these will always come | ||
989 | // after the corresponding Implemented predicate | ||
990 | if angle_open { | ||
991 | write!(f, ", ")?; | ||
992 | } else { | ||
993 | write!(f, "<")?; | ||
994 | angle_open = true; | ||
995 | } | ||
996 | let name = projection_pred.projection_ty.associated_ty.name(f.db); | ||
997 | write!(f, "{} = ", name)?; | ||
998 | projection_pred.ty.hir_fmt(f)?; | ||
999 | } | ||
1000 | GenericPredicate::Error => { | ||
1001 | if angle_open { | ||
1002 | // impl Trait<X, {error}> | ||
1003 | write!(f, ", ")?; | ||
1004 | } else if !first { | ||
1005 | // impl Trait + {error} | ||
1006 | write!(f, " + ")?; | ||
1007 | } | ||
1008 | p.hir_fmt(f)?; | ||
1009 | } | ||
1010 | } | ||
1011 | first = false; | ||
1012 | } | ||
1013 | if angle_open { | ||
1014 | write!(f, ">")?; | ||
1015 | } | ||
1016 | } | ||
1017 | Ty::Unknown => write!(f, "{{unknown}}")?, | ||
1018 | Ty::Infer(..) => write!(f, "_")?, | ||
1019 | } | ||
1020 | Ok(()) | ||
1021 | } | ||
1022 | } | ||
1023 | |||
1024 | impl TraitRef { | ||
1025 | fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result { | ||
1026 | if f.should_truncate() { | ||
1027 | return write!(f, "…"); | ||
1028 | } | ||
1029 | |||
1030 | self.substs[0].hir_fmt(f)?; | ||
1031 | if use_as { | ||
1032 | write!(f, " as ")?; | ||
1033 | } else { | ||
1034 | write!(f, ": ")?; | ||
1035 | } | ||
1036 | write!(f, "{}", self.trait_.name(f.db).unwrap_or_else(Name::missing))?; | ||
1037 | if self.substs.len() > 1 { | ||
1038 | write!(f, "<")?; | ||
1039 | f.write_joined(&self.substs[1..], ", ")?; | ||
1040 | write!(f, ">")?; | ||
1041 | } | ||
1042 | Ok(()) | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1046 | impl HirDisplay for TraitRef { | ||
1047 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | ||
1048 | self.hir_fmt_ext(f, false) | ||
1049 | } | ||
1050 | } | ||
1051 | |||
1052 | impl HirDisplay for &GenericPredicate { | ||
1053 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | ||
1054 | HirDisplay::hir_fmt(*self, f) | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | impl HirDisplay for GenericPredicate { | ||
1059 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | ||
1060 | if f.should_truncate() { | ||
1061 | return write!(f, "…"); | ||
1062 | } | ||
1063 | |||
1064 | match self { | ||
1065 | GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, | ||
1066 | GenericPredicate::Projection(projection_pred) => { | ||
1067 | write!(f, "<")?; | ||
1068 | projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; | ||
1069 | write!( | ||
1070 | f, | ||
1071 | ">::{} = {}", | ||
1072 | projection_pred.projection_ty.associated_ty.name(f.db), | ||
1073 | projection_pred.ty.display(f.db) | ||
1074 | )?; | ||
1075 | } | ||
1076 | GenericPredicate::Error => write!(f, "{{error}}")?, | ||
1077 | } | ||
1078 | Ok(()) | ||
1079 | } | ||
1080 | } | ||
1081 | |||
1082 | impl HirDisplay for Obligation { | ||
1083 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { | ||
1084 | match self { | ||
1085 | Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)), | ||
1086 | Obligation::Projection(proj) => write!( | ||
1087 | f, | ||
1088 | "Normalize({} => {})", | ||
1089 | proj.projection_ty.display(f.db), | ||
1090 | proj.ty.display(f.db) | ||
1091 | ), | ||
1092 | } | ||
1093 | } | ||
1094 | } | ||
diff --git a/crates/ra_hir/src/util.rs b/crates/ra_hir/src/util.rs deleted file mode 100644 index 0095ee45d..000000000 --- a/crates/ra_hir/src/util.rs +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | //! Internal utility functions. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | /// Helper for mutating `Arc<[T]>` (i.e. `Arc::make_mut` for Arc slices). | ||
6 | /// The underlying values are cloned if there are other strong references. | ||
7 | pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] { | ||
8 | if Arc::get_mut(a).is_none() { | ||
9 | *a = a.iter().cloned().collect(); | ||
10 | } | ||
11 | Arc::get_mut(a).unwrap() | ||
12 | } | ||
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index c9f30923e..3666529b0 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -12,25 +12,25 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, | 14 | db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, |
15 | LocalEnumVariantId, LocalStructFieldId, StructOrUnionId, VariantId, | 15 | LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | /// Note that we use `StructData` for unions as well! | 18 | /// Note that we use `StructData` for unions as well! |
19 | #[derive(Debug, Clone, PartialEq, Eq)] | 19 | #[derive(Debug, Clone, PartialEq, Eq)] |
20 | pub struct StructData { | 20 | pub struct StructData { |
21 | pub name: Option<Name>, | 21 | pub name: Name, |
22 | pub variant_data: Arc<VariantData>, | 22 | pub variant_data: Arc<VariantData>, |
23 | } | 23 | } |
24 | 24 | ||
25 | #[derive(Debug, Clone, PartialEq, Eq)] | 25 | #[derive(Debug, Clone, PartialEq, Eq)] |
26 | pub struct EnumData { | 26 | pub struct EnumData { |
27 | pub name: Option<Name>, | 27 | pub name: Name, |
28 | pub variants: Arena<LocalEnumVariantId, EnumVariantData>, | 28 | pub variants: Arena<LocalEnumVariantId, EnumVariantData>, |
29 | } | 29 | } |
30 | 30 | ||
31 | #[derive(Debug, Clone, PartialEq, Eq)] | 31 | #[derive(Debug, Clone, PartialEq, Eq)] |
32 | pub struct EnumVariantData { | 32 | pub struct EnumVariantData { |
33 | pub name: Option<Name>, | 33 | pub name: Name, |
34 | pub variant_data: Arc<VariantData>, | 34 | pub variant_data: Arc<VariantData>, |
35 | } | 35 | } |
36 | 36 | ||
@@ -49,26 +49,38 @@ pub struct StructFieldData { | |||
49 | } | 49 | } |
50 | 50 | ||
51 | impl StructData { | 51 | impl StructData { |
52 | pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructOrUnionId) -> Arc<StructData> { | 52 | pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc<StructData> { |
53 | let src = id.source(db); | 53 | let src = id.source(db); |
54 | let name = src.value.name().map(|n| n.as_name()); | 54 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); |
55 | let variant_data = VariantData::new(src.value.kind()); | 55 | let variant_data = VariantData::new(src.value.kind()); |
56 | let variant_data = Arc::new(variant_data); | 56 | let variant_data = Arc::new(variant_data); |
57 | Arc::new(StructData { name, variant_data }) | 57 | Arc::new(StructData { name, variant_data }) |
58 | } | 58 | } |
59 | pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc<StructData> { | ||
60 | let src = id.source(db); | ||
61 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); | ||