aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock326
-rw-r--r--README.md2
-rw-r--r--crates/ra_assists/src/assists/add_explicit_type.rs13
-rw-r--r--crates/ra_assists/src/assists/add_new.rs4
-rw-r--r--crates/ra_assists/src/assists/fill_match_arms.rs7
-rw-r--r--crates/ra_assists/src/test_db.rs3
-rw-r--r--crates/ra_batch/Cargo.toml2
-rw-r--r--crates/ra_batch/src/lib.rs2
-rw-r--r--crates/ra_cli/Cargo.toml3
-rw-r--r--crates/ra_cli/src/analysis_bench.rs6
-rw-r--r--crates/ra_cli/src/analysis_stats.rs14
-rw-r--r--crates/ra_cli/src/main.rs3
-rw-r--r--crates/ra_cli/src/progress_report.rs120
-rw-r--r--crates/ra_db/Cargo.toml2
-rw-r--r--crates/ra_db/src/lib.rs2
-rw-r--r--crates/ra_hir/Cargo.toml19
-rw-r--r--crates/ra_hir/src/code_model.rs449
-rw-r--r--crates/ra_hir/src/code_model/src.rs12
-rw-r--r--crates/ra_hir/src/db.rs132
-rw-r--r--crates/ra_hir/src/diagnostics.rs86
-rw-r--r--crates/ra_hir/src/from_id.rs104
-rw-r--r--crates/ra_hir/src/from_source.rs26
-rw-r--r--crates/ra_hir/src/lib.rs11
-rw-r--r--crates/ra_hir/src/source_binder.rs113
-rw-r--r--crates/ra_hir/src/ty.rs1092
-rw-r--r--crates/ra_hir/src/util.rs12
-rw-r--r--crates/ra_hir_def/src/adt.rs43
-rw-r--r--crates/ra_hir_def/src/attr.rs6
-rw-r--r--crates/ra_hir_def/src/body.rs7
-rw-r--r--crates/ra_hir_def/src/data.rs60
-rw-r--r--crates/ra_hir_def/src/db.rs12
-rw-r--r--crates/ra_hir_def/src/docs.rs6
-rw-r--r--crates/ra_hir_def/src/generics.rs6
-rw-r--r--crates/ra_hir_def/src/lang_item.rs4
-rw-r--r--crates/ra_hir_def/src/lib.rs57
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs36
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs16
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs13
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs7
-rw-r--r--crates/ra_hir_def/src/path.rs2
-rw-r--r--crates/ra_hir_def/src/resolver.rs12
-rw-r--r--crates/ra_hir_def/src/test_db.rs4
-rw-r--r--crates/ra_hir_expand/src/lib.rs14
-rw-r--r--crates/ra_hir_expand/src/test_db.rs4
-rw-r--r--crates/ra_hir_ty/Cargo.toml32
-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.rs119
-rw-r--r--crates/ra_hir_ty/src/diagnostics.rs91
-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.rs1138
-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.rs84
-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.toml4
-rw-r--r--crates/ra_lsp_server/src/cargo_target_spec.rs2
-rw-r--r--crates/ra_lsp_server/src/conv.rs6
-rw-r--r--crates/ra_lsp_server/src/lib.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs6
-rw-r--r--crates/ra_lsp_server/src/main_loop/subscriptions.rs2
-rw-r--r--crates/ra_lsp_server/src/world.rs2
-rw-r--r--crates/ra_parser/src/grammar/items.rs10
-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.rs1
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs11
-rw-r--r--crates/ra_syntax/src/ast/generated.rs54
-rw-r--r--crates/ra_syntax/src/grammar.ron17
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt4
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt2
-rw-r--r--docs/dev/README.md2
-rw-r--r--docs/dev/architecture.md12
-rw-r--r--docs/dev/guide.md24
-rw-r--r--[-rwxr-xr-x]editors/code/src/utils/terminateProcess.sh0
-rw-r--r--xtask/tests/tidy-tests/docs.rs3
150 files changed, 3558 insertions, 3077 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8f7783deb..2557b5e59 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,7 +10,7 @@ dependencies = [
10 10
11[[package]] 11[[package]]
12name = "anyhow" 12name = "anyhow"
13version = "1.0.22" 13version = "1.0.24"
14source = "registry+https://github.com/rust-lang/crates.io-index" 14source = "registry+https://github.com/rust-lang/crates.io-index"
15 15
16[[package]] 16[[package]]
@@ -105,9 +105,9 @@ version = "0.9.0"
105source = "registry+https://github.com/rust-lang/crates.io-index" 105source = "registry+https://github.com/rust-lang/crates.io-index"
106dependencies = [ 106dependencies = [
107 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 107 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
108 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 108 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
109 "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 109 "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
110 "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", 110 "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
111] 111]
112 112
113[[package]] 113[[package]]
@@ -123,7 +123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
123[[package]] 123[[package]]
124name = "chalk-derive" 124name = "chalk-derive"
125version = "0.1.0" 125version = "0.1.0"
126source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" 126source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30"
127dependencies = [ 127dependencies = [
128 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 128 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
129 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 129 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -133,9 +133,9 @@ dependencies = [
133[[package]] 133[[package]]
134name = "chalk-engine" 134name = "chalk-engine"
135version = "0.9.0" 135version = "0.9.0"
136source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" 136source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30"
137dependencies = [ 137dependencies = [
138 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 138 "chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
139 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 139 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
140 "stacker 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 140 "stacker 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
141] 141]
@@ -143,18 +143,18 @@ dependencies = [
143[[package]] 143[[package]]
144name = "chalk-ir" 144name = "chalk-ir"
145version = "0.1.0" 145version = "0.1.0"
146source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" 146source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30"
147dependencies = [ 147dependencies = [
148 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 148 "chalk-derive 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
149 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 149 "chalk-engine 0.9.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
150 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 150 "chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
151 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", 151 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
152] 152]
153 153
154[[package]] 154[[package]]
155name = "chalk-macros" 155name = "chalk-macros"
156version = "0.1.1" 156version = "0.1.1"
157source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" 157source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30"
158dependencies = [ 158dependencies = [
159 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 159 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
160] 160]
@@ -162,38 +162,37 @@ dependencies = [
162[[package]] 162[[package]]
163name = "chalk-rust-ir" 163name = "chalk-rust-ir"
164version = "0.1.0" 164version = "0.1.0"
165source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" 165source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30"
166dependencies = [ 166dependencies = [
167 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 167 "chalk-derive 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
168 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 168 "chalk-engine 0.9.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
169 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 169 "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
170 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 170 "chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
171] 171]
172 172
173[[package]] 173[[package]]
174name = "chalk-solve" 174name = "chalk-solve"
175version = "0.1.0" 175version = "0.1.0"
176source = "git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478#a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" 176source = "git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30#095cd38a4f16337913bba487f2055b9ca0179f30"
177dependencies = [ 177dependencies = [
178 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 178 "chalk-derive 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
179 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 179 "chalk-engine 0.9.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
180 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 180 "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
181 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 181 "chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
182 "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)", 182 "chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
183 "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", 183 "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
184 "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 184 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
185 "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", 185 "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
186 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 186 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
187] 187]
188 188
189[[package]] 189[[package]]
190name = "chrono" 190name = "chrono"
191version = "0.4.9" 191version = "0.4.10"
192source = "registry+https://github.com/rust-lang/crates.io-index" 192source = "registry+https://github.com/rust-lang/crates.io-index"
193dependencies = [ 193dependencies = [
194 "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
195 "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", 194 "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
196 "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 195 "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
197 "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 196 "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
198] 197]
199 198
@@ -227,7 +226,6 @@ dependencies = [
227 "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 226 "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
228 "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 227 "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
229 "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 228 "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
230 "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
231 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 229 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
232] 230]
233 231
@@ -293,16 +291,6 @@ dependencies = [
293] 291]
294 292
295[[package]] 293[[package]]
296name = "derive-new"
297version = "0.5.8"
298source = "registry+https://github.com/rust-lang/crates.io-index"
299dependencies = [
300 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
301 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
302 "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
303]
304
305[[package]]
306name = "difference" 294name = "difference"
307version = "2.0.0" 295version = "2.0.0"
308source = "registry+https://github.com/rust-lang/crates.io-index" 296source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -356,7 +344,7 @@ name = "flexi_logger"
356version = "0.14.5" 344version = "0.14.5"
357source = "registry+https://github.com/rust-lang/crates.io-index" 345source = "registry+https://github.com/rust-lang/crates.io-index"
358dependencies = [ 346dependencies = [
359 "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", 347 "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
360 "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 348 "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
361 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 349 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
362 "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 350 "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -472,7 +460,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
472dependencies = [ 460dependencies = [
473 "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 461 "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
474 "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 462 "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
475 "unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 463 "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
476] 464]
477 465
478[[package]] 466[[package]]
@@ -484,17 +472,6 @@ dependencies = [
484] 472]
485 473
486[[package]] 474[[package]]
487name = "indicatif"
488version = "0.13.0"
489source = "registry+https://github.com/rust-lang/crates.io-index"
490dependencies = [
491 "console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
492 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
493 "number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
494 "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
495]
496
497[[package]]
498name = "inotify" 475name = "inotify"
499version = "0.6.1" 476version = "0.6.1"
500source = "registry+https://github.com/rust-lang/crates.io-index" 477source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -520,8 +497,8 @@ dependencies = [
520 "console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 497 "console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
521 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 498 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
522 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 499 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
523 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 500 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
524 "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", 501 "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
525 "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", 502 "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
526 "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 503 "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
527] 504]
@@ -536,7 +513,7 @@ dependencies = [
536 513
537[[package]] 514[[package]]
538name = "itertools" 515name = "itertools"
539version = "0.8.1" 516version = "0.8.2"
540source = "registry+https://github.com/rust-lang/crates.io-index" 517source = "registry+https://github.com/rust-lang/crates.io-index"
541dependencies = [ 518dependencies = [
542 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 519 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -622,7 +599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
622 599
623[[package]] 600[[package]]
624name = "lock_api" 601name = "lock_api"
625version = "0.3.1" 602version = "0.3.2"
626source = "registry+https://github.com/rust-lang/crates.io-index" 603source = "registry+https://github.com/rust-lang/crates.io-index"
627dependencies = [ 604dependencies = [
628 "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 605 "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -643,8 +620,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
643dependencies = [ 620dependencies = [
644 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 621 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
645 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 622 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
646 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 623 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
647 "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", 624 "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
648] 625]
649 626
650[[package]] 627[[package]]
@@ -653,8 +630,8 @@ version = "0.61.0"
653source = "registry+https://github.com/rust-lang/crates.io-index" 630source = "registry+https://github.com/rust-lang/crates.io-index"
654dependencies = [ 631dependencies = [
655 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 632 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
656 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 633 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
657 "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", 634 "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
658 "serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 635 "serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
659 "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 636 "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
660] 637]
@@ -665,11 +642,6 @@ version = "0.1.8"
665source = "registry+https://github.com/rust-lang/crates.io-index" 642source = "registry+https://github.com/rust-lang/crates.io-index"
666 643
667[[package]] 644[[package]]
668name = "maybe-uninit"
669version = "2.0.0"
670source = "registry+https://github.com/rust-lang/crates.io-index"
671
672[[package]]
673name = "memchr" 645name = "memchr"
674version = "2.2.1" 646version = "2.2.1"
675source = "registry+https://github.com/rust-lang/crates.io-index" 647source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -684,9 +656,10 @@ dependencies = [
684 656
685[[package]] 657[[package]]
686name = "mio" 658name = "mio"
687version = "0.6.19" 659version = "0.6.21"
688source = "registry+https://github.com/rust-lang/crates.io-index" 660source = "registry+https://github.com/rust-lang/crates.io-index"
689dependencies = [ 661dependencies = [
662 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
690 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 663 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
691 "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 664 "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
692 "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 665 "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -706,7 +679,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
706dependencies = [ 679dependencies = [
707 "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 680 "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
708 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 681 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
709 "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", 682 "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
710 "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 683 "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
711] 684]
712 685
@@ -743,7 +716,7 @@ dependencies = [
743 "inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 716 "inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
744 "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 717 "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
745 "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 718 "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
746 "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", 719 "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
747 "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 720 "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
748 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 721 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
749 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 722 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -755,12 +728,12 @@ version = "0.1.41"
755source = "registry+https://github.com/rust-lang/crates.io-index" 728source = "registry+https://github.com/rust-lang/crates.io-index"
756dependencies = [ 729dependencies = [
757 "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 730 "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
758 "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 731 "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
759] 732]
760 733
761[[package]] 734[[package]]
762name = "num-traits" 735name = "num-traits"
763version = "0.2.9" 736version = "0.2.10"
764source = "registry+https://github.com/rust-lang/crates.io-index" 737source = "registry+https://github.com/rust-lang/crates.io-index"
765dependencies = [ 738dependencies = [
766 "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 739 "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -776,11 +749,6 @@ dependencies = [
776] 749]
777 750
778[[package]] 751[[package]]
779name = "number_prefix"
780version = "0.3.0"
781source = "registry+https://github.com/rust-lang/crates.io-index"
782
783[[package]]
784name = "once_cell" 752name = "once_cell"
785version = "1.2.0" 753version = "1.2.0"
786source = "registry+https://github.com/rust-lang/crates.io-index" 754source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -792,25 +760,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
792 760
793[[package]] 761[[package]]
794name = "parking_lot" 762name = "parking_lot"
795version = "0.9.0" 763version = "0.10.0"
796source = "registry+https://github.com/rust-lang/crates.io-index" 764source = "registry+https://github.com/rust-lang/crates.io-index"
797dependencies = [ 765dependencies = [
798 "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 766 "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
799 "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 767 "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
800 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
801] 768]
802 769
803[[package]] 770[[package]]
804name = "parking_lot_core" 771name = "parking_lot_core"
805version = "0.6.2" 772version = "0.7.0"
806source = "registry+https://github.com/rust-lang/crates.io-index" 773source = "registry+https://github.com/rust-lang/crates.io-index"
807dependencies = [ 774dependencies = [
808 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 775 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
809 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 776 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
810 "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 777 "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
811 "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 778 "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
812 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 779 "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
813 "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
814 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 780 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
815] 781]
816 782
@@ -885,7 +851,7 @@ dependencies = [
885 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 851 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
886 "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 852 "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
887 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 853 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
888 "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 854 "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
889 "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 855 "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
890 "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 856 "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
891 "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 857 "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -923,7 +889,7 @@ name = "ra_assists"
923version = "0.1.0" 889version = "0.1.0"
924dependencies = [ 890dependencies = [
925 "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 891 "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
926 "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 892 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
927 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 893 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
928 "ra_db 0.1.0", 894 "ra_db 0.1.0",
929 "ra_fmt 0.1.0", 895 "ra_fmt 0.1.0",
@@ -941,9 +907,9 @@ dependencies = [
941 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 907 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
942 "ra_db 0.1.0", 908 "ra_db 0.1.0",
943 "ra_hir 0.1.0", 909 "ra_hir 0.1.0",
944 "ra_ide_api 0.1.0", 910 "ra_ide 0.1.0",
945 "ra_project_model 0.1.0", 911 "ra_project_model 0.1.0",
946 "ra_vfs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 912 "ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
947 "ra_vfs_glob 0.1.0", 913 "ra_vfs_glob 0.1.0",
948 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 914 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
949] 915]
@@ -963,12 +929,11 @@ name = "ra_cli"
963version = "0.1.0" 929version = "0.1.0"
964dependencies = [ 930dependencies = [
965 "flexi_logger 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)", 931 "flexi_logger 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
966 "indicatif 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
967 "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 932 "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
968 "ra_batch 0.1.0", 933 "ra_batch 0.1.0",
969 "ra_db 0.1.0", 934 "ra_db 0.1.0",
970 "ra_hir 0.1.0", 935 "ra_hir 0.1.0",
971 "ra_ide_api 0.1.0", 936 "ra_ide 0.1.0",
972 "ra_prof 0.1.0", 937 "ra_prof 0.1.0",
973 "ra_syntax 0.1.0", 938 "ra_syntax 0.1.0",
974] 939]
@@ -982,7 +947,7 @@ dependencies = [
982 "ra_syntax 0.1.0", 947 "ra_syntax 0.1.0",
983 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 948 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
984 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 949 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
985 "salsa 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", 950 "salsa 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
986 "test_utils 0.1.0", 951 "test_utils 0.1.0",
987] 952]
988 953
@@ -990,7 +955,7 @@ dependencies = [
990name = "ra_fmt" 955name = "ra_fmt"
991version = "0.1.0" 956version = "0.1.0"
992dependencies = [ 957dependencies = [
993 "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 958 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
994 "ra_syntax 0.1.0", 959 "ra_syntax 0.1.0",
995] 960]
996 961
@@ -998,27 +963,13 @@ dependencies = [
998name = "ra_hir" 963name = "ra_hir"
999version = "0.1.0" 964version = "0.1.0"
1000dependencies = [ 965dependencies = [
1001 "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
1002 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)",
1003 "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)",
1004 "chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)",
1005 "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
1006 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
1007 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
1008 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 966 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1009 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1010 "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
1011 "ra_arena 0.1.0",
1012 "ra_cfg 0.1.0",
1013 "ra_db 0.1.0", 967 "ra_db 0.1.0",
1014 "ra_hir_def 0.1.0", 968 "ra_hir_def 0.1.0",
1015 "ra_hir_expand 0.1.0", 969 "ra_hir_expand 0.1.0",
1016 "ra_mbe 0.1.0", 970 "ra_hir_ty 0.1.0",
1017 "ra_prof 0.1.0",
1018 "ra_syntax 0.1.0", 971 "ra_syntax 0.1.0",
1019 "ra_tt 0.1.0",
1020 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 972 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1021 "test_utils 0.1.0",
1022] 973]
1023 974
1024[[package]] 975[[package]]
@@ -1055,13 +1006,35 @@ dependencies = [
1055] 1006]
1056 1007
1057[[package]] 1008[[package]]
1058name = "ra_ide_api" 1009name = "ra_hir_ty"
1010version = "0.1.0"
1011dependencies = [
1012 "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
1013 "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
1014 "chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
1015 "chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
1016 "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
1017 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
1018 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
1019 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1020 "ra_arena 0.1.0",
1021 "ra_db 0.1.0",
1022 "ra_hir_def 0.1.0",
1023 "ra_hir_expand 0.1.0",
1024 "ra_prof 0.1.0",
1025 "ra_syntax 0.1.0",
1026 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1027 "test_utils 0.1.0",
1028]
1029
1030[[package]]
1031name = "ra_ide"
1059version = "0.1.0" 1032version = "0.1.0"
1060dependencies = [ 1033dependencies = [
1061 "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1034 "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1062 "fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 1035 "fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
1063 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 1036 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
1064 "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1037 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
1065 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1038 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
1066 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1039 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1067 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1040 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1092,18 +1065,18 @@ dependencies = [
1092 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1065 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1093 "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1066 "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1094 "lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)", 1067 "lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)",
1095 "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1068 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
1096 "ra_ide_api 0.1.0", 1069 "ra_ide 0.1.0",
1097 "ra_prof 0.1.0", 1070 "ra_prof 0.1.0",
1098 "ra_project_model 0.1.0", 1071 "ra_project_model 0.1.0",
1099 "ra_syntax 0.1.0", 1072 "ra_syntax 0.1.0",
1100 "ra_text_edit 0.1.0", 1073 "ra_text_edit 0.1.0",
1101 "ra_vfs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1074 "ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
1102 "ra_vfs_glob 0.1.0", 1075 "ra_vfs_glob 0.1.0",
1103 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1076 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1104 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1077 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1105 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1078 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1106 "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", 1079 "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
1107 "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1080 "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1108 "test_utils 0.1.0", 1081 "test_utils 0.1.0",
1109 "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1082 "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1134,7 +1107,7 @@ name = "ra_prof"
1134version = "0.1.0" 1107version = "0.1.0"
1135dependencies = [ 1108dependencies = [
1136 "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", 1109 "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)",
1137 "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1110 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
1138 "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 1111 "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
1139 "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1112 "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
1140 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1113 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1150,8 +1123,8 @@ dependencies = [
1150 "ra_cfg 0.1.0", 1123 "ra_cfg 0.1.0",
1151 "ra_db 0.1.0", 1124 "ra_db 0.1.0",
1152 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1125 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1153 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1126 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1154 "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", 1127 "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
1155] 1128]
1156 1129
1157[[package]] 1130[[package]]
@@ -1159,11 +1132,11 @@ name = "ra_syntax"
1159version = "0.1.0" 1132version = "0.1.0"
1160dependencies = [ 1133dependencies = [
1161 "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1134 "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
1162 "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1135 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
1163 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1136 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1164 "ra_parser 0.1.0", 1137 "ra_parser 0.1.0",
1165 "ra_text_edit 0.1.0", 1138 "ra_text_edit 0.1.0",
1166 "rowan 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1139 "rowan 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
1167 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1140 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1168 "rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1141 "rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1169 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 1142 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1189,14 +1162,14 @@ dependencies = [
1189 1162
1190[[package]] 1163[[package]]
1191name = "ra_vfs" 1164name = "ra_vfs"
1192version = "0.5.1" 1165version = "0.5.2"
1193source = "registry+https://github.com/rust-lang/crates.io-index" 1166source = "registry+https://github.com/rust-lang/crates.io-index"
1194dependencies = [ 1167dependencies = [
1195 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1168 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1196 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1169 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1197 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1170 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1198 "notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)", 1171 "notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
1199 "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1172 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
1200 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1173 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1201 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1174 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1202 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1175 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1207,7 +1180,7 @@ name = "ra_vfs_glob"
1207version = "0.1.0" 1180version = "0.1.0"
1208dependencies = [ 1181dependencies = [
1209 "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1182 "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1210 "ra_vfs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1183 "ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
1211] 1184]
1212 1185
1213[[package]] 1186[[package]]
@@ -1423,17 +1396,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1423dependencies = [ 1396dependencies = [
1424 "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1397 "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1425 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1398 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1426 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1399 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1427] 1400]
1428 1401
1429[[package]] 1402[[package]]
1430name = "rowan" 1403name = "rowan"
1431version = "0.7.0" 1404version = "0.7.1"
1432source = "registry+https://github.com/rust-lang/crates.io-index" 1405source = "registry+https://github.com/rust-lang/crates.io-index"
1433dependencies = [ 1406dependencies = [
1434 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1407 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1435 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 1408 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
1436 "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 1409 "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
1410 "thin-dst 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1437] 1411]
1438 1412
1439[[package]] 1413[[package]]
@@ -1472,23 +1446,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1472 1446
1473[[package]] 1447[[package]]
1474name = "salsa" 1448name = "salsa"
1475version = "0.13.2" 1449version = "0.14.1"
1476source = "registry+https://github.com/rust-lang/crates.io-index" 1450source = "registry+https://github.com/rust-lang/crates.io-index"
1477dependencies = [ 1451dependencies = [
1478 "crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1452 "crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
1479 "derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
1480 "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1453 "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1481 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1454 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1482 "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1455 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
1483 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1456 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1484 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1457 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1485 "salsa-macros 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", 1458 "salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
1486 "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 1459 "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1487] 1460]
1488 1461
1489[[package]] 1462[[package]]
1490name = "salsa-macros" 1463name = "salsa-macros"
1491version = "0.13.2" 1464version = "0.14.1"
1492source = "registry+https://github.com/rust-lang/crates.io-index" 1465source = "registry+https://github.com/rust-lang/crates.io-index"
1493dependencies = [ 1466dependencies = [
1494 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1467 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1516,7 +1489,7 @@ version = "0.9.0"
1516source = "registry+https://github.com/rust-lang/crates.io-index" 1489source = "registry+https://github.com/rust-lang/crates.io-index"
1517dependencies = [ 1490dependencies = [
1518 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1491 "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
1519 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1492 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1520] 1493]
1521 1494
1522[[package]] 1495[[package]]
@@ -1526,15 +1499,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1526 1499
1527[[package]] 1500[[package]]
1528name = "serde" 1501name = "serde"
1529version = "1.0.102" 1502version = "1.0.103"
1530source = "registry+https://github.com/rust-lang/crates.io-index" 1503source = "registry+https://github.com/rust-lang/crates.io-index"
1531dependencies = [ 1504dependencies = [
1532 "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1505 "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1533] 1506]
1534 1507
1535[[package]] 1508[[package]]
1536name = "serde_derive" 1509name = "serde_derive"
1537version = "1.0.102" 1510version = "1.0.103"
1538source = "registry+https://github.com/rust-lang/crates.io-index" 1511source = "registry+https://github.com/rust-lang/crates.io-index"
1539dependencies = [ 1512dependencies = [
1540 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1513 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1544,12 +1517,12 @@ dependencies = [
1544 1517
1545[[package]] 1518[[package]]
1546name = "serde_json" 1519name = "serde_json"
1547version = "1.0.41" 1520version = "1.0.42"
1548source = "registry+https://github.com/rust-lang/crates.io-index" 1521source = "registry+https://github.com/rust-lang/crates.io-index"
1549dependencies = [ 1522dependencies = [
1550 "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1523 "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1551 "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1524 "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1552 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1525 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1553] 1526]
1554 1527
1555[[package]] 1528[[package]]
@@ -1569,7 +1542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1569dependencies = [ 1542dependencies = [
1570 "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1543 "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1571 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1544 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
1572 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1545 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1573 "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1546 "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
1574] 1547]
1575 1548
@@ -1580,14 +1553,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1580 1553
1581[[package]] 1554[[package]]
1582name = "smallvec" 1555name = "smallvec"
1583version = "0.6.13"
1584source = "registry+https://github.com/rust-lang/crates.io-index"
1585dependencies = [
1586 "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1587]
1588
1589[[package]]
1590name = "smallvec"
1591version = "1.0.0" 1556version = "1.0.0"
1592source = "registry+https://github.com/rust-lang/crates.io-index" 1557source = "registry+https://github.com/rust-lang/crates.io-index"
1593 1558
@@ -1596,7 +1561,7 @@ name = "smol_str"
1596version = "0.1.15" 1561version = "0.1.15"
1597source = "registry+https://github.com/rust-lang/crates.io-index" 1562source = "registry+https://github.com/rust-lang/crates.io-index"
1598dependencies = [ 1563dependencies = [
1599 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1564 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1600] 1565]
1601 1566
1602[[package]] 1567[[package]]
@@ -1652,7 +1617,7 @@ name = "test_utils"
1652version = "0.1.0" 1617version = "0.1.0"
1653dependencies = [ 1618dependencies = [
1654 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1619 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1655 "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", 1620 "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
1656 "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 1621 "text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
1657] 1622]
1658 1623
@@ -1662,6 +1627,11 @@ version = "0.1.9"
1662source = "registry+https://github.com/rust-lang/crates.io-index" 1627source = "registry+https://github.com/rust-lang/crates.io-index"
1663 1628
1664[[package]] 1629[[package]]
1630name = "thin-dst"
1631version = "1.0.0"
1632source = "registry+https://github.com/rust-lang/crates.io-index"
1633
1634[[package]]
1665name = "thread_local" 1635name = "thread_local"
1666version = "0.3.6" 1636version = "0.3.6"
1667source = "registry+https://github.com/rust-lang/crates.io-index" 1637source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1705,10 +1675,10 @@ dependencies = [
1705 1675
1706[[package]] 1676[[package]]
1707name = "unicode-normalization" 1677name = "unicode-normalization"
1708version = "0.1.9" 1678version = "0.1.11"
1709source = "registry+https://github.com/rust-lang/crates.io-index" 1679source = "registry+https://github.com/rust-lang/crates.io-index"
1710dependencies = [ 1680dependencies = [
1711 "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 1681 "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1712] 1682]
1713 1683
1714[[package]] 1684[[package]]
@@ -1717,11 +1687,6 @@ version = "1.6.0"
1717source = "registry+https://github.com/rust-lang/crates.io-index" 1687source = "registry+https://github.com/rust-lang/crates.io-index"
1718 1688
1719[[package]] 1689[[package]]
1720name = "unicode-width"
1721version = "0.1.6"
1722source = "registry+https://github.com/rust-lang/crates.io-index"
1723
1724[[package]]
1725name = "unicode-xid" 1690name = "unicode-xid"
1726version = "0.2.0" 1691version = "0.2.0"
1727source = "registry+https://github.com/rust-lang/crates.io-index" 1692source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1734,7 +1699,7 @@ dependencies = [
1734 "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1699 "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1735 "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1700 "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
1736 "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1701 "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1737 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1702 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1738] 1703]
1739 1704
1740[[package]] 1705[[package]]
@@ -1743,7 +1708,7 @@ version = "0.8.1"
1743source = "registry+https://github.com/rust-lang/crates.io-index" 1708source = "registry+https://github.com/rust-lang/crates.io-index"
1744dependencies = [ 1709dependencies = [
1745 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1710 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1746 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1711 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1747] 1712]
1748 1713
1749[[package]] 1714[[package]]
@@ -1816,12 +1781,12 @@ dependencies = [
1816name = "xtask" 1781name = "xtask"
1817version = "0.1.0" 1782version = "0.1.0"
1818dependencies = [ 1783dependencies = [
1819 "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", 1784 "anyhow 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
1820 "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1785 "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1821 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1786 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
1822 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1787 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1823 "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1788 "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
1824 "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", 1789 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1825 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1790 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
1826] 1791]
1827 1792
@@ -1840,7 +1805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1840 1805
1841[metadata] 1806[metadata]
1842"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" 1807"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
1843"checksum anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "e19f23ab207147bbdbcdfa7f7e4ca5e84963d79bae3937074682177ab9150968" 1808"checksum anyhow 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b412394828b7ca486b362f300b762d8e43dafd6f0d727b63f1cd2ade207c6cef"
1844"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 1809"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
1845"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" 1810"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
1846"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 1811"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
@@ -1856,13 +1821,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1856"checksum cargo_metadata 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8d2d1617e838936c0d2323a65cc151e03ae19a7678dd24f72bccf27119b90a5d" 1821"checksum cargo_metadata 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8d2d1617e838936c0d2323a65cc151e03ae19a7678dd24f72bccf27119b90a5d"
1857"checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" 1822"checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8"
1858"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 1823"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
1859"checksum chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "<none>" 1824"checksum chalk-derive 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "<none>"
1860"checksum chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "<none>" 1825"checksum chalk-engine 0.9.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "<none>"
1861"checksum chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "<none>" 1826"checksum chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "<none>"
1862"checksum chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "<none>" 1827"checksum chalk-macros 0.1.1 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "<none>"
1863"checksum chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "<none>" 1828"checksum chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "<none>"
1864"checksum chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=a88cad7f0a69e05ba8f40b74c58a1c229c1b2478)" = "<none>" 1829"checksum chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)" = "<none>"
1865"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" 1830"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
1866"checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" 1831"checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e"
1867"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1832"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
1868"checksum console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5d540c2d34ac9dd0deb5f3b5f54c36c79efa78f6b3ad19106a554d07a7b5d9f" 1833"checksum console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5d540c2d34ac9dd0deb5f3b5f54c36c79efa78f6b3ad19106a554d07a7b5d9f"
@@ -1872,7 +1837,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1872"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" 1837"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
1873"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" 1838"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700"
1874"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" 1839"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
1875"checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9"
1876"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" 1840"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
1877"checksum drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f" 1841"checksum drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f"
1878"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" 1842"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
@@ -1898,12 +1862,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1898"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" 1862"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
1899"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 1863"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
1900"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" 1864"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
1901"checksum indicatif 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8572bccfb0665e70b7faf44ee28841b8e0823450cd4ad562a76b5a3c4bf48487"
1902"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" 1865"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718"
1903"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" 1866"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
1904"checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349" 1867"checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349"
1905"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 1868"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
1906"checksum itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87fa75c9dea7b07be3138c49abbb83fd4bea199b5cdc76f9804458edc5da0d6e" 1869"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
1907"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" 1870"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
1908"checksum jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c502a5ff9dd2924f1ed32ba96e3b65735d837b4bfd978d3161b1702e66aca4b7" 1871"checksum jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c502a5ff9dd2924f1ed32ba96e3b65735d837b4bfd978d3161b1702e66aca4b7"
1909"checksum jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45" 1872"checksum jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45"
@@ -1916,27 +1879,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1916"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" 1879"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
1917"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" 1880"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
1918"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" 1881"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
1919"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" 1882"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586"
1920"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1883"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
1921"checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12" 1884"checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12"
1922"checksum lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa3268fbe8beb2795c2fb327bf44f4f3d24f5fe9ebc18d7e2980afd444d72bcf" 1885"checksum lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa3268fbe8beb2795c2fb327bf44f4f3d24f5fe9ebc18d7e2980afd444d72bcf"
1923"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1886"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
1924"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
1925"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 1887"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
1926"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" 1888"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
1927"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" 1889"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
1928"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" 1890"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
1929"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1891"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
1930"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" 1892"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
1931"checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b" 1893"checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b"
1932"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" 1894"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
1933"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6" 1895"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
1934"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" 1896"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
1935"checksum number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
1936"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" 1897"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed"
1937"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" 1898"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
1938"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" 1899"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
1939"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" 1900"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1"
1940"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" 1901"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49"
1941"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" 1902"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5"
1942"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1903"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
@@ -1949,7 +1910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1949"checksum psm 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b14fc68b454f875abc8354c2555e1d56596f74833ddc0f77f87f4871ed6a30e0" 1910"checksum psm 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b14fc68b454f875abc8354c2555e1d56596f74833ddc0f77f87f4871ed6a30e0"
1950"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" 1911"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
1951"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 1912"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
1952"checksum ra_vfs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a95d3d1edc70a98d9e42f145bc92c2071dfdc532571591c9eac407c0e4feb89" 1913"checksum ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc898f237e4b4498959ae0100c688793a23e77624d44ef710ba70094217f98e0"
1953"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1914"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
1954"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" 1915"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
1955"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1916"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
@@ -1974,25 +1935,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1974"checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954" 1935"checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954"
1975"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 1936"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
1976"checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5" 1937"checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5"
1977"checksum rowan 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a241900475bf2ba302061550ff50c82b45095ca95d23d1872345793fd42407" 1938"checksum rowan 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ca620bbf9c48c92b5cef19f96354a309ac36b7d8ef7c591e66117335c8b1988b"
1978"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 1939"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
1979"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" 1940"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
1980"checksum rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86aae0c77166108c01305ee1a36a1e77289d7dc6ca0a3cd91ff4992de2d16a5" 1941"checksum rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86aae0c77166108c01305ee1a36a1e77289d7dc6ca0a3cd91ff4992de2d16a5"
1981"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1942"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
1982"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" 1943"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
1983"checksum salsa 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec0865bdd9d8e614686a0cbb76979c735810131d287eb1683e91e4e64a58c387" 1944"checksum salsa 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a006c56096acaaa5e82e5974c28d05ff1e84aa70615f19c53fecf8a1afb2fd2"
1984"checksum salsa-macros 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cac182212d3a1db75ddc42399ff1461b258a694b8318ee7e0baf6c976e39efee" 1945"checksum salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "038a09b6271446f1123f142fe7e5bef6d4687c4cf82e6986be574c2af3745530"
1985"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" 1946"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
1986"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" 1947"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
1987"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1948"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
1988"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1949"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
1989"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" 1950"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702"
1990"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" 1951"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0"
1991"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" 1952"checksum serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "1a3351dcbc1f067e2c92ab7c3c1f288ad1a4cffc470b5aaddb4c2e0a3ae80043"
1992"checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573" 1953"checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
1993"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" 1954"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
1994"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1955"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
1995"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
1996"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" 1956"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
1997"checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b" 1957"checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b"
1998"checksum stacker 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d96fc4f13a0ac088e9a3cd9af1cc8c5cc1ab5deb2145cef661267dfc9c542f8a" 1958"checksum stacker 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d96fc4f13a0ac088e9a3cd9af1cc8c5cc1ab5deb2145cef661267dfc9c542f8a"
@@ -2001,14 +1961,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2001"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 1961"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
2002"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" 1962"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
2003"checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579" 1963"checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579"
1964"checksum thin-dst 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c52fd98a9e4913c466d83381a59245691875d2f3e04611fca57f964bd8aa96e1"
2004"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" 1965"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
2005"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" 1966"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
2006"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" 1967"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
2007"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 1968"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
2008"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1969"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
2009"checksum unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "09c8070a9942f5e7cfccd93f490fdebd230ee3c3c9f107cb25bad5351ef671cf" 1970"checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf"
2010"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" 1971"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
2011"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
2012"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 1972"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
2013"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" 1973"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
2014"checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" 1974"checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
diff --git a/README.md b/README.md
index ea1c25d7f..74c971c0d 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frls-2.2E0
56 56
57## Quick Links 57## Quick Links
58 58
59* API docs: https://rust-analyzer.github.io/rust-analyzer/ra_ide_api/ 59* API docs: https://rust-analyzer.github.io/rust-analyzer/ra_ide/
60 60
61 61
62## License 62## License
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 @@
1use hir::{db::HirDatabase, HirDisplay, Ty}; 1use hir::{db::HirDatabase, HirDisplay};
2use ra_syntax::{ 2use 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
57fn 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)]
66mod tests { 57mod 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
92fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> { 93fn 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
26impl std::panic::RefUnwindSafe for TestDB {} 29impl 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"
15ra_vfs = "0.5.0" 15ra_vfs = "0.5.0"
16ra_vfs_glob = { path = "../ra_vfs_glob" } 16ra_vfs_glob = { path = "../ra_vfs_glob" }
17ra_db = { path = "../ra_db" } 17ra_db = { path = "../ra_db" }
18ra_ide_api = { path = "../ra_ide_api" } 18ra_ide = { path = "../ra_ide" }
19ra_hir = { path = "../ra_hir" } 19ra_hir = { path = "../ra_hir" }
20ra_project_model = { path = "../ra_project_model" } 20ra_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
7use crossbeam_channel::{unbounded, Receiver}; 7use crossbeam_channel::{unbounded, Receiver};
8use ra_db::{CrateGraph, FileId, SourceRootId}; 8use ra_db::{CrateGraph, FileId, SourceRootId};
9use ra_ide_api::{AnalysisChange, AnalysisHost, FeatureFlags}; 9use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags};
10use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; 10use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace};
11use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; 11use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
12use ra_vfs_glob::RustPackageFilterBuilder; 12use 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]
9pico-args = "0.3.0" 9pico-args = "0.3.0"
10flexi_logger = "0.14.0" 10flexi_logger = "0.14.0"
11indicatif = "0.13.0"
12 11
13ra_syntax = { path = "../ra_syntax" } 12ra_syntax = { path = "../ra_syntax" }
14ra_ide_api = { path = "../ra_ide_api" } 13ra_ide = { path = "../ra_ide" }
15ra_batch = { path = "../ra_batch" } 14ra_batch = { path = "../ra_batch" }
16ra_hir = { path = "../ra_hir" } 15ra_hir = { path = "../ra_hir" }
17ra_db = { path = "../ra_db" } 16ra_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};
13use ra_ide_api::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol}; 13use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol};
14 14
15use crate::Result; 15use 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;
6use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; 6use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk};
7use ra_syntax::AstNode; 7use ra_syntax::AstNode;
8 8
9use crate::{Result, Verbosity}; 9use crate::{progress_report::ProgressReport, Result, Verbosity};
10 10
11pub fn run( 11pub 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 @@
3mod analysis_stats; 3mod analysis_stats;
4mod analysis_bench; 4mod analysis_bench;
5mod help; 5mod help;
6mod progress_report;
6 7
7use std::{error::Error, fmt::Write, io::Read}; 8use std::{error::Error, fmt::Write, io::Read};
8 9
9use flexi_logger::Logger; 10use flexi_logger::Logger;
10use pico_args::Arguments; 11use pico_args::Arguments;
11use ra_ide_api::{file_structure, Analysis}; 12use ra_ide::{file_structure, Analysis};
12use ra_prof::profile; 13use ra_prof::profile;
13use ra_syntax::{AstNode, SourceFile}; 14use 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
4use std::io::Write;
5
6/// A Simple ASCII Progress Bar
7pub struct ProgressReport {
8 curr: f32,
9 text: String,
10 hidden: bool,
11
12 len: u64,
13 pos: u64,
14 msg: String,
15}
16
17impl 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"]
8doctest = false 8doctest = false
9 9
10[dependencies] 10[dependencies]
11salsa = "0.13.0" 11salsa = "0.14.1"
12relative-path = "1.0.0" 12relative-path = "1.0.0"
13rustc-hash = "1.0" 13rustc-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.
2mod cancellation; 2mod cancellation;
3mod input; 3mod input;
4pub mod fixture; 4pub 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"]
8doctest = false 8doctest = false
9 9
10[dependencies] 10[dependencies]
11arrayvec = "0.5.1"
12log = "0.4.5" 11log = "0.4.5"
13rustc-hash = "1.0" 12rustc-hash = "1.0"
14parking_lot = "0.9.0"
15ena = "0.13"
16once_cell = "1.0.1"
17 13
18ra_syntax = { path = "../ra_syntax" } 14ra_syntax = { path = "../ra_syntax" }
19ra_arena = { path = "../ra_arena" }
20ra_cfg = { path = "../ra_cfg" }
21ra_db = { path = "../ra_db" } 15ra_db = { path = "../ra_db" }
22mbe = { path = "../ra_mbe", package = "ra_mbe" }
23tt = { path = "../ra_tt", package = "ra_tt" }
24hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } 16hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
25hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } 17hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
26test_utils = { path = "../test_utils" } 18hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
27ra_prof = { path = "../ra_prof" }
28
29chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" }
30chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" }
31chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" }
32lalrpop-intern = "0.15.1"
33
34[dev-dependencies]
35insta = "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
7use hir_def::{ 7use 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};
18use hir_expand::{ 20use hir_expand::{
19 diagnostics::DiagnosticSink, 21 diagnostics::DiagnosticSink,
20 name::{self, AsName}, 22 name::{self, AsName},
21 AstId, MacroDefId, 23 AstId, MacroDefId,
22}; 24};
25use hir_ty::expr::ExprValidator;
23use ra_db::{CrateId, Edition, FileId, FilePosition}; 26use ra_db::{CrateId, Edition, FileId, FilePosition};
24use ra_syntax::{ast, AstNode, SyntaxNode}; 27use ra_syntax::{ast, AstNode, SyntaxNode};
25 28
26use crate::{ 29use 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
169impl Module { 172impl 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
321impl Struct { 324impl 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
370impl Union { 373impl 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 {
469impl_froms!(Adt: Struct, Union, Enum); 491impl_froms!(Adt: Struct, Union, Enum);
470 492
471impl Adt { 493impl 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)]
494pub enum VariantDef { 517pub enum VariantDef {
495 Struct(Struct), 518 Struct(Struct),
519 Union(Union),
496 EnumVariant(EnumVariant), 520 EnumVariant(EnumVariant),
497} 521}
498impl_froms!(VariantDef: Struct, EnumVariant); 522impl_froms!(VariantDef: Struct, Union, EnumVariant);
499 523
500impl VariantDef { 524impl 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 {
538impl_froms!(DefWithBody: Function, Const, Static); 558impl_froms!(DefWithBody: Function, Const, Static);
539 559
540impl DefWithBody { 560impl 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
787impl TypeAlias { 738impl 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
900impl 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)]
911pub struct Local { 857pub 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)]
962pub struct GenericParam { 913pub 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
972impl ImplBlock { 923impl 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)]
967pub struct Type {
968 pub(crate) krate: CrateId,
969 pub(crate) ty: InEnvironment<Ty>,
970}
971
972impl 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
1148impl 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
1008pub enum ScopeDef { 1155pub 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 {
51impl HasSource for Struct { 51impl 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}
57impl HasSource for Union { 57impl 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}
63impl HasSource for Enum { 63impl 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
3use std::sync::Arc; 3pub use hir_def::db::{
4 4 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery,
5use ra_arena::map::ArenaMap; 5 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery,
6use ra_db::salsa; 6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
7 7 LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery,
8use 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
18pub 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};
29pub use hir_expand::db::{ 10pub 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 14pub 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,
36pub 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]
130fn hir_database_is_object_safe() { 22fn 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
3use std::any::Any;
4
5use hir_expand::HirFileId;
6use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
7
8use crate::{db::AstDatabase, Name, Source};
9
10pub use hir_def::diagnostics::UnresolvedModule; 2pub use hir_def::diagnostics::UnresolvedModule;
11pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; 3pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
12 4pub use hir_ty::diagnostics::{MissingFields, MissingOkInTailExpr, NoSuchField};
13#[derive(Debug)]
14pub struct NoSuchField {
15 pub file: HirFileId,
16 pub field: AstPtr<ast::RecordField>,
17}
18
19impl 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)]
34pub struct MissingFields {
35 pub file: HirFileId,
36 pub field_list: AstPtr<ast::RecordFieldList>,
37 pub missed_fields: Vec<Name>,
38}
39
40impl 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
52impl 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)]
63pub struct MissingOkInTailExpr {
64 pub file: HirFileId,
65 pub expr: AstPtr<ast::Expr>,
66}
67
68impl 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
80impl 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
6use hir_def::{ 6use 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
11use crate::{ 11use 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
17impl From<ra_db::CrateId> for Crate { 16impl From<ra_db::CrateId> for Crate {
@@ -138,72 +137,6 @@ impl From<GenericDef> for GenericDefId {
138 } 137 }
139} 138}
140 139
141impl 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
155impl From<AdtId> for TypableDef {
156 fn from(id: AdtId) -> Self {
157 Adt::from(id).into()
158 }
159}
160
161impl From<StructId> for TypableDef {
162 fn from(id: StructId) -> Self {
163 AdtId::StructId(id).into()
164 }
165}
166
167impl From<UnionId> for TypableDef {
168 fn from(id: UnionId) -> Self {
169 AdtId::UnionId(id).into()
170 }
171}
172
173impl From<EnumId> for TypableDef {
174 fn from(id: EnumId) -> Self {
175 AdtId::EnumId(id).into()
176 }
177}
178
179impl From<EnumVariantId> for TypableDef {
180 fn from(id: EnumVariantId) -> Self {
181 EnumVariant::from(id).into()
182 }
183}
184
185impl From<TypeAliasId> for TypableDef {
186 fn from(id: TypeAliasId) -> Self {
187 TypeAlias::from(id).into()
188 }
189}
190
191impl From<FunctionId> for TypableDef {
192 fn from(id: FunctionId) -> Self {
193 Function::from(id).into()
194 }
195}
196impl From<ConstId> for TypableDef {
197 fn from(id: ConstId) -> Self {
198 Const::from(id).into()
199 }
200}
201impl From<StaticId> for TypableDef {
202 fn from(id: StaticId) -> Self {
203 Static::from(id).into()
204 }
205}
206
207impl From<Adt> for GenericDefId { 140impl 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
217impl From<CallableDef> for GenericDefId { 150impl 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
176impl From<StructFieldId> for StructField {
177 fn from(def: StructFieldId) -> Self {
178 StructField { parent: def.parent.into(), id: def.local_id }
179 }
180}
181
244impl From<AttrDef> for AttrDefId { 182impl 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
199impl 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
3use hir_def::{AstItemDef, LocationCtx, ModuleId, StructId, StructOrUnionId, UnionId}; 3use hir_def::{AstItemDef, LocationCtx, ModuleId};
4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
5use ra_syntax::{ 5use 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
23impl FromSource for Struct { 22impl 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}
30impl FromSource for Union { 29impl 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}
37impl FromSource for Enum { 36impl 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;
32pub mod source_binder; 32pub mod source_binder;
33 33
34mod ty; 34mod ty;
35mod expr;
36pub mod diagnostics; 35pub mod diagnostics;
37mod util;
38 36
39mod from_id; 37mod from_id;
40mod code_model; 38mod code_model;
41 39
42pub mod from_source; 40pub mod from_source;
43 41
44#[cfg(test)]
45mod test_db;
46#[cfg(test)]
47mod marks;
48
49pub use crate::{ 42pub 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
66pub use hir_def::{ 58pub 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 @@
8use std::sync::Arc; 8use std::sync::Arc;
9 9
10use hir_def::{ 10use 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};
16use hir_expand::{ 20use hir_expand::{
17 name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source, 21 hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source,
18}; 22};
19use ra_syntax::{ 23use ra_syntax::{
20 ast::{self, AstNode}, 24 ast::{self, AstNode},
@@ -25,10 +29,12 @@ use ra_syntax::{
25 29
26use crate::{ 30use 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
34fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 40fn 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
466fn scope_for( 463fn 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
4mod autoderef; 4pub use hir_ty::*;
5pub(crate) mod primitive;
6pub(crate) mod traits;
7pub(crate) mod method_resolution;
8mod op;
9mod lower;
10mod infer;
11pub(crate) mod display;
12
13#[cfg(test)]
14mod tests;
15
16use std::ops::Deref;
17use std::sync::Arc;
18use std::{fmt, iter, mem};
19
20use hir_def::{generics::GenericParams, AdtId};
21use ra_db::{impl_intern_key, salsa};
22
23use crate::{
24 db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy,
25 GenericDef, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain,
26};
27use display::{HirDisplay, HirFormatter};
28
29pub(crate) use autoderef::autoderef;
30pub(crate) use infer::{infer_query, InferTy, InferenceResult};
31pub use lower::CallableDef;
32pub(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};
37pub(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)]
43pub 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)]
123pub struct TypeCtorId(salsa::InternId);
124impl_intern_key!(TypeCtorId);
125
126impl 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)]
205pub 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)]
214pub struct ProjectionTy {
215 pub associated_ty: TypeAlias,
216 pub parameters: Substs,
217}
218
219impl 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
231impl 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)]
248pub 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)]
301pub struct Substs(Arc<[Ty]>);
302
303impl 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
317impl 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)]
380pub struct SubstsBuilder {
381 vec: Vec<Ty>,
382 param_count: usize,
383}
384
385impl 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
427impl 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)]
438pub struct TraitRef {
439 /// FIXME name?
440 pub trait_: Trait,
441 pub substs: Substs,
442}
443
444impl TraitRef {
445 pub fn self_ty(&self) -> &Ty {
446 &self.substs[0]
447 }
448}
449
450impl 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)]
463pub 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
473impl 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
497impl 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)]
523pub 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)]
531pub struct FnSig {
532 params_and_return: Arc<[Ty]>,
533}
534
535impl 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
554impl 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
568impl 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.
686pub 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
763impl 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
805impl HirDisplay for &Ty {
806 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
807 HirDisplay::hir_fmt(*self, f)
808 }
809}
810
811impl 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
916impl 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
938impl 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
1024impl 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
1046impl 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
1052impl HirDisplay for &GenericPredicate {
1053 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1054 HirDisplay::hir_fmt(*self, f)
1055 }
1056}
1057
1058impl 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
1082impl 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
3use 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.
7pub(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
13use crate::{ 13use 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)]
20pub struct StructData { 20pub 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)]
26pub struct EnumData { 26pub 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)]
32pub struct EnumVariantData { 32pub 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
51impl StructData { 51impl 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());
62 let variant_data = VariantData::new(
63 src.value
64 .record_field_def_list()
65 .map(ast::StructKind::Record)
66 .unwrap_or(ast::StructKind::Unit),
67 );
68 let variant_data = Arc::new(variant_data);
69 Arc::new(StructData { name, variant_data })
70 }
59} 71}
60 72
61impl EnumData { 73impl EnumData {
62 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> { 74 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> {
63 let src = e.source(db); 75 let src = e.source(db);
64 let name = src.value.name().map(|n| n.as_name()); 76 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
65 let mut trace = Trace::new_for_arena(); 77 let mut trace = Trace::new_for_arena();
66 lower_enum(&mut trace, &src.value); 78 lower_enum(&mut trace, &src.value);
67 Arc::new(EnumData { name, variants: trace.into_arena() }) 79 Arc::new(EnumData { name, variants: trace.into_arena() })
68 } 80 }
69 81
70 pub(crate) fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> { 82 pub fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> {
71 let (id, _) = self.variants.iter().find(|(_id, data)| data.name.as_ref() == Some(name))?; 83 let (id, _) = self.variants.iter().find(|(_id, data)| &data.name == name)?;
72 Some(id) 84 Some(id)
73 } 85 }
74} 86}
@@ -92,7 +104,7 @@ fn lower_enum(
92 trace.alloc( 104 trace.alloc(
93 || var.clone(), 105 || var.clone(),
94 || EnumVariantData { 106 || EnumVariantData {
95 name: var.name().map(|it| it.as_name()), 107 name: var.name().map_or_else(Name::missing, |it| it.as_name()),
96 variant_data: Arc::new(VariantData::new(var.kind())), 108 variant_data: Arc::new(VariantData::new(var.kind())),
97 }, 109 },
98 ); 110 );
@@ -117,6 +129,10 @@ impl VariantData {
117 } 129 }
118 } 130 }
119 131
132 pub fn field(&self, name: &Name) -> Option<LocalStructFieldId> {
133 self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None })
134 }
135
120 pub fn is_unit(&self) -> bool { 136 pub fn is_unit(&self) -> bool {
121 match self { 137 match self {
122 VariantData::Unit => true, 138 VariantData::Unit => true,
@@ -137,7 +153,12 @@ impl HasChildSource for VariantId {
137 let src = it.parent.child_source(db); 153 let src = it.parent.child_source(db);
138 src.map(|map| map[it.local_id].kind()) 154 src.map(|map| map[it.local_id].kind())
139 } 155 }
140 VariantId::StructId(it) => it.0.source(db).map(|it| it.kind()), 156 VariantId::StructId(it) => it.source(db).map(|it| it.kind()),
157 VariantId::UnionId(it) => it.source(db).map(|it| {
158 it.record_field_def_list()
159 .map(ast::StructKind::Record)
160 .unwrap_or(ast::StructKind::Unit)
161 }),
141 }; 162 };
142 let mut trace = Trace::new_for_map(); 163 let mut trace = Trace::new_for_map();
143 lower_struct(&mut trace, &src.value); 164 lower_struct(&mut trace, &src.value);
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 53456fc08..fffb22201 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -35,7 +35,7 @@ impl Attrs {
35 match def { 35 match def {
36 AttrDefId::ModuleId(module) => { 36 AttrDefId::ModuleId(module) => {
37 let def_map = db.crate_def_map(module.krate); 37 let def_map = db.crate_def_map(module.krate);
38 let src = match def_map[module.module_id].declaration_source(db) { 38 let src = match def_map[module.local_id].declaration_source(db) {
39 Some(it) => it, 39 Some(it) => it,
40 None => return Attrs::default(), 40 None => return Attrs::default(),
41 }; 41 };
@@ -54,9 +54,9 @@ impl Attrs {
54 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) 54 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
55 } 55 }
56 AttrDefId::AdtId(it) => match it { 56 AttrDefId::AdtId(it) => match it {
57 AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), 57 AdtId::StructId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
58 AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 58 AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
59 AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), 59 AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
60 }, 60 },
61 AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 61 AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
62 AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), 62 AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db),
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index d77ccb272..a57a0176d 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -6,8 +6,7 @@ pub mod scope;
6use std::{ops::Index, sync::Arc}; 6use std::{ops::Index, sync::Arc};
7 7
8use hir_expand::{ 8use hir_expand::{
9 either::Either, hygiene::Hygiene, AstId, HirFileId, MacroCallLoc, MacroDefId, MacroFileKind, 9 either::Either, hygiene::Hygiene, AstId, HirFileId, MacroDefId, MacroFileKind, Source,
10 Source,
11}; 10};
12use ra_arena::{map::ArenaMap, Arena}; 11use ra_arena::{map::ArenaMap, Arena};
13use ra_syntax::{ast, AstNode, AstPtr}; 12use ra_syntax::{ast, AstNode, AstPtr};
@@ -47,7 +46,7 @@ impl Expander {
47 46
48 if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { 47 if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) {
49 if let Some(def) = self.resolve_path_as_macro(db, &path) { 48 if let Some(def) = self.resolve_path_as_macro(db, &path) {
50 let call_id = db.intern_macro(MacroCallLoc { def, ast_id }); 49 let call_id = def.as_call_id(db, ast_id);
51 let file_id = call_id.as_file(MacroFileKind::Expr); 50 let file_id = call_id.as_file(MacroFileKind::Expr);
52 if let Some(node) = db.parse_or_expand(file_id) { 51 if let Some(node) = db.parse_or_expand(file_id) {
53 if let Some(expr) = ast::Expr::cast(node) { 52 if let Some(expr) = ast::Expr::cast(node) {
@@ -83,7 +82,7 @@ impl Expander {
83 } 82 }
84 83
85 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 84 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
86 self.crate_def_map.resolve_path(db, self.module.module_id, path).0.take_macros() 85 self.crate_def_map.resolve_path(db, self.module.local_id, path).0.take_macros()
87 } 86 }
88} 87}
89 88
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index 68bea34df..fee10b237 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -86,39 +86,53 @@ impl TypeAliasData {
86 86
87#[derive(Debug, Clone, PartialEq, Eq)] 87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct TraitData { 88pub struct TraitData {
89 pub name: Option<Name>, 89 pub name: Name,
90 pub items: Vec<AssocItemId>, 90 pub items: Vec<(Name, AssocItemId)>,
91 pub auto: bool, 91 pub auto: bool,
92} 92}
93 93
94impl TraitData { 94impl TraitData {
95 pub(crate) fn trait_data_query(db: &impl DefDatabase, tr: TraitId) -> Arc<TraitData> { 95 pub(crate) fn trait_data_query(db: &impl DefDatabase, tr: TraitId) -> Arc<TraitData> {
96 let src = tr.source(db); 96 let src = tr.source(db);
97 let name = src.value.name().map(|n| n.as_name()); 97 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
98 let auto = src.value.is_auto(); 98 let auto = src.value.is_auto();
99 let ast_id_map = db.ast_id_map(src.file_id); 99 let ast_id_map = db.ast_id_map(src.file_id);
100
101 let container = ContainerId::TraitId(tr);
100 let items = if let Some(item_list) = src.value.item_list() { 102 let items = if let Some(item_list) = src.value.item_list() {
101 item_list 103 item_list
102 .impl_items() 104 .impl_items()
103 .map(|item_node| match item_node { 105 .map(|item_node| match item_node {
104 ast::ImplItem::FnDef(it) => FunctionLoc { 106 ast::ImplItem::FnDef(it) => {
105 container: ContainerId::TraitId(tr), 107 let name = it.name().map_or_else(Name::missing, |it| it.as_name());
106 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), 108 let def = FunctionLoc {
109 container,
110 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
111 }
112 .intern(db)
113 .into();
114 (name, def)
107 } 115 }
108 .intern(db) 116 ast::ImplItem::ConstDef(it) => {
109 .into(), 117 let name = it.name().map_or_else(Name::missing, |it| it.as_name());
110 ast::ImplItem::ConstDef(it) => ConstLoc { 118 let def = ConstLoc {
111 container: ContainerId::TraitId(tr), 119 container,
112 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), 120 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
121 }
122 .intern(db)
123 .into();
124 (name, def)
113 } 125 }
114 .intern(db) 126 ast::ImplItem::TypeAliasDef(it) => {
115 .into(), 127 let name = it.name().map_or_else(Name::missing, |it| it.as_name());
116 ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc { 128 let def = TypeAliasLoc {
117 container: ContainerId::TraitId(tr), 129 container,
118 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), 130 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
131 }
132 .intern(db)
133 .into();
134 (name, def)
119 } 135 }
120 .intern(db)
121 .into(),
122 }) 136 })
123 .collect() 137 .collect()
124 } else { 138 } else {
@@ -128,11 +142,18 @@ impl TraitData {
128 } 142 }
129 143
130 pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ { 144 pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
131 self.items.iter().filter_map(|item| match item { 145 self.items.iter().filter_map(|(_name, item)| match item {
132 AssocItemId::TypeAliasId(t) => Some(*t), 146 AssocItemId::TypeAliasId(t) => Some(*t),
133 _ => None, 147 _ => None,
134 }) 148 })
135 } 149 }
150
151 pub fn associated_type_by_name(&self, name: &Name) -> Option<TypeAliasId> {
152 self.items.iter().find_map(|(item_name, item)| match item {
153 AssocItemId::TypeAliasId(t) if item_name == name => Some(*t),
154 _ => None,
155 })
156 }
136} 157}
137 158
138#[derive(Debug, Clone, PartialEq, Eq)] 159#[derive(Debug, Clone, PartialEq, Eq)]
@@ -193,6 +214,7 @@ impl ImplData {
193 214
194#[derive(Debug, Clone, PartialEq, Eq)] 215#[derive(Debug, Clone, PartialEq, Eq)]
195pub struct ConstData { 216pub struct ConstData {
217 /// const _: () = ();
196 pub name: Option<Name>, 218 pub name: Option<Name>,
197 pub type_ref: TypeRef, 219 pub type_ref: TypeRef,
198} 220}
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 32adb11bd..ef5611ffc 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -18,8 +18,8 @@ use crate::{
18 CrateDefMap, 18 CrateDefMap,
19 }, 19 },
20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, 20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId,
21 ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructOrUnionId, TraitId, TypeAliasId, 21 ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, TypeAliasLoc,
22 TypeAliasLoc, 22 UnionId,
23}; 23};
24 24
25#[salsa::query_group(InternDatabaseStorage)] 25#[salsa::query_group(InternDatabaseStorage)]
@@ -27,7 +27,9 @@ pub trait InternDatabase: SourceDatabase {
27 #[salsa::interned] 27 #[salsa::interned]
28 fn intern_function(&self, loc: FunctionLoc) -> FunctionId; 28 fn intern_function(&self, loc: FunctionLoc) -> FunctionId;
29 #[salsa::interned] 29 #[salsa::interned]
30 fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> StructOrUnionId; 30 fn intern_struct(&self, loc: ItemLoc<ast::StructDef>) -> StructId;
31 #[salsa::interned]
32 fn intern_union(&self, loc: ItemLoc<ast::UnionDef>) -> UnionId;
31 #[salsa::interned] 33 #[salsa::interned]
32 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> EnumId; 34 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> EnumId;
33 #[salsa::interned] 35 #[salsa::interned]
@@ -57,7 +59,9 @@ pub trait DefDatabase: InternDatabase + AstDatabase {
57 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>; 59 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
58 60
59 #[salsa::invoke(StructData::struct_data_query)] 61 #[salsa::invoke(StructData::struct_data_query)]
60 fn struct_data(&self, id: StructOrUnionId) -> Arc<StructData>; 62 fn struct_data(&self, id: StructId) -> Arc<StructData>;
63 #[salsa::invoke(StructData::union_data_query)]
64 fn union_data(&self, id: UnionId) -> Arc<StructData>;
61 65
62 #[salsa::invoke(EnumData::enum_data_query)] 66 #[salsa::invoke(EnumData::enum_data_query)]
63 fn enum_data(&self, e: EnumId) -> Arc<EnumData>; 67 fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs
index 90a8627bc..34ed9b7a5 100644
--- a/crates/ra_hir_def/src/docs.rs
+++ b/crates/ra_hir_def/src/docs.rs
@@ -36,7 +36,7 @@ impl Documentation {
36 match def { 36 match def {
37 AttrDefId::ModuleId(module) => { 37 AttrDefId::ModuleId(module) => {
38 let def_map = db.crate_def_map(module.krate); 38 let def_map = db.crate_def_map(module.krate);
39 let src = def_map[module.module_id].declaration_source(db)?; 39 let src = def_map[module.local_id].declaration_source(db)?;
40 docs_from_ast(&src.value) 40 docs_from_ast(&src.value)
41 } 41 }
42 AttrDefId::StructFieldId(it) => { 42 AttrDefId::StructFieldId(it) => {
@@ -47,9 +47,9 @@ impl Documentation {
47 } 47 }
48 } 48 }
49 AttrDefId::AdtId(it) => match it { 49 AttrDefId::AdtId(it) => match it {
50 AdtId::StructId(it) => docs_from_ast(&it.0.source(db).value), 50 AdtId::StructId(it) => docs_from_ast(&it.source(db).value),
51 AdtId::EnumId(it) => docs_from_ast(&it.source(db).value), 51 AdtId::EnumId(it) => docs_from_ast(&it.source(db).value),
52 AdtId::UnionId(it) => docs_from_ast(&it.0.source(db).value), 52 AdtId::UnionId(it) => docs_from_ast(&it.source(db).value),
53 }, 53 },
54 AttrDefId::EnumVariantId(it) => { 54 AttrDefId::EnumVariantId(it) => {
55 let src = it.parent.child_source(db); 55 let src = it.parent.child_source(db);
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 015fe772e..3f94e40e4 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -60,10 +60,8 @@ impl GenericParams {
60 // FIXME: add `: Sized` bound for everything except for `Self` in traits 60 // FIXME: add `: Sized` bound for everything except for `Self` in traits
61 match def { 61 match def {
62 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), 62 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start),
63 GenericDefId::AdtId(AdtId::StructId(it)) => { 63 GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start),
64 generics.fill(&it.0.source(db).value, start) 64 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start),
65 }
66 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.0.source(db).value, start),
67 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), 65 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start),
68 GenericDefId::TraitId(it) => { 66 GenericDefId::TraitId(it) => {
69 // traits get the Self type as an implicit first type parameter 67 // traits get the Self type as an implicit first type parameter
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
index f15c23db9..f4fdbdcfc 100644
--- a/crates/ra_hir_def/src/lang_item.rs
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -41,7 +41,7 @@ impl LangItems {
41 crate_def_map 41 crate_def_map
42 .modules 42 .modules
43 .iter() 43 .iter()
44 .filter_map(|(module_id, _)| db.module_lang_items(ModuleId { krate, module_id })) 44 .filter_map(|(local_id, _)| db.module_lang_items(ModuleId { krate, local_id }))
45 .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v)))); 45 .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v))));
46 46
47 Arc::new(lang_items) 47 Arc::new(lang_items)
@@ -80,7 +80,7 @@ impl LangItems {
80 fn collect_lang_items(&mut self, db: &impl DefDatabase, module: ModuleId) { 80 fn collect_lang_items(&mut self, db: &impl DefDatabase, module: ModuleId) {
81 // Look for impl targets 81 // Look for impl targets
82 let def_map = db.crate_def_map(module.krate); 82 let def_map = db.crate_def_map(module.krate);
83 let module_data = &def_map[module.module_id]; 83 let module_data = &def_map[module.local_id];
84 for &impl_block in module_data.impls.iter() { 84 for &impl_block in module_data.impls.iter() {
85 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId) 85 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId)
86 } 86 }
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 8e8c2d749..bc5530896 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -27,7 +27,7 @@ pub mod body;
27pub mod resolver; 27pub mod resolver;
28 28
29mod trace; 29mod trace;
30mod nameres; 30pub mod nameres;
31 31
32#[cfg(test)] 32#[cfg(test)]
33mod test_db; 33mod test_db;
@@ -50,7 +50,7 @@ impl_arena_id!(LocalImportId);
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
51pub struct ModuleId { 51pub struct ModuleId {
52 pub krate: CrateId, 52 pub krate: CrateId,
53 pub module_id: LocalModuleId, 53 pub local_id: LocalModuleId,
54} 54}
55 55
56/// An ID of a module, **local** to a specific crate 56/// An ID of a module, **local** to a specific crate
@@ -141,30 +141,26 @@ impl Lookup for FunctionId {
141} 141}
142 142
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
144pub struct StructOrUnionId(salsa::InternId); 144pub struct StructId(salsa::InternId);
145impl_intern_key!(StructOrUnionId); 145impl_intern_key!(StructId);
146impl AstItemDef<ast::StructDef> for StructOrUnionId { 146impl AstItemDef<ast::StructDef> for StructId {
147 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self { 147 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self {
148 db.intern_struct_or_union(loc) 148 db.intern_struct(loc)
149 } 149 }
150 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> { 150 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> {
151 db.lookup_intern_struct_or_union(self) 151 db.lookup_intern_struct(self)
152 } 152 }
153} 153}
154 154
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
156pub struct StructId(pub StructOrUnionId); 156pub struct UnionId(salsa::InternId);
157impl From<StructId> for StructOrUnionId { 157impl_intern_key!(UnionId);
158 fn from(id: StructId) -> StructOrUnionId { 158impl AstItemDef<ast::UnionDef> for UnionId {
159 id.0 159 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::UnionDef>) -> Self {
160 db.intern_union(loc)
160 } 161 }
161} 162 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::UnionDef> {
162 163 db.lookup_intern_union(self)
163#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
164pub struct UnionId(pub StructOrUnionId);
165impl From<UnionId> for StructOrUnionId {
166 fn from(id: UnionId) -> StructOrUnionId {
167 id.0
168 } 164 }
169} 165}
170 166
@@ -402,6 +398,16 @@ impl_froms!(
402 ConstId 398 ConstId
403); 399);
404 400
401impl From<AssocItemId> for GenericDefId {
402 fn from(item: AssocItemId) -> Self {
403 match item {
404 AssocItemId::FunctionId(f) => f.into(),
405 AssocItemId::ConstId(c) => c.into(),
406 AssocItemId::TypeAliasId(t) => t.into(),
407 }
408 }
409}
410
405#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 411#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
406pub enum AttrDefId { 412pub enum AttrDefId {
407 ModuleId(ModuleId), 413 ModuleId(ModuleId),
@@ -435,6 +441,7 @@ impl_froms!(
435pub enum VariantId { 441pub enum VariantId {
436 EnumVariantId(EnumVariantId), 442 EnumVariantId(EnumVariantId),
437 StructId(StructId), 443 StructId(StructId),
444 UnionId(UnionId),
438} 445}
439impl_froms!(VariantId: EnumVariantId, StructId); 446impl_froms!(VariantId: EnumVariantId, StructId);
440 447
@@ -485,13 +492,23 @@ impl HasModule for ConstLoc {
485impl HasModule for AdtId { 492impl HasModule for AdtId {
486 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 493 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
487 match self { 494 match self {
488 AdtId::StructId(it) => it.0.module(db), 495 AdtId::StructId(it) => it.module(db),
489 AdtId::UnionId(it) => it.0.module(db), 496 AdtId::UnionId(it) => it.module(db),
490 AdtId::EnumId(it) => it.module(db), 497 AdtId::EnumId(it) => it.module(db),
491 } 498 }
492 } 499 }
493} 500}
494 501
502impl HasModule for DefWithBodyId {
503 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
504 match self {
505 DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
506 DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
507 DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
508 }
509 }
510}
511
495impl HasModule for StaticLoc { 512impl HasModule for StaticLoc {
496 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { 513 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId {
497 self.container 514 self.container
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 41becf8df..fd8245113 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -6,7 +6,7 @@
6use hir_expand::{ 6use hir_expand::{
7 builtin_macro::find_builtin_macro, 7 builtin_macro::find_builtin_macro,
8 name::{self, AsName, Name}, 8 name::{self, AsName, Name},
9 HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, MacroFileKind, 9 HirFileId, MacroCallId, MacroDefId, MacroDefKind, MacroFileKind,
10}; 10};
11use ra_cfg::CfgOptions; 11use ra_cfg::CfgOptions;
12use ra_db::{CrateId, FileId}; 12use ra_db::{CrateId, FileId};
@@ -25,7 +25,7 @@ use crate::{
25 per_ns::PerNs, 25 per_ns::PerNs,
26 AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId, 26 AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId,
27 Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, 27 Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId,
28 StructOrUnionId, TraitId, TypeAliasLoc, UnionId, 28 TraitId, TypeAliasLoc, UnionId,
29}; 29};
30 30
31pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 31pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -37,7 +37,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
37 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); 37 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
38 def_map.extern_prelude.insert( 38 def_map.extern_prelude.insert(
39 dep.as_name(), 39 dep.as_name(),
40 ModuleId { krate: dep.crate_id, module_id: dep_def_map.root }.into(), 40 ModuleId { krate: dep.crate_id, local_id: dep_def_map.root }.into(),
41 ); 41 );
42 42
43 // look for the prelude 43 // look for the prelude
@@ -323,7 +323,7 @@ where
323 tested_by!(glob_across_crates); 323 tested_by!(glob_across_crates);
324 // glob import from other crate => we can just import everything once 324 // glob import from other crate => we can just import everything once
325 let item_map = self.db.crate_def_map(m.krate); 325 let item_map = self.db.crate_def_map(m.krate);
326 let scope = &item_map[m.module_id].scope; 326 let scope = &item_map[m.local_id].scope;
327 327
328 // Module scoped macros is included 328 // Module scoped macros is included
329 let items = scope 329 let items = scope
@@ -337,7 +337,7 @@ where
337 // glob import from same crate => we do an initial 337 // glob import from same crate => we do an initial
338 // import, and then need to propagate any further 338 // import, and then need to propagate any further
339 // additions 339 // additions
340 let scope = &self.def_map[m.module_id].scope; 340 let scope = &self.def_map[m.local_id].scope;
341 341
342 // Module scoped macros is included 342 // Module scoped macros is included
343 let items = scope 343 let items = scope
@@ -349,7 +349,7 @@ where
349 self.update(module_id, Some(import_id), &items); 349 self.update(module_id, Some(import_id), &items);
350 // record the glob import in case we add further items 350 // record the glob import in case we add further items
351 self.glob_imports 351 self.glob_imports
352 .entry(m.module_id) 352 .entry(m.local_id)
353 .or_default() 353 .or_default()
354 .push((module_id, import_id)); 354 .push((module_id, import_id));
355 } 355 }
@@ -362,7 +362,7 @@ where
362 .variants 362 .variants
363 .iter() 363 .iter()
364 .filter_map(|(local_id, variant_data)| { 364 .filter_map(|(local_id, variant_data)| {
365 let name = variant_data.name.clone()?; 365 let name = variant_data.name.clone();
366 let variant = EnumVariantId { parent: e, local_id }; 366 let variant = EnumVariantId { parent: e, local_id };
367 let res = Resolution { 367 let res = Resolution {
368 def: PerNs::both(variant.into(), variant.into()), 368 def: PerNs::both(variant.into(), variant.into()),
@@ -480,7 +480,7 @@ where
480 ); 480 );
481 481
482 if let Some(def) = resolved_res.resolved_def.take_macros() { 482 if let Some(def) = resolved_res.resolved_def.take_macros() {
483 let call_id = self.db.intern_macro(MacroCallLoc { def, ast_id: *ast_id }); 483 let call_id = def.as_call_id(self.db, *ast_id);
484 resolved.push((*module_id, call_id, def)); 484 resolved.push((*module_id, call_id, def));
485 res = ReachedFixedPoint::No; 485 res = ReachedFixedPoint::No;
486 return false; 486 return false;
@@ -590,7 +590,7 @@ where
590 raw::RawItemKind::Impl(imp) => { 590 raw::RawItemKind::Impl(imp) => {
591 let module = ModuleId { 591 let module = ModuleId {
592 krate: self.def_collector.def_map.krate, 592 krate: self.def_collector.def_map.krate,
593 module_id: self.module_id, 593 local_id: self.module_id,
594 }; 594 };
595 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); 595 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id);
596 let imp_id = ImplId::from_ast_id(ctx, self.raw_items[imp].ast_id); 596 let imp_id = ImplId::from_ast_id(ctx, self.raw_items[imp].ast_id);
@@ -673,7 +673,7 @@ where
673 modules[self.module_id].children.insert(name.clone(), res); 673 modules[self.module_id].children.insert(name.clone(), res);
674 let resolution = Resolution { 674 let resolution = Resolution {
675 def: PerNs::types( 675 def: PerNs::types(
676 ModuleId { krate: self.def_collector.def_map.krate, module_id: res }.into(), 676 ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(),
677 ), 677 ),
678 import: None, 678 import: None,
679 }; 679 };
@@ -682,8 +682,7 @@ where
682 } 682 }
683 683
684 fn define_def(&mut self, def: &raw::DefData) { 684 fn define_def(&mut self, def: &raw::DefData) {
685 let module = 685 let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id };
686 ModuleId { krate: self.def_collector.def_map.krate, module_id: self.module_id };
687 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); 686 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id);
688 687
689 let name = def.name.clone(); 688 let name = def.name.clone();
@@ -698,14 +697,12 @@ where
698 PerNs::values(def.into()) 697 PerNs::values(def.into())
699 } 698 }
700 raw::DefKind::Struct(ast_id) => { 699 raw::DefKind::Struct(ast_id) => {
701 let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); 700 let id = StructId::from_ast_id(ctx, ast_id).into();
702 let s = StructId(id).into(); 701 PerNs::both(id, id)
703 PerNs::both(s, s)
704 } 702 }
705 raw::DefKind::Union(ast_id) => { 703 raw::DefKind::Union(ast_id) => {
706 let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); 704 let id = UnionId::from_ast_id(ctx, ast_id).into();
707 let u = UnionId(id).into(); 705 PerNs::both(id, id)
708 PerNs::both(u, u)
709 } 706 }
710 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), 707 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
711 raw::DefKind::Const(ast_id) => { 708 raw::DefKind::Const(ast_id) => {
@@ -775,8 +772,7 @@ where
775 if let Some(macro_def) = mac.path.as_ident().and_then(|name| { 772 if let Some(macro_def) = mac.path.as_ident().and_then(|name| {
776 self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) 773 self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name)
777 }) { 774 }) {
778 let macro_call_id = 775 let macro_call_id = macro_def.as_call_id(self.def_collector.db, ast_id);
779 self.def_collector.db.intern_macro(MacroCallLoc { def: macro_def, ast_id });
780 776
781 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_def); 777 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_def);
782 return; 778 return;
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index 9455f22bb..b72c55bd1 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -74,19 +74,19 @@ impl CrateDefMap {
74 PathKind::DollarCrate(krate) => { 74 PathKind::DollarCrate(krate) => {
75 if krate == self.krate { 75 if krate == self.krate {
76 tested_by!(macro_dollar_crate_self); 76 tested_by!(macro_dollar_crate_self);
77 PerNs::types(ModuleId { krate: self.krate, module_id: self.root }.into()) 77 PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into())
78 } else { 78 } else {
79 let def_map = db.crate_def_map(krate); 79 let def_map = db.crate_def_map(krate);
80 let module = ModuleId { krate, module_id: def_map.root }; 80 let module = ModuleId { krate, local_id: def_map.root };
81 tested_by!(macro_dollar_crate_other); 81 tested_by!(macro_dollar_crate_other);
82 PerNs::types(module.into()) 82 PerNs::types(module.into())
83 } 83 }
84 } 84 }
85 PathKind::Crate => { 85 PathKind::Crate => {
86 PerNs::types(ModuleId { krate: self.krate, module_id: self.root }.into()) 86 PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into())
87 } 87 }
88 PathKind::Self_ => { 88 PathKind::Self_ => {
89 PerNs::types(ModuleId { krate: self.krate, module_id: original_module }.into()) 89 PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into())
90 } 90 }
91 // plain import or absolute path in 2015: crate-relative with 91 // plain import or absolute path in 2015: crate-relative with
92 // fallback to extern prelude (with the simplification in 92 // fallback to extern prelude (with the simplification in
@@ -113,7 +113,7 @@ impl CrateDefMap {
113 } 113 }
114 PathKind::Super => { 114 PathKind::Super => {
115 if let Some(p) = self.modules[original_module].parent { 115 if let Some(p) = self.modules[original_module].parent {
116 PerNs::types(ModuleId { krate: self.krate, module_id: p }.into()) 116 PerNs::types(ModuleId { krate: self.krate, local_id: p }.into())
117 } else { 117 } else {
118 log::debug!("super path in root module"); 118 log::debug!("super path in root module");
119 return ResolvePathResult::empty(ReachedFixedPoint::Yes); 119 return ResolvePathResult::empty(ReachedFixedPoint::Yes);
@@ -160,7 +160,7 @@ impl CrateDefMap {
160 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; 160 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ };
161 log::debug!("resolving {:?} in other crate", path); 161 log::debug!("resolving {:?} in other crate", path);
162 let defp_map = db.crate_def_map(module.krate); 162 let defp_map = db.crate_def_map(module.krate);
163 let (def, s) = defp_map.resolve_path(db, module.module_id, &path); 163 let (def, s) = defp_map.resolve_path(db, module.local_id, &path);
164 return ResolvePathResult::with( 164 return ResolvePathResult::with(
165 def, 165 def,
166 ReachedFixedPoint::Yes, 166 ReachedFixedPoint::Yes,
@@ -169,7 +169,7 @@ impl CrateDefMap {
169 } 169 }
170 170
171 // Since it is a qualified path here, it should not contains legacy macros 171 // Since it is a qualified path here, it should not contains legacy macros
172 match self[module.module_id].scope.get(&segment.name) { 172 match self[module.local_id].scope.get(&segment.name) {
173 Some(res) => res.def, 173 Some(res) => res.def,
174 _ => { 174 _ => {
175 log::debug!("path segment {:?} not found", segment.name); 175 log::debug!("path segment {:?} not found", segment.name);
@@ -254,7 +254,7 @@ impl CrateDefMap {
254 keep = db.crate_def_map(prelude.krate); 254 keep = db.crate_def_map(prelude.krate);
255 &keep 255 &keep
256 }; 256 };
257 def_map[prelude.module_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) 257 def_map[prelude.local_id].scope.get(name).map_or_else(PerNs::none, |res| res.def)
258 } else { 258 } else {
259 PerNs::none() 259 PerNs::none()
260 } 260 }
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 401af031c..6eb106094 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -176,7 +176,7 @@ pub(super) struct DefData {
176pub(super) enum DefKind { 176pub(super) enum DefKind {
177 Function(FileAstId<ast::FnDef>), 177 Function(FileAstId<ast::FnDef>),
178 Struct(FileAstId<ast::StructDef>), 178 Struct(FileAstId<ast::StructDef>),
179 Union(FileAstId<ast::StructDef>), 179 Union(FileAstId<ast::UnionDef>),
180 Enum(FileAstId<ast::EnumDef>), 180 Enum(FileAstId<ast::EnumDef>),
181 Const(FileAstId<ast::ConstDef>), 181 Const(FileAstId<ast::ConstDef>),
182 Static(FileAstId<ast::StaticDef>), 182 Static(FileAstId<ast::StaticDef>),
@@ -246,11 +246,12 @@ impl RawItemsCollector {
246 ast::ModuleItem::StructDef(it) => { 246 ast::ModuleItem::StructDef(it) => {
247 let id = self.source_ast_id_map.ast_id(&it); 247 let id = self.source_ast_id_map.ast_id(&it);
248 let name = it.name(); 248 let name = it.name();
249 if it.is_union() { 249 (DefKind::Struct(id), name)
250 (DefKind::Union(id), name) 250 }
251 } else { 251 ast::ModuleItem::UnionDef(it) => {
252 (DefKind::Struct(id), name) 252 let id = self.source_ast_id_map.ast_id(&it);
253 } 253 let name = it.name();
254 (DefKind::Union(id), name)
254 } 255 }
255 ast::ModuleItem::EnumDef(it) => { 256 ast::ModuleItem::EnumDef(it) => {
256 (DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name()) 257 (DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name())
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index f502f1cb3..87fcd617c 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -82,6 +82,12 @@ fn crate_def_map_smoke_test() {
82 82
83 //- /foo/bar.rs 83 //- /foo/bar.rs
84 pub struct Baz; 84 pub struct Baz;
85
86 union U {
87 to_be: bool,
88 not_to_be: u8,
89 }
90
85 enum E { V } 91 enum E { V }
86 ", 92 ",
87 ); 93 );
@@ -99,6 +105,7 @@ fn crate_def_map_smoke_test() {
99 â‹®crate::foo::bar 105 â‹®crate::foo::bar
100 â‹®Baz: t v 106 â‹®Baz: t v
101 â‹®E: t 107 â‹®E: t
108 â‹®U: t v
102 "###) 109 "###)
103} 110}
104 111
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 0e606fd0e..6810a26db 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -97,7 +97,7 @@ impl Path {
97 97
98 /// Converts an `ast::Path` to `Path`. Works with use trees. 98 /// Converts an `ast::Path` to `Path`. Works with use trees.
99 /// It correctly handles `$crate` based path from macro call. 99 /// It correctly handles `$crate` based path from macro call.
100 pub(crate) fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> { 100 pub fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
101 let mut kind = PathKind::Plain; 101 let mut kind = PathKind::Plain;
102 let mut segments = Vec::new(); 102 let mut segments = Vec::new();
103 loop { 103 loop {
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 95b3c926d..0847f6dcf 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -61,6 +61,8 @@ pub enum TypeNs {
61 GenericParam(u32), 61 GenericParam(u32),
62 AdtId(AdtId), 62 AdtId(AdtId),
63 AdtSelfType(AdtId), 63 AdtSelfType(AdtId),
64 // Yup, enum variants are added to the types ns, but any usage of variant as
65 // type is an error.
64 EnumVariantId(EnumVariantId), 66 EnumVariantId(EnumVariantId),
65 TypeAliasId(TypeAliasId), 67 TypeAliasId(TypeAliasId),
66 BuiltinType(BuiltinType), 68 BuiltinType(BuiltinType),
@@ -323,7 +325,7 @@ impl Resolver {
323 if let Scope::ModuleScope(m) = scope { 325 if let Scope::ModuleScope(m) = scope {
324 if let Some(prelude) = m.crate_def_map.prelude { 326 if let Some(prelude) = m.crate_def_map.prelude {
325 let prelude_def_map = db.crate_def_map(prelude.krate); 327 let prelude_def_map = db.crate_def_map(prelude.krate);
326 traits.extend(prelude_def_map[prelude.module_id].scope.traits()); 328 traits.extend(prelude_def_map[prelude.local_id].scope.traits());
327 } 329 }
328 traits.extend(m.crate_def_map[m.module_id].scope.traits()); 330 traits.extend(m.crate_def_map[m.module_id].scope.traits());
329 } 331 }
@@ -400,7 +402,7 @@ impl Scope {
400 }); 402 });
401 if let Some(prelude) = m.crate_def_map.prelude { 403 if let Some(prelude) = m.crate_def_map.prelude {
402 let prelude_def_map = db.crate_def_map(prelude.krate); 404 let prelude_def_map = db.crate_def_map(prelude.krate);
403 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { 405 prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, res)| {
404 f(name.clone(), ScopeDef::PerNs(res.def)); 406 f(name.clone(), ScopeDef::PerNs(res.def));
405 }); 407 });
406 } 408 }
@@ -482,7 +484,7 @@ impl Resolver {
482 } 484 }
483} 485}
484 486
485pub trait HasResolver { 487pub trait HasResolver: Copy {
486 /// Builds a resolver for type references inside this def. 488 /// Builds a resolver for type references inside this def.
487 fn resolver(self, db: &impl DefDatabase) -> Resolver; 489 fn resolver(self, db: &impl DefDatabase) -> Resolver;
488} 490}
@@ -490,7 +492,7 @@ pub trait HasResolver {
490impl HasResolver for ModuleId { 492impl HasResolver for ModuleId {
491 fn resolver(self, db: &impl DefDatabase) -> Resolver { 493 fn resolver(self, db: &impl DefDatabase) -> Resolver {
492 let def_map = db.crate_def_map(self.krate); 494 let def_map = db.crate_def_map(self.krate);
493 Resolver::default().push_module_scope(def_map, self.module_id) 495 Resolver::default().push_module_scope(def_map, self.local_id)
494 } 496 }
495} 497}
496 498
@@ -500,7 +502,7 @@ impl HasResolver for TraitId {
500 } 502 }
501} 503}
502 504
503impl<T: Into<AdtId>> HasResolver for T { 505impl<T: Into<AdtId> + Copy> HasResolver for T {
504 fn resolver(self, db: &impl DefDatabase) -> Resolver { 506 fn resolver(self, db: &impl DefDatabase) -> Resolver {
505 let def = self.into(); 507 let def = self.into();
506 def.module(db) 508 def.module(db)
diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs
index 439e8a412..54e3a84bd 100644
--- a/crates/ra_hir_def/src/test_db.rs
+++ b/crates/ra_hir_def/src/test_db.rs
@@ -24,7 +24,9 @@ impl salsa::Database for TestDB {
24 fn salsa_runtime(&self) -> &salsa::Runtime<Self> { 24 fn salsa_runtime(&self) -> &salsa::Runtime<Self> {
25 &self.runtime 25 &self.runtime
26 } 26 }
27 27 fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> {
28 &mut self.runtime
29 }
28 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { 30 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) {
29 let mut events = self.events.lock().unwrap(); 31 let mut events = self.events.lock().unwrap();
30 if let Some(events) = &mut *events { 32 if let Some(events) = &mut *events {
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 4f3ccf1d0..b6a739cda 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -135,6 +135,16 @@ pub struct MacroDefId {
135 pub kind: MacroDefKind, 135 pub kind: MacroDefKind,
136} 136}
137 137
138impl MacroDefId {
139 pub fn as_call_id(
140 self,
141 db: &dyn db::AstDatabase,
142 ast_id: AstId<ast::MacroCall>,
143 ) -> MacroCallId {
144 db.intern_macro(MacroCallLoc { def: self, ast_id })
145 }
146}
147
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 148#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
139pub enum MacroDefKind { 149pub enum MacroDefKind {
140 Declarative, 150 Declarative,
@@ -143,8 +153,8 @@ pub enum MacroDefKind {
143 153
144#[derive(Debug, Clone, PartialEq, Eq, Hash)] 154#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub struct MacroCallLoc { 155pub struct MacroCallLoc {
146 pub def: MacroDefId, 156 pub(crate) def: MacroDefId,
147 pub ast_id: AstId<ast::MacroCall>, 157 pub(crate) ast_id: AstId<ast::MacroCall>,
148} 158}
149 159
150impl MacroCallId { 160impl MacroCallId {
diff --git a/crates/ra_hir_expand/src/test_db.rs b/crates/ra_hir_expand/src/test_db.rs
index d23e75d9e..918736e2a 100644
--- a/crates/ra_hir_expand/src/test_db.rs
+++ b/crates/ra_hir_expand/src/test_db.rs
@@ -23,6 +23,10 @@ impl salsa::Database for TestDB {
23 &self.runtime 23 &self.runtime
24 } 24 }
25 25
26 fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> {
27 &mut self.runtime
28 }
29
26 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { 30 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) {
27 let mut events = self.events.lock().unwrap(); 31 let mut events = self.events.lock().unwrap();
28 if let Some(events) = &mut *events { 32 if let Some(events) = &mut *events {
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
new file mode 100644
index 000000000..429242870
--- /dev/null
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -0,0 +1,32 @@
1[package]
2edition = "2018"
3name = "ra_hir_ty"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6
7[lib]
8doctest = false
9
10[dependencies]
11arrayvec = "0.5.1"
12ena = "0.13"
13log = "0.4.5"
14rustc-hash = "1.0"
15
16hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
17hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
18ra_arena = { path = "../ra_arena" }
19ra_db = { path = "../ra_db" }
20ra_prof = { path = "../ra_prof" }
21ra_syntax = { path = "../ra_syntax" }
22test_utils = { path = "../test_utils" }
23
24# https://github.com/rust-lang/chalk/pull/294
25chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
26chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
27chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
28
29lalrpop-intern = "0.15.1"
30
31[dev-dependencies]
32insta = "0.12.0"
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs
index 41c99d227..9d1d4e48c 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir_ty/src/autoderef.rs
@@ -5,49 +5,56 @@
5 5
6use std::iter::successors; 6use std::iter::successors;
7 7
8use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; 8use hir_def::lang_item::LangItemTarget;
9use hir_expand::name; 9use hir_expand::name;
10use log::{info, warn}; 10use log::{info, warn};
11use ra_db::CrateId;
11 12
12use crate::{db::HirDatabase, Trait}; 13use crate::db::HirDatabase;
13 14
14use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; 15use super::{
16 traits::{InEnvironment, Solution},
17 Canonical, Substs, Ty, TypeWalk,
18};
15 19
16const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
17 21
18pub(crate) fn autoderef<'a>( 22pub fn autoderef<'a>(
19 db: &'a impl HirDatabase, 23 db: &'a impl HirDatabase,
20 resolver: &'a Resolver, 24 krate: Option<CrateId>,
21 ty: Canonical<Ty>, 25 ty: InEnvironment<Canonical<Ty>>,
22) -> impl Iterator<Item = Canonical<Ty>> + 'a { 26) -> impl Iterator<Item = Canonical<Ty>> + 'a {
23 successors(Some(ty), move |ty| deref(db, resolver, ty)).take(AUTODEREF_RECURSION_LIMIT) 27 let InEnvironment { value: ty, environment } = ty;
28 successors(Some(ty), move |ty| {
29 deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() })
30 })
31 .take(AUTODEREF_RECURSION_LIMIT)
24} 32}
25 33
26pub(crate) fn deref( 34pub(crate) fn deref(
27 db: &impl HirDatabase, 35 db: &impl HirDatabase,
28 resolver: &Resolver, 36 krate: CrateId,
29 ty: &Canonical<Ty>, 37 ty: InEnvironment<&Canonical<Ty>>,
30) -> Option<Canonical<Ty>> { 38) -> Option<Canonical<Ty>> {
31 if let Some(derefed) = ty.value.builtin_deref() { 39 if let Some(derefed) = ty.value.value.builtin_deref() {
32 Some(Canonical { value: derefed, num_vars: ty.num_vars }) 40 Some(Canonical { value: derefed, num_vars: ty.value.num_vars })
33 } else { 41 } else {
34 deref_by_trait(db, resolver, ty) 42 deref_by_trait(db, krate, ty)
35 } 43 }
36} 44}
37 45
38fn deref_by_trait( 46fn deref_by_trait(
39 db: &impl HirDatabase, 47 db: &impl HirDatabase,
40 resolver: &Resolver, 48 krate: CrateId,
41 ty: &Canonical<Ty>, 49 ty: InEnvironment<&Canonical<Ty>>,
42) -> Option<Canonical<Ty>> { 50) -> Option<Canonical<Ty>> {
43 let krate = resolver.krate()?;
44 let deref_trait = match db.lang_item(krate.into(), "deref".into())? { 51 let deref_trait = match db.lang_item(krate.into(), "deref".into())? {
45 LangItemTarget::TraitId(t) => Trait::from(t), 52 LangItemTarget::TraitId(it) => it,
46 _ => return None, 53 _ => return None,
47 }; 54 };
48 let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; 55 let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?;
49 56
50 let generic_params = db.generic_params(target.id.into()); 57 let generic_params = db.generic_params(target.into());
51 if generic_params.count_params_including_parent() != 1 { 58 if generic_params.count_params_including_parent() != 1 {
52 // the Target type + Deref trait should only have one generic parameter, 59 // the Target type + Deref trait should only have one generic parameter,
53 // namely Deref's Self type 60 // namely Deref's Self type
@@ -56,10 +63,8 @@ fn deref_by_trait(
56 63
57 // FIXME make the Canonical handling nicer 64 // FIXME make the Canonical handling nicer
58 65
59 let env = super::lower::trait_env(db, resolver);
60
61 let parameters = Substs::build_for_generics(&generic_params) 66 let parameters = Substs::build_for_generics(&generic_params)
62 .push(ty.value.clone().shift_bound_vars(1)) 67 .push(ty.value.value.clone().shift_bound_vars(1))
63 .build(); 68 .build();
64 69
65 let projection = super::traits::ProjectionPredicate { 70 let projection = super::traits::ProjectionPredicate {
@@ -69,9 +74,9 @@ fn deref_by_trait(
69 74
70 let obligation = super::Obligation::Projection(projection); 75 let obligation = super::Obligation::Projection(projection);
71 76
72 let in_env = super::traits::InEnvironment { value: obligation, environment: env }; 77 let in_env = InEnvironment { value: obligation, environment: ty.environment };
73 78
74 let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; 79 let canonical = super::Canonical { num_vars: 1 + ty.value.num_vars, value: in_env };
75 80
76 let solution = db.trait_solve(krate.into(), canonical)?; 81 let solution = db.trait_solve(krate.into(), canonical)?;
77 82
@@ -89,14 +94,14 @@ fn deref_by_trait(
89 // the case. 94 // the case.
90 for i in 1..vars.0.num_vars { 95 for i in 1..vars.0.num_vars {
91 if vars.0.value[i] != Ty::Bound((i - 1) as u32) { 96 if vars.0.value[i] != Ty::Bound((i - 1) as u32) {
92 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty, solution); 97 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
93 return None; 98 return None;
94 } 99 }
95 } 100 }
96 Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars }) 101 Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars })
97 } 102 }
98 Solution::Ambig(_) => { 103 Solution::Ambig(_) => {
99 info!("Ambiguous solution for derefing {:?}: {:?}", ty, solution); 104 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution);
100 None 105 None
101 } 106 }
102 } 107 }
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
new file mode 100644
index 000000000..9ce154593
--- /dev/null
+++ b/crates/ra_hir_ty/src/db.rs
@@ -0,0 +1,119 @@
1//! FIXME: write short doc here
2
3use std::sync::Arc;
4
5use hir_def::{
6 db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId,
7};
8use ra_arena::map::ArenaMap;
9use ra_db::{salsa, CrateId};
10
11use crate::{
12 method_resolution::CrateImplBlocks,
13 traits::{AssocTyValue, Impl},
14 CallableDef, FnSig, GenericPredicate, ImplTy, InferenceResult, Substs, Ty, TyDefId, TypeCtor,
15 ValueTyDefId,
16};
17
18#[salsa::query_group(HirDatabaseStorage)]
19#[salsa::requires(salsa::Database)]
20pub trait HirDatabase: DefDatabase {
21 #[salsa::invoke(crate::infer_query)]
22 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
23
24 #[salsa::invoke(crate::lower::ty_query)]
25 fn ty(&self, def: TyDefId) -> Ty;
26
27 #[salsa::invoke(crate::lower::value_ty_query)]
28 fn value_ty(&self, def: ValueTyDefId) -> Ty;
29
30 #[salsa::invoke(crate::lower::impl_ty_query)]
31 fn impl_ty(&self, def: ImplId) -> ImplTy;
32
33 #[salsa::invoke(crate::lower::field_types_query)]
34 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>;
35
36 #[salsa::invoke(crate::callable_item_sig)]
37 fn callable_item_signature(&self, def: CallableDef) -> FnSig;
38
39 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
40 fn generic_predicates_for_param(
41 &self,
42 def: GenericDefId,
43 param_idx: u32,
44 ) -> Arc<[GenericPredicate]>;
45
46 #[salsa::invoke(crate::lower::generic_predicates_query)]
47 fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>;
48
49 #[salsa::invoke(crate::lower::generic_defaults_query)]
50 fn generic_defaults(&self, def: GenericDefId) -> Substs;
51
52 #[salsa::invoke(crate::method_resolution::CrateImplBlocks::impls_in_crate_query)]
53 fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>;
54
55 #[salsa::invoke(crate::traits::impls_for_trait_query)]
56 fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplId]>;
57
58 /// This provides the Chalk trait solver instance. Because Chalk always
59 /// works from a specific crate, this query is keyed on the crate; and
60 /// because Chalk does its own internal caching, the solver is wrapped in a
61 /// Mutex and the query does an untracked read internally, to make sure the
62 /// cached state is thrown away when input facts change.
63 #[salsa::invoke(crate::traits::trait_solver_query)]
64 fn trait_solver(&self, krate: CrateId) -> crate::traits::TraitSolver;
65
66 // Interned IDs for Chalk integration
67 #[salsa::interned]
68 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId;
69 #[salsa::interned]
70 fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId;
71 #[salsa::interned]
72 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId;
73
74 #[salsa::invoke(crate::traits::chalk::associated_ty_data_query)]
75 fn associated_ty_data(
76 &self,
77 id: chalk_ir::TypeId,
78 ) -> Arc<chalk_rust_ir::AssociatedTyDatum<chalk_ir::family::ChalkIr>>;
79
80 #[salsa::invoke(crate::traits::chalk::trait_datum_query)]
81 fn trait_datum(
82 &self,
83 krate: CrateId,
84 trait_id: chalk_ir::TraitId,
85 ) -> Arc<chalk_rust_ir::TraitDatum<chalk_ir::family::ChalkIr>>;
86
87 #[salsa::invoke(crate::traits::chalk::struct_datum_query)]
88 fn struct_datum(
89 &self,
90 krate: CrateId,
91 struct_id: chalk_ir::StructId,
92 ) -> Arc<chalk_rust_ir::StructDatum<chalk_ir::family::ChalkIr>>;
93
94 #[salsa::invoke(crate::traits::chalk::impl_datum_query)]
95 fn impl_datum(
96 &self,
97 krate: CrateId,
98 impl_id: chalk_ir::ImplId,
99 ) -> Arc<chalk_rust_ir::ImplDatum<chalk_ir::family::ChalkIr>>;
100
101 #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)]
102 fn associated_ty_value(
103 &self,
104 krate: CrateId,
105 id: chalk_rust_ir::AssociatedTyValueId,
106 ) -> Arc<chalk_rust_ir::AssociatedTyValue<chalk_ir::family::ChalkIr>>;
107
108 #[salsa::invoke(crate::traits::trait_solve_query)]
109 fn trait_solve(
110 &self,
111 krate: CrateId,
112 goal: crate::Canonical<crate::InEnvironment<crate::Obligation>>,
113 ) -> Option<crate::traits::Solution>;
114}
115
116#[test]
117fn hir_database_is_object_safe() {
118 fn _assert_object_safe(_: &dyn HirDatabase) {}
119}
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
new file mode 100644
index 000000000..4a13fac23
--- /dev/null
+++ b/crates/ra_hir_ty/src/diagnostics.rs
@@ -0,0 +1,91 @@
1//! FIXME: write short doc here
2
3use std::any::Any;
4
5use hir_expand::{db::AstDatabase, name::Name, HirFileId, Source};
6use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
7
8pub use hir_def::diagnostics::UnresolvedModule;
9pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
10
11#[derive(Debug)]
12pub struct NoSuchField {
13 pub file: HirFileId,
14 pub field: AstPtr<ast::RecordField>,
15}
16
17impl Diagnostic for NoSuchField {
18 fn message(&self) -> String {
19 "no such field".to_string()
20 }
21
22 fn source(&self) -> Source<SyntaxNodePtr> {
23 Source { file_id: self.file, value: self.field.into() }
24 }
25
26 fn as_any(&self) -> &(dyn Any + Send + 'static) {
27 self
28 }
29}
30
31#[derive(Debug)]
32pub struct MissingFields {
33 pub file: HirFileId,
34 pub field_list: AstPtr<ast::RecordFieldList>,
35 pub missed_fields: Vec<Name>,
36}
37
38impl Diagnostic for MissingFields {
39 fn message(&self) -> String {
40 use std::fmt::Write;
41 let mut message = String::from("Missing structure fields:\n");
42 for field in &self.missed_fields {
43 write!(message, "- {}\n", field).unwrap();
44 }
45 message
46 }
47 fn source(&self) -> Source<SyntaxNodePtr> {
48 Source { file_id: self.file, value: self.field_list.into() }
49 }
50 fn as_any(&self) -> &(dyn Any + Send + 'static) {
51 self
52 }
53}
54
55impl AstDiagnostic for MissingFields {
56 type AST = ast::RecordFieldList;
57
58 fn ast(&self, db: &impl AstDatabase) -> Self::AST {
59 let root = db.parse_or_expand(self.source().file_id).unwrap();
60 let node = self.source().value.to_node(&root);
61 ast::RecordFieldList::cast(node).unwrap()
62 }
63}
64
65#[derive(Debug)]
66pub struct MissingOkInTailExpr {
67 pub file: HirFileId,
68 pub expr: AstPtr<ast::Expr>,
69}
70
71impl Diagnostic for MissingOkInTailExpr {
72 fn message(&self) -> String {
73 "wrap return expression in Ok".to_string()
74 }
75 fn source(&self) -> Source<SyntaxNodePtr> {
76 Source { file_id: self.file, value: self.expr.into() }
77 }
78 fn as_any(&self) -> &(dyn Any + Send + 'static) {
79 self
80 }
81}
82
83impl AstDiagnostic for MissingOkInTailExpr {
84 type AST = ast::Expr;
85
86 fn ast(&self, db: &impl AstDatabase) -> Self::AST {
87 let root = db.parse_or_expand(self.file).unwrap();
88 let node = self.source().value.to_node(&root);
89 ast::Expr::cast(node).unwrap()
90 }
91}
diff --git a/crates/ra_hir/src/ty/display.rs b/crates/ra_hir_ty/src/display.rs
index 9bb3ece6c..9bb3ece6c 100644
--- a/crates/ra_hir/src/ty/display.rs
+++ b/crates/ra_hir_ty/src/display.rs
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index 43fedde7a..5c65f9370 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -2,8 +2,12 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{path::known, resolver::HasResolver}; 5use hir_def::{
6use hir_expand::diagnostics::DiagnosticSink; 6 path::{known, Path},
7 resolver::HasResolver,
8 AdtId, FunctionId,
9};
10use hir_expand::{diagnostics::DiagnosticSink, name::Name};
7use ra_syntax::ast; 11use ra_syntax::ast;
8use ra_syntax::AstPtr; 12use ra_syntax::AstPtr;
9use rustc_hash::FxHashSet; 13use rustc_hash::FxHashSet;
@@ -11,8 +15,7 @@ use rustc_hash::FxHashSet;
11use crate::{ 15use crate::{
12 db::HirDatabase, 16 db::HirDatabase,
13 diagnostics::{MissingFields, MissingOkInTailExpr}, 17 diagnostics::{MissingFields, MissingOkInTailExpr},
14 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, 18 ApplicationTy, InferenceResult, Ty, TypeCtor,
15 Adt, Function, Name, Path,
16}; 19};
17 20
18pub use hir_def::{ 21pub use hir_def::{
@@ -26,23 +29,23 @@ pub use hir_def::{
26 }, 29 },
27}; 30};
28 31
29pub(crate) struct ExprValidator<'a, 'b: 'a> { 32pub struct ExprValidator<'a, 'b: 'a> {
30 func: Function, 33 func: FunctionId,
31 infer: Arc<InferenceResult>, 34 infer: Arc<InferenceResult>,
32 sink: &'a mut DiagnosticSink<'b>, 35 sink: &'a mut DiagnosticSink<'b>,
33} 36}
34 37
35impl<'a, 'b> ExprValidator<'a, 'b> { 38impl<'a, 'b> ExprValidator<'a, 'b> {
36 pub(crate) fn new( 39 pub fn new(
37 func: Function, 40 func: FunctionId,
38 infer: Arc<InferenceResult>, 41 infer: Arc<InferenceResult>,
39 sink: &'a mut DiagnosticSink<'b>, 42 sink: &'a mut DiagnosticSink<'b>,
40 ) -> ExprValidator<'a, 'b> { 43 ) -> ExprValidator<'a, 'b> {
41 ExprValidator { func, infer, sink } 44 ExprValidator { func, infer, sink }
42 } 45 }
43 46
44 pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { 47 pub fn validate_body(&mut self, db: &impl HirDatabase) {
45 let body = self.func.body(db); 48 let body = db.body(self.func.into());
46 49
47 for e in body.exprs.iter() { 50 for e in body.exprs.iter() {
48 if let (id, Expr::RecordLit { path, fields, spread }) = e { 51 if let (id, Expr::RecordLit { path, fields, spread }) = e {
@@ -69,16 +72,18 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
69 } 72 }
70 73
71 let struct_def = match self.infer[id].as_adt() { 74 let struct_def = match self.infer[id].as_adt() {
72 Some((Adt::Struct(s), _)) => s, 75 Some((AdtId::StructId(s), _)) => s,
73 _ => return, 76 _ => return,
74 }; 77 };
78 let struct_data = db.struct_data(struct_def);
75 79
76 let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); 80 let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
77 let missed_fields: Vec<Name> = struct_def 81 let missed_fields: Vec<Name> = struct_data
78 .fields(db) 82 .variant_data
83 .fields()
79 .iter() 84 .iter()
80 .filter_map(|f| { 85 .filter_map(|(_f, d)| {
81 let name = f.name(db); 86 let name = d.name.clone();
82 if lit_fields.contains(&name) { 87 if lit_fields.contains(&name) {
83 None 88 None
84 } else { 89 } else {
@@ -89,7 +94,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
89 if missed_fields.is_empty() { 94 if missed_fields.is_empty() {
90 return; 95 return;
91 } 96 }
92 let source_map = self.func.body_source_map(db); 97 let (_, source_map) = db.body_with_source_map(self.func.into());
93 98
94 if let Some(source_ptr) = source_map.expr_syntax(id) { 99 if let Some(source_ptr) = source_map.expr_syntax(id) {
95 if let Some(expr) = source_ptr.value.a() { 100 if let Some(expr) = source_ptr.value.a() {
@@ -121,20 +126,20 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
121 126
122 let std_result_path = known::std_result_result(); 127 let std_result_path = known::std_result_result();
123 128
124 let resolver = self.func.id.resolver(db); 129 let resolver = self.func.resolver(db);
125 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) { 130 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) {
126 Some(it) => it, 131 Some(it) => it,
127 _ => return, 132 _ => return,
128 }; 133 };
129 134
130 let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum.into())); 135 let std_result_ctor = TypeCtor::Adt(AdtId::EnumId(std_result_enum));
131 let params = match &mismatch.expected { 136 let params = match &mismatch.expected {
132 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, 137 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters,
133 _ => return, 138 _ => return,
134 }; 139 };
135 140
136 if params.len() == 2 && &params[0] == &mismatch.actual { 141 if params.len() == 2 && &params[0] == &mismatch.actual {
137 let source_map = self.func.body_source_map(db); 142 let (_, source_map) = db.body_with_source_map(self.func.into());
138 143
139 if let Some(source_ptr) = source_map.expr_syntax(id) { 144 if let Some(source_ptr) = source_map.expr_syntax(id) {
140 if let Some(expr) = source_ptr.value.a() { 145 if let Some(expr) = source_ptr.value.a() {
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir_ty/src/infer.rs
index ddc7d262a..1e9f4b208 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -22,11 +22,13 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
22use rustc_hash::FxHashMap; 22use rustc_hash::FxHashMap;
23 23
24use hir_def::{ 24use hir_def::{
25 body::Body,
25 data::{ConstData, FunctionData}, 26 data::{ConstData, FunctionData},
26 path::known, 27 expr::{BindingAnnotation, ExprId, PatId},
28 path::{known, Path},
27 resolver::{HasResolver, Resolver, TypeNs}, 29 resolver::{HasResolver, Resolver, TypeNs},
28 type_ref::{Mutability, TypeRef}, 30 type_ref::{Mutability, TypeRef},
29 AdtId, DefWithBodyId, 31 AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId,
30}; 32};
31use hir_expand::{diagnostics::DiagnosticSink, name}; 33use hir_expand::{diagnostics::DiagnosticSink, name};
32use ra_arena::map::ArenaMap; 34use ra_arena::map::ArenaMap;
@@ -34,22 +36,16 @@ use ra_prof::profile;
34use test_utils::tested_by; 36use test_utils::tested_by;
35 37
36use super::{ 38use super::{
37 lower, 39 primitive::{FloatTy, IntTy},
38 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 40 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
39 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, 41 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
40 TypeCtor, TypeWalk, Uncertain, 42 TypeWalk, Uncertain,
41};
42use crate::{
43 code_model::TypeAlias,
44 db::HirDatabase,
45 expr::{BindingAnnotation, Body, ExprId, PatId},
46 ty::infer::diagnostics::InferenceDiagnostic,
47 Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, Trait, VariantDef,
48}; 43};
44use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic};
49 45
50macro_rules! ty_app { 46macro_rules! ty_app {
51 ($ctor:pat, $param:pat) => { 47 ($ctor:pat, $param:pat) => {
52 crate::ty::Ty::Apply(crate::ty::ApplicationTy { ctor: $ctor, parameters: $param }) 48 crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param })
53 }; 49 };
54 ($ctor:pat) => { 50 ($ctor:pat) => {
55 ty_app!($ctor, _) 51 ty_app!($ctor, _)
@@ -63,15 +59,15 @@ mod pat;
63mod coerce; 59mod coerce;
64 60
65/// The entry point of type inference. 61/// The entry point of type inference.
66pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { 62pub fn infer_query(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
67 let _p = profile("infer_query"); 63 let _p = profile("infer_query");
68 let resolver = DefWithBodyId::from(def).resolver(db); 64 let resolver = def.resolver(db);
69 let mut ctx = InferenceContext::new(db, def, resolver); 65 let mut ctx = InferenceContext::new(db, def, resolver);
70 66
71 match &def { 67 match def {
72 DefWithBody::Const(c) => ctx.collect_const(&db.const_data(c.id)), 68 DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
73 DefWithBody::Function(f) => ctx.collect_fn(&db.function_data(f.id)), 69 DefWithBodyId::FunctionId(f) => ctx.collect_fn(&db.function_data(f)),
74 DefWithBody::Static(s) => ctx.collect_const(&db.static_data(s.id)), 70 DefWithBodyId::StaticId(s) => ctx.collect_const(&db.static_data(s)),
75 } 71 }
76 72
77 ctx.infer_body(); 73 ctx.infer_body();
@@ -122,50 +118,50 @@ pub struct TypeMismatch {
122#[derive(Clone, PartialEq, Eq, Debug, Default)] 118#[derive(Clone, PartialEq, Eq, Debug, Default)]
123pub struct InferenceResult { 119pub struct InferenceResult {
124 /// For each method call expr, records the function it resolves to. 120 /// For each method call expr, records the function it resolves to.
125 method_resolutions: FxHashMap<ExprId, Function>, 121 method_resolutions: FxHashMap<ExprId, FunctionId>,
126 /// For each field access expr, records the field it resolves to. 122 /// For each field access expr, records the field it resolves to.
127 field_resolutions: FxHashMap<ExprId, StructField>, 123 field_resolutions: FxHashMap<ExprId, StructFieldId>,
128 /// For each field in record literal, records the field it resolves to. 124 /// For each field in record literal, records the field it resolves to.
129 record_field_resolutions: FxHashMap<ExprId, StructField>, 125 record_field_resolutions: FxHashMap<ExprId, StructFieldId>,
130 /// For each struct literal, records the variant it resolves to. 126 /// For each struct literal, records the variant it resolves to.
131 variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>, 127 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
132 /// For each associated item record what it resolves to 128 /// For each associated item record what it resolves to
133 assoc_resolutions: FxHashMap<ExprOrPatId, AssocItem>, 129 assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>,
134 diagnostics: Vec<InferenceDiagnostic>, 130 diagnostics: Vec<InferenceDiagnostic>,
135 pub(super) type_of_expr: ArenaMap<ExprId, Ty>, 131 pub type_of_expr: ArenaMap<ExprId, Ty>,
136 pub(super) type_of_pat: ArenaMap<PatId, Ty>, 132 pub type_of_pat: ArenaMap<PatId, Ty>,
137 pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, 133 pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>,
138} 134}
139 135
140impl InferenceResult { 136impl InferenceResult {
141 pub fn method_resolution(&self, expr: ExprId) -> Option<Function> { 137 pub fn method_resolution(&self, expr: ExprId) -> Option<FunctionId> {
142 self.method_resolutions.get(&expr).copied() 138 self.method_resolutions.get(&expr).copied()
143 } 139 }
144 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { 140 pub fn field_resolution(&self, expr: ExprId) -> Option<StructFieldId> {
145 self.field_resolutions.get(&expr).copied() 141 self.field_resolutions.get(&expr).copied()
146 } 142 }
147 pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructField> { 143 pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructFieldId> {
148 self.record_field_resolutions.get(&expr).copied() 144 self.record_field_resolutions.get(&expr).copied()
149 } 145 }
150 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> { 146 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
151 self.variant_resolutions.get(&id.into()).copied() 147 self.variant_resolutions.get(&id.into()).copied()
152 } 148 }
153 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantDef> { 149 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
154 self.variant_resolutions.get(&id.into()).copied() 150 self.variant_resolutions.get(&id.into()).copied()
155 } 151 }
156 pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<AssocItem> { 152 pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<AssocItemId> {
157 self.assoc_resolutions.get(&id.into()).copied() 153 self.assoc_resolutions.get(&id.into()).copied()
158 } 154 }
159 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<AssocItem> { 155 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<AssocItemId> {
160 self.assoc_resolutions.get(&id.into()).copied() 156 self.assoc_resolutions.get(&id.into()).copied()
161 } 157 }
162 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { 158 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
163 self.type_mismatches.get(expr) 159 self.type_mismatches.get(expr)
164 } 160 }
165 pub(crate) fn add_diagnostics( 161 pub fn add_diagnostics(
166 &self, 162 &self,
167 db: &impl HirDatabase, 163 db: &impl HirDatabase,
168 owner: Function, 164 owner: FunctionId,
169 sink: &mut DiagnosticSink, 165 sink: &mut DiagnosticSink,
170 ) { 166 ) {
171 self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) 167 self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink))
@@ -192,7 +188,7 @@ impl Index<PatId> for InferenceResult {
192#[derive(Clone, Debug)] 188#[derive(Clone, Debug)]
193struct InferenceContext<'a, D: HirDatabase> { 189struct InferenceContext<'a, D: HirDatabase> {
194 db: &'a D, 190 db: &'a D,
195 owner: DefWithBody, 191 owner: DefWithBodyId,
196 body: Arc<Body>, 192 body: Arc<Body>,
197 resolver: Resolver, 193 resolver: Resolver,
198 var_unification_table: InPlaceUnificationTable<TypeVarId>, 194 var_unification_table: InPlaceUnificationTable<TypeVarId>,
@@ -210,13 +206,13 @@ struct InferenceContext<'a, D: HirDatabase> {
210} 206}
211 207
212impl<'a, D: HirDatabase> InferenceContext<'a, D> { 208impl<'a, D: HirDatabase> InferenceContext<'a, D> {
213 fn new(db: &'a D, owner: DefWithBody, resolver: Resolver) -> Self { 209 fn new(db: &'a D, owner: DefWithBodyId, resolver: Resolver) -> Self {
214 InferenceContext { 210 InferenceContext {
215 result: InferenceResult::default(), 211 result: InferenceResult::default(),
216 var_unification_table: InPlaceUnificationTable::new(), 212 var_unification_table: InPlaceUnificationTable::new(),
217 obligations: Vec::default(), 213 obligations: Vec::default(),
218 return_ty: Ty::Unknown, // set in collect_fn_signature 214 return_ty: Ty::Unknown, // set in collect_fn_signature
219 trait_env: lower::trait_env(db, &resolver), 215 trait_env: TraitEnvironment::lower(db, &resolver),
220 coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), 216 coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver),
221 db, 217 db,
222 owner, 218 owner,
@@ -244,20 +240,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
244 self.result.type_of_expr.insert(expr, ty); 240 self.result.type_of_expr.insert(expr, ty);
245 } 241 }
246 242
247 fn write_method_resolution(&mut self, expr: ExprId, func: Function) { 243 fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId) {
248 self.result.method_resolutions.insert(expr, func); 244 self.result.method_resolutions.insert(expr, func);
249 } 245 }
250 246
251 fn write_field_resolution(&mut self, expr: ExprId, field: StructField) { 247 fn write_field_resolution(&mut self, expr: ExprId, field: StructFieldId) {
252 self.result.field_resolutions.insert(expr, field); 248 self.result.field_resolutions.insert(expr, field);
253 } 249 }
254 250
255 fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantDef) { 251 fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) {
256 self.result.variant_resolutions.insert(id, variant); 252 self.result.variant_resolutions.insert(id, variant);
257 } 253 }
258 254
259 fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItem) { 255 fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId) {
260 self.result.assoc_resolutions.insert(id, item); 256 self.result.assoc_resolutions.insert(id, item.into());
261 } 257 }
262 258
263 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { 259 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
@@ -515,51 +511,28 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
515 }) 511 })
516 } 512 }
517 513
518 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) { 514 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) {
519 let path = match path { 515 let path = match path {
520 Some(path) => path, 516 Some(path) => path,
521 None => return (Ty::Unknown, None), 517 None => return (Ty::Unknown, None),
522 }; 518 };
523 let resolver = &self.resolver; 519 let resolver = &self.resolver;
524 let def: TypableDef = 520 // FIXME: this should resolve assoc items as well, see this example:
525 // FIXME: this should resolve assoc items as well, see this example: 521 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
526 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 522 match resolver.resolve_path_in_type_ns_fully(self.db, &path) {
527 match resolver.resolve_path_in_type_ns_fully(self.db, &path) { 523 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => {
528 Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(), 524 let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into());
529 Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(), 525 let ty = self.db.ty(strukt.into());
530 Some(TypeNs::AdtSelfType(adt)) => adt.into(),
531 Some(TypeNs::EnumVariantId(it)) => it.into(),
532 Some(TypeNs::TypeAliasId(it)) => it.into(),
533
534 Some(TypeNs::SelfType(_)) |
535 Some(TypeNs::GenericParam(_)) |
536 Some(TypeNs::BuiltinType(_)) |
537 Some(TypeNs::TraitId(_)) |
538 Some(TypeNs::AdtId(AdtId::EnumId(_))) |
539 None => {
540 return (Ty::Unknown, None)
541 }
542 };
543 // FIXME remove the duplication between here and `Ty::from_path`?
544 let substs = Ty::substs_from_path(self.db, resolver, path, def);
545 match def {
546 TypableDef::Adt(Adt::Struct(s)) => {
547 let ty = s.ty(self.db);
548 let ty = self.insert_type_vars(ty.apply_substs(substs)); 526 let ty = self.insert_type_vars(ty.apply_substs(substs));
549 (ty, Some(s.into())) 527 (ty, Some(strukt.into()))
550 } 528 }
551 TypableDef::EnumVariant(var) => { 529 Some(TypeNs::EnumVariantId(var)) => {
552 let ty = var.parent_enum(self.db).ty(self.db); 530 let substs = Ty::substs_from_path(self.db, resolver, path, var.into());
531 let ty = self.db.ty(var.parent.into());
553 let ty = self.insert_type_vars(ty.apply_substs(substs)); 532 let ty = self.insert_type_vars(ty.apply_substs(substs));
554 (ty, Some(var.into())) 533 (ty, Some(var.into()))
555 } 534 }
556 TypableDef::Adt(Adt::Enum(_)) 535 Some(_) | None => (Ty::Unknown, None),
557 | TypableDef::Adt(Adt::Union(_))
558 | TypableDef::TypeAlias(_)
559 | TypableDef::Function(_)
560 | TypableDef::Const(_)
561 | TypableDef::Static(_)
562 | TypableDef::BuiltinType(_) => (Ty::Unknown, None),
563 } 536 }
564 } 537 }
565 538
@@ -581,28 +554,28 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
581 self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); 554 self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
582 } 555 }
583 556
584 fn resolve_into_iter_item(&self) -> Option<TypeAlias> { 557 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
585 let path = known::std_iter_into_iterator(); 558 let path = known::std_iter_into_iterator();
586 let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); 559 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
587 trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) 560 self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE)
588 } 561 }
589 562
590 fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { 563 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
591 let path = known::std_ops_try(); 564 let path = known::std_ops_try();
592 let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); 565 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
593 trait_.associated_type_by_name(self.db, &name::OK_TYPE) 566 self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE)
594 } 567 }
595 568
596 fn resolve_future_future_output(&self) -> Option<TypeAlias> { 569 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
597 let path = known::std_future_future(); 570 let path = known::std_future_future();
598 let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); 571 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
599 trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) 572 self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE)
600 } 573 }
601 574
602 fn resolve_boxed_box(&self) -> Option<Adt> { 575 fn resolve_boxed_box(&self) -> Option<AdtId> {
603 let path = known::std_boxed_box(); 576 let path = known::std_boxed_box();
604 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 577 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
605 Some(Adt::Struct(struct_.into())) 578 Some(struct_.into())
606 } 579 }
607} 580}
608 581
@@ -720,9 +693,10 @@ impl Expectation {
720} 693}
721 694
722mod diagnostics { 695mod diagnostics {
696 use hir_def::{expr::ExprId, FunctionId, HasSource, Lookup};
723 use hir_expand::diagnostics::DiagnosticSink; 697 use hir_expand::diagnostics::DiagnosticSink;
724 698
725 use crate::{db::HirDatabase, diagnostics::NoSuchField, expr::ExprId, Function, HasSource}; 699 use crate::{db::HirDatabase, diagnostics::NoSuchField};
726 700
727 #[derive(Debug, PartialEq, Eq, Clone)] 701 #[derive(Debug, PartialEq, Eq, Clone)]
728 pub(super) enum InferenceDiagnostic { 702 pub(super) enum InferenceDiagnostic {
@@ -733,13 +707,14 @@ mod diagnostics {
733 pub(super) fn add_to( 707 pub(super) fn add_to(
734 &self, 708 &self,
735 db: &impl HirDatabase, 709 db: &impl HirDatabase,
736 owner: Function, 710 owner: FunctionId,
737 sink: &mut DiagnosticSink, 711 sink: &mut DiagnosticSink,
738 ) { 712 ) {
739 match self { 713 match self {
740 InferenceDiagnostic::NoSuchField { expr, field } => { 714 InferenceDiagnostic::NoSuchField { expr, field } => {
741 let file = owner.source(db).file_id; 715 let file = owner.lookup(db).source(db).file_id;
742 let field = owner.body_source_map(db).field_syntax(*expr, *field); 716 let (_, source_map) = db.body_with_source_map(owner.into());
717 let field = source_map.field_syntax(*expr, *field);
743 sink.push(NoSuchField { file, field }) 718 sink.push(NoSuchField { file, field })
744 } 719 }
745 } 720 }
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs
index 54765da35..719a0f395 100644
--- a/crates/ra_hir/src/ty/infer/coerce.rs
+++ b/crates/ra_hir_ty/src/infer/coerce.rs
@@ -4,17 +4,13 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; 7use hir_def::{lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AdtId};
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9use test_utils::tested_by; 9use test_utils::tested_by;
10 10
11use crate::{ 11use crate::{autoderef, db::HirDatabase, ImplTy, Substs, Ty, TypeCtor, TypeWalk};
12 db::HirDatabase,
13 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk},
14 Adt, Mutability,
15};
16 12
17use super::{InferTy, InferenceContext, TypeVarValue}; 13use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue};
18 14
19impl<'a, D: HirDatabase> InferenceContext<'a, D> { 15impl<'a, D: HirDatabase> InferenceContext<'a, D> {
20 /// Unify two types, but may coerce the first one to the second one 16 /// Unify two types, but may coerce the first one to the second one
@@ -57,9 +53,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
57 53
58 impls 54 impls
59 .iter() 55 .iter()
60 .filter_map(|impl_block| { 56 .filter_map(|&impl_id| {
57 let trait_ref = match db.impl_ty(impl_id) {
58 ImplTy::TraitRef(it) => it,
59 ImplTy::Inherent(_) => return None,
60 };
61
61 // `CoerseUnsized` has one generic parameter for the target type. 62 // `CoerseUnsized` has one generic parameter for the target type.
62 let trait_ref = impl_block.target_trait_ref(db)?;
63 let cur_from_ty = trait_ref.substs.0.get(0)?; 63 let cur_from_ty = trait_ref.substs.0.get(0)?;
64 let cur_to_ty = trait_ref.substs.0.get(1)?; 64 let cur_to_ty = trait_ref.substs.0.get(1)?;
65 65
@@ -242,11 +242,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
242 // - T is not part of the type of any other fields 242 // - T is not part of the type of any other fields
243 // - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T> 243 // - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T>
244 ( 244 (
245 ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), 245 ty_app!(TypeCtor::Adt(AdtId::StructId(struct1)), st1),
246 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), 246 ty_app!(TypeCtor::Adt(AdtId::StructId(struct2)), st2),
247 ) if struct1 == struct2 => { 247 ) if struct1 == struct2 => {
248 let field_tys = self.db.field_types(struct1.id.into()); 248 let field_tys = self.db.field_types((*struct1).into());
249 let struct_data = self.db.struct_data(struct1.id.0); 249 let struct_data = self.db.struct_data(*struct1);
250 250
251 let mut fields = struct_data.variant_data.fields().iter(); 251 let mut fields = struct_data.variant_data.fields().iter();
252 let (last_field_id, _data) = fields.next_back()?; 252 let (last_field_id, _data) = fields.next_back()?;
@@ -320,9 +320,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
320 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone()); 320 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone());
321 let to_ty = self.resolve_ty_shallow(&to_ty); 321 let to_ty = self.resolve_ty_shallow(&to_ty);
322 // FIXME: Auto DerefMut 322 // FIXME: Auto DerefMut
323 for derefed_ty in 323 for derefed_ty in autoderef::autoderef(
324 autoderef::autoderef(self.db, &self.resolver.clone(), canonicalized.value.clone()) 324 self.db,
325 { 325 self.resolver.krate(),
326 InEnvironment {
327 value: canonicalized.value.clone(),
328 environment: self.trait_env.clone(),
329 },
330 ) {
326 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 331 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
327 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 332 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) {
328 // Stop when constructor matches. 333 // Stop when constructor matches.
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 663ff9435..2f9ca4bbb 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -5,21 +5,18 @@ use std::sync::Arc;
5 5
6use hir_def::{ 6use hir_def::{
7 builtin_type::Signedness, 7 builtin_type::Signedness,
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
8 generics::GenericParams, 9 generics::GenericParams,
9 path::{GenericArg, GenericArgs}, 10 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 11 resolver::resolver_for_expr,
12 AdtId, ContainerId, Lookup, StructFieldId,
11}; 13};
12use hir_expand::name; 14use hir_expand::name::{self, Name};
13 15
14use crate::{ 16use crate::{
15 db::HirDatabase, 17 autoderef, db::HirDatabase, method_resolution, op, traits::InEnvironment, utils::variant_data,
16 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 18 CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs,
17 ty::{ 19 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain,
18 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace,
19 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
20 Uncertain,
21 },
22 Adt, Name,
23}; 20};
24 21
25use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 22use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
@@ -136,8 +133,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
136 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, 133 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 },
137 Substs(sig_tys.into()), 134 Substs(sig_tys.into()),
138 ); 135 );
139 let closure_ty = 136 let closure_ty = Ty::apply_one(
140 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 137 TypeCtor::Closure { def: self.owner.into(), expr: tgt_expr },
138 sig_ty,
139 );
141 140
142 // Eagerly try to relate the closure type with the expected 141 // Eagerly try to relate the closure type with the expected
143 // type, otherwise we often won't have enough information to 142 // type, otherwise we often won't have enough information to
@@ -216,22 +215,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
216 let substs = ty.substs().unwrap_or_else(Substs::empty); 215 let substs = ty.substs().unwrap_or_else(Substs::empty);
217 let field_types = 216 let field_types =
218 def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default(); 217 def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default();
218 let variant_data = def_id.map(|it| variant_data(self.db, it));
219 for (field_idx, field) in fields.iter().enumerate() { 219 for (field_idx, field) in fields.iter().enumerate() {
220 let field_def = def_id.and_then(|it| match it.field(self.db, &field.name) { 220 let field_def =
221 Some(field) => Some(field), 221 variant_data.as_ref().and_then(|it| match it.field(&field.name) {
222 None => { 222 Some(local_id) => {
223 self.push_diagnostic(InferenceDiagnostic::NoSuchField { 223 Some(StructFieldId { parent: def_id.unwrap(), local_id })
224 expr: tgt_expr, 224 }
225 field: field_idx, 225 None => {
226 }); 226 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
227 None 227 expr: tgt_expr,
228 } 228 field: field_idx,
229 }); 229 });
230 None
231 }
232 });
230 if let Some(field_def) = field_def { 233 if let Some(field_def) = field_def {
231 self.result.record_field_resolutions.insert(field.expr, field_def); 234 self.result.record_field_resolutions.insert(field.expr, field_def);
232 } 235 }
233 let field_ty = field_def 236 let field_ty = field_def
234 .map_or(Ty::Unknown, |it| field_types[it.id].clone()) 237 .map_or(Ty::Unknown, |it| field_types[it.local_id].clone())
235 .subst(&substs); 238 .subst(&substs);
236 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 239 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
237 } 240 }
@@ -245,20 +248,28 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
245 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); 248 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty);
246 let ty = autoderef::autoderef( 249 let ty = autoderef::autoderef(
247 self.db, 250 self.db,
248 &self.resolver.clone(), 251 self.resolver.krate(),
249 canonicalized.value.clone(), 252 InEnvironment {
253 value: canonicalized.value.clone(),
254 environment: self.trait_env.clone(),
255 },
250 ) 256 )
251 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 257 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
252 Ty::Apply(a_ty) => match a_ty.ctor { 258 Ty::Apply(a_ty) => match a_ty.ctor {
253 TypeCtor::Tuple { .. } => name 259 TypeCtor::Tuple { .. } => name
254 .as_tuple_index() 260 .as_tuple_index()
255 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 261 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()),
256 TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { 262 TypeCtor::Adt(AdtId::StructId(s)) => {
257 self.write_field_resolution(tgt_expr, field); 263 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
258 self.db.field_types(s.id.into())[field.id] 264 let field = StructFieldId { parent: s.into(), local_id }.into();
259 .clone() 265 self.write_field_resolution(tgt_expr, field);
260 .subst(&a_ty.parameters) 266 self.db.field_types(s.into())[field.local_id]
261 }), 267 .clone()
268 .subst(&a_ty.parameters)
269 })
270 }
271 // FIXME:
272 TypeCtor::Adt(AdtId::UnionId(_)) => None,
262 _ => None, 273 _ => None,
263 }, 274 },
264 _ => None, 275 _ => None,
@@ -337,16 +348,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
337 Expr::UnaryOp { expr, op } => { 348 Expr::UnaryOp { expr, op } => {
338 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 349 let inner_ty = self.infer_expr(*expr, &Expectation::none());
339 match op { 350 match op {
340 UnaryOp::Deref => { 351 UnaryOp::Deref => match self.resolver.krate() {
341 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); 352 Some(krate) => {
342 if let Some(derefed_ty) = 353 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty);
343 autoderef::deref(self.db, &self.resolver, &canonicalized.value) 354 match autoderef::deref(
344 { 355 self.db,
345 canonicalized.decanonicalize_ty(derefed_ty.value) 356 krate,
346 } else { 357 InEnvironment {
347 Ty::Unknown 358 value: &canonicalized.value,
359 environment: self.trait_env.clone(),
360 },
361 ) {
362 Some(derefed_ty) => {
363 canonicalized.decanonicalize_ty(derefed_ty.value)
364 }
365 None => Ty::Unknown,
366 }
348 } 367 }
349 } 368 None => Ty::Unknown,
369 },
350 UnaryOp::Neg => { 370 UnaryOp::Neg => {
351 match &inner_ty { 371 match &inner_ty {
352 Ty::Apply(a_ty) => match a_ty.ctor { 372 Ty::Apply(a_ty) => match a_ty.ctor {
@@ -538,11 +558,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
538 Some((ty, func)) => { 558 Some((ty, func)) => {
539 let ty = canonicalized_receiver.decanonicalize_ty(ty); 559 let ty = canonicalized_receiver.decanonicalize_ty(ty);
540 self.write_method_resolution(tgt_expr, func); 560 self.write_method_resolution(tgt_expr, func);
541 ( 561 (ty, self.db.value_ty(func.into()), Some(self.db.generic_params(func.into())))
542 ty,
543 self.db.type_for_def(func.into(), Namespace::Values),
544 Some(self.db.generic_params(func.id.into())),
545 )
546 } 562 }
547 None => (receiver_ty, Ty::Unknown, None), 563 None => (receiver_ty, Ty::Unknown, None),
548 }; 564 };
@@ -648,18 +664,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
648 } 664 }
649 // add obligation for trait implementation, if this is a trait method 665 // add obligation for trait implementation, if this is a trait method
650 match def { 666 match def {
651 CallableDef::Function(f) => { 667 CallableDef::FunctionId(f) => {
652 if let Some(trait_) = f.parent_trait(self.db) { 668 if let ContainerId::TraitId(trait_) = f.lookup(self.db).container {
653 // construct a TraitDef 669 // construct a TraitDef
654 let substs = a_ty.parameters.prefix( 670 let substs = a_ty.parameters.prefix(
655 self.db 671 self.db
656 .generic_params(trait_.id.into()) 672 .generic_params(trait_.into())
657 .count_params_including_parent(), 673 .count_params_including_parent(),
658 ); 674 );
659 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); 675 self.obligations.push(Obligation::Trait(TraitRef {
676 trait_: trait_.into(),
677 substs,
678 }));
660 } 679 }
661 } 680 }
662 CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {} 681 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {}
663 } 682 }
664 } 683 }
665 } 684 }
diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index 641d61e87..1ebb36239 100644
--- a/crates/ra_hir/src/ty/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -3,15 +3,16 @@
3use std::iter::repeat; 3use std::iter::repeat;
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use hir_def::{
7 expr::{BindingAnnotation, Pat, PatId, RecordFieldPat},
8 path::Path,
9 type_ref::Mutability,
10};
11use hir_expand::name::Name;
6use test_utils::tested_by; 12use test_utils::tested_by;
7 13
8use super::{BindingMode, InferenceContext}; 14use super::{BindingMode, InferenceContext};
9use crate::{ 15use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, TypeWalk};
10 db::HirDatabase,
11 expr::{BindingAnnotation, Pat, PatId, RecordFieldPat},
12 ty::{Mutability, Substs, Ty, TypeCtor, TypeWalk},
13 Name, Path,
14};
15 16
16impl<'a, D: HirDatabase> InferenceContext<'a, D> { 17impl<'a, D: HirDatabase> InferenceContext<'a, D> {
17 fn infer_tuple_struct_pat( 18 fn infer_tuple_struct_pat(
@@ -22,16 +23,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
22 default_bm: BindingMode, 23 default_bm: BindingMode,
23 ) -> Ty { 24 ) -> Ty {
24 let (ty, def) = self.resolve_variant(path); 25 let (ty, def) = self.resolve_variant(path);
25 26 let var_data = def.map(|it| variant_data(self.db, it));
26 self.unify(&ty, expected); 27 self.unify(&ty, expected);
27 28
28 let substs = ty.substs().unwrap_or_else(Substs::empty); 29 let substs = ty.substs().unwrap_or_else(Substs::empty);
29 30
30 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); 31 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default();
32
31 for (i, &subpat) in subpats.iter().enumerate() { 33 for (i, &subpat) in subpats.iter().enumerate() {
32 let expected_ty = def 34 let expected_ty = var_data
33 .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) 35 .as_ref()
34 .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) 36 .and_then(|d| d.field(&Name::new_tuple_field(i)))
37 .map_or(Ty::Unknown, |field| field_tys[field].clone())
35 .subst(&substs); 38 .subst(&substs);
36 let expected_ty = self.normalize_associated_types_in(expected_ty); 39 let expected_ty = self.normalize_associated_types_in(expected_ty);
37 self.infer_pat(subpat, &expected_ty, default_bm); 40 self.infer_pat(subpat, &expected_ty, default_bm);
@@ -49,6 +52,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
49 id: PatId, 52 id: PatId,
50 ) -> Ty { 53 ) -> Ty {
51 let (ty, def) = self.resolve_variant(path); 54 let (ty, def) = self.resolve_variant(path);
55 let var_data = def.map(|it| variant_data(self.db, it));
52 if let Some(variant) = def { 56 if let Some(variant) = def {
53 self.write_variant_resolution(id.into(), variant); 57 self.write_variant_resolution(id.into(), variant);
54 } 58 }
@@ -59,10 +63,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
59 63
60 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); 64 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default();
61 for subpat in subpats { 65 for subpat in subpats {
62 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); 66 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name));
63 let expected_ty = matching_field 67 let expected_ty =
64 .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) 68 matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs);
65 .subst(&substs);
66 let expected_ty = self.normalize_associated_types_in(expected_ty); 69 let expected_ty = self.normalize_associated_types_in(expected_ty);
67 self.infer_pat(subpat.pat, &expected_ty, default_bm); 70 self.infer_pat(subpat.pat, &expected_ty, default_bm);
68 } 71 }
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index ee54d8217..14be66836 100644
--- a/crates/ra_hir/src/ty/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -1,15 +1,13 @@
1//! Path expression resolution. 1//! Path expression resolution.
2 2
3use hir_def::{ 3use hir_def::{
4 path::PathSegment, 4 path::{Path, PathKind, PathSegment},
5 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, 5 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
6 AssocItemId, ContainerId, Lookup,
6}; 7};
8use hir_expand::name::Name;
7 9
8use crate::{ 10use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId};
9 db::HirDatabase,
10 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk},
11 AssocItem, Container, Function, Name, Path,
12};
13 11
14use super::{ExprOrPatId, InferenceContext, TraitRef}; 12use super::{ExprOrPatId, InferenceContext, TraitRef};
15 13
@@ -32,7 +30,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
32 path: &Path, 30 path: &Path,
33 id: ExprOrPatId, 31 id: ExprOrPatId,
34 ) -> Option<Ty> { 32 ) -> Option<Ty> {
35 let (value, self_subst) = if let crate::PathKind::Type(type_ref) = &path.kind { 33 let (value, self_subst) = if let PathKind::Type(type_ref) = &path.kind {
36 if path.segments.is_empty() { 34 if path.segments.is_empty() {
37 // This can't actually happen syntax-wise 35 // This can't actually happen syntax-wise
38 return None; 36 return None;
@@ -56,7 +54,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
56 } 54 }
57 }; 55 };
58 56
59 let typable: TypableDef = match value { 57 let typable: ValueTyDefId = match value {
60 ValueNs::LocalBinding(pat) => { 58 ValueNs::LocalBinding(pat) => {
61 let ty = self.result.type_of_pat.get(pat)?.clone(); 59 let ty = self.result.type_of_pat.get(pat)?.clone();
62 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 60 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
@@ -69,11 +67,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
69 ValueNs::EnumVariantId(it) => it.into(), 67 ValueNs::EnumVariantId(it) => it.into(),
70 }; 68 };
71 69
72 let mut ty = self.db.type_for_def(typable, Namespace::Values); 70 let mut ty = self.db.value_ty(typable);
73 if let Some(self_subst) = self_subst { 71 if let Some(self_subst) = self_subst {
74 ty = ty.subst(&self_subst); 72 ty = ty.subst(&self_subst);
75 } 73 }
76
77 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 74 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
78 let ty = ty.subst(&substs); 75 let ty = ty.subst(&substs);
79 Some(ty) 76 Some(ty)
@@ -143,28 +140,35 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
143 id: ExprOrPatId, 140 id: ExprOrPatId,
144 ) -> Option<(ValueNs, Option<Substs>)> { 141 ) -> Option<(ValueNs, Option<Substs>)> {
145 let trait_ = trait_ref.trait_; 142 let trait_ = trait_ref.trait_;
146 let item = trait_.items(self.db).iter().copied().find_map(|item| match item { 143 let item = self
147 AssocItem::Function(func) => { 144 .db
148 if segment.name == func.name(self.db) { 145 .trait_data(trait_)
149 Some(AssocItem::Function(func)) 146 .items
150 } else { 147 .iter()
151 None 148 .map(|(_name, id)| (*id).into())
149 .find_map(|item| match item {
150 AssocItemId::FunctionId(func) => {
151 if segment.name == self.db.function_data(func).name {
152 Some(AssocItemId::FunctionId(func))
153 } else {
154 None
155 }
152 } 156 }
153 }
154 157
155 AssocItem::Const(konst) => { 158 AssocItemId::ConstId(konst) => {
156 if konst.name(self.db).map_or(false, |n| n == segment.name) { 159 if self.db.const_data(konst).name.as_ref().map_or(false, |n| n == &segment.name)
157 Some(AssocItem::Const(konst)) 160 {
158 } else { 161 Some(AssocItemId::ConstId(konst))
159 None 162 } else {
163 None
164 }
160 } 165 }
161 } 166 AssocItemId::TypeAliasId(_) => None,
162 AssocItem::TypeAlias(_) => None, 167 })?;
163 })?;
164 let def = match item { 168 let def = match item {
165 AssocItem::Function(f) => ValueNs::FunctionId(f.id), 169 AssocItemId::FunctionId(f) => ValueNs::FunctionId(f),
166 AssocItem::Const(c) => ValueNs::ConstId(c.id), 170 AssocItemId::ConstId(c) => ValueNs::ConstId(c),
167 AssocItem::TypeAlias(_) => unreachable!(), 171 AssocItemId::TypeAliasId(_) => unreachable!(),
168 }; 172 };
169 let substs = Substs::build_for_def(self.db, item) 173 let substs = Substs::build_for_def(self.db, item)
170 .use_parent_substs(&trait_ref.substs) 174 .use_parent_substs(&trait_ref.substs)
@@ -194,16 +198,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
194 Some(name), 198 Some(name),
195 method_resolution::LookupMode::Path, 199 method_resolution::LookupMode::Path,
196 move |_ty, item| { 200 move |_ty, item| {
197 let def = match item { 201 let (def, container) = match item {
198 AssocItem::Function(f) => ValueNs::FunctionId(f.id), 202 AssocItemId::FunctionId(f) => {
199 AssocItem::Const(c) => ValueNs::ConstId(c.id), 203 (ValueNs::FunctionId(f), f.lookup(self.db).container)
200 AssocItem::TypeAlias(_) => unreachable!(), 204 }
205 AssocItemId::ConstId(c) => (ValueNs::ConstId(c), c.lookup(self.db).container),
206 AssocItemId::TypeAliasId(_) => unreachable!(),
201 }; 207 };
202 let substs = match item.container(self.db) { 208 let substs = match container {
203 Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()), 209 ContainerId::ImplId(_) => self.find_self_types(&def, ty.clone()),
204 Container::Trait(t) => { 210 ContainerId::TraitId(trait_) => {
205 // we're picking this method 211 // we're picking this method
206 let trait_substs = Substs::build_for_def(self.db, t) 212 let trait_substs = Substs::build_for_def(self.db, trait_)
207 .push(ty.clone()) 213 .push(ty.clone())
208 .fill(std::iter::repeat_with(|| self.new_type_var())) 214 .fill(std::iter::repeat_with(|| self.new_type_var()))
209 .build(); 215 .build();
@@ -212,37 +218,41 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
212 .fill_with_params() 218 .fill_with_params()
213 .build(); 219 .build();
214 self.obligations.push(super::Obligation::Trait(TraitRef { 220 self.obligations.push(super::Obligation::Trait(TraitRef {
215 trait_: t, 221 trait_,
216 substs: trait_substs, 222 substs: trait_substs,
217 })); 223 }));
218 Some(substs) 224 Some(substs)
219 } 225 }
226 ContainerId::ModuleId(_) => None,
220 }; 227 };
221 228
222 self.write_assoc_resolution(id, item); 229 self.write_assoc_resolution(id, item.into());
223 Some((def, substs)) 230 Some((def, substs))
224 }, 231 },
225 ) 232 )
226 } 233 }
227 234
228 fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> { 235 fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> {
229 if let ValueNs::FunctionId(func) = def { 236 if let ValueNs::FunctionId(func) = *def {
230 let func = Function::from(*func);
231 // We only do the infer if parent has generic params 237 // We only do the infer if parent has generic params
232 let gen = self.db.generic_params(func.id.into()); 238 let gen = self.db.generic_params(func.into());
233 if gen.count_parent_params() == 0 { 239 if gen.count_parent_params() == 0 {
234 return None; 240 return None;
235 } 241 }
236 242
237 let impl_block = func.impl_block(self.db)?.target_ty(self.db); 243 let impl_id = match func.lookup(self.db).container {
238 let impl_block_substs = impl_block.substs()?; 244 ContainerId::ImplId(it) => it,
245 _ => return None,
246 };
247 let self_ty = self.db.impl_ty(impl_id).self_type().clone();
248 let self_ty_substs = self_ty.substs()?;
239 let actual_substs = actual_def_ty.substs()?; 249 let actual_substs = actual_def_ty.substs()?;
240 250
241 let mut new_substs = vec![Ty::Unknown; gen.count_parent_params()]; 251 let mut new_substs = vec![Ty::Unknown; gen.count_parent_params()];
242 252
243 // The following code *link up* the function actual parma type 253 // The following code *link up* the function actual parma type
244 // and impl_block type param index 254 // and impl_block type param index
245 impl_block_substs.iter().zip(actual_substs.iter()).for_each(|(param, pty)| { 255 self_ty_substs.iter().zip(actual_substs.iter()).for_each(|(param, pty)| {
246 if let Ty::Param { idx, .. } = param { 256 if let Ty::Param { idx, .. } = param {
247 if let Some(s) = new_substs.get_mut(*idx as usize) { 257 if let Some(s) = new_substs.get_mut(*idx as usize) {
248 *s = pty.clone(); 258 *s = pty.clone();
diff --git a/crates/ra_hir/src/ty/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs
index 64d9394cf..f3a875678 100644
--- a/crates/ra_hir/src/ty/infer/unify.rs
+++ b/crates/ra_hir_ty/src/infer/unify.rs
@@ -1,12 +1,10 @@
1//! Unification and canonicalization logic. 1//! Unification and canonicalization logic.
2 2
3use super::{InferenceContext, Obligation}; 3use super::{InferenceContext, Obligation};
4use crate::db::HirDatabase; 4use crate::{
5use crate::ty::{ 5 db::HirDatabase, utils::make_mut_slice, Canonical, InEnvironment, InferTy, ProjectionPredicate,
6 Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, 6 ProjectionTy, Substs, TraitRef, Ty, TypeWalk,
7 TypeWalk,
8}; 7};
9use crate::util::make_mut_slice;
10 8
11impl<'a, D: HirDatabase> InferenceContext<'a, D> { 9impl<'a, D: HirDatabase> InferenceContext<'a, D> {
12 pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b, D> 10 pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b, D>
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
new file mode 100644
index 000000000..b45c8f82f
--- /dev/null
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -0,0 +1,1138 @@
1//! The type system. We currently use this to infer types for completion, hover
2//! information and various assists.
3
4macro_rules! impl_froms {
5 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
6 $(
7 impl From<$v> for $e {
8 fn from(it: $v) -> $e {
9 $e::$v(it)
10 }
11 }
12 $($(
13 impl From<$sv> for $e {
14 fn from(it: $sv) -> $e {
15 $e::$v($v::$sv(it))
16 }
17 }
18 )*)?
19 )*
20 }
21}
22
23mod autoderef;
24pub mod primitive;
25pub mod traits;
26pub mod method_resolution;
27mod op;
28mod lower;
29mod infer;
30pub mod display;
31pub(crate) mod utils;
32pub mod db;
33pub mod diagnostics;
34pub mod expr;
35
36#[cfg(test)]
37mod tests;
38#[cfg(test)]
39mod test_db;
40mod marks;
41
42use std::ops::Deref;
43use std::sync::Arc;
44use std::{fmt, iter, mem};
45
46use hir_def::{
47 expr::ExprId, generics::GenericParams, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId,
48 GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
49};
50use hir_expand::name::Name;
51use ra_db::{impl_intern_key, salsa, CrateId};
52
53use crate::{
54 db::HirDatabase,
55 primitive::{FloatTy, IntTy, Uncertain},
56 utils::make_mut_slice,
57};
58use display::{HirDisplay, HirFormatter};
59
60pub use autoderef::autoderef;
61pub use infer::{infer_query, InferTy, InferenceResult};
62pub use lower::CallableDef;
63pub use lower::{callable_item_sig, TyDefId, ValueTyDefId};
64pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
65
66/// A type constructor or type name: this might be something like the primitive
67/// type `bool`, a struct like `Vec`, or things like function pointers or
68/// tuples.
69#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
70pub enum TypeCtor {
71 /// The primitive boolean type. Written as `bool`.
72 Bool,
73
74 /// The primitive character type; holds a Unicode scalar value
75 /// (a non-surrogate code point). Written as `char`.
76 Char,
77
78 /// A primitive integer type. For example, `i32`.
79 Int(Uncertain<IntTy>),
80
81 /// A primitive floating-point type. For example, `f64`.
82 Float(Uncertain<FloatTy>),
83
84 /// Structures, enumerations and unions.
85 Adt(AdtId),
86
87 /// The pointee of a string slice. Written as `str`.
88 Str,
89
90 /// The pointee of an array slice. Written as `[T]`.
91 Slice,
92
93 /// An array with the given length. Written as `[T; n]`.
94 Array,
95
96 /// A raw pointer. Written as `*mut T` or `*const T`
97 RawPtr(Mutability),
98
99 /// A reference; a pointer with an associated lifetime. Written as
100 /// `&'a mut T` or `&'a T`.
101 Ref(Mutability),
102
103 /// The anonymous type of a function declaration/definition. Each
104 /// function has a unique type, which is output (for a function
105 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
106 ///
107 /// This includes tuple struct / enum variant constructors as well.
108 ///
109 /// For example the type of `bar` here:
110 ///
111 /// ```
112 /// fn foo() -> i32 { 1 }
113 /// let bar = foo; // bar: fn() -> i32 {foo}
114 /// ```
115 FnDef(CallableDef),
116
117 /// A pointer to a function. Written as `fn() -> i32`.
118 ///
119 /// For example the type of `bar` here:
120 ///
121 /// ```
122 /// fn foo() -> i32 { 1 }
123 /// let bar: fn() -> i32 = foo;
124 /// ```
125 FnPtr { num_args: u16 },
126
127 /// The never type `!`.
128 Never,
129
130 /// A tuple type. For example, `(i32, bool)`.
131 Tuple { cardinality: u16 },
132
133 /// Represents an associated item like `Iterator::Item`. This is used
134 /// when we have tried to normalize a projection like `T::Item` but
135 /// couldn't find a better representation. In that case, we generate
136 /// an **application type** like `(Iterator::Item)<T>`.
137 AssociatedType(TypeAliasId),
138
139 /// The type of a specific closure.
140 ///
141 /// The closure signature is stored in a `FnPtr` type in the first type
142 /// parameter.
143 Closure { def: DefWithBodyId, expr: ExprId },
144}
145
146/// This exists just for Chalk, because Chalk just has a single `StructId` where
147/// we have different kinds of ADTs, primitive types and special type
148/// constructors like tuples and function pointers.
149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150pub struct TypeCtorId(salsa::InternId);
151impl_intern_key!(TypeCtorId);
152
153impl TypeCtor {
154 pub fn num_ty_params(self, db: &impl HirDatabase) -> usize {
155 match self {
156 TypeCtor::Bool
157 | TypeCtor::Char
158 | TypeCtor::Int(_)
159 | TypeCtor::Float(_)
160 | TypeCtor::Str
161 | TypeCtor::Never => 0,
162 TypeCtor::Slice
163 | TypeCtor::Array
164 | TypeCtor::RawPtr(_)
165 | TypeCtor::Ref(_)
166 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure
167 => 1,
168 TypeCtor::Adt(adt) => {
169 let generic_params = db.generic_params(AdtId::from(adt).into());
170 generic_params.count_params_including_parent()
171 }
172 TypeCtor::FnDef(callable) => {
173 let generic_params = db.generic_params(callable.into());
174 generic_params.count_params_including_parent()
175 }
176 TypeCtor::AssociatedType(type_alias) => {
177 let generic_params = db.generic_params(type_alias.into());
178 generic_params.count_params_including_parent()
179 }
180 TypeCtor::FnPtr { num_args } => num_args as usize + 1,
181 TypeCtor::Tuple { cardinality } => cardinality as usize,
182 }
183 }
184
185 pub fn krate(self, db: &impl HirDatabase) -> Option<CrateId> {
186 match self {
187 TypeCtor::Bool
188 | TypeCtor::Char
189 | TypeCtor::Int(_)
190 | TypeCtor::Float(_)
191 | TypeCtor::Str
192 | TypeCtor::Never
193 | TypeCtor::Slice
194 | TypeCtor::Array
195 | TypeCtor::RawPtr(_)
196 | TypeCtor::Ref(_)
197 | TypeCtor::FnPtr { .. }
198 | TypeCtor::Tuple { .. } => None,
199 // Closure's krate is irrelevant for coherence I would think?
200 TypeCtor::Closure { .. } => None,
201 TypeCtor::Adt(adt) => Some(adt.module(db).krate),
202 TypeCtor::FnDef(callable) => Some(callable.krate(db)),
203 TypeCtor::AssociatedType(type_alias) => Some(type_alias.lookup(db).module(db).krate),
204 }
205 }
206
207 pub fn as_generic_def(self) -> Option<GenericDefId> {
208 match self {
209 TypeCtor::Bool
210 | TypeCtor::Char
211 | TypeCtor::Int(_)
212 | TypeCtor::Float(_)
213 | TypeCtor::Str
214 | TypeCtor::Never
215 | TypeCtor::Slice
216 | TypeCtor::Array
217 | TypeCtor::RawPtr(_)
218 | TypeCtor::Ref(_)
219 | TypeCtor::FnPtr { .. }
220 | TypeCtor::Tuple { .. }
221 | TypeCtor::Closure { .. } => None,
222 TypeCtor::Adt(adt) => Some(adt.into()),
223 TypeCtor::FnDef(callable) => Some(callable.into()),
224 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
225 }
226 }
227}
228
229/// A nominal type with (maybe 0) type parameters. This might be a primitive
230/// type like `bool`, a struct, tuple, function pointer, reference or
231/// several other things.
232#[derive(Clone, PartialEq, Eq, Debug, Hash)]
233pub struct ApplicationTy {
234 pub ctor: TypeCtor,
235 pub parameters: Substs,
236}
237
238/// A "projection" type corresponds to an (unnormalized)
239/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
240/// trait and all its parameters are fully known.
241#[derive(Clone, PartialEq, Eq, Debug, Hash)]
242pub struct ProjectionTy {
243 pub associated_ty: TypeAliasId,
244 pub parameters: Substs,
245}
246
247impl ProjectionTy {
248 pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef {
249 TraitRef { trait_: self.trait_(db).into(), substs: self.parameters.clone() }
250 }
251
252 fn trait_(&self, db: &impl HirDatabase) -> TraitId {
253 match self.associated_ty.lookup(db).container {
254 ContainerId::TraitId(it) => it,
255 _ => panic!("projection ty without parent trait"),
256 }
257 }
258}
259
260impl TypeWalk for ProjectionTy {
261 fn walk(&self, f: &mut impl FnMut(&Ty)) {
262 self.parameters.walk(f);
263 }
264
265 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
266 self.parameters.walk_mut_binders(f, binders);
267 }
268}
269
270/// A type.
271///
272/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
273/// the same thing (but in a different way).
274///
275/// This should be cheap to clone.
276#[derive(Clone, PartialEq, Eq, Debug, Hash)]
277pub enum Ty {
278 /// A nominal type with (maybe 0) type parameters. This might be a primitive
279 /// type like `bool`, a struct, tuple, function pointer, reference or
280 /// several other things.
281 Apply(ApplicationTy),
282
283 /// A "projection" type corresponds to an (unnormalized)
284 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
285 /// trait and all its parameters are fully known.
286 Projection(ProjectionTy),
287
288 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
289 Param {
290 /// The index of the parameter (starting with parameters from the
291 /// surrounding impl, then the current function).
292 idx: u32,
293 /// The name of the parameter, for displaying.
294 // FIXME get rid of this
295 name: Name,
296 },
297
298 /// A bound type variable. Used during trait resolution to represent Chalk
299 /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type.
300 Bound(u32),
301
302 /// A type variable used during type checking. Not to be confused with a
303 /// type parameter.
304 Infer(InferTy),
305
306 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
307 ///
308 /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)`
309 /// represents the `Self` type inside the bounds. This is currently
310 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
311 /// didn't seem worth the overhead yet.
312 Dyn(Arc<[GenericPredicate]>),
313
314 /// An opaque type (`impl Trait`).
315 ///
316 /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for
317 /// more.
318 Opaque(Arc<[GenericPredicate]>),
319
320 /// A placeholder for a type which could not be computed; this is propagated
321 /// to avoid useless error messages. Doubles as a placeholder where type
322 /// variables are inserted before type checking, since we want to try to
323 /// infer a better type here anyway -- for the IDE use case, we want to try
324 /// to infer as much as possible even in the presence of type errors.
325 Unknown,
326}
327
328/// A list of substitutions for generic parameters.
329#[derive(Clone, PartialEq, Eq, Debug, Hash)]
330pub struct Substs(Arc<[Ty]>);
331
332impl TypeWalk for Substs {
333 fn walk(&self, f: &mut impl FnMut(&Ty)) {
334 for t in self.0.iter() {
335 t.walk(f);
336 }
337 }
338
339 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
340 for t in make_mut_slice(&mut self.0) {
341 t.walk_mut_binders(f, binders);
342 }
343 }
344}
345
346impl Substs {
347 pub fn empty() -> Substs {
348 Substs(Arc::new([]))
349 }
350
351 pub fn single(ty: Ty) -> Substs {
352 Substs(Arc::new([ty]))
353 }
354
355 pub fn prefix(&self, n: usize) -> Substs {
356 Substs(self.0[..std::cmp::min(self.0.len(), n)].into())
357 }
358
359 pub fn as_single(&self) -> &Ty {
360 if self.0.len() != 1 {
361 panic!("expected substs of len 1, got {:?}", self);
362 }
363 &self.0[0]
364 }
365
366 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
367 pub fn identity(generic_params: &GenericParams) -> Substs {
368 Substs(
369 generic_params
370 .params_including_parent()
371 .into_iter()
372 .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() })
373 .collect(),
374 )
375 }
376
377 /// Return Substs that replace each parameter by a bound variable.
378 pub fn bound_vars(generic_params: &GenericParams) -> Substs {
379 Substs(
380 generic_params
381 .params_including_parent()
382 .into_iter()
383 .map(|p| Ty::Bound(p.idx))
384 .collect(),
385 )
386 }
387
388 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
389 let def = def.into();
390 let params = db.generic_params(def);
391 let param_count = params.count_params_including_parent();
392 Substs::builder(param_count)
393 }
394
395 pub fn build_for_generics(generic_params: &GenericParams) -> SubstsBuilder {
396 Substs::builder(generic_params.count_params_including_parent())
397 }
398
399 pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder {
400 Substs::builder(type_ctor.num_ty_params(db))
401 }
402
403 fn builder(param_count: usize) -> SubstsBuilder {
404 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
405 }
406}
407
408#[derive(Debug, Clone)]
409pub struct SubstsBuilder {
410 vec: Vec<Ty>,
411 param_count: usize,
412}
413
414impl SubstsBuilder {
415 pub fn build(self) -> Substs {
416 assert_eq!(self.vec.len(), self.param_count);
417 Substs(self.vec.into())
418 }
419
420 pub fn push(mut self, ty: Ty) -> Self {
421 self.vec.push(ty);
422 self
423 }
424
425 fn remaining(&self) -> usize {
426 self.param_count - self.vec.len()
427 }
428
429 pub fn fill_with_bound_vars(self, starting_from: u32) -> Self {
430 self.fill((starting_from..).map(Ty::Bound))
431 }
432
433 pub fn fill_with_params(self) -> Self {
434 let start = self.vec.len() as u32;
435 self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() }))
436 }
437
438 pub fn fill_with_unknown(self) -> Self {
439 self.fill(iter::repeat(Ty::Unknown))
440 }
441
442 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self {
443 self.vec.extend(filler.take(self.remaining()));
444 assert_eq!(self.remaining(), 0);
445 self
446 }
447
448 pub fn use_parent_substs(mut self, parent_substs: &Substs) -> Self {
449 assert!(self.vec.is_empty());
450 assert!(parent_substs.len() <= self.param_count);
451 self.vec.extend(parent_substs.iter().cloned());
452 self
453 }
454}
455
456impl Deref for Substs {
457 type Target = [Ty];
458
459 fn deref(&self) -> &[Ty] {
460 &self.0
461 }
462}
463
464/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
465/// Name to be bikeshedded: TraitBound? TraitImplements?
466#[derive(Clone, PartialEq, Eq, Debug, Hash)]
467pub struct TraitRef {
468 /// FIXME name?
469 pub trait_: TraitId,
470 pub substs: Substs,
471}
472
473impl TraitRef {
474 pub fn self_ty(&self) -> &Ty {
475 &self.substs[0]
476 }
477}
478
479impl TypeWalk for TraitRef {
480 fn walk(&self, f: &mut impl FnMut(&Ty)) {
481 self.substs.walk(f);
482 }
483
484 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
485 self.substs.walk_mut_binders(f, binders);
486 }
487}
488
489#[derive(Clone, PartialEq, Eq, Debug)]
490pub enum ImplTy {
491 Inherent(Ty),
492 TraitRef(TraitRef),
493}
494
495impl ImplTy {
496 pub(crate) fn self_type(&self) -> &Ty {
497 match self {
498 ImplTy::Inherent(it) => it,
499 ImplTy::TraitRef(tr) => &tr.substs[0],
500 }
501 }
502}
503
504/// Like `generics::WherePredicate`, but with resolved types: A condition on the
505/// parameters of a generic item.
506#[derive(Debug, Clone, PartialEq, Eq, Hash)]
507pub enum GenericPredicate {
508 /// The given trait needs to be implemented for its type parameters.
509 Implemented(TraitRef),
510 /// An associated type bindings like in `Iterator<Item = T>`.
511 Projection(ProjectionPredicate),
512 /// We couldn't resolve the trait reference. (If some type parameters can't
513 /// be resolved, they will just be Unknown).
514 Error,
515}
516
517impl GenericPredicate {
518 pub fn is_error(&self) -> bool {
519 match self {
520 GenericPredicate::Error => true,
521 _ => false,
522 }
523 }
524
525 pub fn is_implemented(&self) -> bool {
526 match self {
527 GenericPredicate::Implemented(_) => true,
528 _ => false,
529 }
530 }
531
532 pub fn trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
533 match self {
534 GenericPredicate::Implemented(tr) => Some(tr.clone()),
535 GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)),
536 GenericPredicate::Error => None,
537 }
538 }
539}
540
541impl TypeWalk for GenericPredicate {
542 fn walk(&self, f: &mut impl FnMut(&Ty)) {
543 match self {
544 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
545 GenericPredicate::Projection(projection_pred) => projection_pred.walk(f),
546 GenericPredicate::Error => {}
547 }
548 }
549
550 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
551 match self {
552 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
553 GenericPredicate::Projection(projection_pred) => {
554 projection_pred.walk_mut_binders(f, binders)
555 }
556 GenericPredicate::Error => {}
557 }
558 }
559}
560
561/// Basically a claim (currently not validated / checked) that the contained
562/// type / trait ref contains no inference variables; any inference variables it
563/// contained have been replaced by bound variables, and `num_vars` tells us how
564/// many there are. This is used to erase irrelevant differences between types
565/// before using them in queries.
566#[derive(Debug, Clone, PartialEq, Eq, Hash)]
567pub struct Canonical<T> {
568 pub value: T,
569 pub num_vars: usize,
570}
571
572/// A function signature as seen by type inference: Several parameter types and
573/// one return type.
574#[derive(Clone, PartialEq, Eq, Debug)]
575pub struct FnSig {
576 params_and_return: Arc<[Ty]>,
577}
578
579impl FnSig {
580 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
581 params.push(ret);
582 FnSig { params_and_return: params.into() }
583 }
584
585 pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig {
586 FnSig { params_and_return: Arc::clone(&substs.0) }
587 }
588
589 pub fn params(&self) -> &[Ty] {
590 &self.params_and_return[0..self.params_and_return.len() - 1]
591 }
592
593 pub fn ret(&self) -> &Ty {
594 &self.params_and_return[self.params_and_return.len() - 1]
595 }
596}
597
598impl TypeWalk for FnSig {
599 fn walk(&self, f: &mut impl FnMut(&Ty)) {
600 for t in self.params_and_return.iter() {
601 t.walk(f);
602 }
603 }
604
605 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
606 for t in make_mut_slice(&mut self.params_and_return) {
607 t.walk_mut_binders(f, binders);
608 }
609 }
610}
611
612impl Ty {
613 pub fn simple(ctor: TypeCtor) -> Ty {
614 Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() })
615 }
616 pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty {
617 Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) })
618 }
619 pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty {
620 Ty::Apply(ApplicationTy { ctor, parameters })
621 }
622 pub fn unit() -> Self {
623 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty())
624 }
625
626 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
627 match self {
628 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => {
629 Some((parameters.as_single(), *mutability))
630 }
631 _ => None,
632 }
633 }
634
635 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
636 match self {
637 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => {
638 Some((*adt_def, parameters))
639 }
640 _ => None,
641 }
642 }
643
644 pub fn as_tuple(&self) -> Option<&Substs> {
645 match self {
646 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => {
647 Some(parameters)
648 }
649 _ => None,
650 }
651 }
652
653 pub fn as_callable(&self) -> Option<(CallableDef, &Substs)> {
654 match self {
655 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => {
656 Some((*callable_def, parameters))
657 }
658 _ => None,
659 }
660 }
661
662 fn builtin_deref(&self) -> Option<Ty> {
663 match self {
664 Ty::Apply(a_ty) => match a_ty.ctor {
665 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())),
666 TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
667 _ => None,
668 },
669 _ => None,
670 }
671 }
672
673 fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
674 match self {
675 Ty::Apply(a_ty) => match a_ty.ctor {
676 TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)),
677 TypeCtor::FnDef(def) => {
678 let sig = db.callable_item_signature(def);
679 Some(sig.subst(&a_ty.parameters))
680 }
681 TypeCtor::Closure { .. } => {
682 let sig_param = &a_ty.parameters[0];
683 sig_param.callable_sig(db)
684 }
685 _ => None,
686 },
687 _ => None,
688 }
689 }
690
691 /// If this is a type with type parameters (an ADT or function), replaces
692 /// the `Substs` for these type parameters with the given ones. (So e.g. if
693 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
694 /// `Option<u32>` afterwards.)
695 pub fn apply_substs(self, substs: Substs) -> Ty {
696 match self {
697 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => {
698 assert_eq!(previous_substs.len(), substs.len());
699 Ty::Apply(ApplicationTy { ctor, parameters: substs })
700 }
701 _ => self,
702 }
703 }
704
705 /// Returns the type parameters of this type if it has some (i.e. is an ADT
706 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
707 pub fn substs(&self) -> Option<Substs> {
708 match self {
709 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()),
710 _ => None,
711 }
712 }
713
714 /// If this is an `impl Trait` or `dyn Trait`, returns that trait.
715 pub fn inherent_trait(&self) -> Option<TraitId> {
716 match self {
717 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
718 predicates.iter().find_map(|pred| match pred {
719 GenericPredicate::Implemented(tr) => Some(tr.trait_),
720 _ => None,
721 })
722 }
723 _ => None,
724 }
725 }
726}
727
728/// This allows walking structures that contain types to do something with those
729/// types, similar to Chalk's `Fold` trait.
730pub trait TypeWalk {
731 fn walk(&self, f: &mut impl FnMut(&Ty));
732 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
733 self.walk_mut_binders(&mut |ty, _binders| f(ty), 0);
734 }
735 /// Walk the type, counting entered binders.
736 ///
737 /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers
738 /// to the innermost binder, 1 to the next, etc.. So when we want to
739 /// substitute a certain bound variable, we can't just walk the whole type
740 /// and blindly replace each instance of a certain index; when we 'enter'
741 /// things that introduce new bound variables, we have to keep track of
742 /// that. Currently, the only thing that introduces bound variables on our
743 /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound
744 /// variable for the self type.
745 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize);
746
747 fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self
748 where
749 Self: Sized,
750 {
751 self.walk_mut(&mut |ty_mut| {
752 let ty = mem::replace(ty_mut, Ty::Unknown);
753 *ty_mut = f(ty);
754 });
755 self
756 }
757
758 /// Replaces type parameters in this type using the given `Substs`. (So e.g.
759 /// if `self` is `&[T]`, where type parameter T has index 0, and the
760 /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
761 fn subst(self, substs: &Substs) -> Self
762 where
763 Self: Sized,
764 {
765 self.fold(&mut |ty| match ty {
766 Ty::Param { idx, name } => {
767 substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name })
768 }
769 ty => ty,
770 })
771 }
772
773 /// Substitutes `Ty::Bound` vars (as opposed to type parameters).
774 fn subst_bound_vars(mut self, substs: &Substs) -> Self
775 where
776 Self: Sized,
777 {
778 self.walk_mut_binders(
779 &mut |ty, binders| match ty {
780 &mut Ty::Bound(idx) => {
781 if idx as usize >= binders && (idx as usize - binders) < substs.len() {
782 *ty = substs.0[idx as usize - binders].clone();
783 }
784 }
785 _ => {}
786 },
787 0,
788 );
789 self
790 }
791
792 /// Shifts up `Ty::Bound` vars by `n`.
793 fn shift_bound_vars(self, n: i32) -> Self
794 where
795 Self: Sized,
796 {
797 self.fold(&mut |ty| match ty {
798 Ty::Bound(idx) => {
799 assert!(idx as i32 >= -n);
800 Ty::Bound((idx as i32 + n) as u32)
801 }
802 ty => ty,
803 })
804 }
805}
806
807impl TypeWalk for Ty {
808 fn walk(&self, f: &mut impl FnMut(&Ty)) {
809 match self {
810 Ty::Apply(a_ty) => {
811 for t in a_ty.parameters.iter() {
812 t.walk(f);
813 }
814 }
815 Ty::Projection(p_ty) => {
816 for t in p_ty.parameters.iter() {
817 t.walk(f);
818 }
819 }
820 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
821 for p in predicates.iter() {
822 p.walk(f);
823 }
824 }
825 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
826 }
827 f(self);
828 }
829
830 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
831 match self {
832 Ty::Apply(a_ty) => {
833 a_ty.parameters.walk_mut_binders(f, binders);
834 }
835 Ty::Projection(p_ty) => {
836 p_ty.parameters.walk_mut_binders(f, binders);
837 }
838 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
839 for p in make_mut_slice(predicates) {
840 p.walk_mut_binders(f, binders + 1);
841 }
842 }
843 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
844 }
845 f(self, binders);
846 }
847}
848
849impl HirDisplay for &Ty {
850 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
851 HirDisplay::hir_fmt(*self, f)
852 }
853}
854
855impl HirDisplay for ApplicationTy {
856 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
857 if f.should_truncate() {
858 return write!(f, "…");
859 }
860
861 match self.ctor {
862 TypeCtor::Bool => write!(f, "bool")?,
863 TypeCtor::Char => write!(f, "char")?,
864 TypeCtor::Int(t) => write!(f, "{}", t)?,
865 TypeCtor::Float(t) => write!(f, "{}", t)?,
866 TypeCtor::Str => write!(f, "str")?,
867 TypeCtor::Slice => {
868 let t = self.parameters.as_single();
869 write!(f, "[{}]", t.display(f.db))?;
870 }
871 TypeCtor::Array => {
872 let t = self.parameters.as_single();
873 write!(f, "[{};_]", t.display(f.db))?;
874 }
875 TypeCtor::RawPtr(m) => {
876 let t = self.parameters.as_single();
877 write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;
878 }
879 TypeCtor::Ref(m) => {
880 let t = self.parameters.as_single();
881 write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
882 }
883 TypeCtor::Never => write!(f, "!")?,
884 TypeCtor::Tuple { .. } => {
885 let ts = &self.parameters;
886 if ts.len() == 1 {
887 write!(f, "({},)", ts[0].display(f.db))?;
888 } else {
889 write!(f, "(")?;
890 f.write_joined(&*ts.0, ", ")?;
891 write!(f, ")")?;
892 }
893 }
894 TypeCtor::FnPtr { .. } => {
895 let sig = FnSig::from_fn_ptr_substs(&self.parameters);
896 write!(f, "fn(")?;
897 f.write_joined(sig.params(), ", ")?;
898 write!(f, ") -> {}", sig.ret().display(f.db))?;
899 }
900 TypeCtor::FnDef(def) => {
901 let sig = f.db.callable_item_signature(def);
902 let name = match def {
903 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
904 CallableDef::StructId(s) => f.db.struct_data(s).name.clone(),
905 CallableDef::EnumVariantId(e) => {
906 let enum_data = f.db.enum_data(e.parent);
907 enum_data.variants[e.local_id].name.clone()
908 }
909 };
910 match def {
911 CallableDef::FunctionId(_) => write!(f, "fn {}", name)?,
912 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {
913 write!(f, "{}", name)?
914 }
915 }
916 if self.parameters.len() > 0 {
917 write!(f, "<")?;
918 f.write_joined(&*self.parameters.0, ", ")?;
919 write!(f, ">")?;
920 }
921 write!(f, "(")?;
922 f.write_joined(sig.params(), ", ")?;
923 write!(f, ") -> {}", sig.ret().display(f.db))?;
924 }
925 TypeCtor::Adt(def_id) => {
926 let name = match def_id {
927 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
928 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
929 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
930 };
931 write!(f, "{}", name)?;
932 if self.parameters.len() > 0 {
933 write!(f, "<")?;
934 f.write_joined(&*self.parameters.0, ", ")?;
935 write!(f, ">")?;
936 }
937 }
938 TypeCtor::AssociatedType(type_alias) => {
939 let trait_ = match type_alias.lookup(f.db).container {
940 ContainerId::TraitId(it) => it,
941 _ => panic!("not an associated type"),
942 };
943 let trait_name = f.db.trait_data(trait_).name.clone();
944 let name = f.db.type_alias_data(type_alias).name.clone();
945 write!(f, "{}::{}", trait_name, name)?;
946 if self.parameters.len() > 0 {
947 write!(f, "<")?;
948 f.write_joined(&*self.parameters.0, ", ")?;
949 write!(f, ">")?;
950 }
951 }
952 TypeCtor::Closure { .. } => {
953 let sig = self.parameters[0]
954 .callable_sig(f.db)
955 .expect("first closure parameter should contain signature");
956 write!(f, "|")?;
957 f.write_joined(sig.params(), ", ")?;
958 write!(f, "| -> {}", sig.ret().display(f.db))?;
959 }
960 }
961 Ok(())
962 }
963}
964
965impl HirDisplay for ProjectionTy {
966 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
967 if f.should_truncate() {
968 return write!(f, "…");
969 }
970
971 let trait_name = f.db.trait_data(self.trait_(f.db)).name.clone();
972 write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?;
973 if self.parameters.len() > 1 {
974 write!(f, "<")?;
975 f.write_joined(&self.parameters[1..], ", ")?;
976 write!(f, ">")?;
977 }
978 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
979 Ok(())
980 }
981}
982
983impl HirDisplay for Ty {
984 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
985 if f.should_truncate() {
986 return write!(f, "…");
987 }
988
989 match self {
990 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
991 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
992 Ty::Param { name, .. } => write!(f, "{}", name)?,
993 Ty::Bound(idx) => write!(f, "?{}", idx)?,
994 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
995 match self {
996 Ty::Dyn(_) => write!(f, "dyn ")?,
997 Ty::Opaque(_) => write!(f, "impl ")?,
998 _ => unreachable!(),
999 };
1000 // Note: This code is written to produce nice results (i.e.
1001 // corresponding to surface Rust) for types that can occur in
1002 // actual Rust. It will have weird results if the predicates
1003 // aren't as expected (i.e. self types = $0, projection
1004 // predicates for a certain trait come after the Implemented
1005 // predicate for that trait).
1006 let mut first = true;
1007 let mut angle_open = false;
1008 for p in predicates.iter() {
1009 match p {
1010 GenericPredicate::Implemented(trait_ref) => {
1011 if angle_open {
1012 write!(f, ">")?;
1013 }
1014 if !first {
1015 write!(f, " + ")?;
1016 }
1017 // We assume that the self type is $0 (i.e. the
1018 // existential) here, which is the only thing that's
1019 // possible in actual Rust, and hence don't print it
1020 write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
1021 if trait_ref.substs.len() > 1 {
1022 write!(f, "<")?;
1023 f.write_joined(&trait_ref.substs[1..], ", ")?;
1024 // there might be assoc type bindings, so we leave the angle brackets open
1025 angle_open = true;
1026 }
1027 }
1028 GenericPredicate::Projection(projection_pred) => {
1029 // in types in actual Rust, these will always come
1030 // after the corresponding Implemented predicate
1031 if angle_open {
1032 write!(f, ", ")?;
1033 } else {
1034 write!(f, "<")?;
1035 angle_open = true;
1036 }
1037 let name =
1038 f.db.type_alias_data(projection_pred.projection_ty.associated_ty)
1039 .name
1040 .clone();
1041 write!(f, "{} = ", name)?;
1042 projection_pred.ty.hir_fmt(f)?;
1043 }
1044 GenericPredicate::Error => {
1045 if angle_open {
1046 // impl Trait<X, {error}>
1047 write!(f, ", ")?;
1048 } else if !first {
1049 // impl Trait + {error}
1050 write!(f, " + ")?;
1051 }
1052 p.hir_fmt(f)?;
1053 }
1054 }
1055 first = false;
1056 }
1057 if angle_open {
1058 write!(f, ">")?;
1059 }
1060 }
1061 Ty::Unknown => write!(f, "{{unknown}}")?,
1062 Ty::Infer(..) => write!(f, "_")?,
1063 }
1064 Ok(())
1065 }
1066}
1067
1068impl TraitRef {
1069 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result {
1070 if f.should_truncate() {
1071 return write!(f, "…");
1072 }
1073
1074 self.substs[0].hir_fmt(f)?;
1075 if use_as {
1076 write!(f, " as ")?;
1077 } else {
1078 write!(f, ": ")?;
1079 }
1080 write!(f, "{}", f.db.trait_data(self.trait_).name.clone())?;
1081 if self.substs.len() > 1 {
1082 write!(f, "<")?;
1083 f.write_joined(&self.substs[1..], ", ")?;
1084 write!(f, ">")?;
1085 }
1086 Ok(())
1087 }
1088}
1089
1090impl HirDisplay for TraitRef {
1091 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1092 self.hir_fmt_ext(f, false)
1093 }
1094}
1095
1096impl HirDisplay for &GenericPredicate {
1097 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1098 HirDisplay::hir_fmt(*self, f)
1099 }
1100}
1101
1102impl HirDisplay for GenericPredicate {
1103 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1104 if f.should_truncate() {
1105 return write!(f, "…");
1106 }
1107
1108 match self {
1109 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
1110 GenericPredicate::Projection(projection_pred) => {
1111 write!(f, "<")?;
1112 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
1113 write!(
1114 f,
1115 ">::{} = {}",
1116 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name,
1117 projection_pred.ty.display(f.db)
1118 )?;
1119 }
1120 GenericPredicate::Error => write!(f, "{{error}}")?,
1121 }
1122 Ok(())
1123 }
1124}
1125
1126impl HirDisplay for Obligation {
1127 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1128 match self {
1129 Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)),
1130 Obligation::Projection(proj) => write!(
1131 f,
1132 "Normalize({} => {})",
1133 proj.projection_ty.display(f.db),
1134 proj.ty.display(f.db)
1135 ),
1136 }
1137 }
1138}
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir_ty/src/lower.rs
index a39beb2a0..091c60f4f 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -9,43 +9,30 @@ use std::iter;
9use std::sync::Arc; 9use std::sync::Arc;
10 10
11use hir_def::{ 11use hir_def::{
12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, 12 builtin_type::BuiltinType,
13 generics::WherePredicate, 13 generics::WherePredicate,
14 path::{GenericArg, PathSegment}, 14 path::{GenericArg, Path, PathKind, PathSegment},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, GenericDefId, LocalStructFieldId, VariantId, 17 AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId,
18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
18}; 19};
19use ra_arena::map::ArenaMap; 20use ra_arena::map::ArenaMap;
21use ra_db::CrateId;
20 22
21use super::{
22 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
23 TypeWalk,
24};
25use crate::{ 23use crate::{
26 db::HirDatabase, 24 db::HirDatabase,
27 ty::{ 25 primitive::{FloatTy, IntTy},
28 primitive::{FloatTy, IntTy, Uncertain}, 26 utils::{
29 Adt, 27 all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice,
28 variant_data,
30 }, 29 },
31 util::make_mut_slice, 30 FnSig, GenericPredicate, ImplTy, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment,
32 Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, 31 TraitRef, Ty, TypeCtor, TypeWalk,
33 Trait, TypeAlias, Union,
34}; 32};
35 33
36// FIXME: this is only really used in `type_for_def`, which contains a bunch of
37// impossible cases. Perhaps we should recombine `TypeableDef` and `Namespace`
38// into a `AsTypeDef`, `AsValueDef` enums?
39#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
40pub enum Namespace {
41 Types,
42 Values,
43 // Note that only type inference uses this enum, and it doesn't care about macros.
44 // Macro,
45}
46
47impl Ty { 34impl Ty {
48 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { 35 pub fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self {
49 match type_ref { 36 match type_ref {
50 TypeRef::Never => Ty::simple(TypeCtor::Never), 37 TypeRef::Never => Ty::simple(TypeCtor::Never),
51 TypeRef::Tuple(inner) => { 38 TypeRef::Tuple(inner) => {
@@ -114,7 +101,7 @@ impl Ty {
114 TypeRef::Path(path) => path, 101 TypeRef::Path(path) => path,
115 _ => return None, 102 _ => return None,
116 }; 103 };
117 if let crate::PathKind::Type(_) = &path.kind { 104 if let PathKind::Type(_) = &path.kind {
118 return None; 105 return None;
119 } 106 }
120 if path.segments.len() > 1 { 107 if path.segments.len() > 1 {
@@ -158,19 +145,16 @@ impl Ty {
158 ) -> Ty { 145 ) -> Ty {
159 let ty = match resolution { 146 let ty = match resolution {
160 TypeNs::TraitId(trait_) => { 147 TypeNs::TraitId(trait_) => {
161 let trait_ref = TraitRef::from_resolved_path( 148 let trait_ref =
162 db, 149 TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None);
163 resolver,
164 trait_.into(),
165 resolved_segment,
166 None,
167 );
168 return if remaining_segments.len() == 1 { 150 return if remaining_segments.len() == 1 {
169 let segment = &remaining_segments[0]; 151 let segment = &remaining_segments[0];
170 match trait_ref 152 let associated_ty = associated_type_by_name_including_super_traits(
171 .trait_ 153 db,
172 .associated_type_by_name_including_super_traits(db, &segment.name) 154 trait_ref.trait_,
173 { 155 &segment.name,
156 );
157 match associated_ty {
174 Some(associated_ty) => { 158 Some(associated_ty) => {
175 // FIXME handle type parameters on the segment 159 // FIXME handle type parameters on the segment
176 Ty::Projection(ProjectionTy { 160 Ty::Projection(ProjectionTy {
@@ -195,8 +179,8 @@ impl Ty {
195 let name = resolved_segment.name.clone(); 179 let name = resolved_segment.name.clone();
196 Ty::Param { idx, name } 180 Ty::Param { idx, name }
197 } 181 }
198 TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db), 182 TypeNs::SelfType(impl_id) => db.impl_ty(impl_id).self_type().clone(),
199 TypeNs::AdtSelfType(adt) => Adt::from(adt).ty(db), 183 TypeNs::AdtSelfType(adt) => db.ty(adt.into()),
200 184
201 TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), 185 TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()),
202 TypeNs::BuiltinType(it) => { 186 TypeNs::BuiltinType(it) => {
@@ -214,7 +198,7 @@ impl Ty {
214 198
215 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { 199 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty {
216 // Resolve the path (in type namespace) 200 // Resolve the path (in type namespace)
217 if let crate::PathKind::Type(type_ref) = &path.kind { 201 if let PathKind::Type(type_ref) = &path.kind {
218 let ty = Ty::from_hir(db, resolver, &type_ref); 202 let ty = Ty::from_hir(db, resolver, &type_ref);
219 let remaining_segments = &path.segments[..]; 203 let remaining_segments = &path.segments[..];
220 return Ty::from_type_relative_path(db, resolver, ty, remaining_segments); 204 return Ty::from_type_relative_path(db, resolver, ty, remaining_segments);
@@ -258,9 +242,9 @@ impl Ty {
258 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), 242 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_),
259 _ => None, 243 _ => None,
260 }); 244 });
261 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); 245 let traits = traits_from_env.flat_map(|t| all_super_traits(db, t));
262 for t in traits { 246 for t in traits {
263 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { 247 if let Some(associated_ty) = db.trait_data(t).associated_type_by_name(&segment.name) {
264 let substs = 248 let substs =
265 Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); 249 Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build();
266 // FIXME handle type parameters on the segment 250 // FIXME handle type parameters on the segment
@@ -274,27 +258,15 @@ impl Ty {
274 db: &impl HirDatabase, 258 db: &impl HirDatabase,
275 resolver: &Resolver, 259 resolver: &Resolver,
276 segment: &PathSegment, 260 segment: &PathSegment,
277 typable: TypableDef, 261 typable: TyDefId,
278 ) -> Ty { 262 ) -> Ty {
279 let ty = db.type_for_def(typable, Namespace::Types); 263 let generic_def = match typable {
280 let substs = Ty::substs_from_path_segment(db, resolver, segment, typable); 264 TyDefId::BuiltinType(_) => None,
281 ty.subst(&substs) 265 TyDefId::AdtId(it) => Some(it.into()),
282 } 266 TyDefId::TypeAliasId(it) => Some(it.into()),
283
284 pub(super) fn substs_from_path_segment(
285 db: &impl HirDatabase,
286 resolver: &Resolver,
287 segment: &PathSegment,
288 resolved: TypableDef,
289 ) -> Substs {
290 let def_generic: Option<GenericDef> = match resolved {
291 TypableDef::Function(func) => Some(func.into()),
292 TypableDef::Adt(adt) => Some(adt.into()),
293 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()),
294 TypableDef::TypeAlias(t) => Some(t.into()),
295 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None,
296 }; 267 };
297 substs_from_path_segment(db, resolver, segment, def_generic, false) 268 let substs = substs_from_path_segment(db, resolver, segment, generic_def, false);
269 db.ty(typable).subst(&substs)
298 } 270 }
299 271
300 /// Collect generic arguments from a path into a `Substs`. See also 272 /// Collect generic arguments from a path into a `Substs`. See also
@@ -303,17 +275,18 @@ impl Ty {
303 db: &impl HirDatabase, 275 db: &impl HirDatabase,
304 resolver: &Resolver, 276 resolver: &Resolver,
305 path: &Path, 277 path: &Path,
306 resolved: TypableDef, 278 // Note that we don't call `db.value_type(resolved)` here,
279 // `ValueTyDefId` is just a convenient way to pass generics and
280 // special-case enum variants
281 resolved: ValueTyDefId,
307 ) -> Substs { 282 ) -> Substs {
308 let last = path.segments.last().expect("path should have at least one segment"); 283 let last = path.segments.last().expect("path should have at least one segment");
309 let segment = match resolved { 284 let (segment, generic_def) = match resolved {
310 TypableDef::Function(_) 285 ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
311 | TypableDef::Adt(_) 286 ValueTyDefId::StructId(it) => (last, Some(it.into())),
312 | TypableDef::Const(_) 287 ValueTyDefId::ConstId(it) => (last, Some(it.into())),
313 | TypableDef::Static(_) 288 ValueTyDefId::StaticId(_) => (last, None),
314 | TypableDef::TypeAlias(_) 289 ValueTyDefId::EnumVariantId(var) => {
315 | TypableDef::BuiltinType(_) => last,
316 TypableDef::EnumVariant(_) => {
317 // the generic args for an enum variant may be either specified 290 // the generic args for an enum variant may be either specified
318 // on the segment referring to the enum, or on the segment 291 // on the segment referring to the enum, or on the segment
319 // referring to the variant. So `Option::<T>::None` and 292 // referring to the variant. So `Option::<T>::None` and
@@ -327,10 +300,10 @@ impl Ty {
327 // Option::None::<T> 300 // Option::None::<T>
328 last 301 last
329 }; 302 };
330 segment 303 (segment, Some(var.parent.into()))
331 } 304 }
332 }; 305 };
333 Ty::substs_from_path_segment(db, resolver, segment, resolved) 306 substs_from_path_segment(db, resolver, segment, generic_def, false)
334 } 307 }
335} 308}
336 309
@@ -338,7 +311,7 @@ pub(super) fn substs_from_path_segment(
338 db: &impl HirDatabase, 311 db: &impl HirDatabase,
339 resolver: &Resolver, 312 resolver: &Resolver,
340 segment: &PathSegment, 313 segment: &PathSegment,
341 def_generic: Option<GenericDef>, 314 def_generic: Option<GenericDefId>,
342 add_self_param: bool, 315 add_self_param: bool,
343) -> Substs { 316) -> Substs {
344 let mut substs = Vec::new(); 317 let mut substs = Vec::new();
@@ -376,7 +349,7 @@ pub(super) fn substs_from_path_segment(
376 349
377 // handle defaults 350 // handle defaults
378 if let Some(def_generic) = def_generic { 351 if let Some(def_generic) = def_generic {
379 let default_substs = db.generic_defaults(def_generic); 352 let default_substs = db.generic_defaults(def_generic.into());
380 assert_eq!(substs.len(), default_substs.len()); 353 assert_eq!(substs.len(), default_substs.len());
381 354
382 for (i, default_ty) in default_substs.iter().enumerate() { 355 for (i, default_ty) in default_substs.iter().enumerate() {
@@ -390,7 +363,7 @@ pub(super) fn substs_from_path_segment(
390} 363}
391 364
392impl TraitRef { 365impl TraitRef {
393 pub(crate) fn from_path( 366 fn from_path(
394 db: &impl HirDatabase, 367 db: &impl HirDatabase,
395 resolver: &Resolver, 368 resolver: &Resolver,
396 path: &Path, 369 path: &Path,
@@ -404,10 +377,10 @@ impl TraitRef {
404 Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) 377 Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty))
405 } 378 }
406 379
407 pub(super) fn from_resolved_path( 380 pub(crate) fn from_resolved_path(
408 db: &impl HirDatabase, 381 db: &impl HirDatabase,
409 resolver: &Resolver, 382 resolver: &Resolver,
410 resolved: Trait, 383 resolved: TraitId,
411 segment: &PathSegment, 384 segment: &PathSegment,
412 explicit_self_ty: Option<Ty>, 385 explicit_self_ty: Option<Ty>,
413 ) -> Self { 386 ) -> Self {
@@ -418,7 +391,7 @@ impl TraitRef {
418 TraitRef { trait_: resolved, substs } 391 TraitRef { trait_: resolved, substs }
419 } 392 }
420 393
421 pub(crate) fn from_hir( 394 fn from_hir(
422 db: &impl HirDatabase, 395 db: &impl HirDatabase,
423 resolver: &Resolver, 396 resolver: &Resolver,
424 type_ref: &TypeRef, 397 type_ref: &TypeRef,
@@ -435,18 +408,13 @@ impl TraitRef {
435 db: &impl HirDatabase, 408 db: &impl HirDatabase,
436 resolver: &Resolver, 409 resolver: &Resolver,
437 segment: &PathSegment, 410 segment: &PathSegment,
438 resolved: Trait, 411 resolved: TraitId,
439 ) -> Substs { 412 ) -> Substs {
440 let has_self_param = 413 let has_self_param =
441 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); 414 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false);
442 substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) 415 substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param)
443 } 416 }
444 417
445 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef {
446 let substs = Substs::identity(&db.generic_params(trait_.id.into()));
447 TraitRef { trait_, substs }
448 }
449
450 pub(crate) fn from_type_bound( 418 pub(crate) fn from_type_bound(
451 db: &impl HirDatabase, 419 db: &impl HirDatabase,
452 resolver: &Resolver, 420 resolver: &Resolver,
@@ -502,10 +470,11 @@ fn assoc_type_bindings_from_type_bound<'a>(
502 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 470 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
503 .map(move |(name, type_ref)| { 471 .map(move |(name, type_ref)| {
504 let associated_ty = 472 let associated_ty =
505 match trait_ref.trait_.associated_type_by_name_including_super_traits(db, &name) { 473 associated_type_by_name_including_super_traits(db, trait_ref.trait_, &name);
506 None => return GenericPredicate::Error, 474 let associated_ty = match associated_ty {
507 Some(t) => t, 475 None => return GenericPredicate::Error,
508 }; 476 Some(t) => t,
477 };
509 let projection_ty = 478 let projection_ty =
510 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; 479 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() };
511 let ty = Ty::from_hir(db, resolver, type_ref); 480 let ty = Ty::from_hir(db, resolver, type_ref);
@@ -514,39 +483,12 @@ fn assoc_type_bindings_from_type_bound<'a>(
514 }) 483 })
515} 484}
516 485
517/// Build the declared type of an item. This depends on the namespace; e.g. for
518/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
519/// the constructor function `(usize) -> Foo` which lives in the values
520/// namespace.
521pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty {
522 match (def, ns) {
523 (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f),
524 (TypableDef::Adt(Adt::Struct(s)), Namespace::Values) => type_for_struct_constructor(db, s),
525 (TypableDef::Adt(adt), Namespace::Types) => type_for_adt(db, adt),
526 (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v),
527 (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t),
528 (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c),
529 (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c),
530 (TypableDef::BuiltinType(t), Namespace::Types) => type_for_builtin(t),
531
532 // 'error' cases:
533 (TypableDef::Function(_), Namespace::Types) => Ty::Unknown,
534 (TypableDef::Adt(Adt::Union(_)), Namespace::Values) => Ty::Unknown,
535 (TypableDef::Adt(Adt::Enum(_)), Namespace::Values) => Ty::Unknown,
536 (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown,
537 (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown,
538 (TypableDef::Const(_), Namespace::Types) => Ty::Unknown,
539 (TypableDef::Static(_), Namespace::Types) => Ty::Unknown,
540 (TypableDef::BuiltinType(_), Namespace::Values) => Ty::Unknown,
541 }
542}
543
544/// Build the signature of a callable item (function, struct or enum variant). 486/// Build the signature of a callable item (function, struct or enum variant).
545pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { 487pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig {
546 match def { 488 match def {
547 CallableDef::Function(f) => fn_sig_for_fn(db, f), 489 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f),
548 CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s), 490 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s),
549 CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e), 491 CallableDef::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
550 } 492 }
551} 493}
552 494
@@ -555,12 +497,11 @@ pub(crate) fn field_types_query(
555 db: &impl HirDatabase, 497 db: &impl HirDatabase,
556 variant_id: VariantId, 498 variant_id: VariantId,
557) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { 499) -> Arc<ArenaMap<LocalStructFieldId, Ty>> {
558 let (resolver, var_data) = match variant_id { 500 let var_data = variant_data(db, variant_id);
559 VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()), 501 let resolver = match variant_id {
560 VariantId::EnumVariantId(it) => ( 502 VariantId::StructId(it) => it.resolver(db),
561 it.parent.resolver(db), 503 VariantId::UnionId(it) => it.resolver(db),
562 db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), 504 VariantId::EnumVariantId(it) => it.parent.resolver(db),
563 ),
564 }; 505 };
565 let mut res = ArenaMap::default(); 506 let mut res = ArenaMap::default();
566 for (field_id, field_data) in var_data.fields().iter() { 507 for (field_id, field_data) in var_data.fields().iter() {
@@ -579,10 +520,10 @@ pub(crate) fn field_types_query(
579/// these are fine: `T: Foo<U::Item>, U: Foo<()>`. 520/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
580pub(crate) fn generic_predicates_for_param_query( 521pub(crate) fn generic_predicates_for_param_query(
581 db: &impl HirDatabase, 522 db: &impl HirDatabase,
582 def: GenericDef, 523 def: GenericDefId,
583 param_idx: u32, 524 param_idx: u32,
584) -> Arc<[GenericPredicate]> { 525) -> Arc<[GenericPredicate]> {
585 let resolver = GenericDefId::from(def).resolver(db); 526 let resolver = def.resolver(db);
586 resolver 527 resolver
587 .where_predicates_in_scope() 528 .where_predicates_in_scope()
588 // we have to filter out all other predicates *first*, before attempting to lower them 529 // we have to filter out all other predicates *first*, before attempting to lower them
@@ -591,24 +532,23 @@ pub(crate) fn generic_predicates_for_param_query(
591 .collect() 532 .collect()
592} 533}
593 534
594pub(crate) fn trait_env( 535impl TraitEnvironment {
595 db: &impl HirDatabase, 536 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
596 resolver: &Resolver, 537 let predicates = resolver
597) -> Arc<super::TraitEnvironment> { 538 .where_predicates_in_scope()
598 let predicates = resolver 539 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
599 .where_predicates_in_scope() 540 .collect::<Vec<_>>();
600 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
601 .collect::<Vec<_>>();
602 541
603 Arc::new(super::TraitEnvironment { predicates }) 542 Arc::new(TraitEnvironment { predicates })
543 }
604} 544}
605 545
606/// Resolve the where clause(s) of an item with generics. 546/// Resolve the where clause(s) of an item with generics.
607pub(crate) fn generic_predicates_query( 547pub(crate) fn generic_predicates_query(
608 db: &impl HirDatabase, 548 db: &impl HirDatabase,
609 def: GenericDef, 549 def: GenericDefId,
610) -> Arc<[GenericPredicate]> { 550) -> Arc<[GenericPredicate]> {
611 let resolver = GenericDefId::from(def).resolver(db); 551 let resolver = def.resolver(db);
612 resolver 552 resolver
613 .where_predicates_in_scope() 553 .where_predicates_in_scope()
614 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 554 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
@@ -616,8 +556,8 @@ pub(crate) fn generic_predicates_query(
616} 556}
617 557
618/// Resolve the default type params from generics 558/// Resolve the default type params from generics
619pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { 559pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs {
620 let resolver = GenericDefId::from(def).resolver(db); 560 let resolver = def.resolver(db);
621 let generic_params = db.generic_params(def.into()); 561 let generic_params = db.generic_params(def.into());
622 562
623 let defaults = generic_params 563 let defaults = generic_params
@@ -629,9 +569,9 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
629 Substs(defaults) 569 Substs(defaults)
630} 570}
631 571
632fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 572fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig {
633 let data = db.function_data(def.id); 573 let data = db.function_data(def);
634 let resolver = def.id.resolver(db); 574 let resolver = def.resolver(db);
635 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 575 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
636 let ret = Ty::from_hir(db, &resolver, &data.ret_type); 576 let ret = Ty::from_hir(db, &resolver, &data.ret_type);
637 FnSig::from_params_and_return(params, ret) 577 FnSig::from_params_and_return(params, ret)
@@ -639,24 +579,24 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
639 579
640/// Build the declared type of a function. This should not need to look at the 580/// Build the declared type of a function. This should not need to look at the
641/// function body. 581/// function body.
642fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 582fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty {
643 let generics = db.generic_params(def.id.into()); 583 let generics = db.generic_params(def.into());
644 let substs = Substs::identity(&generics); 584 let substs = Substs::identity(&generics);
645 Ty::apply(TypeCtor::FnDef(def.into()), substs) 585 Ty::apply(TypeCtor::FnDef(def.into()), substs)
646} 586}
647 587
648/// Build the declared type of a const. 588/// Build the declared type of a const.
649fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { 589fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty {
650 let data = db.const_data(def.id); 590 let data = db.const_data(def);
651 let resolver = def.id.resolver(db); 591 let resolver = def.resolver(db);
652 592
653 Ty::from_hir(db, &resolver, &data.type_ref) 593 Ty::from_hir(db, &resolver, &data.type_ref)
654} 594}
655 595
656/// Build the declared type of a static. 596/// Build the declared type of a static.
657fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { 597fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty {
658 let data = db.static_data(def.id); 598 let data = db.static_data(def);
659 let resolver = def.id.resolver(db); 599 let resolver = def.resolver(db);
660 600
661 Ty::from_hir(db, &resolver, &data.type_ref) 601 Ty::from_hir(db, &resolver, &data.type_ref)
662} 602}
@@ -672,160 +612,148 @@ fn type_for_builtin(def: BuiltinType) -> Ty {
672 }) 612 })
673} 613}
674 614
675impl From<BuiltinInt> for IntTy { 615fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig {
676 fn from(t: BuiltinInt) -> Self { 616 let struct_data = db.struct_data(def.into());
677 IntTy { signedness: t.signedness, bitness: t.bitness }
678 }
679}
680
681impl From<BuiltinFloat> for FloatTy {
682 fn from(t: BuiltinFloat) -> Self {
683 FloatTy { bitness: t.bitness }
684 }
685}
686
687impl From<Option<BuiltinInt>> for Uncertain<IntTy> {
688 fn from(t: Option<BuiltinInt>) -> Self {
689 match t {
690 None => Uncertain::Unknown,
691 Some(t) => Uncertain::Known(t.into()),
692 }
693 }
694}
695
696impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
697 fn from(t: Option<BuiltinFloat>) -> Self {
698 match t {
699 None => Uncertain::Unknown,
700 Some(t) => Uncertain::Known(t.into()),
701 }
702 }
703}
704
705fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
706 let struct_data = db.struct_data(def.id.into());
707 let fields = struct_data.variant_data.fields(); 617 let fields = struct_data.variant_data.fields();
708 let resolver = def.id.resolver(db); 618 let resolver = def.resolver(db);
709 let params = fields 619 let params = fields
710 .iter() 620 .iter()
711 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 621 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
712 .collect::<Vec<_>>(); 622 .collect::<Vec<_>>();
713 let ret = type_for_adt(db, def); 623 let ret = type_for_adt(db, def.into());
714 FnSig::from_params_and_return(params, ret) 624 FnSig::from_params_and_return(params, ret)
715} 625}
716 626
717/// Build the type of a tuple struct constructor. 627/// Build the type of a tuple struct constructor.
718fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { 628fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty {
719 let struct_data = db.struct_data(def.id.into()); 629 let struct_data = db.struct_data(def.into());
720 if struct_data.variant_data.is_unit() { 630 if struct_data.variant_data.is_unit() {
721 return type_for_adt(db, def); // Unit struct 631 return type_for_adt(db, def.into()); // Unit struct
722 } 632 }
723 let generics = db.generic_params(def.id.into()); 633 let generics = db.generic_params(def.into());
724 let substs = Substs::identity(&generics); 634 let substs = Substs::identity(&generics);
725 Ty::apply(TypeCtor::FnDef(def.into()), substs) 635 Ty::apply(TypeCtor::FnDef(def.into()), substs)
726} 636}
727 637
728fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { 638fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig {
729 let var_data = def.variant_data(db); 639 let enum_data = db.enum_data(def.parent);
730 let fields = var_data.fields(); 640 let var_data = &enum_data.variants[def.local_id];
731 let resolver = def.parent.id.resolver(db); 641 let fields = var_data.variant_data.fields();
642 let resolver = def.parent.resolver(db);
732 let params = fields 643 let params = fields
733 .iter() 644 .iter()
734 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 645 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
735 .collect::<Vec<_>>(); 646 .collect::<Vec<_>>();
736 let generics = db.generic_params(def.parent_enum(db).id.into()); 647 let generics = db.generic_params(def.parent.into());
737 let substs = Substs::identity(&generics); 648 let substs = Substs::identity(&generics);
738 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); 649 let ret = type_for_adt(db, def.parent.into()).subst(&substs);
739 FnSig::from_params_and_return(params, ret) 650 FnSig::from_params_and_return(params, ret)
740} 651}
741 652
742/// Build the type of a tuple enum variant constructor. 653/// Build the type of a tuple enum variant constructor.
743fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { 654fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty {
744 let var_data = def.variant_data(db); 655 let enum_data = db.enum_data(def.parent);
656 let var_data = &enum_data.variants[def.local_id].variant_data;
745 if var_data.is_unit() { 657 if var_data.is_unit() {
746 return type_for_adt(db, def.parent_enum(db)); // Unit variant 658 return type_for_adt(db, def.parent.into()); // Unit variant
747 } 659 }
748 let generics = db.generic_params(def.parent_enum(db).id.into()); 660 let generics = db.generic_params(def.parent.into());
749 let substs = Substs::identity(&generics); 661 let substs = Substs::identity(&generics);
750 Ty::apply(TypeCtor::FnDef(def.into()), substs) 662 Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs)
751} 663}
752 664
753fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { 665fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty {
754 let adt = adt.into(); 666 let generics = db.generic_params(adt.into());
755 let adt_id: AdtId = adt.into();
756 let generics = db.generic_params(adt_id.into());
757 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) 667 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics))
758} 668}
759 669
760fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 670fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty {
761 let generics = db.generic_params(t.id.into()); 671 let generics = db.generic_params(t.into());
762 let resolver = t.id.resolver(db); 672 let resolver = t.resolver(db);
763 let type_ref = t.type_ref(db); 673 let type_ref = &db.type_alias_data(t).type_ref;
764 let substs = Substs::identity(&generics); 674 let substs = Substs::identity(&generics);
765 let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); 675 let inner = Ty::from_hir(db, &resolver, type_ref.as_ref().unwrap_or(&TypeRef::Error));
766 inner.subst(&substs) 676 inner.subst(&substs)
767} 677}
768 678
769#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 679#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
770pub enum TypableDef {
771 Function(Function),
772 Adt(Adt),
773 EnumVariant(EnumVariant),
774 TypeAlias(TypeAlias),
775 Const(Const),
776 Static(Static),
777 BuiltinType(BuiltinType),
778}
779impl_froms!(
780 TypableDef: Function,
781 Adt(Struct, Enum, Union),
782 EnumVariant,
783 TypeAlias,
784 Const,
785 Static,
786 BuiltinType
787);
788
789impl From<ModuleDef> for Option<TypableDef> {
790 fn from(def: ModuleDef) -> Option<TypableDef> {
791 let res = match def {
792 ModuleDef::Function(f) => f.into(),
793 ModuleDef::Adt(adt) => adt.into(),
794 ModuleDef::EnumVariant(v) => v.into(),
795 ModuleDef::TypeAlias(t) => t.into(),
796 ModuleDef::Const(v) => v.into(),
797 ModuleDef::Static(v) => v.into(),
798 ModuleDef::BuiltinType(t) => t.into(),
799 ModuleDef::Module(_) | ModuleDef::Trait(_) => return None,
800 };
801 Some(res)
802 }
803}
804
805#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
806pub enum CallableDef { 680pub enum CallableDef {
807 Function(Function), 681 FunctionId(FunctionId),
808 Struct(Struct), 682 StructId(StructId),
809 EnumVariant(EnumVariant), 683 EnumVariantId(EnumVariantId),
810} 684}
811impl_froms!(CallableDef: Function, Struct, EnumVariant); 685impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId);
812 686
813impl CallableDef { 687impl CallableDef {
814 pub fn krate(self, db: &impl HirDatabase) -> Option<crate::Crate> { 688 pub fn krate(self, db: &impl HirDatabase) -> CrateId {
815 match self { 689 match self {
816 CallableDef::Function(f) => f.krate(db), 690 CallableDef::FunctionId(f) => f.lookup(db).module(db).krate,
817 CallableDef::Struct(s) => s.krate(db), 691 CallableDef::StructId(s) => s.module(db).krate,
818 CallableDef::EnumVariant(e) => e.parent_enum(db).krate(db), 692 CallableDef::EnumVariantId(e) => e.parent.module(db).krate,
819 } 693 }
820 } 694 }
821} 695}
822 696
823impl From<CallableDef> for GenericDef { 697impl From<CallableDef> for GenericDefId {
824 fn from(def: CallableDef) -> GenericDef { 698 fn from(def: CallableDef) -> GenericDefId {
825 match def { 699 match def {
826 CallableDef::Function(f) => f.into(), 700 CallableDef::FunctionId(f) => f.into(),
827 CallableDef::Struct(s) => s.into(), 701 CallableDef::StructId(s) => s.into(),
828 CallableDef::EnumVariant(e) => e.into(), 702 CallableDef::EnumVariantId(e) => e.into(),
703 }
704 }
705}
706
707#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
708pub enum TyDefId {
709 BuiltinType(BuiltinType),
710 AdtId(AdtId),
711 TypeAliasId(TypeAliasId),
712}
713impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId);
714
715#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
716pub enum ValueTyDefId {
717 FunctionId(FunctionId),
718 StructId(StructId),
719 EnumVariantId(EnumVariantId),
720 ConstId(ConstId),
721 StaticId(StaticId),
722}
723impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId);
724
725/// Build the declared type of an item. This depends on the namespace; e.g. for
726/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
727/// the constructor function `(usize) -> Foo` which lives in the values
728/// namespace.
729pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty {
730 match def {
731 TyDefId::BuiltinType(it) => type_for_builtin(it),
732 TyDefId::AdtId(it) => type_for_adt(db, it),
733 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
734 }
735}
736pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty {
737 match def {
738 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
739 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
740 ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
741 ValueTyDefId::ConstId(it) => type_for_const(db, it),
742 ValueTyDefId::StaticId(it) => type_for_static(db, it),
743 }
744}
745
746pub(crate) fn impl_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> ImplTy {
747 let impl_data = db.impl_data(impl_id);
748 let resolver = impl_id.resolver(db);
749 let self_ty = Ty::from_hir(db, &resolver, &impl_data.target_type);
750 match impl_data.target_trait.as_ref() {
751 Some(trait_ref) => {
752 match TraitRef::from_hir(db, &resolver, trait_ref, Some(self_ty.clone())) {
753 Some(it) => ImplTy::TraitRef(it),
754 None => ImplTy::Inherent(self_ty),
755 }
829 } 756 }
757 None => ImplTy::Inherent(self_ty),
830 } 758 }
831} 759}
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir_ty/src/marks.rs
index 0f754eb9c..0f754eb9c 100644
--- a/crates/ra_hir/src/marks.rs
+++ b/crates/ra_hir_ty/src/marks.rs
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index caa5f5f74..ee1936b0e 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -5,18 +5,23 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef}; 8use hir_def::{
9 lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocItemId, AstItemDef,
10 FunctionId, HasModule, ImplId, TraitId,
11};
12use hir_expand::name::Name;
13use ra_db::CrateId;
14use ra_prof::profile;
9use rustc_hash::FxHashMap; 15use rustc_hash::FxHashMap;
10 16
11use crate::{ 17use crate::{
18 autoderef,
12 db::HirDatabase, 19 db::HirDatabase,
13 ty::primitive::{FloatBitness, Uncertain}, 20 primitive::{FloatBitness, Uncertain},
14 ty::{Ty, TypeCtor}, 21 utils::all_super_traits,
15 AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, 22 Canonical, ImplTy, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor,
16}; 23};
17 24
18use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef};
19
20/// This is used as a key for indexing impls. 25/// This is used as a key for indexing impls.
21#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 26#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
22pub enum TyFingerprint { 27pub enum TyFingerprint {
@@ -37,99 +42,101 @@ impl TyFingerprint {
37 42
38#[derive(Debug, PartialEq, Eq)] 43#[derive(Debug, PartialEq, Eq)]
39pub struct CrateImplBlocks { 44pub struct CrateImplBlocks {
40 impls: FxHashMap<TyFingerprint, Vec<ImplBlock>>, 45 impls: FxHashMap<TyFingerprint, Vec<ImplId>>,
41 impls_by_trait: FxHashMap<Trait, Vec<ImplBlock>>, 46 impls_by_trait: FxHashMap<TraitId, Vec<ImplId>>,
42} 47}
43 48
44impl CrateImplBlocks { 49impl CrateImplBlocks {
45 pub(crate) fn impls_in_crate_query( 50 pub(crate) fn impls_in_crate_query(
46 db: &impl HirDatabase, 51 db: &impl HirDatabase,
47 krate: Crate, 52 krate: CrateId,
48 ) -> Arc<CrateImplBlocks> { 53 ) -> Arc<CrateImplBlocks> {
49 let mut crate_impl_blocks = 54 let _p = profile("impls_in_crate_query");
55 let mut res =
50 CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; 56 CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() };
51 if let Some(module) = krate.root_module(db) { 57
52 crate_impl_blocks.collect_recursive(db, module); 58 let crate_def_map = db.crate_def_map(krate);
59 for (_module_id, module_data) in crate_def_map.modules.iter() {
60 for &impl_id in module_data.impls.iter() {
61 match db.impl_ty(impl_id) {
62 ImplTy::TraitRef(tr) => {
63 res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id);
64 }
65 ImplTy::Inherent(self_ty) => {
66 if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty) {
67 res.impls.entry(self_ty_fp).or_default().push(impl_id);
68 }
69 }
70 }
71 }
53 } 72 }
54 Arc::new(crate_impl_blocks) 73
74 Arc::new(res)
55 } 75 }
56 pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + '_ { 76 pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplId> + '_ {
57 let fingerprint = TyFingerprint::for_impl(ty); 77 let fingerprint = TyFingerprint::for_impl(ty);
58 fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() 78 fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied()
59 } 79 }
60 80
61 pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplBlock> + '_ { 81 pub fn lookup_impl_blocks_for_trait(&self, tr: TraitId) -> impl Iterator<Item = ImplId> + '_ {
62 self.impls_by_trait.get(&tr).into_iter().flatten().copied() 82 self.impls_by_trait.get(&tr).into_iter().flatten().copied()
63 } 83 }
64 84
65 pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { 85 pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a {
66 self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() 86 self.impls.values().chain(self.impls_by_trait.values()).flatten().copied()
67 } 87 }
68
69 fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) {
70 for impl_block in module.impl_blocks(db) {
71 let target_ty = impl_block.target_ty(db);
72
73 if impl_block.target_trait(db).is_some() {
74 if let Some(tr) = impl_block.target_trait_ref(db) {
75 self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block);
76 }
77 } else {
78 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
79 self.impls.entry(target_ty_fp).or_default().push(impl_block);
80 }
81 }
82 }
83
84 for child in module.children(db) {
85 self.collect_recursive(db, child);
86 }
87 }
88} 88}
89 89
90fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { 90impl Ty {
91 // Types like slice can have inherent impls in several crates, (core and alloc). 91 pub fn def_crates(
92 // The corresponding impls are marked with lang items, so we can use them to find the required crates. 92 &self,
93 macro_rules! lang_item_crate { 93 db: &impl HirDatabase,
94 cur_crate: CrateId,
95 ) -> Option<ArrayVec<[CrateId; 2]>> {
96 // Types like slice can have inherent impls in several crates, (core and alloc).
97 // The corresponding impls are marked with lang items, so we can use them to find the required crates.
98 macro_rules! lang_item_crate {
94 ($($name:expr),+ $(,)?) => {{ 99 ($($name:expr),+ $(,)?) => {{
95 let mut v = ArrayVec::<[LangItemTarget; 2]>::new(); 100 let mut v = ArrayVec::<[LangItemTarget; 2]>::new();
96 $( 101 $(
97 v.extend(db.lang_item(cur_crate.crate_id, $name.into())); 102 v.extend(db.lang_item(cur_crate, $name.into()));
98 )+ 103 )+
99 v 104 v
100 }}; 105 }};
101 } 106 }
102 107
103 let lang_item_targets = match ty { 108 let lang_item_targets = match self {
104 Ty::Apply(a_ty) => match a_ty.ctor { 109 Ty::Apply(a_ty) => match a_ty.ctor {
105 TypeCtor::Adt(def_id) => return Some(std::iter::once(def_id.krate(db)?).collect()), 110 TypeCtor::Adt(def_id) => {
106 TypeCtor::Bool => lang_item_crate!("bool"), 111 return Some(std::iter::once(def_id.module(db).krate).collect())
107 TypeCtor::Char => lang_item_crate!("char"), 112 }
108 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { 113 TypeCtor::Bool => lang_item_crate!("bool"),
109 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 114 TypeCtor::Char => lang_item_crate!("char"),
110 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), 115 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness {
111 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), 116 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
117 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"),
118 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
119 },
120 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()),
121 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
122 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
123 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
124 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
125 _ => return None,
112 }, 126 },
113 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()),
114 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
115 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
116 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
117 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
118 _ => return None, 127 _ => return None,
119 }, 128 };
120 _ => return None, 129 let res = lang_item_targets
121 }; 130 .into_iter()
122 let res = lang_item_targets 131 .filter_map(|it| match it {
123 .into_iter() 132 LangItemTarget::ImplBlockId(it) => Some(it),
124 .filter_map(|it| match it { 133 _ => None,
125 LangItemTarget::ImplBlockId(it) => Some(it), 134 })
126 _ => None, 135 .map(|it| it.module(db).krate)
127 }) 136 .collect();
128 .map(|it| it.module(db).krate.into()) 137 Some(res)
129 .collect(); 138 }
130 Some(res)
131} 139}
132
133/// Look up the method with the given name, returning the actual autoderefed 140/// Look up the method with the given name, returning the actual autoderefed
134/// receiver type (but without autoref applied yet). 141/// receiver type (but without autoref applied yet).
135pub(crate) fn lookup_method( 142pub(crate) fn lookup_method(
@@ -137,10 +144,10 @@ pub(crate) fn lookup_method(
137 db: &impl HirDatabase, 144 db: &impl HirDatabase,
138 name: &Name, 145 name: &Name,
139 resolver: &Resolver, 146 resolver: &Resolver,
140) -> Option<(Ty, Function)> { 147) -> Option<(Ty, FunctionId)> {
141 iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f 148 iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f
142 { 149 {
143 AssocItem::Function(f) => Some((ty.clone(), f)), 150 AssocItemId::FunctionId(f) => Some((ty.clone(), f)),
144 _ => None, 151 _ => None,
145 }) 152 })
146} 153}
@@ -160,13 +167,13 @@ pub enum LookupMode {
160// This would be nicer if it just returned an iterator, but that runs into 167// This would be nicer if it just returned an iterator, but that runs into
161// lifetime problems, because we need to borrow temp `CrateImplBlocks`. 168// lifetime problems, because we need to borrow temp `CrateImplBlocks`.
162// FIXME add a context type here? 169// FIXME add a context type here?
163pub(crate) fn iterate_method_candidates<T>( 170pub fn iterate_method_candidates<T>(
164 ty: &Canonical<Ty>, 171 ty: &Canonical<Ty>,
165 db: &impl HirDatabase, 172 db: &impl HirDatabase,
166 resolver: &Resolver, 173 resolver: &Resolver,
167 name: Option<&Name>, 174 name: Option<&Name>,
168 mode: LookupMode, 175 mode: LookupMode,
169 mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, 176 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
170) -> Option<T> { 177) -> Option<T> {
171 let krate = resolver.krate()?; 178 let krate = resolver.krate()?;
172 match mode { 179 match mode {
@@ -179,16 +186,12 @@ pub(crate) fn iterate_method_candidates<T>(
179 // Also note that when we've got a receiver like &S, even if the method we 186 // Also note that when we've got a receiver like &S, even if the method we
180 // find in the end takes &self, we still do the autoderef step (just as 187 // find in the end takes &self, we still do the autoderef step (just as
181 // rustc does an autoderef and then autoref again). 188 // rustc does an autoderef and then autoref again).
182 189 let environment = TraitEnvironment::lower(db, resolver);
183 for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { 190 let ty = InEnvironment { value: ty.clone(), environment };
184 if let Some(result) = iterate_inherent_methods( 191 for derefed_ty in autoderef::autoderef(db, resolver.krate(), ty) {
185 &derefed_ty, 192 if let Some(result) =
186 db, 193 iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback)
187 name, 194 {
188 mode,
189 krate.into(),
190 &mut callback,
191 ) {
192 return Some(result); 195 return Some(result);
193 } 196 }
194 if let Some(result) = iterate_trait_method_candidates( 197 if let Some(result) = iterate_trait_method_candidates(
@@ -226,30 +229,29 @@ fn iterate_trait_method_candidates<T>(
226 resolver: &Resolver, 229 resolver: &Resolver,
227 name: Option<&Name>, 230 name: Option<&Name>,
228 mode: LookupMode, 231 mode: LookupMode,
229 mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, 232 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
230) -> Option<T> { 233) -> Option<T> {
231 let krate = resolver.krate()?; 234 let krate = resolver.krate()?;
232 // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) 235 // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that)
233 let env = lower::trait_env(db, resolver); 236 let env = TraitEnvironment::lower(db, resolver);
234 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope 237 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope
235 let inherent_trait = ty.value.inherent_trait().into_iter(); 238 let inherent_trait = ty.value.inherent_trait().into_iter();
236 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 239 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
237 let traits_from_env = env 240 let traits_from_env = env
238 .trait_predicates_for_self_ty(&ty.value) 241 .trait_predicates_for_self_ty(&ty.value)
239 .map(|tr| tr.trait_) 242 .map(|tr| tr.trait_)
240 .flat_map(|t| t.all_super_traits(db)); 243 .flat_map(|t| all_super_traits(db, t));
241 let traits = inherent_trait 244 let traits =
242 .chain(traits_from_env) 245 inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter());
243 .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from));
244 'traits: for t in traits { 246 'traits: for t in traits {
245 let data = db.trait_data(t.id); 247 let data = db.trait_data(t);
246 248
247 // we'll be lazy about checking whether the type implements the 249 // we'll be lazy about checking whether the type implements the
248 // trait, but if we find out it doesn't, we'll skip the rest of the 250 // trait, but if we find out it doesn't, we'll skip the rest of the
249 // iteration 251 // iteration
250 let mut known_implemented = false; 252 let mut known_implemented = false;
251 for &item in data.items.iter() { 253 for (_name, item) in data.items.iter() {
252 if !is_valid_candidate(db, name, mode, item.into()) { 254 if !is_valid_candidate(db, name, mode, (*item).into()) {
253 continue; 255 continue;
254 } 256 }
255 if !known_implemented { 257 if !known_implemented {
@@ -259,7 +261,7 @@ fn iterate_trait_method_candidates<T>(
259 } 261 }
260 } 262 }
261 known_implemented = true; 263 known_implemented = true;
262 if let Some(result) = callback(&ty.value, item.into()) { 264 if let Some(result) = callback(&ty.value, (*item).into()) {
263 return Some(result); 265 return Some(result);
264 } 266 }
265 } 267 }
@@ -272,18 +274,18 @@ fn iterate_inherent_methods<T>(
272 db: &impl HirDatabase, 274 db: &impl HirDatabase,
273 name: Option<&Name>, 275 name: Option<&Name>,
274 mode: LookupMode, 276 mode: LookupMode,
275 krate: Crate, 277 krate: CrateId,
276 mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, 278 mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
277) -> Option<T> { 279) -> Option<T> {
278 for krate in def_crates(db, krate, &ty.value)? { 280 for krate in ty.value.def_crates(db, krate)? {
279 let impls = db.impls_in_crate(krate); 281 let impls = db.impls_in_crate(krate);
280 282
281 for impl_block in impls.lookup_impl_blocks(&ty.value) { 283 for impl_block in impls.lookup_impl_blocks(&ty.value) {
282 for item in impl_block.items(db) { 284 for &item in db.impl_data(impl_block).items.iter() {
283 if !is_valid_candidate(db, name, mode, item) { 285 if !is_valid_candidate(db, name, mode, item) {
284 continue; 286 continue;
285 } 287 }
286 if let Some(result) = callback(&ty.value, item) { 288 if let Some(result) = callback(&ty.value, item.into()) {
287 return Some(result); 289 return Some(result);
288 } 290 }
289 } 291 }
@@ -296,71 +298,47 @@ fn is_valid_candidate(
296 db: &impl HirDatabase, 298 db: &impl HirDatabase,
297 name: Option<&Name>, 299 name: Option<&Name>,
298 mode: LookupMode, 300 mode: LookupMode,
299 item: AssocItem, 301 item: AssocItemId,
300) -> bool { 302) -> bool {
301 match item { 303 match item {
302 AssocItem::Function(m) => { 304 AssocItemId::FunctionId(m) => {
303 let data = db.function_data(m.id); 305 let data = db.function_data(m);
304 name.map_or(true, |name| data.name == *name) 306 name.map_or(true, |name| &data.name == name)
305 && (data.has_self_param || mode == LookupMode::Path) 307 && (data.has_self_param || mode == LookupMode::Path)
306 } 308 }
307 AssocItem::Const(c) => { 309 AssocItemId::ConstId(c) => {
308 name.map_or(true, |name| Some(name) == c.name(db).as_ref()) 310 let data = db.const_data(c);
309 && (mode == LookupMode::Path) 311 name.map_or(true, |name| data.name.as_ref() == Some(name)) && (mode == LookupMode::Path)
310 } 312 }
311 _ => false, 313 _ => false,
312 } 314 }
313} 315}
314 316
315pub(crate) fn implements_trait( 317pub fn implements_trait(
316 ty: &Canonical<Ty>, 318 ty: &Canonical<Ty>,
317 db: &impl HirDatabase, 319 db: &impl HirDatabase,
318 resolver: &Resolver, 320 resolver: &Resolver,
319 krate: Crate, 321 krate: CrateId,
320 trait_: Trait, 322 trait_: TraitId,
321) -> bool { 323) -> bool {
322 if ty.value.inherent_trait() == Some(trait_) { 324 if ty.value.inherent_trait() == Some(trait_) {
323 // FIXME this is a bit of a hack, since Chalk should say the same thing 325 // FIXME this is a bit of a hack, since Chalk should say the same thing
324 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet 326 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
325 return true; 327 return true;
326 } 328 }
327 let env = lower::trait_env(db, resolver); 329 let env = TraitEnvironment::lower(db, resolver);
328 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 330 let goal = generic_implements_goal(db, env, trait_, ty.clone());
329 let solution = db.trait_solve(krate, goal); 331 let solution = db.trait_solve(krate.into(), goal);
330 332
331 solution.is_some() 333 solution.is_some()
332} 334}
333 335
334impl Ty {
335 // This would be nicer if it just returned an iterator, but that runs into
336 // lifetime problems, because we need to borrow temp `CrateImplBlocks`.
337 pub fn iterate_impl_items<T>(
338 self,
339 db: &impl HirDatabase,
340 krate: Crate,
341 mut callback: impl FnMut(AssocItem) -> Option<T>,
342 ) -> Option<T> {
343 for krate in def_crates(db, krate, &self)? {
344 let impls = db.impls_in_crate(krate);
345
346 for impl_block in impls.lookup_impl_blocks(&self) {
347 for item in impl_block.items(db) {
348 if let Some(result) = callback(item) {
349 return Some(result);
350 }
351 }
352 }
353 }
354 None
355 }
356}
357
358/// This creates Substs for a trait with the given Self type and type variables 336/// This creates Substs for a trait with the given Self type and type variables
359/// for all other parameters, to query Chalk with it. 337/// for all other parameters, to query Chalk with it.
360fn generic_implements_goal( 338fn generic_implements_goal(
361 db: &impl HirDatabase, 339 db: &impl HirDatabase,
362 env: Arc<TraitEnvironment>, 340 env: Arc<TraitEnvironment>,
363 trait_: Trait, 341 trait_: TraitId,
364 self_ty: Canonical<Ty>, 342 self_ty: Canonical<Ty>,
365) -> Canonical<InEnvironment<super::Obligation>> { 343) -> Canonical<InEnvironment<super::Obligation>> {
366 let num_vars = self_ty.num_vars; 344 let num_vars = self_ty.num_vars;
diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir_ty/src/op.rs
index bcfa3a6a2..09c47a76d 100644
--- a/crates/ra_hir/src/ty/op.rs
+++ b/crates/ra_hir_ty/src/op.rs
@@ -1,10 +1,8 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use hir_def::expr::{BinaryOp, CmpOp};
2 3
3use super::{InferTy, Ty, TypeCtor}; 4use super::{InferTy, Ty, TypeCtor};
4use crate::{ 5use crate::ApplicationTy;
5 expr::{BinaryOp, CmpOp},
6 ty::ApplicationTy,
7};
8 6
9pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { 7pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
10 match op { 8 match op {
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir_ty/src/primitive.rs
index 47789db87..02a8179d9 100644
--- a/crates/ra_hir/src/ty/primitive.rs
+++ b/crates/ra_hir_ty/src/primitive.rs
@@ -1,8 +1,11 @@
1//! FIXME: write short doc here 1//! Defines primitive types, which have a couple of peculiarities:
2//!
3//! * during type inference, they can be uncertain (ie, `let x = 92;`)
4//! * they don't belong to any particular crate.
2 5
3use std::fmt; 6use std::fmt;
4 7
5pub use hir_def::builtin_type::{FloatBitness, IntBitness, Signedness}; 8pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness};
6 9
7#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] 10#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
8pub enum Uncertain<T> { 11pub enum Uncertain<T> {
@@ -107,7 +110,7 @@ impl IntTy {
107 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } 110 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 }
108 } 111 }
109 112
110 pub(crate) fn ty_to_string(self) -> &'static str { 113 pub fn ty_to_string(self) -> &'static str {
111 match (self.signedness, self.bitness) { 114 match (self.signedness, self.bitness) {
112 (Signedness::Signed, IntBitness::Xsize) => "isize", 115 (Signedness::Signed, IntBitness::Xsize) => "isize",
113 (Signedness::Signed, IntBitness::X8) => "i8", 116 (Signedness::Signed, IntBitness::X8) => "i8",
@@ -151,10 +154,40 @@ impl FloatTy {
151 FloatTy { bitness: FloatBitness::X64 } 154 FloatTy { bitness: FloatBitness::X64 }
152 } 155 }
153 156
154 pub(crate) fn ty_to_string(self) -> &'static str { 157 pub fn ty_to_string(self) -> &'static str {
155 match self.bitness { 158 match self.bitness {
156 FloatBitness::X32 => "f32", 159 FloatBitness::X32 => "f32",
157 FloatBitness::X64 => "f64", 160 FloatBitness::X64 => "f64",
158 } 161 }
159 } 162 }
160} 163}
164
165impl From<BuiltinInt> for IntTy {
166 fn from(t: BuiltinInt) -> Self {
167 IntTy { signedness: t.signedness, bitness: t.bitness }
168 }
169}
170
171impl From<BuiltinFloat> for FloatTy {
172 fn from(t: BuiltinFloat) -> Self {
173 FloatTy { bitness: t.bitness }
174 }
175}
176
177impl From<Option<BuiltinInt>> for Uncertain<IntTy> {
178 fn from(t: Option<BuiltinInt>) -> Self {
179 match t {
180 None => Uncertain::Unknown,
181 Some(t) => Uncertain::Known(t.into()),
182 }
183 }
184}
185
186impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
187 fn from(t: Option<BuiltinFloat>) -> Self {
188 match t {
189 None => Uncertain::Unknown,
190 Some(t) => Uncertain::Known(t.into()),
191 }
192 }
193}
diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index efee2f658..1dc9793f9 100644
--- a/crates/ra_hir/src/test_db.rs
+++ b/crates/ra_hir_ty/src/test_db.rs
@@ -1,21 +1,23 @@
1//! Database used for testing `hir`. 1//! Database used for testing `hir`.
2 2
3use std::{panic, sync::Arc}; 3use std::{
4 panic,
5 sync::{Arc, Mutex},
6};
4 7
5use hir_def::{db::DefDatabase, ModuleId}; 8use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId};
6use hir_expand::diagnostics::DiagnosticSink; 9use hir_expand::diagnostics::DiagnosticSink;
7use parking_lot::Mutex;
8use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase}; 10use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase};
9 11
10use crate::{db, debug::HirDebugHelper}; 12use crate::{db::HirDatabase, expr::ExprValidator};
11 13
12#[salsa::database( 14#[salsa::database(
13 ra_db::SourceDatabaseExtStorage, 15 ra_db::SourceDatabaseExtStorage,
14 ra_db::SourceDatabaseStorage, 16 ra_db::SourceDatabaseStorage,
15 db::InternDatabaseStorage, 17 hir_expand::db::AstDatabaseStorage,
16 db::AstDatabaseStorage, 18 hir_def::db::InternDatabaseStorage,
17 db::DefDatabaseStorage, 19 hir_def::db::DefDatabaseStorage,
18 db::HirDatabaseStorage 20 crate::db::HirDatabaseStorage
19)] 21)]
20#[derive(Debug, Default)] 22#[derive(Debug, Default)]
21pub struct TestDB { 23pub struct TestDB {
@@ -28,8 +30,12 @@ impl salsa::Database for TestDB {
28 &self.runtime 30 &self.runtime
29 } 31 }
30 32
33 fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> {
34 &mut self.runtime
35 }
36
31 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { 37 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) {
32 let mut events = self.events.lock(); 38 let mut events = self.events.lock().unwrap();
33 if let Some(events) = &mut *events { 39 if let Some(events) = &mut *events {
34 events.push(event()); 40 events.push(event());
35 } 41 }
@@ -63,32 +69,53 @@ impl FileLoader for TestDB {
63 } 69 }
64} 70}
65 71
66// FIXME: improve `WithFixture` to bring useful hir debugging back 72impl TestDB {
67impl HirDebugHelper for TestDB { 73 pub fn module_for_file(&self, file_id: FileId) -> ModuleId {
68 fn crate_name(&self, _krate: CrateId) -> Option<String> { 74 for &krate in self.relevant_crates(file_id).iter() {
69 None 75 let crate_def_map = self.crate_def_map(krate);
76 for (local_id, data) in crate_def_map.modules.iter() {
77 if data.definition == Some(file_id) {
78 return ModuleId { krate, local_id };
79 }
80 }
81 }
82 panic!("Can't find module for file")
70 } 83 }
71 84
72 fn file_path(&self, _file_id: FileId) -> Option<String> { 85 // FIXME: don't duplicate this
73 None
74 }
75}
76
77impl TestDB {
78 pub fn diagnostics(&self) -> String { 86 pub fn diagnostics(&self) -> String {
79 let mut buf = String::new(); 87 let mut buf = String::new();
80 let crate_graph = self.crate_graph(); 88 let crate_graph = self.crate_graph();
81 for krate in crate_graph.iter().next() { 89 for krate in crate_graph.iter().next() {
82 let crate_def_map = self.crate_def_map(krate); 90 let crate_def_map = self.crate_def_map(krate);
91
92 let mut fns = Vec::new();
83 for (module_id, _) in crate_def_map.modules.iter() { 93 for (module_id, _) in crate_def_map.modules.iter() {
84 let module_id = ModuleId { krate, module_id }; 94 for decl in crate_def_map[module_id].scope.declarations() {
85 let module = crate::Module::from(module_id); 95 match decl {
86 module.diagnostics( 96 ModuleDefId::FunctionId(f) => fns.push(f),
87 self, 97 _ => (),
88 &mut DiagnosticSink::new(|d| { 98 }
89 buf += &format!("{:?}: {}\n", d.syntax_node(self).text(), d.message()); 99 }
90 }), 100
91 ) 101 for &impl_id in crate_def_map[module_id].impls.iter() {
102 let impl_data = self.impl_data(impl_id);
103 for item in impl_data.items.iter() {
104 if let AssocItemId::FunctionId(f) = item {
105 fns.push(*f)
106 }
107 }
108 }
109 }
110
111 for f in fns {
112 let infer = self.infer(f.into());
113 let mut sink = DiagnosticSink::new(|d| {
114 buf += &format!("{:?}: {}\n", d.syntax_node(self).text(), d.message());
115 });
116 infer.add_diagnostics(self, f, &mut sink);
117 let mut validator = ExprValidator::new(f, infer, &mut sink);
118 validator.validate_body(self);
92 } 119 }
93 } 120 }
94 buf 121 buf
@@ -97,9 +124,9 @@ impl TestDB {
97 124
98impl TestDB { 125impl TestDB {
99 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<TestDB>> { 126 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<TestDB>> {
100 *self.events.lock() = Some(Vec::new()); 127 *self.events.lock().unwrap() = Some(Vec::new());
101 f(); 128 f();
102 self.events.lock().take().unwrap() 129 self.events.lock().unwrap().take().unwrap()
103 } 130 }
104 131
105 pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> { 132 pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir_ty/src/tests.rs
index 3209c66bd..c8461b447 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -4,20 +4,20 @@ mod coercion;
4use std::fmt::Write; 4use std::fmt::Write;
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use hir_def::{
8 body::BodySourceMap, db::DefDatabase, nameres::CrateDefMap, AssocItemId, DefWithBodyId,
9 LocalModuleId, Lookup, ModuleDefId,
10};
11use hir_expand::Source;
7use insta::assert_snapshot; 12use insta::assert_snapshot;
8use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; 13use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase};
9use ra_syntax::{ 14use ra_syntax::{
10 algo, 15 algo,
11 ast::{self, AstNode}, 16 ast::{self, AstNode},
12 SyntaxKind::*,
13}; 17};
14use rustc_hash::FxHashSet;
15use test_utils::covers; 18use test_utils::covers;
16 19
17use crate::{ 20use crate::{db::HirDatabase, display::HirDisplay, test_db::TestDB, InferenceResult};
18 expr::BodySourceMap, test_db::TestDB, ty::display::HirDisplay, ty::InferenceResult, Source,
19 SourceAnalyzer,
20};
21 21
22// These tests compare the inference results for all expressions in a file 22// These tests compare the inference results for all expressions in a file
23// against snapshots of the expected results using insta. Use cargo-insta to 23// against snapshots of the expected results using insta. Use cargo-insta to
@@ -4674,10 +4674,20 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
4674fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { 4674fn type_at_pos(db: &TestDB, pos: FilePosition) -> String {
4675 let file = db.parse(pos.file_id).ok().unwrap(); 4675 let file = db.parse(pos.file_id).ok().unwrap();
4676 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); 4676 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
4677 let analyzer = 4677
4678 SourceAnalyzer::new(db, Source::new(pos.file_id.into(), expr.syntax()), Some(pos.offset)); 4678 let module = db.module_for_file(pos.file_id);
4679 let ty = analyzer.type_of(db, &expr).unwrap(); 4679 let crate_def_map = db.crate_def_map(module.krate);
4680 ty.display(db).to_string() 4680 for decl in crate_def_map[module.local_id].scope.declarations() {
4681 if let ModuleDefId::FunctionId(func) = decl {
4682 let (_body, source_map) = db.body_with_source_map(func.into());
4683 if let Some(expr_id) = source_map.node_expr(Source::new(pos.file_id.into(), &expr)) {
4684 let infer = db.infer(func.into());
4685 let ty = &infer[expr_id];
4686 return ty.display(db).to_string();
4687 }
4688 }
4689 }
4690 panic!("Can't find expression")
4681} 4691}
4682 4692
4683fn type_at(content: &str) -> String { 4693fn type_at(content: &str) -> String {
@@ -4687,7 +4697,6 @@ fn type_at(content: &str) -> String {
4687 4697
4688fn infer(content: &str) -> String { 4698fn infer(content: &str) -> String {
4689 let (db, file_id) = TestDB::with_single_file(content); 4699 let (db, file_id) = TestDB::with_single_file(content);
4690 let source_file = db.parse(file_id).ok().unwrap();
4691 4700
4692 let mut acc = String::new(); 4701 let mut acc = String::new();
4693 4702
@@ -4740,20 +4749,69 @@ fn infer(content: &str) -> String {
4740 } 4749 }
4741 }; 4750 };
4742 4751
4743 let mut analyzed = FxHashSet::default(); 4752 let module = db.module_for_file(file_id);
4744 for node in source_file.syntax().descendants() { 4753 let crate_def_map = db.crate_def_map(module.krate);
4745 if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { 4754
4746 let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); 4755 let mut defs: Vec<DefWithBodyId> = Vec::new();
4747 if analyzed.insert(analyzer.analyzed_declaration()) { 4756 visit_module(&db, &crate_def_map, module.local_id, &mut |it| defs.push(it));
4748 infer_def(analyzer.inference_result(), analyzer.body_source_map()); 4757 defs.sort_by_key(|def| match def {
4749 } 4758 DefWithBodyId::FunctionId(it) => {
4759 it.lookup(&db).ast_id.to_node(&db).syntax().text_range().start()
4760 }
4761 DefWithBodyId::ConstId(it) => {
4762 it.lookup(&db).ast_id.to_node(&db).syntax().text_range().start()
4763 }
4764 DefWithBodyId::StaticId(it) => {
4765 it.lookup(&db).ast_id.to_node(&db).syntax().text_range().start()
4750 } 4766 }
4767 });
4768 for def in defs {
4769 let (_body, source_map) = db.body_with_source_map(def);
4770 let infer = db.infer(def);
4771 infer_def(infer, source_map);
4751 } 4772 }
4752 4773
4753 acc.truncate(acc.trim_end().len()); 4774 acc.truncate(acc.trim_end().len());
4754 acc 4775 acc
4755} 4776}
4756 4777
4778fn visit_module(
4779 db: &TestDB,
4780 crate_def_map: &CrateDefMap,
4781 module_id: LocalModuleId,
4782 cb: &mut dyn FnMut(DefWithBodyId),
4783) {
4784 for decl in crate_def_map[module_id].scope.declarations() {
4785 match decl {
4786 ModuleDefId::FunctionId(it) => cb(it.into()),
4787 ModuleDefId::ConstId(it) => cb(it.into()),
4788 ModuleDefId::StaticId(it) => cb(it.into()),
4789 ModuleDefId::TraitId(it) => {
4790 let trait_data = db.trait_data(it);
4791 for &(_, item) in trait_data.items.iter() {
4792 match item {
4793 AssocItemId::FunctionId(it) => cb(it.into()),
4794 AssocItemId::ConstId(it) => cb(it.into()),
4795 AssocItemId::TypeAliasId(_) => (),
4796 }
4797 }
4798 }
4799 ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it.local_id, cb),
4800 _ => (),
4801 }
4802 }
4803 for &impl_id in crate_def_map[module_id].impls.iter() {
4804 let impl_data = db.impl_data(impl_id);
4805 for &item in impl_data.items.iter() {
4806 match item {
4807 AssocItemId::FunctionId(it) => cb(it.into()),
4808 AssocItemId::ConstId(it) => cb(it.into()),
4809 AssocItemId::TypeAliasId(_) => (),
4810 }
4811 }
4812 }
4813}
4814
4757fn ellipsize(mut text: String, max_len: usize) -> String { 4815fn ellipsize(mut text: String, max_len: usize) -> String {
4758 if text.len() <= max_len { 4816 if text.len() <= max_len {
4759 return text; 4817 return text;
@@ -4783,10 +4841,12 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
4783 ", 4841 ",
4784 ); 4842 );
4785 { 4843 {
4786 let file = db.parse(pos.file_id).ok().unwrap();
4787 let node = file.syntax().token_at_offset(pos.offset).right_biased().unwrap().parent();
4788 let events = db.log_executed(|| { 4844 let events = db.log_executed(|| {
4789 SourceAnalyzer::new(&db, Source::new(pos.file_id.into(), &node), None); 4845 let module = db.module_for_file(pos.file_id);
4846 let crate_def_map = db.crate_def_map(module.krate);
4847 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
4848 db.infer(def);
4849 });
4790 }); 4850 });
4791 assert!(format!("{:?}", events).contains("infer")) 4851 assert!(format!("{:?}", events).contains("infer"))
4792 } 4852 }
@@ -4803,10 +4863,12 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
4803 db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text)); 4863 db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text));
4804 4864
4805 { 4865 {
4806 let file = db.parse(pos.file_id).ok().unwrap();
4807 let node = file.syntax().token_at_offset(pos.offset).right_biased().unwrap().parent();
4808 let events = db.log_executed(|| { 4866 let events = db.log_executed(|| {
4809 SourceAnalyzer::new(&db, Source::new(pos.file_id.into(), &node), None); 4867 let module = db.module_for_file(pos.file_id);
4868 let crate_def_map = db.crate_def_map(module.krate);
4869 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
4870 db.infer(def);
4871 });
4810 }); 4872 });
4811 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) 4873 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
4812 } 4874 }
@@ -4832,7 +4894,8 @@ fn no_such_field_diagnostics() {
4832 4894
4833 assert_snapshot!(diagnostics, @r###" 4895 assert_snapshot!(diagnostics, @r###"
4834 "baz: 62": no such field 4896 "baz: 62": no such field
4835 "{\n foo: 92,\n baz: 62,\n }": fill structure fields 4897 "{\n foo: 92,\n baz: 62,\n }": Missing structure fields:
4898 - bar
4836 "### 4899 "###
4837 ); 4900 );
4838} 4901}
diff --git a/crates/ra_hir/src/ty/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index 1530fcc63..1530fcc63 100644
--- a/crates/ra_hir/src/ty/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
diff --git a/crates/ra_hir/src/ty/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs
index c202f545a..c202f545a 100644
--- a/crates/ra_hir/src/ty/tests/never_type.rs
+++ b/crates/ra_hir_ty/src/tests/never_type.rs
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir_ty/src/traits.rs
index 268fa09e4..76189a60b 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -2,13 +2,15 @@
2use std::sync::{Arc, Mutex}; 2use std::sync::{Arc, Mutex};
3 3
4use chalk_ir::{cast::Cast, family::ChalkIr}; 4use chalk_ir::{cast::Cast, family::ChalkIr};
5use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId};
5use log::debug; 6use log::debug;
6use ra_db::{impl_intern_key, salsa}; 7use ra_db::{impl_intern_key, salsa, CrateId};
7use ra_prof::profile; 8use ra_prof::profile;
8use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
9 10
11use crate::db::HirDatabase;
12
10use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
11use crate::{db::HirDatabase, expr::ExprId, Crate, DefWithBody, ImplBlock, Trait, TypeAlias};
12 14
13use self::chalk::{from_chalk, ToChalk}; 15use self::chalk::{from_chalk, ToChalk};
14 16
@@ -16,7 +18,7 @@ pub(crate) mod chalk;
16 18
17#[derive(Debug, Clone)] 19#[derive(Debug, Clone)]
18pub struct TraitSolver { 20pub struct TraitSolver {
19 krate: Crate, 21 krate: CrateId,
20 inner: Arc<Mutex<chalk_solve::Solver<ChalkIr>>>, 22 inner: Arc<Mutex<chalk_solve::Solver<ChalkIr>>>,
21} 23}
22 24
@@ -58,12 +60,12 @@ const CHALK_SOLVER_MAX_SIZE: usize = 4;
58#[derive(Debug, Copy, Clone)] 60#[derive(Debug, Copy, Clone)]
59struct ChalkContext<'a, DB> { 61struct ChalkContext<'a, DB> {
60 db: &'a DB, 62 db: &'a DB,
61 krate: Crate, 63 krate: CrateId,
62} 64}
63 65
64pub(crate) fn trait_solver_query( 66pub(crate) fn trait_solver_query(
65 db: &(impl HirDatabase + salsa::Database), 67 db: &(impl HirDatabase + salsa::Database),
66 krate: Crate, 68 krate: CrateId,
67) -> TraitSolver { 69) -> TraitSolver {
68 db.salsa_runtime().report_untracked_read(); 70 db.salsa_runtime().report_untracked_read();
69 // krate parameter is just so we cache a unique solver per crate 71 // krate parameter is just so we cache a unique solver per crate
@@ -75,17 +77,17 @@ pub(crate) fn trait_solver_query(
75/// Collects impls for the given trait in the whole dependency tree of `krate`. 77/// Collects impls for the given trait in the whole dependency tree of `krate`.
76pub(crate) fn impls_for_trait_query( 78pub(crate) fn impls_for_trait_query(
77 db: &impl HirDatabase, 79 db: &impl HirDatabase,
78 krate: Crate, 80 krate: CrateId,
79 trait_: Trait, 81 trait_: TraitId,
80) -> Arc<[ImplBlock]> { 82) -> Arc<[ImplId]> {
81 let mut impls = FxHashSet::default(); 83 let mut impls = FxHashSet::default();
82 // We call the query recursively here. On the one hand, this means we can 84 // We call the query recursively here. On the one hand, this means we can
83 // reuse results from queries for different crates; on the other hand, this 85 // reuse results from queries for different crates; on the other hand, this
84 // will only ever get called for a few crates near the root of the tree (the 86 // will only ever get called for a few crates near the root of the tree (the
85 // ones the user is editing), so this may actually be a waste of memory. I'm 87 // ones the user is editing), so this may actually be a waste of memory. I'm
86 // doing it like this mainly for simplicity for now. 88 // doing it like this mainly for simplicity for now.
87 for dep in krate.dependencies(db) { 89 for dep in db.crate_graph().dependencies(krate) {
88 impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); 90 impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter());
89 } 91 }
90 let crate_impl_blocks = db.impls_in_crate(krate); 92 let crate_impl_blocks = db.impls_in_crate(krate);
91 impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_)); 93 impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_));
@@ -174,7 +176,7 @@ impl TypeWalk for ProjectionPredicate {
174/// Solve a trait goal using Chalk. 176/// Solve a trait goal using Chalk.
175pub(crate) fn trait_solve_query( 177pub(crate) fn trait_solve_query(
176 db: &impl HirDatabase, 178 db: &impl HirDatabase,
177 krate: Crate, 179 krate: CrateId,
178 goal: Canonical<InEnvironment<Obligation>>, 180 goal: Canonical<InEnvironment<Obligation>>,
179) -> Option<Solution> { 181) -> Option<Solution> {
180 let _p = profile("trait_solve_query"); 182 let _p = profile("trait_solve_query");
@@ -290,7 +292,7 @@ impl FnTrait {
290 292
291#[derive(Debug, Clone, PartialEq, Eq, Hash)] 293#[derive(Debug, Clone, PartialEq, Eq, Hash)]
292pub struct ClosureFnTraitImplData { 294pub struct ClosureFnTraitImplData {
293 def: DefWithBody, 295 def: DefWithBodyId,
294 expr: ExprId, 296 expr: ExprId,
295 fn_trait: FnTrait, 297 fn_trait: FnTrait,
296} 298}
@@ -300,7 +302,7 @@ pub struct ClosureFnTraitImplData {
300#[derive(Debug, Clone, PartialEq, Eq, Hash)] 302#[derive(Debug, Clone, PartialEq, Eq, Hash)]
301pub enum Impl { 303pub enum Impl {
302 /// A normal impl from an impl block. 304 /// A normal impl from an impl block.
303 ImplBlock(ImplBlock), 305 ImplBlock(ImplId),
304 /// Closure types implement the Fn traits synthetically. 306 /// Closure types implement the Fn traits synthetically.
305 ClosureFnTraitImpl(ClosureFnTraitImplData), 307 ClosureFnTraitImpl(ClosureFnTraitImplData),
306} 308}
@@ -315,7 +317,7 @@ impl_intern_key!(GlobalImplId);
315#[derive(Debug, Clone, PartialEq, Eq, Hash)] 317#[derive(Debug, Clone, PartialEq, Eq, Hash)]
316pub enum AssocTyValue { 318pub enum AssocTyValue {
317 /// A normal assoc type value from an impl block. 319 /// A normal assoc type value from an impl block.
318 TypeAlias(TypeAlias), 320 TypeAlias(TypeAliasId),
319 /// The output type of the Fn trait implementation. 321 /// The output type of the Fn trait implementation.
320 ClosureFnTraitImplOutput(ClosureFnTraitImplData), 322 ClosureFnTraitImplOutput(ClosureFnTraitImplData),
321} 323}
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 1a93e5e50..35de37e6b 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -4,22 +4,24 @@ use std::sync::Arc;
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, family::ChalkIr, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId, 7 cast::Cast, family::ChalkIr, Identifier, Parameter, PlaceholderIndex, TypeId, TypeKindId,
8 TypeKindId, TypeName, UniverseIndex, 8 TypeName, UniverseIndex,
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11use ra_db::CrateId;
11 12
12use hir_def::lang_item::LangItemTarget; 13use hir_def::{
14 expr::Expr, lang_item::LangItemTarget, AssocItemId, AstItemDef, ContainerId, GenericDefId,
15 ImplId, Lookup, TraitId, TypeAliasId,
16};
13use hir_expand::name; 17use hir_expand::name;
14 18
15use ra_db::salsa::{InternId, InternKey}; 19use ra_db::salsa::{InternId, InternKey};
16 20
17use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 21use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
18use crate::{ 22use crate::{
19 db::HirDatabase, 23 db::HirDatabase, display::HirDisplay, ApplicationTy, GenericPredicate, ImplTy, ProjectionTy,
20 ty::display::HirDisplay, 24 Substs, TraitRef, Ty, TypeCtor, TypeWalk,
21 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
22 Crate, GenericDef, ImplBlock, Trait, TypeAlias,
23}; 25};
24 26
25/// This represents a trait whose name we could not resolve. 27/// This represents a trait whose name we could not resolve.
@@ -167,15 +169,15 @@ impl ToChalk for TraitRef {
167 } 169 }
168} 170}
169 171
170impl ToChalk for Trait { 172impl ToChalk for TraitId {
171 type Chalk = chalk_ir::TraitId; 173 type Chalk = chalk_ir::TraitId;
172 174
173 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { 175 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId {
174 chalk_ir::TraitId(id_to_chalk(self.id)) 176 chalk_ir::TraitId(id_to_chalk(self))
175 } 177 }
176 178
177 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait { 179 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId {
178 Trait { id: id_from_chalk(trait_id.0) } 180 id_from_chalk(trait_id.0)
179 } 181 }
180} 182}
181 183
@@ -203,15 +205,15 @@ impl ToChalk for Impl {
203 } 205 }
204} 206}
205 207
206impl ToChalk for TypeAlias { 208impl ToChalk for TypeAliasId {
207 type Chalk = chalk_ir::TypeId; 209 type Chalk = chalk_ir::TypeId;
208 210
209 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { 211 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId {
210 chalk_ir::TypeId(id_to_chalk(self.id)) 212 chalk_ir::TypeId(id_to_chalk(self))
211 } 213 }
212 214
213 fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAlias { 215 fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAliasId {
214 TypeAlias { id: id_from_chalk(type_alias_id.0) } 216 id_from_chalk(type_alias_id.0)
215 } 217 }
216} 218}
217 219
@@ -402,7 +404,7 @@ fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
402 404
403fn convert_where_clauses( 405fn convert_where_clauses(
404 db: &impl HirDatabase, 406 db: &impl HirDatabase,
405 def: GenericDef, 407 def: GenericDefId,
406 substs: &Substs, 408 substs: &Substs,
407) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> { 409) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> {
408 let generic_predicates = db.generic_predicates(def); 410 let generic_predicates = db.generic_predicates(def);
@@ -431,25 +433,25 @@ where
431 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum<ChalkIr>> { 433 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum<ChalkIr>> {
432 self.db.struct_datum(self.krate, struct_id) 434 self.db.struct_datum(self.krate, struct_id)
433 } 435 }
434 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum<ChalkIr>> { 436 fn impl_datum(&self, impl_id: chalk_ir::ImplId) -> Arc<ImplDatum<ChalkIr>> {
435 self.db.impl_datum(self.krate, impl_id) 437 self.db.impl_datum(self.krate, impl_id)
436 } 438 }
437 fn impls_for_trait( 439 fn impls_for_trait(
438 &self, 440 &self,
439 trait_id: chalk_ir::TraitId, 441 trait_id: chalk_ir::TraitId,
440 parameters: &[Parameter<ChalkIr>], 442 parameters: &[Parameter<ChalkIr>],
441 ) -> Vec<ImplId> { 443 ) -> Vec<chalk_ir::ImplId> {
442 debug!("impls_for_trait {:?}", trait_id); 444 debug!("impls_for_trait {:?}", trait_id);
443 if trait_id == UNKNOWN_TRAIT { 445 if trait_id == UNKNOWN_TRAIT {
444 return Vec::new(); 446 return Vec::new();
445 } 447 }
446 let trait_: Trait = from_chalk(self.db, trait_id); 448 let trait_: TraitId = from_chalk(self.db, trait_id);
447 let mut result: Vec<_> = self 449 let mut result: Vec<_> = self
448 .db 450 .db
449 .impls_for_trait(self.krate, trait_) 451 .impls_for_trait(self.krate, trait_.into())
450 .iter() 452 .iter()
451 .copied() 453 .copied()
452 .map(Impl::ImplBlock) 454 .map(|it| Impl::ImplBlock(it.into()))
453 .map(|impl_| impl_.to_chalk(self.db)) 455 .map(|impl_| impl_.to_chalk(self.db))
454 .collect(); 456 .collect();
455 457
@@ -485,7 +487,7 @@ where
485 &self, 487 &self,
486 id: chalk_rust_ir::AssociatedTyValueId, 488 id: chalk_rust_ir::AssociatedTyValueId,
487 ) -> Arc<AssociatedTyValue<ChalkIr>> { 489 ) -> Arc<AssociatedTyValue<ChalkIr>> {
488 self.db.associated_ty_value(self.krate, id) 490 self.db.associated_ty_value(self.krate.into(), id)
489 } 491 }
490 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> { 492 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> {
491 vec![] 493 vec![]
@@ -504,12 +506,12 @@ pub(crate) fn associated_ty_data_query(
504 id: TypeId, 506 id: TypeId,
505) -> Arc<AssociatedTyDatum<ChalkIr>> { 507) -> Arc<AssociatedTyDatum<ChalkIr>> {
506 debug!("associated_ty_data {:?}", id); 508 debug!("associated_ty_data {:?}", id);
507 let type_alias: TypeAlias = from_chalk(db, id); 509 let type_alias: TypeAliasId = from_chalk(db, id);
508 let trait_ = match type_alias.container(db) { 510 let trait_ = match type_alias.lookup(db).container {
509 Some(crate::Container::Trait(t)) => t, 511 ContainerId::TraitId(t) => t,
510 _ => panic!("associated type not in trait"), 512 _ => panic!("associated type not in trait"),
511 }; 513 };
512 let generic_params = db.generic_params(type_alias.id.into()); 514 let generic_params = db.generic_params(type_alias.into());
513 let bound_data = chalk_rust_ir::AssociatedTyDatumBound { 515 let bound_data = chalk_rust_ir::AssociatedTyDatumBound {
514 // FIXME add bounds and where clauses 516 // FIXME add bounds and where clauses
515 bounds: vec![], 517 bounds: vec![],
@@ -518,7 +520,7 @@ pub(crate) fn associated_ty_data_query(
518 let datum = AssociatedTyDatum { 520 let datum = AssociatedTyDatum {
519 trait_id: trait_.to_chalk(db), 521 trait_id: trait_.to_chalk(db),
520 id, 522 id,
521 name: lalrpop_intern::intern(&type_alias.name(db).to_string()), 523 name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()),
522 binders: make_binders(bound_data, generic_params.count_params_including_parent()), 524 binders: make_binders(bound_data, generic_params.count_params_including_parent()),
523 }; 525 };
524 Arc::new(datum) 526 Arc::new(datum)
@@ -526,7 +528,7 @@ pub(crate) fn associated_ty_data_query(
526 528
527pub(crate) fn trait_datum_query( 529pub(crate) fn trait_datum_query(
528 db: &impl HirDatabase, 530 db: &impl HirDatabase,
529 krate: Crate, 531 krate: CrateId,
530 trait_id: chalk_ir::TraitId, 532 trait_id: chalk_ir::TraitId,
531) -> Arc<TraitDatum<ChalkIr>> { 533) -> Arc<TraitDatum<ChalkIr>> {
532 debug!("trait_datum {:?}", trait_id); 534 debug!("trait_datum {:?}", trait_id);
@@ -548,13 +550,14 @@ pub(crate) fn trait_datum_query(
548 associated_ty_ids: vec![], 550 associated_ty_ids: vec![],
549 }); 551 });
550 } 552 }
551 let trait_: Trait = from_chalk(db, trait_id); 553 let trait_: TraitId = from_chalk(db, trait_id);
552 debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); 554 let trait_data = db.trait_data(trait_);
553 let generic_params = db.generic_params(trait_.id.into()); 555 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
556 let generic_params = db.generic_params(trait_.into());
554 let bound_vars = Substs::bound_vars(&generic_params); 557 let bound_vars = Substs::bound_vars(&generic_params);
555 let flags = chalk_rust_ir::TraitFlags { 558 let flags = chalk_rust_ir::TraitFlags {
556 auto: trait_.is_auto(db), 559 auto: trait_data.auto,
557 upstream: trait_.module(db).krate() != krate, 560 upstream: trait_.module(db).krate != krate,
558 non_enumerable: true, 561 non_enumerable: true,
559 coinductive: false, // only relevant for Chalk testing 562 coinductive: false, // only relevant for Chalk testing
560 // FIXME set these flags correctly 563 // FIXME set these flags correctly
@@ -562,15 +565,8 @@ pub(crate) fn trait_datum_query(
562 fundamental: false, 565 fundamental: false,
563 }; 566 };
564 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); 567 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
565 let associated_ty_ids = trait_ 568 let associated_ty_ids =
566 .items(db) 569 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
567 .into_iter()
568 .filter_map(|trait_item| match trait_item {
569 crate::AssocItem::TypeAlias(type_alias) => Some(type_alias),
570 _ => None,
571 })
572 .map(|type_alias| type_alias.to_chalk(db))
573 .collect();
574 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses }; 570 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
575 let trait_datum = TraitDatum { 571 let trait_datum = TraitDatum {
576 id: trait_id, 572 id: trait_id,
@@ -583,7 +579,7 @@ pub(crate) fn trait_datum_query(
583 579
584pub(crate) fn struct_datum_query( 580pub(crate) fn struct_datum_query(
585 db: &impl HirDatabase, 581 db: &impl HirDatabase,
586 krate: Crate, 582 krate: CrateId,
587 struct_id: chalk_ir::StructId, 583 struct_id: chalk_ir::StructId,
588) -> Arc<StructDatum<ChalkIr>> { 584) -> Arc<StructDatum<ChalkIr>> {
589 debug!("struct_datum {:?}", struct_id); 585 debug!("struct_datum {:?}", struct_id);
@@ -615,8 +611,8 @@ pub(crate) fn struct_datum_query(
615 611
616pub(crate) fn impl_datum_query( 612pub(crate) fn impl_datum_query(
617 db: &impl HirDatabase, 613 db: &impl HirDatabase,
618 krate: Crate, 614 krate: CrateId,
619 impl_id: ImplId, 615 impl_id: chalk_ir::ImplId,
620) -> Arc<ImplDatum<ChalkIr>> { 616) -> Arc<ImplDatum<ChalkIr>> {
621 let _p = ra_prof::profile("impl_datum"); 617 let _p = ra_prof::profile("impl_datum");
622 debug!("impl_datum {:?}", impl_id); 618 debug!("impl_datum {:?}", impl_id);
@@ -630,24 +626,30 @@ pub(crate) fn impl_datum_query(
630 626
631fn impl_block_datum( 627fn impl_block_datum(
632 db: &impl HirDatabase, 628 db: &impl HirDatabase,
633 krate: Crate, 629 krate: CrateId,
630 chalk_id: chalk_ir::ImplId,
634 impl_id: ImplId, 631 impl_id: ImplId,
635 impl_block: ImplBlock,
636) -> Option<Arc<ImplDatum<ChalkIr>>> { 632) -> Option<Arc<ImplDatum<ChalkIr>>> {
637 let generic_params = db.generic_params(impl_block.id.into()); 633 let trait_ref = match db.impl_ty(impl_id) {
634 ImplTy::TraitRef(it) => it,
635 ImplTy::Inherent(_) => return None,
636 };
637 let impl_data = db.impl_data(impl_id);
638
639 let generic_params = db.generic_params(impl_id.into());
638 let bound_vars = Substs::bound_vars(&generic_params); 640 let bound_vars = Substs::bound_vars(&generic_params);
639 let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); 641 let trait_ref = trait_ref.subst(&bound_vars);
640 let trait_ = trait_ref.trait_; 642 let trait_ = trait_ref.trait_;
641 let impl_type = if impl_block.krate(db) == krate { 643 let impl_type = if impl_id.module(db).krate == krate {
642 chalk_rust_ir::ImplType::Local 644 chalk_rust_ir::ImplType::Local
643 } else { 645 } else {
644 chalk_rust_ir::ImplType::External 646 chalk_rust_ir::ImplType::External
645 }; 647 };
646 let where_clauses = convert_where_clauses(db, impl_block.into(), &bound_vars); 648 let where_clauses = convert_where_clauses(db, impl_id.into(), &bound_vars);
647 let negative = impl_block.is_negative(db); 649 let negative = impl_data.is_negative;
648 debug!( 650 debug!(
649 "impl {:?}: {}{} where {:?}", 651 "impl {:?}: {}{} where {:?}",
650 impl_id, 652 chalk_id,
651 if negative { "!" } else { "" }, 653 if negative { "!" } else { "" },
652 trait_ref.display(db), 654 trait_ref.display(db),
653 where_clauses 655 where_clauses
@@ -661,16 +663,18 @@ fn impl_block_datum(
661 }; 663 };
662 664
663 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses }; 665 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses };
664 let associated_ty_value_ids = impl_block 666 let trait_data = db.trait_data(trait_);
665 .items(db) 667 let associated_ty_value_ids = impl_data
666 .into_iter() 668 .items
669 .iter()
667 .filter_map(|item| match item { 670 .filter_map(|item| match item {
668 crate::AssocItem::TypeAlias(type_alias) => Some(type_alias), 671 AssocItemId::TypeAliasId(type_alias) => Some(*type_alias),
669 _ => None, 672 _ => None,
670 }) 673 })
671 .filter(|type_alias| { 674 .filter(|&type_alias| {
672 // don't include associated types that don't exist in the trait 675 // don't include associated types that don't exist in the trait
673 trait_.associated_type_by_name(db, &type_alias.name(db)).is_some() 676 let name = &db.type_alias_data(type_alias).name;
677 trait_data.associated_type_by_name(name).is_some()
674 }) 678 })
675 .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) 679 .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db))
676 .collect(); 680 .collect();
@@ -701,7 +705,7 @@ fn invalid_impl_datum() -> Arc<ImplDatum<ChalkIr>> {
701 705
702fn closure_fn_trait_impl_datum( 706fn closure_fn_trait_impl_datum(
703 db: &impl HirDatabase, 707 db: &impl HirDatabase,
704 krate: Crate, 708 krate: CrateId,
705 data: super::ClosureFnTraitImplData, 709 data: super::ClosureFnTraitImplData,
706) -> Option<Arc<ImplDatum<ChalkIr>>> { 710) -> Option<Arc<ImplDatum<ChalkIr>>> {
707 // for some closure |X, Y| -> Z: 711 // for some closure |X, Y| -> Z:
@@ -713,10 +717,10 @@ fn closure_fn_trait_impl_datum(
713 // and don't want to return a valid value only to find out later that FnOnce 717 // and don't want to return a valid value only to find out later that FnOnce
714 // is broken 718 // is broken
715 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; 719 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
716 fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?; 720 let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name::OUTPUT_TYPE)?;
717 721
718 let num_args: u16 = match &db.body(data.def.into())[data.expr] { 722 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
719 crate::expr::Expr::Lambda { args, .. } => args.len() as u16, 723 Expr::Lambda { args, .. } => args.len() as u16,
720 _ => { 724 _ => {
721 log::warn!("closure for closure type {:?} not found", data); 725 log::warn!("closure for closure type {:?} not found", data);
722 0 726 0
@@ -735,7 +739,7 @@ fn closure_fn_trait_impl_datum(
735 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty); 739 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty);
736 740
737 let trait_ref = TraitRef { 741 let trait_ref = TraitRef {
738 trait_, 742 trait_: trait_.into(),
739 substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(), 743 substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(),
740 }; 744 };
741 745
@@ -758,7 +762,7 @@ fn closure_fn_trait_impl_datum(
758 762
759pub(crate) fn associated_ty_value_query( 763pub(crate) fn associated_ty_value_query(
760 db: &impl HirDatabase, 764 db: &impl HirDatabase,
761 krate: Crate, 765 krate: CrateId,
762 id: chalk_rust_ir::AssociatedTyValueId, 766 id: chalk_rust_ir::AssociatedTyValueId,
763) -> Arc<chalk_rust_ir::AssociatedTyValue<ChalkIr>> { 767) -> Arc<chalk_rust_ir::AssociatedTyValue<ChalkIr>> {
764 let data: AssocTyValue = from_chalk(db, id); 768 let data: AssocTyValue = from_chalk(db, id);
@@ -774,24 +778,31 @@ pub(crate) fn associated_ty_value_query(
774 778
775fn type_alias_associated_ty_value( 779fn type_alias_associated_ty_value(
776 db: &impl HirDatabase, 780 db: &impl HirDatabase,
777 _krate: Crate, 781 _krate: CrateId,
778 type_alias: TypeAlias, 782 type_alias: TypeAliasId,
779) -> Arc<AssociatedTyValue<ChalkIr>> { 783) -> Arc<AssociatedTyValue<ChalkIr>> {
780 let impl_block = type_alias.impl_block(db).expect("assoc ty value should be in impl"); 784 let type_alias_data = db.type_alias_data(type_alias);
781 let impl_id = Impl::ImplBlock(impl_block).to_chalk(db); 785 let impl_id = match type_alias.lookup(db).container {
782 let trait_ = impl_block 786 ContainerId::ImplId(it) => it,
783 .target_trait_ref(db) 787 _ => panic!("assoc ty value should be in impl"),
784 .expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved 788 };
785 .trait_; 789
786 let assoc_ty = trait_ 790 let trait_ref = match db.impl_ty(impl_id) {
787 .associated_type_by_name(db, &type_alias.name(db)) 791 ImplTy::TraitRef(it) => it,
792 // we don't return any assoc ty values if the impl'd trait can't be resolved
793 ImplTy::Inherent(_) => panic!("assoc ty value should not exist"),
794 };
795
796 let assoc_ty = db
797 .trait_data(trait_ref.trait_)
798 .associated_type_by_name(&type_alias_data.name)
788 .expect("assoc ty value should not exist"); // validated when building the impl data as well 799 .expect("assoc ty value should not exist"); // validated when building the impl data as well
789 let generic_params = db.generic_params(impl_block.id.into()); 800 let generic_params = db.generic_params(impl_id.into());
790 let bound_vars = Substs::bound_vars(&generic_params); 801 let bound_vars = Substs::bound_vars(&generic_params);
791 let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); 802 let ty = db.ty(type_alias.into()).subst(&bound_vars);
792 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; 803 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
793 let value = chalk_rust_ir::AssociatedTyValue { 804 let value = chalk_rust_ir::AssociatedTyValue {
794 impl_id, 805 impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db),
795 associated_ty_id: assoc_ty.to_chalk(db), 806 associated_ty_id: assoc_ty.to_chalk(db),
796 value: make_binders(value_bound, bound_vars.len()), 807 value: make_binders(value_bound, bound_vars.len()),
797 }; 808 };
@@ -800,13 +811,13 @@ fn type_alias_associated_ty_value(
800 811
801fn closure_fn_trait_output_assoc_ty_value( 812fn closure_fn_trait_output_assoc_ty_value(
802 db: &impl HirDatabase, 813 db: &impl HirDatabase,
803 krate: Crate, 814 krate: CrateId,
804 data: super::ClosureFnTraitImplData, 815 data: super::ClosureFnTraitImplData,
805) -> Arc<AssociatedTyValue<ChalkIr>> { 816) -> Arc<AssociatedTyValue<ChalkIr>> {
806 let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db); 817 let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db);
807 818
808 let num_args: u16 = match &db.body(data.def.into())[data.expr] { 819 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
809 crate::expr::Expr::Lambda { args, .. } => args.len() as u16, 820 Expr::Lambda { args, .. } => args.len() as u16,
810 _ => { 821 _ => {
811 log::warn!("closure for closure type {:?} not found", data); 822 log::warn!("closure for closure type {:?} not found", data);
812 0 823 0
@@ -818,8 +829,9 @@ fn closure_fn_trait_output_assoc_ty_value(
818 let fn_once_trait = 829 let fn_once_trait =
819 get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist"); 830 get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist");
820 831
821 let output_ty_id = fn_once_trait 832 let output_ty_id = db
822 .associated_type_by_name(db, &name::OUTPUT_TYPE) 833 .trait_data(fn_once_trait)
834 .associated_type_by_name(&name::OUTPUT_TYPE)
823 .expect("assoc ty value should not exist"); 835 .expect("assoc ty value should not exist");
824 836
825 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: output_ty.to_chalk(db) }; 837 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: output_ty.to_chalk(db) };
@@ -832,10 +844,14 @@ fn closure_fn_trait_output_assoc_ty_value(
832 Arc::new(value) 844 Arc::new(value)
833} 845}
834 846
835fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<Trait> { 847fn get_fn_trait(
836 let target = db.lang_item(krate.crate_id, fn_trait.lang_item_name().into())?; 848 db: &impl HirDatabase,
849 krate: CrateId,
850 fn_trait: super::FnTrait,
851) -> Option<TraitId> {
852 let target = db.lang_item(krate, fn_trait.lang_item_name().into())?;
837 match target { 853 match target {
838 LangItemTarget::TraitId(t) => Some(t.into()), 854 LangItemTarget::TraitId(t) => Some(t),
839 _ => None, 855 _ => None,
840 } 856 }
841} 857}
@@ -847,38 +863,38 @@ fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId {
847 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } 863 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() }
848} 864}
849 865
850impl From<chalk_ir::StructId> for crate::ty::TypeCtorId { 866impl From<chalk_ir::StructId> for crate::TypeCtorId {
851 fn from(struct_id: chalk_ir::StructId) -> Self { 867 fn from(struct_id: chalk_ir::StructId) -> Self {
852 id_from_chalk(struct_id.0) 868 id_from_chalk(struct_id.0)
853 } 869 }
854} 870}
855 871
856impl From<crate::ty::TypeCtorId> for chalk_ir::StructId { 872impl From<crate::TypeCtorId> for chalk_ir::StructId {
857 fn from(type_ctor_id: crate::ty::TypeCtorId) -> Self { 873 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
858 chalk_ir::StructId(id_to_chalk(type_ctor_id)) 874 chalk_ir::StructId(id_to_chalk(type_ctor_id))
859 } 875 }
860} 876}
861 877
862impl From<chalk_ir::ImplId> for crate::ty::traits::GlobalImplId { 878impl From<chalk_ir::ImplId> for crate::traits::GlobalImplId {
863 fn from(impl_id: chalk_ir::ImplId) -> Self { 879 fn from(impl_id: chalk_ir::ImplId) -> Self {
864 id_from_chalk(impl_id.0) 880 id_from_chalk(impl_id.0)
865 } 881 }
866} 882}
867 883
868impl From<crate::ty::traits::GlobalImplId> for chalk_ir::ImplId { 884impl From<crate::traits::GlobalImplId> for chalk_ir::ImplId {
869 fn from(impl_id: crate::ty::traits::GlobalImplId) -> Self { 885 fn from(impl_id: crate::traits::GlobalImplId) -> Self {
870 chalk_ir::ImplId(id_to_chalk(impl_id)) 886 chalk_ir::ImplId(id_to_chalk(impl_id))
871 } 887 }
872} 888}
873 889
874impl From<chalk_rust_ir::AssociatedTyValueId> for crate::ty::traits::AssocTyValueId { 890impl From<chalk_rust_ir::AssociatedTyValueId> for crate::traits::AssocTyValueId {
875 fn from(id: chalk_rust_ir::AssociatedTyValueId) -> Self { 891 fn from(id: chalk_rust_ir::AssociatedTyValueId) -> Self {
876 id_from_chalk(id.0) 892 id_from_chalk(id.0)
877 } 893 }
878} 894}
879 895
880impl From<crate::ty::traits::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId { 896impl From<crate::traits::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId {
881 fn from(assoc_ty_value_id: crate::ty::traits::AssocTyValueId) -> Self { 897 fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self {
882 chalk_rust_ir::AssociatedTyValueId(id_to_chalk(assoc_ty_value_id)) 898 chalk_rust_ir::AssociatedTyValueId(id_to_chalk(assoc_ty_value_id))
883 } 899 }
884} 900}
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs
new file mode 100644
index 000000000..e4ba890ef
--- /dev/null
+++ b/crates/ra_hir_ty/src/utils.rs
@@ -0,0 +1,84 @@
1//! Helper functions for working with def, which don't need to be a separate
2//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
3use std::sync::Arc;
4
5use hir_def::{
6 adt::VariantData,
7 db::DefDatabase,
8 resolver::{HasResolver, TypeNs},
9 type_ref::TypeRef,
10 TraitId, TypeAliasId, VariantId,
11};
12use hir_expand::name::{self, Name};
13
14// FIXME: this is wrong, b/c it can't express `trait T: PartialEq<()>`.
15// We should return a `TraitREf` here.
16fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> {
17 let resolver = trait_.resolver(db);
18 // returning the iterator directly doesn't easily work because of
19 // lifetime problems, but since there usually shouldn't be more than a
20 // few direct traits this should be fine (we could even use some kind of
21 // SmallVec if performance is a concern)
22 db.generic_params(trait_.into())
23 .where_predicates
24 .iter()
25 .filter_map(|pred| match &pred.type_ref {
26 TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(),
27 _ => None,
28 })
29 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) {
30 Some(TypeNs::TraitId(t)) => Some(t),
31 _ => None,
32 })
33 .collect()
34}
35
36/// Returns an iterator over the whole super trait hierarchy (including the
37/// trait itself).
38pub(super) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> {
39 // we need to take care a bit here to avoid infinite loops in case of cycles
40 // (i.e. if we have `trait A: B; trait B: A;`)
41 let mut result = vec![trait_];
42 let mut i = 0;
43 while i < result.len() {
44 let t = result[i];
45 // yeah this is quadratic, but trait hierarchies should be flat
46 // enough that this doesn't matter
47 for tt in direct_super_traits(db, t) {
48 if !result.contains(&tt) {
49 result.push(tt);
50 }
51 }
52 i += 1;
53 }
54 result
55}
56
57pub(super) fn associated_type_by_name_including_super_traits(
58 db: &impl DefDatabase,
59 trait_: TraitId,
60 name: &Name,
61) -> Option<TypeAliasId> {
62 all_super_traits(db, trait_)
63 .into_iter()
64 .find_map(|t| db.trait_data(t).associated_type_by_name(name))
65}
66
67pub(super) fn variant_data(db: &impl DefDatabase, var: VariantId) -> Arc<VariantData> {
68 match var {
69 VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
70 VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
71 VariantId::EnumVariantId(it) => {
72 db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
73 }
74 }
75}
76
77/// Helper for mutating `Arc<[T]>` (i.e. `Arc::make_mut` for Arc slices).
78/// The underlying values are cloned if there are other strong references.
79pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] {
80 if Arc::get_mut(a).is_none() {
81 *a = a.iter().cloned().collect();
82 }
83 Arc::get_mut(a).unwrap()
84}
diff --git a/crates/ra_ide_api/Cargo.toml b/crates/ra_ide/Cargo.toml
index 15346f388..e6383dd35 100644
--- a/crates/ra_ide_api/Cargo.toml
+++ b/crates/ra_ide/Cargo.toml
@@ -1,6 +1,6 @@
1[package] 1[package]
2edition = "2018" 2edition = "2018"
3name = "ra_ide_api" 3name = "ra_ide"
4version = "0.1.0" 4version = "0.1.0"
5authors = ["rust-analyzer developers"] 5authors = ["rust-analyzer developers"]
6 6
@@ -32,7 +32,7 @@ ra_prof = { path = "../ra_prof" }
32test_utils = { path = "../test_utils" } 32test_utils = { path = "../test_utils" }
33ra_assists = { path = "../ra_assists" } 33ra_assists = { path = "../ra_assists" }
34 34
35# ra_ide_api should depend only on the top-level `hir` package. if you need 35# ra_ide should depend only on the top-level `hir` package. if you need
36# something from some `hir_xxx` subpackage, reexport the API via `hir`. 36# something from some `hir_xxx` subpackage, reexport the API via `hir`.
37hir = { path = "../ra_hir", package = "ra_hir" } 37hir = { path = "../ra_hir", package = "ra_hir" }
38 38
diff --git a/crates/ra_ide_api/src/assists.rs b/crates/ra_ide/src/assists.rs
index e00589733..e00589733 100644
--- a/crates/ra_ide_api/src/assists.rs
+++ b/crates/ra_ide/src/assists.rs
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index 7c367230e..d559dc4d0 100644
--- a/crates/ra_ide_api/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -18,22 +18,22 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
18 // Find the calling expression and it's NameRef 18 // Find the calling expression and it's NameRef
19 let calling_node = FnCallNode::with_node(&syntax, position.offset)?; 19 let calling_node = FnCallNode::with_node(&syntax, position.offset)?;
20 let name_ref = calling_node.name_ref()?; 20 let name_ref = calling_node.name_ref()?;
21 let name_ref = hir::Source::new(position.file_id.into(), name_ref.syntax());
21 22
22 let analyzer = hir::SourceAnalyzer::new( 23 let analyzer = hir::SourceAnalyzer::new(db, name_ref, None);
23 db,
24 hir::Source::new(position.file_id.into(), name_ref.syntax()),
25 None,
26 );
27 let (mut call_info, has_self) = match &calling_node { 24 let (mut call_info, has_self) = match &calling_node {
28 FnCallNode::CallExpr(expr) => { 25 FnCallNode::CallExpr(expr) => {
29 //FIXME: apply subst 26 //FIXME: Type::as_callable is broken
30 let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; 27 let callable_def = analyzer.type_of(db, &expr.expr()?)?.as_callable()?;
31 match callable_def { 28 match callable_def {
32 hir::CallableDef::Function(it) => { 29 hir::CallableDef::FunctionId(it) => {
33 (CallInfo::with_fn(db, it), it.has_self_param(db)) 30 let fn_def = it.into();
31 (CallInfo::with_fn(db, fn_def), fn_def.has_self_param(db))
32 }
33 hir::CallableDef::StructId(it) => (CallInfo::with_struct(db, it.into())?, false),
34 hir::CallableDef::EnumVariantId(it) => {
35 (CallInfo::with_enum_variant(db, it.into())?, false)
34 } 36 }
35 hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it)?, false),
36 hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it)?, false),
37 } 37 }
38 } 38 }
39 FnCallNode::MethodCallExpr(expr) => { 39 FnCallNode::MethodCallExpr(expr) => {
@@ -41,7 +41,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
41 (CallInfo::with_fn(db, function), function.has_self_param(db)) 41 (CallInfo::with_fn(db, function), function.has_self_param(db))
42 } 42 }
43 FnCallNode::MacroCallExpr(expr) => { 43 FnCallNode::MacroCallExpr(expr) => {
44 let macro_def = analyzer.resolve_macro_call(db, &expr)?; 44 let macro_def = analyzer.resolve_macro_call(db, name_ref.with_value(&expr))?;
45 (CallInfo::with_macro(db, macro_def)?, false) 45 (CallInfo::with_macro(db, macro_def)?, false)
46 } 46 }
47 }; 47 };
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide/src/change.rs
index 0f692460d..4a76d1dd8 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide/src/change.rs
@@ -171,7 +171,7 @@ impl RootDatabase {
171 log::info!("apply_change {:?}", change); 171 log::info!("apply_change {:?}", change);
172 { 172 {
173 let _p = profile("RootDatabase::apply_change/cancellation"); 173 let _p = profile("RootDatabase::apply_change/cancellation");
174 self.salsa_runtime().synthetic_write(Durability::LOW); 174 self.salsa_runtime_mut().synthetic_write(Durability::LOW);
175 } 175 }
176 if !change.new_roots.is_empty() { 176 if !change.new_roots.is_empty() {
177 let mut local_roots = Vec::clone(&self.local_roots()); 177 let mut local_roots = Vec::clone(&self.local_roots());
@@ -323,7 +323,8 @@ impl RootDatabase {
323 hir::db::DocumentationQuery 323 hir::db::DocumentationQuery
324 hir::db::ExprScopesQuery 324 hir::db::ExprScopesQuery
325 hir::db::InferQuery 325 hir::db::InferQuery
326 hir::db::TypeForDefQuery 326 hir::db::TyQuery
327 hir::db::ValueTyQuery
327 hir::db::FieldTypesQuery 328 hir::db::FieldTypesQuery
328 hir::db::CallableItemSignatureQuery 329 hir::db::CallableItemSignatureQuery
329 hir::db::GenericPredicatesQuery 330 hir::db::GenericPredicatesQuery
diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide/src/completion.rs
index abe1f36ce..abe1f36ce 100644
--- a/crates/ra_ide_api/src/completion.rs
+++ b/crates/ra_ide/src/completion.rs
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index 5a3f9b5f6..b6fe48627 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{Adt, Ty, TypeCtor}; 3use hir::Type;
4 4
5use crate::completion::completion_item::CompletionKind; 5use crate::completion::completion_item::CompletionKind;
6use crate::{ 6use crate::{
@@ -22,12 +22,12 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
22 }; 22 };
23 23
24 if !ctx.is_call { 24 if !ctx.is_call {
25 complete_fields(acc, ctx, receiver_ty.clone()); 25 complete_fields(acc, ctx, &receiver_ty);
26 } 26 }
27 complete_methods(acc, ctx, receiver_ty.clone()); 27 complete_methods(acc, ctx, &receiver_ty);
28 28
29 // Suggest .await syntax for types that implement Future trait 29 // Suggest .await syntax for types that implement Future trait
30 if ctx.analyzer.impls_future(ctx.db, receiver_ty) { 30 if ctx.analyzer.impls_future(ctx.db, receiver_ty.into_ty()) {
31 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await") 31 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await")
32 .detail("expr.await") 32 .detail("expr.await")
33 .insert_text("await") 33 .insert_text("await")
@@ -35,28 +35,18 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
35 } 35 }
36} 36}
37 37
38fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { 38fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) {
39 for receiver in ctx.analyzer.autoderef(ctx.db, receiver) { 39 for receiver in receiver.autoderef(ctx.db) {
40 if let Ty::Apply(a_ty) = receiver { 40 for (field, ty) in receiver.fields(ctx.db) {
41 match a_ty.ctor { 41 acc.add_field(ctx, field, &ty);
42 TypeCtor::Adt(Adt::Struct(s)) => { 42 }
43 for field in s.fields(ctx.db) { 43 for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() {
44 acc.add_field(ctx, field, &a_ty.parameters); 44 acc.add_tuple_field(ctx, i, &ty);
45 } 45 }
46 }
47 // FIXME unions
48 TypeCtor::Tuple { .. } => {
49 for (i, ty) in a_ty.parameters.iter().enumerate() {
50 acc.add_tuple_field(ctx, i, ty);
51 }
52 }
53 _ => {}
54 }
55 };
56 } 46 }
57} 47}
58 48
59fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { 49fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) {
60 let mut seen_methods = FxHashSet::default(); 50 let mut seen_methods = FxHashSet::default();
61 ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| { 51 ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| {
62 if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) { 52 if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) {
diff --git a/crates/ra_ide_api/src/completion/complete_fn_param.rs b/crates/ra_ide/src/completion/complete_fn_param.rs
index 502458706..502458706 100644
--- a/crates/ra_ide_api/src/completion/complete_fn_param.rs
+++ b/crates/ra_ide/src/completion/complete_fn_param.rs
diff --git a/crates/ra_ide_api/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs
index eb7cd9ac2..eb7cd9ac2 100644
--- a/crates/ra_ide_api/src/completion/complete_keyword.rs
+++ b/crates/ra_ide/src/completion/complete_keyword.rs
diff --git a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs
index faadd1e3f..faadd1e3f 100644
--- a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs
+++ b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs
index 63e25e0bf..89e0009a1 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide/src/completion/complete_path.rs
@@ -50,7 +50,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
50 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), 50 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
51 _ => unreachable!(), 51 _ => unreachable!(),
52 }; 52 };
53 ctx.analyzer.iterate_path_candidates(ctx.db, ty.clone(), None, |_ty, item| { 53 ctx.analyzer.iterate_path_candidates(ctx.db, &ty, None, |_ty, item| {
54 match item { 54 match item {
55 hir::AssocItem::Function(func) => { 55 hir::AssocItem::Function(func) => {
56 if !func.has_self_param(ctx.db) { 56 if !func.has_self_param(ctx.db) {
diff --git a/crates/ra_ide_api/src/completion/complete_pattern.rs b/crates/ra_ide/src/completion/complete_pattern.rs
index fd03b1c40..fd03b1c40 100644
--- a/crates/ra_ide_api/src/completion/complete_pattern.rs
+++ b/crates/ra_ide/src/completion/complete_pattern.rs
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs
index 17b75cf7e..646a30c76 100644
--- a/crates/ra_ide_api/src/completion/complete_postfix.rs
+++ b/crates/ra_ide/src/completion/complete_postfix.rs
@@ -1,6 +1,5 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{Ty, TypeCtor};
4use ra_syntax::{ast::AstNode, TextRange, TextUnit}; 3use ra_syntax::{ast::AstNode, TextRange, TextUnit};
5use ra_text_edit::TextEdit; 4use ra_text_edit::TextEdit;
6 5
@@ -30,9 +29,12 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
30 dot_receiver.syntax().text().to_string() 29 dot_receiver.syntax().text().to_string()
31 }; 30 };
32 31
33 let receiver_ty = ctx.analyzer.type_of(ctx.db, &dot_receiver); 32 let receiver_ty = match ctx.analyzer.type_of(ctx.db, &dot_receiver) {
33 Some(it) => it,
34 None => return,
35 };
34 36
35 if is_bool_or_unknown(receiver_ty) { 37 if receiver_ty.is_bool() || receiver_ty.is_unknown() {
36 postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text)) 38 postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text))
37 .add_to(acc); 39 .add_to(acc);
38 postfix_snippet( 40 postfix_snippet(
@@ -75,14 +77,6 @@ fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet:
75 .snippet_edit(edit) 77 .snippet_edit(edit)
76} 78}
77 79
78fn is_bool_or_unknown(ty: Option<Ty>) -> bool {
79 match &ty {
80 Some(Ty::Apply(app)) if app.ctor == TypeCtor::Bool => true,
81 Some(Ty::Unknown) | None => true,
82 Some(_) => false,
83 }
84}
85
86#[cfg(test)] 80#[cfg(test)]
87mod tests { 81mod tests {
88 use insta::assert_debug_snapshot; 82 use insta::assert_debug_snapshot;
diff --git a/crates/ra_ide_api/src/completion/complete_record_literal.rs b/crates/ra_ide/src/completion/complete_record_literal.rs
index 45a4a9738..577c394d2 100644
--- a/crates/ra_ide_api/src/completion/complete_record_literal.rs
+++ b/crates/ra_ide/src/completion/complete_record_literal.rs
@@ -1,7 +1,5 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::Substs;
4
5use crate::completion::{CompletionContext, Completions}; 3use crate::completion::{CompletionContext, Completions};
6 4
7/// Complete fields in fields literals. 5/// Complete fields in fields literals.
@@ -15,10 +13,9 @@ pub(super) fn complete_record_literal(acc: &mut Completions, ctx: &CompletionCon
15 Some(it) => it, 13 Some(it) => it,
16 _ => return, 14 _ => return,
17 }; 15 };
18 let substs = &ty.substs().unwrap_or_else(Substs::empty);
19 16
20 for field in variant.fields(ctx.db) { 17 for (field, field_ty) in ty.variant_fields(ctx.db, variant) {
21 acc.add_field(ctx, field, substs); 18 acc.add_field(ctx, field, &field_ty);
22 } 19 }
23} 20}
24 21
diff --git a/crates/ra_ide_api/src/completion/complete_record_pattern.rs b/crates/ra_ide/src/completion/complete_record_pattern.rs
index aa0fd6d24..a56c7e3a1 100644
--- a/crates/ra_ide_api/src/completion/complete_record_pattern.rs
+++ b/crates/ra_ide/src/completion/complete_record_pattern.rs
@@ -1,7 +1,5 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::Substs;
4
5use crate::completion::{CompletionContext, Completions}; 3use crate::completion::{CompletionContext, Completions};
6 4
7pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) { 5pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) {
@@ -14,10 +12,9 @@ pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionCon
14 Some(it) => it, 12 Some(it) => it,
15 _ => return, 13 _ => return,
16 }; 14 };
17 let substs = &ty.substs().unwrap_or_else(Substs::empty);
18 15
19 for field in variant.fields(ctx.db) { 16 for (field, field_ty) in ty.variant_fields(ctx.db, variant) {
20 acc.add_field(ctx, field, substs); 17 acc.add_field(ctx, field, &field_ty);
21 } 18 }
22} 19}
23 20
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs
index d5739b58a..d5739b58a 100644
--- a/crates/ra_ide_api/src/completion/complete_scope.rs
+++ b/crates/ra_ide/src/completion/complete_scope.rs
diff --git a/crates/ra_ide_api/src/completion/complete_snippet.rs b/crates/ra_ide/src/completion/complete_snippet.rs
index 1f2988b36..1f2988b36 100644
--- a/crates/ra_ide_api/src/completion/complete_snippet.rs
+++ b/crates/ra_ide/src/completion/complete_snippet.rs
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index b8345c91d..b8345c91d 100644
--- a/crates/ra_ide_api/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs
index 93f336370..93f336370 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide/src/completion/completion_item.rs
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index bac3f7582..97475fc0b 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -1,12 +1,12 @@
1//! This modules takes care of rendering various definitions as completion items. 1//! This modules takes care of rendering various definitions as completion items.
2 2
3use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; 3use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Type};
4use join_to_string::join; 4use join_to_string::join;
5use ra_syntax::ast::NameOwner; 5use ra_syntax::ast::NameOwner;
6use test_utils::tested_by; 6use test_utils::tested_by;
7 7
8use crate::completion::{ 8use crate::completion::{
9 db, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, 9 CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions,
10}; 10};
11 11
12use crate::display::{const_label, function_label, macro_label, type_label}; 12use crate::display::{const_label, function_label, macro_label, type_label};
@@ -16,7 +16,7 @@ impl Completions {
16 &mut self, 16 &mut self,
17 ctx: &CompletionContext, 17 ctx: &CompletionContext,
18 field: hir::StructField, 18 field: hir::StructField,
19 substs: &hir::Substs, 19 ty: &Type,
20 ) { 20 ) {
21 let is_deprecated = is_deprecated(field, ctx.db); 21 let is_deprecated = is_deprecated(field, ctx.db);
22 CompletionItem::new( 22 CompletionItem::new(
@@ -25,13 +25,13 @@ impl Completions {
25 field.name(ctx.db).to_string(), 25 field.name(ctx.db).to_string(),
26 ) 26 )
27 .kind(CompletionItemKind::Field) 27 .kind(CompletionItemKind::Field)
28 .detail(field.ty(ctx.db).subst(substs).display(ctx.db).to_string()) 28 .detail(ty.display(ctx.db).to_string())
29 .set_documentation(field.docs(ctx.db)) 29 .set_documentation(field.docs(ctx.db))
30 .set_deprecated(is_deprecated) 30 .set_deprecated(is_deprecated)
31 .add_to(self); 31 .add_to(self);
32 } 32 }
33 33
34 pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &hir::Ty) { 34 pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &Type) {
35 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string()) 35 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string())
36 .kind(CompletionItemKind::Field) 36 .kind(CompletionItemKind::Field)
37 .detail(ty.display(ctx.db).to_string()) 37 .detail(ty.display(ctx.db).to_string())
@@ -98,7 +98,7 @@ impl Completions {
98 CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone()); 98 CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone());
99 if let ScopeDef::Local(local) = resolution { 99 if let ScopeDef::Local(local) = resolution {
100 let ty = local.ty(ctx.db); 100 let ty = local.ty(ctx.db);
101 if ty != Ty::Unknown { 101 if !ty.is_unknown() {
102 completion_item = completion_item.detail(ty.display(ctx.db).to_string()); 102 completion_item = completion_item.detail(ty.display(ctx.db).to_string());
103 } 103 }
104 }; 104 };
@@ -108,19 +108,17 @@ impl Completions {
108 && !ctx.has_type_args 108 && !ctx.has_type_args
109 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis") 109 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
110 { 110 {
111 let generic_def: Option<hir::GenericDef> = match resolution { 111 let has_non_default_type_params = match resolution {
112 ScopeDef::ModuleDef(Adt(it)) => Some((*it).into()), 112 ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
113 ScopeDef::ModuleDef(TypeAlias(it)) => Some((*it).into()), 113 ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
114 _ => None, 114 _ => false,
115 }; 115 };
116 if let Some(def) = generic_def { 116 if has_non_default_type_params {
117 if has_non_default_type_params(def, ctx.db) { 117 tested_by!(inserts_angle_brackets_for_generics);
118 tested_by!(inserts_angle_brackets_for_generics); 118 completion_item = completion_item
119 completion_item = completion_item 119 .lookup_by(local_name.clone())
120 .lookup_by(local_name.clone()) 120 .label(format!("{}<…>", local_name))
121 .label(format!("{}<…>", local_name)) 121 .insert_snippet(format!("{}<$0>", local_name));
122 .insert_snippet(format!("{}<$0>", local_name));
123 }
124 } 122 }
125 } 123 }
126 124
@@ -269,10 +267,7 @@ impl Completions {
269 267
270 pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { 268 pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) {
271 let is_deprecated = is_deprecated(variant, ctx.db); 269 let is_deprecated = is_deprecated(variant, ctx.db);
272 let name = match variant.name(ctx.db) { 270 let name = variant.name(ctx.db);
273 Some(it) => it,
274 None => return,
275 };
276 let detail_types = variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db)); 271 let detail_types = variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db));
277 let detail = join(detail_types.map(|t| t.display(ctx.db).to_string())) 272 let detail = join(detail_types.map(|t| t.display(ctx.db).to_string()))
278 .separator(", ") 273 .separator(", ")
@@ -291,11 +286,6 @@ fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool {
291 node.attrs(db).by_key("deprecated").exists() 286 node.attrs(db).by_key("deprecated").exists()
292} 287}
293 288
294fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool {
295 let subst = db.generic_defaults(def);
296 subst.iter().any(|ty| ty == &Ty::Unknown)
297}
298
299#[cfg(test)] 289#[cfg(test)]
300mod tests { 290mod tests {
301 use insta::assert_debug_snapshot; 291 use insta::assert_debug_snapshot;
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide/src/db.rs
index c2a9dcdd1..f739ebecd 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide/src/db.rs
@@ -65,6 +65,9 @@ impl salsa::Database for RootDatabase {
65 fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { 65 fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
66 &self.runtime 66 &self.runtime
67 } 67 }
68 fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> {
69 &mut self.runtime
70 }
68 fn on_propagated_panic(&self) -> ! { 71 fn on_propagated_panic(&self) -> ! {
69 Canceled::throw() 72 Canceled::throw()
70 } 73 }
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index cc1ccab4b..cc1ccab4b 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide/src/display.rs
index 30617412a..30617412a 100644
--- a/crates/ra_ide_api/src/display.rs
+++ b/crates/ra_ide/src/display.rs
diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs
index d96de4e4c..324ad9552 100644
--- a/crates/ra_ide_api/src/display/function_signature.rs
+++ b/crates/ra_ide/src/display/function_signature.rs
@@ -93,12 +93,9 @@ impl FunctionSignature {
93 _ => (), 93 _ => (),
94 }; 94 };
95 95
96 let parent_name = match variant.parent_enum(db).name(db) { 96 let parent_name = variant.parent_enum(db).name(db).to_string();
97 Some(name) => name.to_string(),
98 None => "missing".into(),
99 };
100 97
101 let name = format!("{}::{}", parent_name, variant.name(db).unwrap()); 98 let name = format!("{}::{}", parent_name, variant.name(db));
102 99
103 let params = variant 100 let params = variant
104 .fields(db) 101 .fields(db)
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index 6ac60722b..6ac60722b 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
diff --git a/crates/ra_ide_api/src/display/short_label.rs b/crates/ra_ide/src/display/short_label.rs
index 5d2bce3d2..9ffc9b980 100644
--- a/crates/ra_ide_api/src/display/short_label.rs
+++ b/crates/ra_ide/src/display/short_label.rs
@@ -19,6 +19,12 @@ impl ShortLabel for ast::StructDef {
19 } 19 }
20} 20}
21 21
22impl ShortLabel for ast::UnionDef {
23 fn short_label(&self) -> Option<String> {
24 short_label_from_node(self, "union ")
25 }
26}
27
22impl ShortLabel for ast::EnumDef { 28impl ShortLabel for ast::EnumDef {
23 fn short_label(&self) -> Option<String> { 29 fn short_label(&self) -> Option<String> {
24 short_label_from_node(self, "enum ") 30 short_label_from_node(self, "enum ")
diff --git a/crates/ra_ide_api/src/display/structure.rs b/crates/ra_ide/src/display/structure.rs
index a80d65ac7..a80d65ac7 100644
--- a/crates/ra_ide_api/src/display/structure.rs
+++ b/crates/ra_ide/src/display/structure.rs
diff --git a/crates/ra_ide_api/src/expand.rs b/crates/ra_ide/src/expand.rs
index 2f1abf509..2f1abf509 100644
--- a/crates/ra_ide_api/src/expand.rs
+++ b/crates/ra_ide/src/expand.rs
diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide/src/expand_macro.rs
index 0b540b8cd..abc602244 100644
--- a/crates/ra_ide_api/src/expand_macro.rs
+++ b/crates/ra_ide/src/expand_macro.rs
@@ -269,4 +269,27 @@ fn some_thing() -> u32 {
269 assert_eq!(res.name, "foo"); 269 assert_eq!(res.name, "foo");
270 assert_snapshot!(res.expansion, @r###"bar!()"###); 270 assert_snapshot!(res.expansion, @r###"bar!()"###);
271 } 271 }
272
273 #[test]
274 fn macro_expand_with_dollar_crate() {
275 let res = check_expand_macro(
276 r#"
277 //- /lib.rs
278 #[macro_export]
279 macro_rules! bar {
280 () => {0};
281 }
282 macro_rules! foo {
283 () => {$crate::bar!()};
284 }
285
286 fn main() {
287 let res = fo<|>o!();
288 }
289 "#,
290 );
291
292 assert_eq!(res.name, "foo");
293 assert_snapshot!(res.expansion, @r###"0"###);
294 }
272} 295}
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs
index 4b7bfc0b1..4b7bfc0b1 100644
--- a/crates/ra_ide_api/src/extend_selection.rs
+++ b/crates/ra_ide/src/extend_selection.rs
diff --git a/crates/ra_ide_api/src/feature_flags.rs b/crates/ra_ide/src/feature_flags.rs
index de4ae513d..de4ae513d 100644
--- a/crates/ra_ide_api/src/feature_flags.rs
+++ b/crates/ra_ide/src/feature_flags.rs
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide/src/folding_ranges.rs
index 4eeb76d14..4eeb76d14 100644
--- a/crates/ra_ide_api/src/folding_ranges.rs
+++ b/crates/ra_ide/src/folding_ranges.rs
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index b6c72efdf..c10a6c844 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -71,10 +71,11 @@ pub(crate) fn reference_definition(
71 Some(nav) => return Exact(nav), 71 Some(nav) => return Exact(nav),
72 None => return Approximate(vec![]), 72 None => return Approximate(vec![]),
73 }, 73 },
74 Some(SelfType(ty)) => { 74 Some(SelfType(imp)) => {
75 if let Some((adt, _)) = ty.as_adt() { 75 // FIXME: ideally, this should point to the type in the impl, and
76 return Exact(adt.to_nav(db)); 76 // not at the whole impl. And goto **type** definition should bring
77 } 77 // us to the actual type
78 return Exact(imp.to_nav(db));
78 } 79 }
79 Some(Local(local)) => return Exact(local.to_nav(db)), 80 Some(Local(local)) => return Exact(local.to_nav(db)),
80 Some(GenericParam(_)) => { 81 Some(GenericParam(_)) => {
@@ -503,7 +504,7 @@ mod tests {
503 } 504 }
504 } 505 }
505 ", 506 ",
506 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", 507 "impl IMPL_BLOCK FileId(1) [12; 73)",
507 ); 508 );
508 509
509 check_goto( 510 check_goto(
@@ -516,7 +517,7 @@ mod tests {
516 } 517 }
517 } 518 }
518 ", 519 ",
519 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", 520 "impl IMPL_BLOCK FileId(1) [12; 73)",
520 ); 521 );
521 522
522 check_goto( 523 check_goto(
@@ -529,7 +530,7 @@ mod tests {
529 } 530 }
530 } 531 }
531 ", 532 ",
532 "Foo ENUM_DEF FileId(1) [0; 14) [5; 8)", 533 "impl IMPL_BLOCK FileId(1) [15; 75)",
533 ); 534 );
534 535
535 check_goto( 536 check_goto(
@@ -541,7 +542,7 @@ mod tests {
541 } 542 }
542 } 543 }
543 ", 544 ",
544 "Foo ENUM_DEF FileId(1) [0; 14) [5; 8)", 545 "impl IMPL_BLOCK FileId(1) [15; 62)",
545 ); 546 );
546 } 547 }
547 548
@@ -560,7 +561,7 @@ mod tests {
560 } 561 }
561 } 562 }
562 ", 563 ",
563 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", 564 "impl IMPL_BLOCK FileId(1) [49; 115)",
564 ); 565 );
565 566
566 check_goto( 567 check_goto(
@@ -572,11 +573,11 @@ mod tests {
572 } 573 }
573 impl Make for Foo { 574 impl Make for Foo {
574 fn new() -> Self<|> { 575 fn new() -> Self<|> {
575 Self{} 576 Self {}
576 } 577 }
577 } 578 }
578 ", 579 ",
579 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", 580 "impl IMPL_BLOCK FileId(1) [49; 115)",
580 ); 581 );
581 } 582 }
582 583
diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs
index 28a83a3e2..992a08809 100644
--- a/crates/ra_ide_api/src/goto_type_definition.rs
+++ b/crates/ra_ide/src/goto_type_definition.rs
@@ -24,7 +24,7 @@ pub(crate) fn goto_type_definition(
24 24
25 let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); 25 let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None);
26 26
27 let ty: hir::Ty = if let Some(ty) = 27 let ty: hir::Type = if let Some(ty) =
28 ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) 28 ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e))
29 { 29 {
30 ty 30 ty
@@ -35,7 +35,7 @@ pub(crate) fn goto_type_definition(
35 return None; 35 return None;
36 }; 36 };
37 37
38 let adt_def = analyzer.autoderef(db, ty).find_map(|ty| ty.as_adt().map(|adt| adt.0))?; 38 let adt_def = ty.autoderef(db).find_map(|ty| ty.as_adt())?;
39 39
40 let nav = adt_def.to_nav(db); 40 let nav = adt_def.to_nav(db);
41 Some(RangeInfo::new(node.text_range(), vec![nav])) 41 Some(RangeInfo::new(node.text_range(), vec![nav]))
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide/src/hover.rs
index 9839be985..260a7b869 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -133,20 +133,12 @@ fn hover_text_from_name_kind(
133 hir::ModuleDef::TypeAlias(it) => from_def_source(db, it), 133 hir::ModuleDef::TypeAlias(it) => from_def_source(db, it),
134 hir::ModuleDef::BuiltinType(it) => Some(it.to_string()), 134 hir::ModuleDef::BuiltinType(it) => Some(it.to_string()),
135 }, 135 },
136 SelfType(ty) => match ty.as_adt() {
137 Some((adt_def, _)) => match adt_def {
138 hir::Adt::Struct(it) => from_def_source(db, it),
139 hir::Adt::Union(it) => from_def_source(db, it),
140 hir::Adt::Enum(it) => from_def_source(db, it),
141 },
142 _ => None,
143 },
144 Local(_) => { 136 Local(_) => {
145 // Hover for these shows type names 137 // Hover for these shows type names
146 *no_fallback = true; 138 *no_fallback = true;
147 None 139 None
148 } 140 }
149 GenericParam(_) => { 141 GenericParam(_) | SelfType(_) => {
150 // FIXME: Hover for generic param 142 // FIXME: Hover for generic param
151 None 143 None
152 } 144 }
@@ -622,49 +614,52 @@ fn func(foo: i32) { if true { <|>foo; }; }
622 ", 614 ",
623 ); 615 );
624 let hover = analysis.hover(position).unwrap().unwrap(); 616 let hover = analysis.hover(position).unwrap().unwrap();
625 assert_eq!(trim_markup_opt(hover.info.first()), Some("struct Thing")); 617 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
626 assert_eq!(hover.info.is_exact(), true);
627
628 let (analysis, position) = single_file_with_position(
629 "
630 struct Thing { x: u32 }
631 impl Thing {
632 fn new() -> Self<|> {
633 Self { x: 0 }
634 }
635 }
636 ",
637 );
638 let hover = analysis.hover(position).unwrap().unwrap();
639 assert_eq!(trim_markup_opt(hover.info.first()), Some("struct Thing"));
640 assert_eq!(hover.info.is_exact(), true);
641
642 let (analysis, position) = single_file_with_position(
643 "
644 enum Thing { A }
645 impl Thing {
646 pub fn new() -> Self<|> {
647 Thing::A
648 }
649 }
650 ",
651 );
652 let hover = analysis.hover(position).unwrap().unwrap();
653 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing"));
654 assert_eq!(hover.info.is_exact(), true); 618 assert_eq!(hover.info.is_exact(), true);
655 619
656 let (analysis, position) = single_file_with_position( 620 /* FIXME: revive these tests
657 " 621 let (analysis, position) = single_file_with_position(
658 enum Thing { A } 622 "
659 impl Thing { 623 struct Thing { x: u32 }
660 pub fn thing(a: Self<|>) { 624 impl Thing {
661 } 625 fn new() -> Self<|> {
662 } 626 Self { x: 0 }
663 ", 627 }
664 ); 628 }
665 let hover = analysis.hover(position).unwrap().unwrap(); 629 ",
666 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); 630 );
667 assert_eq!(hover.info.is_exact(), true); 631
632 let hover = analysis.hover(position).unwrap().unwrap();
633 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
634 assert_eq!(hover.info.is_exact(), true);
635
636 let (analysis, position) = single_file_with_position(
637 "
638 enum Thing { A }
639 impl Thing {
640 pub fn new() -> Self<|> {
641 Thing::A
642 }
643 }
644 ",
645 );
646 let hover = analysis.hover(position).unwrap().unwrap();
647 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing"));
648 assert_eq!(hover.info.is_exact(), true);
649
650 let (analysis, position) = single_file_with_position(
651 "
652 enum Thing { A }
653 impl Thing {
654 pub fn thing(a: Self<|>) {
655 }
656 }
657 ",
658 );
659 let hover = analysis.hover(position).unwrap().unwrap();
660 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing"));
661 assert_eq!(hover.info.is_exact(), true);
662 */
668 } 663 }
669 664
670 #[test] 665 #[test]
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide/src/impls.rs
index 3e3012559..aa480e399 100644
--- a/crates/ra_ide_api/src/impls.rs
+++ b/crates/ra_ide/src/impls.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{db::HirDatabase, ApplicationTy, FromSource, Ty, TypeCtor}; 3use hir::{FromSource, ImplBlock};
4use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
5use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; 5use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
6 6
@@ -49,15 +49,19 @@ fn impls_for_def(
49 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; 49 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() };
50 hir::Enum::from_source(db, src)?.ty(db) 50 hir::Enum::from_source(db, src)?.ty(db)
51 } 51 }
52 ast::NominalDef::UnionDef(def) => {
53 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() };
54 hir::Union::from_source(db, src)?.ty(db)
55 }
52 }; 56 };
53 57
54 let krate = module.krate(); 58 let krate = module.krate();
55 let impls = db.impls_in_crate(krate); 59 let impls = ImplBlock::all_in_crate(db, krate);
56 60
57 Some( 61 Some(
58 impls 62 impls
59 .all_impls() 63 .into_iter()
60 .filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db))) 64 .filter(|impl_block| ty.is_equal_for_find_impls(&impl_block.target_ty(db)))
61 .map(|imp| imp.to_nav(db)) 65 .map(|imp| imp.to_nav(db))
62 .collect(), 66 .collect(),
63 ) 67 )
@@ -73,22 +77,9 @@ fn impls_for_trait(
73 let tr = hir::Trait::from_source(db, src)?; 77 let tr = hir::Trait::from_source(db, src)?;
74 78
75 let krate = module.krate(); 79 let krate = module.krate();
76 let impls = db.impls_in_crate(krate); 80 let impls = ImplBlock::for_trait(db, krate, tr);
77 81
78 Some(impls.lookup_impl_blocks_for_trait(tr).map(|imp| imp.to_nav(db)).collect()) 82 Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect())
79}
80
81fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool {
82 match (original_ty, impl_ty) {
83 (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor {
84 TypeCtor::Ref(..) => match parameters.as_single() {
85 Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor,
86 _ => false,
87 },
88 _ => a_original_ty.ctor == *ctor,
89 },
90 _ => false,
91 }
92} 83}
93 84
94#[cfg(test)] 85#[cfg(test)]
diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index 24a7ca5e7..45149bf0c 100644
--- a/crates/ra_ide_api/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -1,7 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use crate::{db::RootDatabase, FileId}; 3use crate::{db::RootDatabase, FileId};
4use hir::{HirDisplay, SourceAnalyzer, Ty}; 4use hir::{HirDisplay, SourceAnalyzer};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, AstNode, TypeAscriptionOwner}, 6 ast::{self, AstNode, TypeAscriptionOwner},
7 match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange, 7 match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange,
@@ -100,8 +100,11 @@ fn get_pat_type_hints(
100 .into_iter() 100 .into_iter()
101 .filter(|pat| !skip_root_pat_hint || pat != original_pat) 101 .filter(|pat| !skip_root_pat_hint || pat != original_pat)
102 .filter_map(|pat| { 102 .filter_map(|pat| {
103 get_node_displayable_type(db, &analyzer, &pat) 103 let ty = analyzer.type_of_pat(db, &pat)?;
104 .map(|pat_type| (pat.syntax().text_range(), pat_type)) 104 if ty.is_unknown() {
105 return None;
106 }
107 Some((pat.syntax().text_range(), ty))
105 }) 108 })
106 .map(|(range, pat_type)| InlayHint { 109 .map(|(range, pat_type)| InlayHint {
107 range, 110 range,
@@ -158,20 +161,6 @@ fn get_leaf_pats(root_pat: ast::Pat) -> Vec<ast::Pat> {
158 leaf_pats 161 leaf_pats
159} 162}
160 163
161fn get_node_displayable_type(
162 db: &RootDatabase,
163 analyzer: &SourceAnalyzer,
164 node_pat: &ast::Pat,
165) -> Option<Ty> {
166 analyzer.type_of_pat(db, node_pat).and_then(|resolved_type| {
167 if let Ty::Apply(_) = resolved_type {
168 Some(resolved_type)
169 } else {
170 None
171 }
172 })
173}
174
175#[cfg(test)] 164#[cfg(test)]
176mod tests { 165mod tests {
177 use crate::mock_analysis::single_file; 166 use crate::mock_analysis::single_file;
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs
index 7deeb3494..7deeb3494 100644
--- a/crates/ra_ide_api/src/join_lines.rs
+++ b/crates/ra_ide/src/join_lines.rs
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide/src/lib.rs
index cb6c24eaa..d1bff4a76 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -1,4 +1,4 @@
1//! ra_ide_api crate provides "ide-centric" APIs for the rust-analyzer. That is, 1//! ra_ide crate provides "ide-centric" APIs for the rust-analyzer. That is,
2//! it generally operates with files and text ranges, and returns results as 2//! it generally operates with files and text ranges, and returns results as
3//! Strings, suitable for displaying to the human. 3//! Strings, suitable for displaying to the human.
4//! 4//!
diff --git a/crates/ra_ide_api/src/line_index.rs b/crates/ra_ide/src/line_index.rs
index 710890d27..710890d27 100644
--- a/crates/ra_ide_api/src/line_index.rs
+++ b/crates/ra_ide/src/line_index.rs
diff --git a/crates/ra_ide_api/src/line_index_utils.rs b/crates/ra_ide/src/line_index_utils.rs
index bd1e08feb..bd1e08feb 100644
--- a/crates/ra_ide_api/src/line_index_utils.rs
+++ b/crates/ra_ide/src/line_index_utils.rs
diff --git a/crates/ra_ide_api/src/marks.rs b/crates/ra_ide/src/marks.rs
index 848ae4dc7..848ae4dc7 100644
--- a/crates/ra_ide_api/src/marks.rs
+++ b/crates/ra_ide/src/marks.rs
diff --git a/crates/ra_ide_api/src/matching_brace.rs b/crates/ra_ide/src/matching_brace.rs
index d1204fac0..d1204fac0 100644
--- a/crates/ra_ide_api/src/matching_brace.rs
+++ b/crates/ra_ide/src/matching_brace.rs
diff --git a/crates/ra_ide_api/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs
index bf8a54932..bf8a54932 100644
--- a/crates/ra_ide_api/src/mock_analysis.rs
+++ b/crates/ra_ide/src/mock_analysis.rs
diff --git a/crates/ra_ide_api/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs
index 6027e7d54..6027e7d54 100644
--- a/crates/ra_ide_api/src/parent_module.rs
+++ b/crates/ra_ide/src/parent_module.rs
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide/src/references.rs
index cb343e59a..21a1ea69e 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -83,10 +83,7 @@ pub(crate) fn find_all_refs(
83 NameKind::Field(field) => field.to_nav(db), 83 NameKind::Field(field) => field.to_nav(db),
84 NameKind::AssocItem(assoc) => assoc.to_nav(db), 84 NameKind::AssocItem(assoc) => assoc.to_nav(db),
85 NameKind::Def(def) => NavigationTarget::from_def(db, def)?, 85 NameKind::Def(def) => NavigationTarget::from_def(db, def)?,
86 NameKind::SelfType(ref ty) => match ty.as_adt() { 86 NameKind::SelfType(imp) => imp.to_nav(db),
87 Some((adt, _)) => adt.to_nav(db),
88 None => return None,
89 },
90 NameKind::Local(local) => local.to_nav(db), 87 NameKind::Local(local) => local.to_nav(db),
91 NameKind::GenericParam(_) => return None, 88 NameKind::GenericParam(_) => return None,
92 }; 89 };
diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs
index cab06dea9..5cea805ec 100644
--- a/crates/ra_ide_api/src/references/classify.rs
+++ b/crates/ra_ide/src/references/classify.rs
@@ -152,7 +152,7 @@ pub(crate) fn classify_name_ref(
152 152
153 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { 153 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
154 tested_by!(goto_definition_works_for_macros); 154 tested_by!(goto_definition_works_for_macros);
155 if let Some(macro_def) = analyzer.resolve_macro_call(db, &macro_call) { 155 if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(&macro_call)) {
156 let kind = NameKind::Macro(macro_def); 156 let kind = NameKind::Macro(macro_def);
157 return Some(NameDefinition { kind, container, visibility }); 157 return Some(NameDefinition { kind, container, visibility });
158 } 158 }
@@ -178,8 +178,7 @@ pub(crate) fn classify_name_ref(
178 Some(NameDefinition { kind, container, visibility }) 178 Some(NameDefinition { kind, container, visibility })
179 } 179 }
180 PathResolution::SelfType(impl_block) => { 180 PathResolution::SelfType(impl_block) => {
181 let ty = impl_block.target_ty(db); 181 let kind = NameKind::SelfType(impl_block);
182 let kind = NameKind::SelfType(ty);
183 let container = impl_block.module(db); 182 let container = impl_block.module(db);
184 Some(NameDefinition { kind, container, visibility }) 183 Some(NameDefinition { kind, container, visibility })
185 } 184 }
diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide/src/references/name_definition.rs
index aca23f79e..10d3a2364 100644
--- a/crates/ra_ide_api/src/references/name_definition.rs
+++ b/crates/ra_ide/src/references/name_definition.rs
@@ -4,8 +4,8 @@
4//! Note that the reference search is possible for not all of the classified items. 4//! Note that the reference search is possible for not all of the classified items.
5 5
6use hir::{ 6use hir::{
7 Adt, AssocItem, GenericParam, HasSource, Local, MacroDef, Module, ModuleDef, StructField, Ty, 7 Adt, AssocItem, GenericParam, HasSource, ImplBlock, Local, MacroDef, Module, ModuleDef,
8 VariantDef, 8 StructField, VariantDef,
9}; 9};
10use ra_syntax::{ast, ast::VisibilityOwner}; 10use ra_syntax::{ast, ast::VisibilityOwner};
11 11
@@ -17,7 +17,7 @@ pub enum NameKind {
17 Field(StructField), 17 Field(StructField),
18 AssocItem(AssocItem), 18 AssocItem(AssocItem),
19 Def(ModuleDef), 19 Def(ModuleDef),
20 SelfType(Ty), 20 SelfType(ImplBlock),
21 Local(Local), 21 Local(Local),
22 GenericParam(GenericParam), 22 GenericParam(GenericParam),
23} 23}
@@ -46,6 +46,7 @@ pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDe
46 let container = parent.module(db); 46 let container = parent.module(db);
47 let visibility = match parent { 47 let visibility = match parent {
48 VariantDef::Struct(s) => s.source(db).value.visibility(), 48 VariantDef::Struct(s) => s.source(db).value.visibility(),
49 VariantDef::Union(e) => e.source(db).value.visibility(),
49 VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), 50 VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(),
50 }; 51 };
51 NameDefinition { kind, container, visibility } 52 NameDefinition { kind, container, visibility }
diff --git a/crates/ra_ide_api/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs
index d58496049..d58496049 100644
--- a/crates/ra_ide_api/src/references/rename.rs
+++ b/crates/ra_ide/src/references/rename.rs
diff --git a/crates/ra_ide_api/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs
index f5c9589f4..f5c9589f4 100644
--- a/crates/ra_ide_api/src/references/search_scope.rs
+++ b/crates/ra_ide/src/references/search_scope.rs
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index 8039a5164..8039a5164 100644
--- a/crates/ra_ide_api/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
diff --git a/crates/ra_ide_api/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index b39c4d371..b39c4d371 100644
--- a/crates/ra_ide_api/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
diff --git a/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
index 79f11ea80..79f11ea80 100644
--- a/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html
+++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
diff --git a/crates/ra_ide_api/src/source_change.rs b/crates/ra_ide/src/source_change.rs
index f5f7f8807..f5f7f8807 100644
--- a/crates/ra_ide_api/src/source_change.rs
+++ b/crates/ra_ide/src/source_change.rs
diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide/src/status.rs
index 1bb27eb85..1bb27eb85 100644
--- a/crates/ra_ide_api/src/status.rs
+++ b/crates/ra_ide/src/status.rs
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide/src/symbol_index.rs
index 5729eb5b3..5729eb5b3 100644
--- a/crates/ra_ide_api/src/symbol_index.rs
+++ b/crates/ra_ide/src/symbol_index.rs
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 2b653fe8f..9a3e4c82f 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -2,7 +2,7 @@
2 2
3use rustc_hash::{FxHashMap, FxHashSet}; 3use rustc_hash::{FxHashMap, FxHashSet};
4 4
5use hir::{Mutability, Name, Source}; 5use hir::{Name, Source};
6use ra_db::SourceDatabase; 6use ra_db::SourceDatabase;
7use ra_prof::profile; 7use ra_prof::profile;
8use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T}; 8use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T};
@@ -230,11 +230,10 @@ fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str {
230 Local(local) => { 230 Local(local) => {
231 if local.is_mut(db) { 231 if local.is_mut(db) {
232 "variable.mut" 232 "variable.mut"
233 } else if local.ty(db).is_mutable_reference() {
234 "variable.mut"
233 } else { 235 } else {
234 match local.ty(db).as_reference() { 236 "variable"
235 Some((_, Mutability::Mut)) => "variable.mut",
236 _ => "variable",
237 }
238 } 237 }
239 } 238 }
240 } 239 }
@@ -307,7 +306,7 @@ fn main() {
307"# 306"#
308 .trim(), 307 .trim(),
309 ); 308 );
310 let dst_file = project_dir().join("crates/ra_ide_api/src/snapshots/highlighting.html"); 309 let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlighting.html");
311 let actual_html = &analysis.highlight_as_html(file_id, false).unwrap(); 310 let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
312 let expected_html = &read_text(&dst_file); 311 let expected_html = &read_text(&dst_file);
313 std::fs::write(dst_file, &actual_html).unwrap(); 312 std::fs::write(dst_file, &actual_html).unwrap();
@@ -333,8 +332,7 @@ fn bar() {
333"# 332"#
334 .trim(), 333 .trim(),
335 ); 334 );
336 let dst_file = 335 let dst_file = project_dir().join("crates/ra_ide/src/snapshots/rainbow_highlighting.html");
337 project_dir().join("crates/ra_ide_api/src/snapshots/rainbow_highlighting.html");
338 let actual_html = &analysis.highlight_as_html(file_id, true).unwrap(); 336 let actual_html = &analysis.highlight_as_html(file_id, true).unwrap();
339 let expected_html = &read_text(&dst_file); 337 let expected_html = &read_text(&dst_file);
340 std::fs::write(dst_file, &actual_html).unwrap(); 338 std::fs::write(dst_file, &actual_html).unwrap();
diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs
index 4d0f0fc47..4d0f0fc47 100644
--- a/crates/ra_ide_api/src/syntax_tree.rs
+++ b/crates/ra_ide/src/syntax_tree.rs
diff --git a/crates/ra_ide_api/src/test_utils.rs b/crates/ra_ide/src/test_utils.rs
index 8adb214d4..8adb214d4 100644
--- a/crates/ra_ide_api/src/test_utils.rs
+++ b/crates/ra_ide/src/test_utils.rs
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide/src/typing.rs
index 21e5be9b3..21e5be9b3 100644
--- a/crates/ra_ide_api/src/typing.rs
+++ b/crates/ra_ide/src/typing.rs
diff --git a/crates/ra_ide_api/src/wasm_shims.rs b/crates/ra_ide/src/wasm_shims.rs
index 088cc9be4..088cc9be4 100644
--- a/crates/ra_ide_api/src/wasm_shims.rs
+++ b/crates/ra_ide/src/wasm_shims.rs
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml
index 72dbe06dc..21aef842c 100644
--- a/crates/ra_lsp_server/Cargo.toml
+++ b/crates/ra_lsp_server/Cargo.toml
@@ -17,12 +17,12 @@ flexi_logger = "0.14.0"
17log = "0.4.3" 17log = "0.4.3"
18lsp-types = { version = "0.61.0", features = ["proposed"] } 18lsp-types = { version = "0.61.0", features = ["proposed"] }
19rustc-hash = "1.0" 19rustc-hash = "1.0"
20parking_lot = "0.9.0" 20parking_lot = "0.10.0"
21jod-thread = "0.1.0" 21jod-thread = "0.1.0"
22ra_vfs = "0.5.0" 22ra_vfs = "0.5.0"
23ra_syntax = { path = "../ra_syntax" } 23ra_syntax = { path = "../ra_syntax" }
24ra_text_edit = { path = "../ra_text_edit" } 24ra_text_edit = { path = "../ra_text_edit" }
25ra_ide_api = { path = "../ra_ide_api" } 25ra_ide = { path = "../ra_ide" }
26lsp-server = "0.3.0" 26lsp-server = "0.3.0"
27ra_project_model = { path = "../ra_project_model" } 27ra_project_model = { path = "../ra_project_model" }
28ra_prof = { path = "../ra_prof" } 28ra_prof = { path = "../ra_prof" }
diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs
index d996b53de..c4a9e7101 100644
--- a/crates/ra_lsp_server/src/cargo_target_spec.rs
+++ b/crates/ra_lsp_server/src/cargo_target_spec.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use ra_ide_api::{FileId, RunnableKind}; 3use ra_ide::{FileId, RunnableKind};
4use ra_project_model::{self, ProjectWorkspace, TargetKind}; 4use ra_project_model::{self, ProjectWorkspace, TargetKind};
5 5
6use crate::{world::WorldSnapshot, Result}; 6use crate::{world::WorldSnapshot, Result};
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index 94ed619fa..b13093cfe 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -6,7 +6,7 @@ use lsp_types::{
6 SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem, 6 SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem,
7 TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit, 7 TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit,
8}; 8};
9use ra_ide_api::{ 9use ra_ide::{
10 translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, 10 translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition,
11 FileRange, FileSystemEdit, Fold, FoldKind, InsertTextFormat, LineCol, LineIndex, 11 FileRange, FileSystemEdit, Fold, FoldKind, InsertTextFormat, LineCol, LineIndex,
12 NavigationTarget, RangeInfo, Severity, SourceChange, SourceFileEdit, 12 NavigationTarget, RangeInfo, Severity, SourceChange, SourceFileEdit,
@@ -173,7 +173,7 @@ impl ConvWith<&LineIndex> for Range {
173 } 173 }
174} 174}
175 175
176impl Conv for ra_ide_api::Documentation { 176impl Conv for ra_ide::Documentation {
177 type Output = lsp_types::Documentation; 177 type Output = lsp_types::Documentation;
178 fn conv(self) -> Documentation { 178 fn conv(self) -> Documentation {
179 Documentation::MarkupContent(MarkupContent { 179 Documentation::MarkupContent(MarkupContent {
@@ -183,7 +183,7 @@ impl Conv for ra_ide_api::Documentation {
183 } 183 }
184} 184}
185 185
186impl Conv for ra_ide_api::FunctionSignature { 186impl Conv for ra_ide::FunctionSignature {
187 type Output = lsp_types::SignatureInformation; 187 type Output = lsp_types::SignatureInformation;
188 fn conv(self) -> Self::Output { 188 fn conv(self) -> Self::Output {
189 use lsp_types::{ParameterInformation, ParameterLabel, SignatureInformation}; 189 use lsp_types::{ParameterInformation, ParameterLabel, SignatureInformation};
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs
index 9c36402b0..2ca149fd5 100644
--- a/crates/ra_lsp_server/src/lib.rs
+++ b/crates/ra_lsp_server/src/lib.rs
@@ -1,6 +1,6 @@
1//! Implementation of the LSP for rust-analyzer. 1//! Implementation of the LSP for rust-analyzer.
2//! 2//!
3//! This crate takes Rust-specific analysis results from ra_ide_api and 3//! This crate takes Rust-specific analysis results from ra_ide and
4//! translates into LSP types. 4//! translates into LSP types.
5//! 5//!
6//! It also is the root of all state. `world` module defines the bulk of the 6//! It also is the root of all state. `world` module defines the bulk of the
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 0dc0aeee8..83845f1e0 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -9,7 +9,7 @@ use std::{error::Error, fmt, panic, path::PathBuf, sync::Arc, time::Instant};
9use crossbeam_channel::{select, unbounded, RecvError, Sender}; 9use crossbeam_channel::{select, unbounded, RecvError, Sender};
10use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; 10use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
11use lsp_types::{ClientCapabilities, NumberOrString}; 11use lsp_types::{ClientCapabilities, NumberOrString};
12use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; 12use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId};
13use ra_prof::profile; 13use ra_prof::profile;
14use ra_vfs::{VfsTask, Watch}; 14use ra_vfs::{VfsTask, Watch};
15use relative_path::RelativePathBuf; 15use relative_path::RelativePathBuf;
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index e552f2106..c81fa7f67 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -9,7 +9,7 @@ use lsp_types::{
9 Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse, 9 Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse,
10 Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, 10 Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit,
11}; 11};
12use ra_ide_api::{ 12use ra_ide::{
13 AssistId, FileId, FilePosition, FileRange, Query, Runnable, RunnableKind, SearchScope, 13 AssistId, FileId, FilePosition, FileRange, Query, Runnable, RunnableKind, SearchScope,
14}; 14};
15use ra_prof::profile; 15use ra_prof::profile;
@@ -162,7 +162,7 @@ pub fn handle_on_type_formatting(
162 let line_index = world.analysis().file_line_index(position.file_id)?; 162 let line_index = world.analysis().file_line_index(position.file_id)?;
163 let line_endings = world.file_line_endings(position.file_id); 163 let line_endings = world.file_line_endings(position.file_id);
164 164
165 // in `ra_ide_api`, the `on_type` invariant is that 165 // in `ra_ide`, the `on_type` invariant is that
166 // `text.char_at(position) == typed_char`. 166 // `text.char_at(position) == typed_char`.
167 position.offset = position.offset - TextUnit::of_char('.'); 167 position.offset = position.offset - TextUnit::of_char('.');
168 let char_typed = params.ch.chars().next().unwrap_or('\0'); 168 let char_typed = params.ch.chars().next().unwrap_or('\0');
@@ -894,7 +894,7 @@ pub fn handle_inlay_hints(
894 label: api_type.label.to_string(), 894 label: api_type.label.to_string(),
895 range: api_type.range.conv_with(&line_index), 895 range: api_type.range.conv_with(&line_index),
896 kind: match api_type.kind { 896 kind: match api_type.kind {
897 ra_ide_api::InlayKind::TypeHint => InlayKind::TypeHint, 897 ra_ide::InlayKind::TypeHint => InlayKind::TypeHint,
898 }, 898 },
899 }) 899 })
900 .collect()) 900 .collect())
diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs
index 3856263b0..609b2adcc 100644
--- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs
+++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use ra_ide_api::FileId; 3use ra_ide::FileId;
4use rustc_hash::FxHashSet; 4use rustc_hash::FxHashSet;
5 5
6#[derive(Default, Debug)] 6#[derive(Default, Debug)]
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs
index 9bdea70c7..927449b45 100644
--- a/crates/ra_lsp_server/src/world.rs
+++ b/crates/ra_lsp_server/src/world.rs
@@ -9,7 +9,7 @@ use crossbeam_channel::{unbounded, Receiver};
9use lsp_server::ErrorCode; 9use lsp_server::ErrorCode;
10use lsp_types::Url; 10use lsp_types::Url;
11use parking_lot::RwLock; 11use parking_lot::RwLock;
12use ra_ide_api::{ 12use ra_ide::{
13 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FeatureFlags, FileId, LibraryData, 13 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FeatureFlags, FileId, LibraryData,
14 SourceRootId, 14 SourceRootId,
15}; 15};
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 85f7eeb00..370990e21 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -1,13 +1,13 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3mod consts; 3mod consts;
4mod nominal; 4mod adt;
5mod traits; 5mod traits;
6mod use_item; 6mod use_item;
7 7
8pub(crate) use self::{ 8pub(crate) use self::{
9 adt::{enum_variant_list, record_field_def_list},
9 expressions::{match_arm_list, record_field_list}, 10 expressions::{match_arm_list, record_field_list},
10 nominal::{enum_variant_list, record_field_def_list},
11 traits::{impl_item_list, trait_item_list}, 11 traits::{impl_item_list, trait_item_list},
12 use_item::use_tree_list, 12 use_item::use_tree_list,
13}; 13};
@@ -247,7 +247,7 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
247 // a: i32, 247 // a: i32,
248 // b: f32, 248 // b: f32,
249 // } 249 // }
250 nominal::struct_def(p, m, T![struct]); 250 adt::struct_def(p, m);
251 } 251 }
252 IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { 252 IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => {
253 // test union_items 253 // test union_items
@@ -256,9 +256,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
256 // a: i32, 256 // a: i32,
257 // b: f32, 257 // b: f32,
258 // } 258 // }
259 nominal::struct_def(p, m, T![union]); 259 adt::union_def(p, m);
260 } 260 }
261 T![enum] => nominal::enum_def(p, m), 261 T![enum] => adt::enum_def(p, m),
262 T![use] => use_item::use_item(p, m), 262 T![use] => use_item::use_item(p, m),
263 T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::const_def(p, m), 263 T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::const_def(p, m),
264 T![static] => consts::static_def(p, m), 264 T![static] => consts::static_def(p, m),
diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/adt.rs
index 9d8fb8486..c777bc9d0 100644
--- a/crates/ra_parser/src/grammar/items/nominal.rs
+++ b/crates/ra_parser/src/grammar/items/adt.rs
@@ -2,10 +2,19 @@
2 2
3use super::*; 3use super::*;
4 4
5pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { 5pub(super) fn struct_def(p: &mut Parser, m: Marker) {
6 assert!(p.at(T![struct]) || p.at_contextual_kw("union")); 6 assert!(p.at(T![struct]));
7 p.bump_remap(kind); 7 p.bump(T![struct]);
8 struct_or_union(p, m, T![struct], STRUCT_DEF);
9}
10
11pub(super) fn union_def(p: &mut Parser, m: Marker) {
12 assert!(p.at_contextual_kw("union"));
13 p.bump_remap(T![union]);
14 struct_or_union(p, m, T![union], UNION_DEF);
15}
8 16
17fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
9 name_r(p, ITEM_RECOVERY_SET); 18 name_r(p, ITEM_RECOVERY_SET);
10 type_params::opt_type_param_list(p); 19 type_params::opt_type_param_list(p);
11 match p.current() { 20 match p.current() {
@@ -22,11 +31,11 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
22 } 31 }
23 } 32 }
24 } 33 }
25 T![;] if kind == T![struct] => { 34 T![;] if kw == T![struct] => {
26 p.bump(T![;]); 35 p.bump(T![;]);
27 } 36 }
28 T!['{'] => record_field_def_list(p), 37 T!['{'] => record_field_def_list(p),
29 T!['('] if kind == T![struct] => { 38 T!['('] if kw == T![struct] => {
30 tuple_field_def_list(p); 39 tuple_field_def_list(p);
31 // test tuple_struct_where 40 // test tuple_struct_where
32 // struct Test<T>(T) where T: Clone; 41 // struct Test<T>(T) where T: Clone;
@@ -34,14 +43,14 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
34 type_params::opt_where_clause(p); 43 type_params::opt_where_clause(p);
35 p.expect(T![;]); 44 p.expect(T![;]);
36 } 45 }
37 _ if kind == T![struct] => { 46 _ if kw == T![struct] => {
38 p.error("expected `;`, `{`, or `(`"); 47 p.error("expected `;`, `{`, or `(`");
39 } 48 }
40 _ => { 49 _ => {
41 p.error("expected `{`"); 50 p.error("expected `{`");
42 } 51 }
43 } 52 }
44 m.complete(p, STRUCT_DEF); 53 m.complete(p, def);
45} 54}
46 55
47pub(super) fn enum_def(p: &mut Parser, m: Marker) { 56pub(super) fn enum_def(p: &mut Parser, m: Marker) {
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index 96b5bce88..fe0fcdb33 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -122,6 +122,7 @@ pub enum SyntaxKind {
122 R_DOLLAR, 122 R_DOLLAR,
123 SOURCE_FILE, 123 SOURCE_FILE,
124 STRUCT_DEF, 124 STRUCT_DEF,
125 UNION_DEF,
125 ENUM_DEF, 126 ENUM_DEF,
126 FN_DEF, 127 FN_DEF,
127 RET_TYPE, 128 RET_TYPE,
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index 513ed7920..a8f625176 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -196,17 +196,6 @@ impl StructKind {
196} 196}
197 197
198impl ast::StructDef { 198impl ast::StructDef {
199 pub fn is_union(&self) -> bool {
200 for child in self.syntax().children_with_tokens() {
201 match child.kind() {
202 T![struct] => return false,
203 T![union] => return true,
204 _ => (),
205 }
206 }
207 false
208 }
209
210 pub fn kind(&self) -> StructKind { 199 pub fn kind(&self) -> StructKind {
211 StructKind::from_node(self) 200 StructKind::from_node(self)
212 } 201 }
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index de506d7cd..c06076e3d 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -1856,6 +1856,7 @@ impl Module {
1856#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1856#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1857pub enum ModuleItem { 1857pub enum ModuleItem {
1858 StructDef(StructDef), 1858 StructDef(StructDef),
1859 UnionDef(UnionDef),
1859 EnumDef(EnumDef), 1860 EnumDef(EnumDef),
1860 FnDef(FnDef), 1861 FnDef(FnDef),
1861 TraitDef(TraitDef), 1862 TraitDef(TraitDef),
@@ -1872,6 +1873,11 @@ impl From<StructDef> for ModuleItem {
1872 ModuleItem::StructDef(node) 1873 ModuleItem::StructDef(node)
1873 } 1874 }
1874} 1875}
1876impl From<UnionDef> for ModuleItem {
1877 fn from(node: UnionDef) -> ModuleItem {
1878 ModuleItem::UnionDef(node)
1879 }
1880}
1875impl From<EnumDef> for ModuleItem { 1881impl From<EnumDef> for ModuleItem {
1876 fn from(node: EnumDef) -> ModuleItem { 1882 fn from(node: EnumDef) -> ModuleItem {
1877 ModuleItem::EnumDef(node) 1883 ModuleItem::EnumDef(node)
@@ -1925,14 +1931,15 @@ impl From<Module> for ModuleItem {
1925impl AstNode for ModuleItem { 1931impl AstNode for ModuleItem {
1926 fn can_cast(kind: SyntaxKind) -> bool { 1932 fn can_cast(kind: SyntaxKind) -> bool {
1927 match kind { 1933 match kind {
1928 STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_BLOCK | USE_ITEM 1934 STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF
1929 | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true, 1935 | IMPL_BLOCK | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true,
1930 _ => false, 1936 _ => false,
1931 } 1937 }
1932 } 1938 }
1933 fn cast(syntax: SyntaxNode) -> Option<Self> { 1939 fn cast(syntax: SyntaxNode) -> Option<Self> {
1934 let res = match syntax.kind() { 1940 let res = match syntax.kind() {
1935 STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }), 1941 STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }),
1942 UNION_DEF => ModuleItem::UnionDef(UnionDef { syntax }),
1936 ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }), 1943 ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }),
1937 FN_DEF => ModuleItem::FnDef(FnDef { syntax }), 1944 FN_DEF => ModuleItem::FnDef(FnDef { syntax }),
1938 TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }), 1945 TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }),
@@ -1950,6 +1957,7 @@ impl AstNode for ModuleItem {
1950 fn syntax(&self) -> &SyntaxNode { 1957 fn syntax(&self) -> &SyntaxNode {
1951 match self { 1958 match self {
1952 ModuleItem::StructDef(it) => &it.syntax, 1959 ModuleItem::StructDef(it) => &it.syntax,
1960 ModuleItem::UnionDef(it) => &it.syntax,
1953 ModuleItem::EnumDef(it) => &it.syntax, 1961 ModuleItem::EnumDef(it) => &it.syntax,
1954 ModuleItem::FnDef(it) => &it.syntax, 1962 ModuleItem::FnDef(it) => &it.syntax,
1955 ModuleItem::TraitDef(it) => &it.syntax, 1963 ModuleItem::TraitDef(it) => &it.syntax,
@@ -2038,6 +2046,7 @@ impl NeverType {}
2038pub enum NominalDef { 2046pub enum NominalDef {
2039 StructDef(StructDef), 2047 StructDef(StructDef),
2040 EnumDef(EnumDef), 2048 EnumDef(EnumDef),
2049 UnionDef(UnionDef),
2041} 2050}
2042impl From<StructDef> for NominalDef { 2051impl From<StructDef> for NominalDef {
2043 fn from(node: StructDef) -> NominalDef { 2052 fn from(node: StructDef) -> NominalDef {
@@ -2049,10 +2058,15 @@ impl From<EnumDef> for NominalDef {
2049 NominalDef::EnumDef(node) 2058 NominalDef::EnumDef(node)
2050 } 2059 }
2051} 2060}
2061impl From<UnionDef> for NominalDef {
2062 fn from(node: UnionDef) -> NominalDef {
2063 NominalDef::UnionDef(node)
2064 }
2065}
2052impl AstNode for NominalDef { 2066impl AstNode for NominalDef {
2053 fn can_cast(kind: SyntaxKind) -> bool { 2067 fn can_cast(kind: SyntaxKind) -> bool {
2054 match kind { 2068 match kind {
2055 STRUCT_DEF | ENUM_DEF => true, 2069 STRUCT_DEF | ENUM_DEF | UNION_DEF => true,
2056 _ => false, 2070 _ => false,
2057 } 2071 }
2058 } 2072 }
@@ -2060,6 +2074,7 @@ impl AstNode for NominalDef {
2060 let res = match syntax.kind() { 2074 let res = match syntax.kind() {
2061 STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }), 2075 STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }),
2062 ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }), 2076 ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }),
2077 UNION_DEF => NominalDef::UnionDef(UnionDef { syntax }),
2063 _ => return None, 2078 _ => return None,
2064 }; 2079 };
2065 Some(res) 2080 Some(res)
@@ -2068,6 +2083,7 @@ impl AstNode for NominalDef {
2068 match self { 2083 match self {
2069 NominalDef::StructDef(it) => &it.syntax, 2084 NominalDef::StructDef(it) => &it.syntax,
2070 NominalDef::EnumDef(it) => &it.syntax, 2085 NominalDef::EnumDef(it) => &it.syntax,
2086 NominalDef::UnionDef(it) => &it.syntax,
2071 } 2087 }
2072 } 2088 }
2073} 2089}
@@ -3789,6 +3805,38 @@ impl AstNode for TypeRef {
3789} 3805}
3790impl TypeRef {} 3806impl TypeRef {}
3791#[derive(Debug, Clone, PartialEq, Eq, Hash)] 3807#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3808pub struct UnionDef {
3809 pub(crate) syntax: SyntaxNode,
3810}
3811impl AstNode for UnionDef {
3812 fn can_cast(kind: SyntaxKind) -> bool {
3813 match kind {
3814 UNION_DEF => true,
3815 _ => false,
3816 }
3817 }
3818 fn cast(syntax: SyntaxNode) -> Option<Self> {
3819 if Self::can_cast(syntax.kind()) {
3820 Some(Self { syntax })
3821 } else {
3822 None
3823 }
3824 }
3825 fn syntax(&self) -> &SyntaxNode {
3826 &self.syntax
3827 }
3828}
3829impl ast::VisibilityOwner for UnionDef {}
3830impl ast::NameOwner for UnionDef {}
3831impl ast::TypeParamsOwner for UnionDef {}
3832impl ast::AttrsOwner for UnionDef {}
3833impl ast::DocCommentsOwner for UnionDef {}
3834impl UnionDef {
3835 pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
3836 AstChildren::new(&self.syntax).next()
3837 }
3838}
3839#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3792pub struct UseItem { 3840pub struct UseItem {
3793 pub(crate) syntax: SyntaxNode, 3841 pub(crate) syntax: SyntaxNode,
3794} 3842}
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 88d1dc109..d1be40abe 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -126,6 +126,7 @@ Grammar(
126 "SOURCE_FILE", 126 "SOURCE_FILE",
127 127
128 "STRUCT_DEF", 128 "STRUCT_DEF",
129 "UNION_DEF",
129 "ENUM_DEF", 130 "ENUM_DEF",
130 "FN_DEF", 131 "FN_DEF",
131 "RET_TYPE", 132 "RET_TYPE",
@@ -285,6 +286,16 @@ Grammar(
285 "DocCommentsOwner" 286 "DocCommentsOwner"
286 ] 287 ]
287 ), 288 ),
289 "UnionDef": (
290 traits: [
291 "VisibilityOwner",
292 "NameOwner",
293 "TypeParamsOwner",
294 "AttrsOwner",
295 "DocCommentsOwner"
296 ],
297 options: ["RecordFieldDefList"],
298 ),
288 "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), 299 "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]),
289 "RecordFieldDef": ( 300 "RecordFieldDef": (
290 traits: [ 301 traits: [
@@ -388,7 +399,7 @@ Grammar(
388 ]), 399 ]),
389 400
390 "NominalDef": ( 401 "NominalDef": (
391 enum: ["StructDef", "EnumDef"], 402 enum: ["StructDef", "EnumDef", "UnionDef"],
392 traits: [ 403 traits: [
393 "NameOwner", 404 "NameOwner",
394 "TypeParamsOwner", 405 "TypeParamsOwner",
@@ -396,9 +407,9 @@ Grammar(
396 ], 407 ],
397 ), 408 ),
398 "ModuleItem": ( 409 "ModuleItem": (
399 enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", 410 enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock",
400 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ], 411 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ],
401 traits: ["AttrsOwner"] 412 traits: ["AttrsOwner"],
402 ), 413 ),
403 "ImplItem": ( 414 "ImplItem": (
404 enum: ["FnDef", "TypeAliasDef", "ConstDef"], 415 enum: ["FnDef", "TypeAliasDef", "ConstDef"],
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt
index f9ace02ee..9d7982684 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 51) 1SOURCE_FILE@[0; 51)
2 STRUCT_DEF@[0; 12) 2 UNION_DEF@[0; 12)
3 UNION_KW@[0; 5) "union" 3 UNION_KW@[0; 5) "union"
4 WHITESPACE@[5; 6) " " 4 WHITESPACE@[5; 6) " "
5 NAME@[6; 9) 5 NAME@[6; 9)
@@ -9,7 +9,7 @@ SOURCE_FILE@[0; 51)
9 L_CURLY@[10; 11) "{" 9 L_CURLY@[10; 11) "{"
10 R_CURLY@[11; 12) "}" 10 R_CURLY@[11; 12) "}"
11 WHITESPACE@[12; 13) "\n" 11 WHITESPACE@[12; 13) "\n"
12 STRUCT_DEF@[13; 50) 12 UNION_DEF@[13; 50)
13 UNION_KW@[13; 18) "union" 13 UNION_KW@[13; 18) "union"
14 WHITESPACE@[18; 19) " " 14 WHITESPACE@[18; 19) " "
15 NAME@[19; 22) 15 NAME@[19; 22)
diff --git a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt
index 3260cc589..90538b90d 100644
--- a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt
@@ -1592,7 +1592,7 @@ SOURCE_FILE@[0; 3813)
1592 BLOCK@[2845; 2906) 1592 BLOCK@[2845; 2906)
1593 L_CURLY@[2845; 2846) "{" 1593 L_CURLY@[2845; 2846) "{"
1594 WHITESPACE@[2846; 2851) "\n " 1594 WHITESPACE@[2846; 2851) "\n "
1595 STRUCT_DEF@[2851; 2904) 1595 UNION_DEF@[2851; 2904)
1596 UNION_KW@[2851; 2856) "union" 1596 UNION_KW@[2851; 2856) "union"
1597 WHITESPACE@[2856; 2857) " " 1597 WHITESPACE@[2856; 2857) " "
1598 NAME@[2857; 2862) 1598 NAME@[2857; 2862)
diff --git a/docs/dev/README.md b/docs/dev/README.md
index 0823ca09a..0f64d7e5f 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -14,7 +14,7 @@ To learn more about how rust-analyzer works, see
14 14
15We also publish rustdoc docs to pages: 15We also publish rustdoc docs to pages:
16 16
17https://rust-analyzer.github.io/rust-analyzer/ra_ide_api/ 17https://rust-analyzer.github.io/rust-analyzer/ra_ide/
18 18
19Various organizational and process issues are discussed in this document. 19Various organizational and process issues are discussed in this document.
20 20
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md
index 6fd396dee..629645757 100644
--- a/docs/dev/architecture.md
+++ b/docs/dev/architecture.md
@@ -106,7 +106,7 @@ guessing a HIR for a particular source position.
106 106
107Underneath, HIR works on top of salsa, using a `HirDatabase` trait. 107Underneath, HIR works on top of salsa, using a `HirDatabase` trait.
108 108
109### `crates/ra_ide_api` 109### `crates/ra_ide`
110 110
111A stateful library for analyzing many Rust files as they change. `AnalysisHost` 111A stateful library for analyzing many Rust files as they change. `AnalysisHost`
112is a mutable entity (clojure's atom) which holds the current state, incorporates 112is a mutable entity (clojure's atom) which holds the current state, incorporates
@@ -124,11 +124,11 @@ offsets and strings as output. This works on top of rich code model powered by
124 124
125### `crates/ra_lsp_server` 125### `crates/ra_lsp_server`
126 126
127An LSP implementation which wraps `ra_ide_api` into a language server protocol. 127An LSP implementation which wraps `ra_ide` into a language server protocol.
128 128
129### `ra_vfs` 129### `ra_vfs`
130 130
131Although `hir` and `ra_ide_api` don't do any IO, we need to be able to read 131Although `hir` and `ra_ide` don't do any IO, we need to be able to read
132files from disk at the end of the day. This is what `ra_vfs` does. It also 132files from disk at the end of the day. This is what `ra_vfs` does. It also
133manages overlays: "dirty" files in the editor, whose "true" contents is 133manages overlays: "dirty" files in the editor, whose "true" contents is
134different from data on disk. This is more or less the single really 134different from data on disk. This is more or less the single really
@@ -162,13 +162,13 @@ disk. For this reason, we try to avoid writing too many tests on this boundary:
162in a statically typed language, it's hard to make an error in the protocol 162in a statically typed language, it's hard to make an error in the protocol
163itself if messages are themselves typed. 163itself if messages are themselves typed.
164 164
165The middle, and most important, boundary is `ra_ide_api`. Unlike 165The middle, and most important, boundary is `ra_ide`. Unlike
166`ra_lsp_server`, which exposes API, `ide_api` uses Rust API and is intended to 166`ra_lsp_server`, which exposes API, `ide` uses Rust API and is intended to
167use by various tools. Typical test creates an `AnalysisHost`, calls some 167use by various tools. Typical test creates an `AnalysisHost`, calls some
168`Analysis` functions and compares the results against expectation. 168`Analysis` functions and compares the results against expectation.
169 169
170The innermost and most elaborate boundary is `hir`. It has a much richer 170The innermost and most elaborate boundary is `hir`. It has a much richer
171vocabulary of types than `ide_api`, but the basic testing setup is the same: we 171vocabulary of types than `ide`, but the basic testing setup is the same: we
172create a database, run some queries, assert result. 172create a database, run some queries, assert result.
173 173
174For comparisons, we use [insta](https://github.com/mitsuhiko/insta/) library for 174For comparisons, we use [insta](https://github.com/mitsuhiko/insta/) library for
diff --git a/docs/dev/guide.md b/docs/dev/guide.md
index abbe4c154..c163a74b3 100644
--- a/docs/dev/guide.md
+++ b/docs/dev/guide.md
@@ -40,8 +40,8 @@ terms of files and offsets, and **not** in terms of Rust concepts like structs,
40traits, etc. The "typed" API with Rust specific types is slightly lower in the 40traits, etc. The "typed" API with Rust specific types is slightly lower in the
41stack, we'll talk about it later. 41stack, we'll talk about it later.
42 42
43[`AnalysisHost`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L265-L284 43[`AnalysisHost`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/lib.rs#L265-L284
44[`Analysis`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L291-L478 44[`Analysis`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/lib.rs#L291-L478
45 45
46The reason for this separation of `Analysis` and `AnalysisHost` is that we want to apply 46The reason for this separation of `Analysis` and `AnalysisHost` is that we want to apply
47changes "uniquely", but we might also want to fork an `Analysis` and send it to 47changes "uniquely", but we might also want to fork an `Analysis` and send it to
@@ -69,7 +69,7 @@ the `AnalysisHost::apply_change` method, which accepts a single argument, a
69"transaction", so it suffices to study its methods to understand all of the 69"transaction", so it suffices to study its methods to understand all of the
70input data. 70input data.
71 71
72[`AnalysisChange`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L119-L167 72[`AnalysisChange`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/lib.rs#L119-L167
73 73
74The `(add|change|remove)_file` methods control the set of the input files, where 74The `(add|change|remove)_file` methods control the set of the input files, where
75each file has an integer id (`FileId`, picked by the client), text (`String`) 75each file has an integer id (`FileId`, picked by the client), text (`String`)
@@ -253,7 +253,7 @@ All analyzer information is stored in a salsa database. `Analysis` and
253`AnalysisHost` types are newtype wrappers for [`RootDatabase`] -- a salsa 253`AnalysisHost` types are newtype wrappers for [`RootDatabase`] -- a salsa
254database. 254database.
255 255
256[`RootDatabase`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/db.rs#L88-L134 256[`RootDatabase`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/db.rs#L88-L134
257 257
258Salsa input queries are defined in [`FilesDatabase`] (which is a part of 258Salsa input queries are defined in [`FilesDatabase`] (which is a part of
259`RootDatabase`). They closely mirror the familiar `AnalysisChange` structure: 259`RootDatabase`). They closely mirror the familiar `AnalysisChange` structure:
@@ -565,11 +565,11 @@ the type to completion.
565[schedule it on the threadpool]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L428 565[schedule it on the threadpool]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L428
566[catch]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L436-L442 566[catch]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L436-L442
567[the handler]: https://salsa.zulipchat.com/#narrow/stream/181542-rfcs.2Fsalsa-query-group/topic/design.20next.20steps 567[the handler]: https://salsa.zulipchat.com/#narrow/stream/181542-rfcs.2Fsalsa-query-group/topic/design.20next.20steps
568[ask analysis for completion]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L439-L444 568[ask analysis for completion]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/lib.rs#L439-L444
569[completion implementation]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L46-L62 569[completion implementation]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion.rs#L46-L62
570[`CompletionContext`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L14-L37 570[`CompletionContext`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/completion_context.rs#L14-L37
571["IntelliJ Trick"]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L72-L75 571["IntelliJ Trick"]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/completion_context.rs#L72-L75
572[find an ancestor `fn` node]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L116-L120 572[find an ancestor `fn` node]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/completion_context.rs#L116-L120
573[semantic model]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L123 573[semantic model]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/completion_context.rs#L123
574[series of independent completion routines]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L52-L59 574[series of independent completion routines]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion.rs#L52-L59
575[`complete_dot`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/complete_dot.rs#L6-L22 575[`complete_dot`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide/src/completion/complete_dot.rs#L6-L22
diff --git a/editors/code/src/utils/terminateProcess.sh b/editors/code/src/utils/terminateProcess.sh
index 2ec9e1c2e..2ec9e1c2e 100755..100644
--- a/editors/code/src/utils/terminateProcess.sh
+++ b/editors/code/src/utils/terminateProcess.sh
diff --git a/xtask/tests/tidy-tests/docs.rs b/xtask/tests/tidy-tests/docs.rs
index fae871285..8a005d6c4 100644
--- a/xtask/tests/tidy-tests/docs.rs
+++ b/xtask/tests/tidy-tests/docs.rs
@@ -74,7 +74,7 @@ fn no_docs_comments() {
74 "ra_db", 74 "ra_db",
75 "ra_hir", 75 "ra_hir",
76 "ra_hir_expand", 76 "ra_hir_expand",
77 "ra_ide_api", 77 "ra_ide",
78 "ra_lsp_server", 78 "ra_lsp_server",
79 "ra_mbe", 79 "ra_mbe",
80 "ra_parser", 80 "ra_parser",
@@ -83,6 +83,7 @@ fn no_docs_comments() {
83 "ra_syntax", 83 "ra_syntax",
84 "ra_text_edit", 84 "ra_text_edit",
85 "ra_tt", 85 "ra_tt",
86 "ra_hir_ty",
86 ]; 87 ];
87 88
88 let mut has_fixmes = whitelist.iter().map(|it| (*it, false)).collect::<HashMap<&str, bool>>(); 89 let mut has_fixmes = whitelist.iter().map(|it| (*it, false)).collect::<HashMap<&str, bool>>();