aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock81
-rw-r--r--crates/ra_assists/src/assist_ctx.rs2
-rw-r--r--crates/ra_assists/src/assists/add_missing_impl_members.rs131
-rw-r--r--crates/ra_assists/src/doc_tests/generated.rs22
-rw-r--r--crates/ra_hir/src/code_model.rs11
-rw-r--r--crates/ra_hir_def/src/data.rs21
-rw-r--r--crates/ra_hir_def/src/path.rs8
-rw-r--r--crates/ra_hir_ty/Cargo.toml7
-rw-r--r--crates/ra_hir_ty/src/db.rs35
-rw-r--r--crates/ra_hir_ty/src/infer.rs23
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs4
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs74
-rw-r--r--crates/ra_hir_ty/src/traits.rs24
-rw-r--r--crates/ra_hir_ty/src/traits/builtin.rs49
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs468
-rw-r--r--crates/ra_lsp_server/Cargo.toml2
-rw-r--r--crates/ra_lsp_server/src/caps.rs1
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs4
-rw-r--r--docs/user/assists.md22
-rw-r--r--xtask/src/main.rs2
20 files changed, 634 insertions, 357 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 55afcda7b..792e30494 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -66,6 +66,11 @@ dependencies = [
66] 66]
67 67
68[[package]] 68[[package]]
69name = "base64"
70version = "0.11.0"
71source = "registry+https://github.com/rust-lang/crates.io-index"
72
73[[package]]
69name = "bit-set" 74name = "bit-set"
70version = "0.5.1" 75version = "0.5.1"
71source = "registry+https://github.com/rust-lang/crates.io-index" 76source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -128,7 +133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
128[[package]] 133[[package]]
129name = "chalk-derive" 134name = "chalk-derive"
130version = "0.1.0" 135version = "0.1.0"
131source = "git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb#151949dece8117d180b5d197a7afa968c3ba14bb" 136source = "git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5#ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5"
132dependencies = [ 137dependencies = [
133 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 138 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
134 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 139 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -138,27 +143,27 @@ dependencies = [
138[[package]] 143[[package]]
139name = "chalk-engine" 144name = "chalk-engine"
140version = "0.9.0" 145version = "0.9.0"
141source = "git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb#151949dece8117d180b5d197a7afa968c3ba14bb" 146source = "git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5#ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5"
142dependencies = [ 147dependencies = [
143 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 148 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
144 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 149 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
145] 150]
146 151
147[[package]] 152[[package]]
148name = "chalk-ir" 153name = "chalk-ir"
149version = "0.1.0" 154version = "0.1.0"
150source = "git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb#151949dece8117d180b5d197a7afa968c3ba14bb" 155source = "git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5#ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5"
151dependencies = [ 156dependencies = [
152 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 157 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
153 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 158 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
154 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 159 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
155 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", 160 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
156] 161]
157 162
158[[package]] 163[[package]]
159name = "chalk-macros" 164name = "chalk-macros"
160version = "0.1.1" 165version = "0.1.1"
161source = "git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb#151949dece8117d180b5d197a7afa968c3ba14bb" 166source = "git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5#ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5"
162dependencies = [ 167dependencies = [
163 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 168 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
164] 169]
@@ -166,24 +171,24 @@ dependencies = [
166[[package]] 171[[package]]
167name = "chalk-rust-ir" 172name = "chalk-rust-ir"
168version = "0.1.0" 173version = "0.1.0"
169source = "git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb#151949dece8117d180b5d197a7afa968c3ba14bb" 174source = "git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5#ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5"
170dependencies = [ 175dependencies = [
171 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 176 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
172 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 177 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
173 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 178 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
174 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 179 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
175] 180]
176 181
177[[package]] 182[[package]]
178name = "chalk-solve" 183name = "chalk-solve"
179version = "0.1.0" 184version = "0.1.0"
180source = "git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb#151949dece8117d180b5d197a7afa968c3ba14bb" 185source = "git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5#ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5"
181dependencies = [ 186dependencies = [
182 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 187 "chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
183 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 188 "chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
184 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 189 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
185 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 190 "chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
186 "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 191 "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
187 "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", 192 "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
188 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 193 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
189 "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", 194 "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -620,9 +625,10 @@ dependencies = [
620 625
621[[package]] 626[[package]]
622name = "lsp-types" 627name = "lsp-types"
623version = "0.65.0" 628version = "0.67.1"
624source = "registry+https://github.com/rust-lang/crates.io-index" 629source = "registry+https://github.com/rust-lang/crates.io-index"
625dependencies = [ 630dependencies = [
631 "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
626 "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)",
627 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 633 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
628 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 634 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -995,9 +1001,9 @@ name = "ra_hir_ty"
995version = "0.1.0" 1001version = "0.1.0"
996dependencies = [ 1002dependencies = [
997 "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1003 "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
998 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 1004 "chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
999 "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 1005 "chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
1000 "chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)", 1006 "chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)",
1001 "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", 1007 "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
1002 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 1008 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
1003 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", 1009 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1034,7 +1040,7 @@ dependencies = [
1034 "ra_syntax 0.1.0", 1040 "ra_syntax 0.1.0",
1035 "ra_text_edit 0.1.0", 1041 "ra_text_edit 0.1.0",
1036 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1042 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1037 "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1043 "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1038 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1044 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1039 "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1045 "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1040 "test_utils 0.1.0", 1046 "test_utils 0.1.0",
@@ -1050,7 +1056,7 @@ dependencies = [
1050 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1056 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1051 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1057 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1052 "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1058 "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1053 "lsp-types 0.65.0 (registry+https://github.com/rust-lang/crates.io-index)", 1059 "lsp-types 0.67.1 (registry+https://github.com/rust-lang/crates.io-index)",
1054 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 1060 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
1055 "ra_ide 0.1.0", 1061 "ra_ide 0.1.0",
1056 "ra_prof 0.1.0", 1062 "ra_prof 0.1.0",
@@ -1314,17 +1320,17 @@ dependencies = [
1314 1320
1315[[package]] 1321[[package]]
1316name = "rayon" 1322name = "rayon"
1317version = "1.2.1" 1323version = "1.3.0"
1318source = "registry+https://github.com/rust-lang/crates.io-index" 1324source = "registry+https://github.com/rust-lang/crates.io-index"
1319dependencies = [ 1325dependencies = [
1320 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1326 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1321 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 1327 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
1322 "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 1328 "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
1323] 1329]
1324 1330
1325[[package]] 1331[[package]]
1326name = "rayon-core" 1332name = "rayon-core"
1327version = "1.6.1" 1333version = "1.7.0"
1328source = "registry+https://github.com/rust-lang/crates.io-index" 1334source = "registry+https://github.com/rust-lang/crates.io-index"
1329dependencies = [ 1335dependencies = [
1330 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1336 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1773,6 +1779,7 @@ dependencies = [
1773"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" 1779"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
1774"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" 1780"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
1775"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 1781"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
1782"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
1776"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" 1783"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
1777"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" 1784"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
1778"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 1785"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
@@ -1782,12 +1789,12 @@ dependencies = [
1782"checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" 1789"checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202"
1783"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" 1790"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
1784"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 1791"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
1785"checksum chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)" = "<none>" 1792"checksum chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>"
1786"checksum chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)" = "<none>" 1793"checksum chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>"
1787"checksum chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)" = "<none>" 1794"checksum chalk-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>"
1788"checksum chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)" = "<none>" 1795"checksum chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>"
1789"checksum chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)" = "<none>" 1796"checksum chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>"
1790"checksum chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=151949dece8117d180b5d197a7afa968c3ba14bb)" = "<none>" 1797"checksum chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>"
1791"checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" 1798"checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e"
1792"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1799"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
1793"checksum console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5d540c2d34ac9dd0deb5f3b5f54c36c79efa78f6b3ad19106a554d07a7b5d9f" 1800"checksum console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5d540c2d34ac9dd0deb5f3b5f54c36c79efa78f6b3ad19106a554d07a7b5d9f"
@@ -1842,7 +1849,7 @@ dependencies = [
1842"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" 1849"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586"
1843"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1850"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
1844"checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12" 1851"checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12"
1845"checksum lsp-types 0.65.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fe9e427e63e6172699737b47f1044bcade7046e2404d59ebd90c459da47cd2b" 1852"checksum lsp-types 0.67.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aea9639ebf210bd5de66931cbdb2d4a8bcc1fa1e5b2dece7daa6b387ab42e803"
1846"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1853"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
1847"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 1854"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
1848"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" 1855"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
@@ -1884,8 +1891,8 @@ dependencies = [
1884"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 1891"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
1885"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" 1892"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
1886"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1893"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
1887"checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd" 1894"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
1888"checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791" 1895"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
1889"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1896"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
1890"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 1897"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
1891"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" 1898"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index 993aebc47..28152f724 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -46,7 +46,7 @@ pub(crate) enum Assist {
46/// 46///
47/// Note, however, that we don't actually use such two-phase logic at the 47/// Note, however, that we don't actually use such two-phase logic at the
48/// moment, because the LSP API is pretty awkward in this place, and it's much 48/// moment, because the LSP API is pretty awkward in this place, and it's much
49/// easier to just compute the edit eagerly :-)#[derive(Debug, Clone)] 49/// easier to just compute the edit eagerly :-)
50#[derive(Debug)] 50#[derive(Debug)]
51pub(crate) struct AssistCtx<'a, DB> { 51pub(crate) struct AssistCtx<'a, DB> {
52 pub(crate) db: &'a DB, 52 pub(crate) db: &'a DB,
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs
index cef669cb5..bc49e71fe 100644
--- a/crates/ra_assists/src/assists/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs
@@ -1,3 +1,5 @@
1use std::collections::HashMap;
2
1use hir::{db::HirDatabase, HasSource}; 3use hir::{db::HirDatabase, HasSource};
2use ra_syntax::{ 4use ra_syntax::{
3 ast::{self, edit, make, AstNode, NameOwner}, 5 ast::{self, edit, make, AstNode, NameOwner},
@@ -17,26 +19,26 @@ enum AddMissingImplMembersMode {
17// Adds scaffold for required impl members. 19// Adds scaffold for required impl members.
18// 20//
19// ``` 21// ```
20// trait T { 22// trait Trait<T> {
21// Type X; 23// Type X;
22// fn foo(&self); 24// fn foo(&self) -> T;
23// fn bar(&self) {} 25// fn bar(&self) {}
24// } 26// }
25// 27//
26// impl T for () {<|> 28// impl Trait<u32> for () {<|>
27// 29//
28// } 30// }
29// ``` 31// ```
30// -> 32// ->
31// ``` 33// ```
32// trait T { 34// trait Trait<T> {
33// Type X; 35// Type X;
34// fn foo(&self); 36// fn foo(&self) -> T;
35// fn bar(&self) {} 37// fn bar(&self) {}
36// } 38// }
37// 39//
38// impl T for () { 40// impl Trait<u32> for () {
39// fn foo(&self) { unimplemented!() } 41// fn foo(&self) -> u32 { unimplemented!() }
40// 42//
41// } 43// }
42// ``` 44// ```
@@ -54,13 +56,13 @@ pub(crate) fn add_missing_impl_members(ctx: AssistCtx<impl HirDatabase>) -> Opti
54// Adds scaffold for overriding default impl members. 56// Adds scaffold for overriding default impl members.
55// 57//
56// ``` 58// ```
57// trait T { 59// trait Trait {
58// Type X; 60// Type X;
59// fn foo(&self); 61// fn foo(&self);
60// fn bar(&self) {} 62// fn bar(&self) {}
61// } 63// }
62// 64//
63// impl T for () { 65// impl Trait for () {
64// Type X = (); 66// Type X = ();
65// fn foo(&self) {}<|> 67// fn foo(&self) {}<|>
66// 68//
@@ -68,13 +70,13 @@ pub(crate) fn add_missing_impl_members(ctx: AssistCtx<impl HirDatabase>) -> Opti
68// ``` 70// ```
69// -> 71// ->
70// ``` 72// ```
71// trait T { 73// trait Trait {
72// Type X; 74// Type X;
73// fn foo(&self); 75// fn foo(&self);
74// fn bar(&self) {} 76// fn bar(&self) {}
75// } 77// }
76// 78//
77// impl T for () { 79// impl Trait for () {
78// Type X = (); 80// Type X = ();
79// fn foo(&self) {} 81// fn foo(&self) {}
80// fn bar(&self) {} 82// fn bar(&self) {}
@@ -99,7 +101,7 @@ fn add_missing_impl_members_inner(
99 let impl_node = ctx.find_node_at_offset::<ast::ImplBlock>()?; 101 let impl_node = ctx.find_node_at_offset::<ast::ImplBlock>()?;
100 let impl_item_list = impl_node.item_list()?; 102 let impl_item_list = impl_node.item_list()?;
101 103
102 let trait_def = { 104 let (trait_, trait_def) = {
103 let analyzer = ctx.source_analyzer(impl_node.syntax(), None); 105 let analyzer = ctx.source_analyzer(impl_node.syntax(), None);
104 106
105 resolve_target_trait_def(ctx.db, &analyzer, &impl_node)? 107 resolve_target_trait_def(ctx.db, &analyzer, &impl_node)?
@@ -132,10 +134,25 @@ fn add_missing_impl_members_inner(
132 return None; 134 return None;
133 } 135 }
134 136
137 let file_id = ctx.frange.file_id;
138 let db = ctx.db;
139
135 ctx.add_assist(AssistId(assist_id), label, |edit| { 140 ctx.add_assist(AssistId(assist_id), label, |edit| {
136 let n_existing_items = impl_item_list.impl_items().count(); 141 let n_existing_items = impl_item_list.impl_items().count();
142 let substs = get_syntactic_substs(impl_node).unwrap_or_default();
143 let generic_def: hir::GenericDef = trait_.into();
144 let substs_by_param: HashMap<_, _> = generic_def
145 .params(db)
146 .into_iter()
147 // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky
148 .skip(1)
149 .zip(substs.into_iter())
150 .collect();
137 let items = missing_items 151 let items = missing_items
138 .into_iter() 152 .into_iter()
153 .map(|it| {
154 substitute_type_params(db, hir::InFile::new(file_id.into(), it), &substs_by_param)
155 })
139 .map(|it| match it { 156 .map(|it| match it {
140 ast::ImplItem::FnDef(def) => ast::ImplItem::FnDef(add_body(def)), 157 ast::ImplItem::FnDef(def) => ast::ImplItem::FnDef(add_body(def)),
141 _ => it, 158 _ => it,
@@ -160,13 +177,63 @@ fn add_body(fn_def: ast::FnDef) -> ast::FnDef {
160 } 177 }
161} 178}
162 179
180// FIXME: It would probably be nicer if we could get this via HIR (i.e. get the
181// trait ref, and then go from the types in the substs back to the syntax)
182// FIXME: This should be a general utility (not even just for assists)
183fn get_syntactic_substs(impl_block: ast::ImplBlock) -> Option<Vec<ast::TypeRef>> {
184 let target_trait = impl_block.target_trait()?;
185 let path_type = match target_trait {
186 ast::TypeRef::PathType(path) => path,
187 _ => return None,
188 };
189 let type_arg_list = path_type.path()?.segment()?.type_arg_list()?;
190 let mut result = Vec::new();
191 for type_arg in type_arg_list.type_args() {
192 let type_arg: ast::TypeArg = type_arg;
193 result.push(type_arg.type_ref()?);
194 }
195 Some(result)
196}
197
198// FIXME: This should be a general utility (not even just for assists)
199fn substitute_type_params<N: AstNode>(
200 db: &impl HirDatabase,
201 node: hir::InFile<N>,
202 substs: &HashMap<hir::TypeParam, ast::TypeRef>,
203) -> N {
204 let type_param_replacements = node
205 .value
206 .syntax()
207 .descendants()
208 .filter_map(ast::TypeRef::cast)
209 .filter_map(|n| {
210 let path = match &n {
211 ast::TypeRef::PathType(path_type) => path_type.path()?,
212 _ => return None,
213 };
214 let analyzer = hir::SourceAnalyzer::new(db, node.with_value(n.syntax()), None);
215 let resolution = analyzer.resolve_path(db, &path)?;
216 match resolution {
217 hir::PathResolution::TypeParam(tp) => Some((n, substs.get(&tp)?.clone())),
218 _ => None,
219 }
220 })
221 .collect::<Vec<_>>();
222
223 if type_param_replacements.is_empty() {
224 node.value
225 } else {
226 edit::replace_descendants(&node.value, type_param_replacements.into_iter())
227 }
228}
229
163/// Given an `ast::ImplBlock`, resolves the target trait (the one being 230/// Given an `ast::ImplBlock`, resolves the target trait (the one being
164/// implemented) to a `ast::TraitDef`. 231/// implemented) to a `ast::TraitDef`.
165fn resolve_target_trait_def( 232fn resolve_target_trait_def(
166 db: &impl HirDatabase, 233 db: &impl HirDatabase,
167 analyzer: &hir::SourceAnalyzer, 234 analyzer: &hir::SourceAnalyzer,
168 impl_block: &ast::ImplBlock, 235 impl_block: &ast::ImplBlock,
169) -> Option<ast::TraitDef> { 236) -> Option<(hir::Trait, ast::TraitDef)> {
170 let ast_path = impl_block 237 let ast_path = impl_block
171 .target_trait() 238 .target_trait()
172 .map(|it| it.syntax().clone()) 239 .map(|it| it.syntax().clone())
@@ -174,7 +241,9 @@ fn resolve_target_trait_def(
174 .path()?; 241 .path()?;
175 242
176 match analyzer.resolve_path(db, &ast_path) { 243 match analyzer.resolve_path(db, &ast_path) {
177 Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def.source(db).value), 244 Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => {
245 Some((def, def.source(db).value))
246 }
178 _ => None, 247 _ => None,
179 } 248 }
180} 249}
@@ -281,6 +350,40 @@ impl Foo for S {
281 } 350 }
282 351
283 #[test] 352 #[test]
353 fn fill_in_type_params_1() {
354 check_assist(
355 add_missing_impl_members,
356 "
357trait Foo<T> { fn foo(&self, t: T) -> &T; }
358struct S;
359impl Foo<u32> for S { <|> }",
360 "
361trait Foo<T> { fn foo(&self, t: T) -> &T; }
362struct S;
363impl Foo<u32> for S {
364 <|>fn foo(&self, t: u32) -> &u32 { unimplemented!() }
365}",
366 );
367 }
368
369 #[test]
370 fn fill_in_type_params_2() {
371 check_assist(
372 add_missing_impl_members,
373 "
374trait Foo<T> { fn foo(&self, t: T) -> &T; }
375struct S;
376impl<U> Foo<U> for S { <|> }",
377 "
378trait Foo<T> { fn foo(&self, t: T) -> &T; }
379struct S;
380impl<U> Foo<U> for S {
381 <|>fn foo(&self, t: U) -> &U { unimplemented!() }
382}",
383 );
384 }
385
386 #[test]
284 fn test_cursor_after_empty_impl_block() { 387 fn test_cursor_after_empty_impl_block() {
285 check_assist( 388 check_assist(
286 add_missing_impl_members, 389 add_missing_impl_members,
diff --git a/crates/ra_assists/src/doc_tests/generated.rs b/crates/ra_assists/src/doc_tests/generated.rs
index 4586eeb59..7d84dc8fb 100644
--- a/crates/ra_assists/src/doc_tests/generated.rs
+++ b/crates/ra_assists/src/doc_tests/generated.rs
@@ -101,26 +101,26 @@ fn doctest_add_impl_default_members() {
101 check( 101 check(
102 "add_impl_default_members", 102 "add_impl_default_members",
103 r#####" 103 r#####"
104trait T { 104trait Trait {
105 Type X; 105 Type X;
106 fn foo(&self); 106 fn foo(&self);
107 fn bar(&self) {} 107 fn bar(&self) {}
108} 108}
109 109
110impl T for () { 110impl Trait for () {
111 Type X = (); 111 Type X = ();
112 fn foo(&self) {}<|> 112 fn foo(&self) {}<|>
113 113
114} 114}
115"#####, 115"#####,
116 r#####" 116 r#####"
117trait T { 117trait Trait {
118 Type X; 118 Type X;
119 fn foo(&self); 119 fn foo(&self);
120 fn bar(&self) {} 120 fn bar(&self) {}
121} 121}
122 122
123impl T for () { 123impl Trait for () {
124 Type X = (); 124 Type X = ();
125 fn foo(&self) {} 125 fn foo(&self) {}
126 fn bar(&self) {} 126 fn bar(&self) {}
@@ -135,25 +135,25 @@ fn doctest_add_impl_missing_members() {
135 check( 135 check(
136 "add_impl_missing_members", 136 "add_impl_missing_members",
137 r#####" 137 r#####"
138trait T { 138trait Trait<T> {
139 Type X; 139 Type X;
140 fn foo(&self); 140 fn foo(&self) -> T;
141 fn bar(&self) {} 141 fn bar(&self) {}
142} 142}
143 143
144impl T for () {<|> 144impl Trait<u32> for () {<|>
145 145
146} 146}
147"#####, 147"#####,
148 r#####" 148 r#####"
149trait T { 149trait Trait<T> {
150 Type X; 150 Type X;
151 fn foo(&self); 151 fn foo(&self) -> T;
152 fn bar(&self) {} 152 fn bar(&self) {}
153} 153}
154 154
155impl T for () { 155impl Trait<u32> for () {
156 fn foo(&self) { unimplemented!() } 156 fn foo(&self) -> u32 { unimplemented!() }
157 157
158} 158}
159"#####, 159"#####,
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index bcfc0d03e..76d8f85f1 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -644,6 +644,17 @@ impl_froms!(
644 Const 644 Const
645); 645);
646 646
647impl GenericDef {
648 pub fn params(self, db: &impl HirDatabase) -> Vec<TypeParam> {
649 let generics: Arc<hir_def::generics::GenericParams> = db.generic_params(self.into());
650 generics
651 .types
652 .iter()
653 .map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
654 .collect()
655 }
656}
657
647#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 658#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
648pub struct Local { 659pub struct Local {
649 pub(crate) parent: DefWithBody, 660 pub(crate) parent: DefWithBody,
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index 1aa9a9b7d..c900a6a18 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -10,8 +10,9 @@ use ra_syntax::ast::{self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAs
10 10
11use crate::{ 11use crate::{
12 db::DefDatabase, 12 db::DefDatabase,
13 path::{path, GenericArgs, Path},
13 src::HasSource, 14 src::HasSource,
14 type_ref::{Mutability, TypeRef}, 15 type_ref::{Mutability, TypeBound, TypeRef},
15 AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule, 16 AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule,
16 ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, 17 ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
17}; 18};
@@ -62,11 +63,29 @@ impl FunctionData {
62 TypeRef::unit() 63 TypeRef::unit()
63 }; 64 };
64 65
66 let ret_type = if src.value.is_async() {
67 let future_impl = desugar_future_path(ret_type);
68 let ty_bound = TypeBound::Path(future_impl);
69 TypeRef::ImplTrait(vec![ty_bound])
70 } else {
71 ret_type
72 };
73
65 let sig = FunctionData { name, params, ret_type, has_self_param }; 74 let sig = FunctionData { name, params, ret_type, has_self_param };
66 Arc::new(sig) 75 Arc::new(sig)
67 } 76 }
68} 77}
69 78
79fn desugar_future_path(orig: TypeRef) -> Path {
80 let path = path![std::future::Future];
81 let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments.len() - 1).collect();
82 let mut last = GenericArgs::empty();
83 last.bindings.push((name![Output], orig));
84 generic_args.push(Some(Arc::new(last)));
85
86 Path::from_known_path(path, generic_args)
87}
88
70#[derive(Debug, Clone, PartialEq, Eq)] 89#[derive(Debug, Clone, PartialEq, Eq)]
71pub struct TypeAliasData { 90pub struct TypeAliasData {
72 pub name: Name, 91 pub name: Name,
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 8e1294201..107d2d799 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -130,6 +130,14 @@ impl Path {
130 Path { type_anchor: None, mod_path: name_ref.as_name().into(), generic_args: vec![None] } 130 Path { type_anchor: None, mod_path: name_ref.as_name().into(), generic_args: vec![None] }
131 } 131 }
132 132
133 /// Converts a known mod path to `Path`.
134 pub(crate) fn from_known_path(
135 path: ModPath,
136 generic_args: Vec<Option<Arc<GenericArgs>>>,
137 ) -> Path {
138 Path { type_anchor: None, mod_path: path, generic_args }
139 }
140
133 pub fn kind(&self) -> &PathKind { 141 pub fn kind(&self) -> &PathKind {
134 &self.mod_path.kind 142 &self.mod_path.kind
135 } 143 }
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index d277bf2bc..60793db44 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -21,10 +21,9 @@ ra_prof = { path = "../ra_prof" }
21ra_syntax = { path = "../ra_syntax" } 21ra_syntax = { path = "../ra_syntax" }
22test_utils = { path = "../test_utils" } 22test_utils = { path = "../test_utils" }
23 23
24# https://github.com/rust-lang/chalk/pull/294 24chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" }
25chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" } 25chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" }
26chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" } 26chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5" }
27chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "151949dece8117d180b5d197a7afa968c3ba14bb" }
28 27
29lalrpop-intern = "0.15.1" 28lalrpop-intern = "0.15.1"
30 29
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index 222a36a9f..d52f65b83 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -10,7 +10,7 @@ use ra_db::{salsa, CrateId};
10 10
11use crate::{ 11use crate::{
12 method_resolution::CrateImplBlocks, 12 method_resolution::CrateImplBlocks,
13 traits::{AssocTyValue, Impl}, 13 traits::{chalk, AssocTyValue, Impl},
14 CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor, 14 CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor,
15 ValueTyDefId, 15 ValueTyDefId,
16}; 16};
@@ -77,39 +77,24 @@ pub trait HirDatabase: DefDatabase {
77 #[salsa::interned] 77 #[salsa::interned]
78 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId; 78 fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId;
79 79
80 #[salsa::invoke(crate::traits::chalk::associated_ty_data_query)] 80 #[salsa::invoke(chalk::associated_ty_data_query)]
81 fn associated_ty_data( 81 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>;
82 &self,
83 id: chalk_ir::TypeId,
84 ) -> Arc<chalk_rust_ir::AssociatedTyDatum<chalk_ir::family::ChalkIr>>;
85 82
86 #[salsa::invoke(crate::traits::chalk::trait_datum_query)] 83 #[salsa::invoke(chalk::trait_datum_query)]
87 fn trait_datum( 84 fn trait_datum(&self, krate: CrateId, trait_id: chalk::TraitId) -> Arc<chalk::TraitDatum>;
88 &self,
89 krate: CrateId,
90 trait_id: chalk_ir::TraitId,
91 ) -> Arc<chalk_rust_ir::TraitDatum<chalk_ir::family::ChalkIr>>;
92 85
93 #[salsa::invoke(crate::traits::chalk::struct_datum_query)] 86 #[salsa::invoke(chalk::struct_datum_query)]
94 fn struct_datum( 87 fn struct_datum(&self, krate: CrateId, struct_id: chalk::StructId) -> Arc<chalk::StructDatum>;
95 &self,
96 krate: CrateId,
97 struct_id: chalk_ir::StructId,
98 ) -> Arc<chalk_rust_ir::StructDatum<chalk_ir::family::ChalkIr>>;
99 88
100 #[salsa::invoke(crate::traits::chalk::impl_datum_query)] 89 #[salsa::invoke(crate::traits::chalk::impl_datum_query)]
101 fn impl_datum( 90 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>;
102 &self,
103 krate: CrateId,
104 impl_id: chalk_ir::ImplId,
105 ) -> Arc<chalk_rust_ir::ImplDatum<chalk_ir::family::ChalkIr>>;
106 91
107 #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)] 92 #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)]
108 fn associated_ty_value( 93 fn associated_ty_value(
109 &self, 94 &self,
110 krate: CrateId, 95 krate: CrateId,
111 id: chalk_rust_ir::AssociatedTyValueId, 96 id: chalk::AssociatedTyValueId,
112 ) -> Arc<chalk_rust_ir::AssociatedTyValue<chalk_ir::family::ChalkIr>>; 97 ) -> Arc<chalk::AssociatedTyValue>;
113 98
114 #[salsa::invoke(crate::traits::trait_solve_query)] 99 #[salsa::invoke(crate::traits::trait_solve_query)]
115 fn trait_solve( 100 fn trait_solve(
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index e97b81473..32c0d07a5 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -37,8 +37,8 @@ use test_utils::tested_by;
37use super::{ 37use super::{
38 primitive::{FloatTy, IntTy}, 38 primitive::{FloatTy, IntTy},
39 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 39 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
40 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, 40 ApplicationTy, GenericPredicate, InEnvironment, ProjectionTy, Substs, TraitEnvironment,
41 TypeWalk, Uncertain, 41 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain,
42}; 42};
43use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; 43use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic};
44 44
@@ -379,6 +379,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
379 ) -> Ty { 379 ) -> Ty {
380 match assoc_ty { 380 match assoc_ty {
381 Some(res_assoc_ty) => { 381 Some(res_assoc_ty) => {
382 // FIXME:
383 // Check if inner_ty is is `impl Trait` and contained input TypeAlias id
384 // this is a workaround while Chalk assoc type projection doesn't always work yet,
385 // but once that is fixed I don't think we should keep this
386 // (we'll probably change how associated types are resolved anyway)
387 if let Ty::Opaque(ref predicates) = inner_ty {
388 for p in predicates.iter() {
389 if let GenericPredicate::Projection(projection) = p {
390 if projection.projection_ty.associated_ty == res_assoc_ty {
391 if let ty_app!(_, params) = &projection.ty {
392 if params.len() == 0 {
393 return projection.ty.clone();
394 }
395 }
396 }
397 }
398 }
399 }
400
382 let ty = self.table.new_type_var(); 401 let ty = self.table.new_type_var();
383 let builder = Substs::build_for_def(self.db, res_assoc_ty) 402 let builder = Substs::build_for_def(self.db, res_assoc_ty)
384 .push(inner_ty) 403 .push(inner_ty)
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index 45164c9e9..ce9a06fde 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -865,7 +865,7 @@ mod foo {
865 865
866#[test] 866#[test]
867fn method_resolution_where_clause_for_unknown_trait() { 867fn method_resolution_where_clause_for_unknown_trait() {
868 // The blanket impl shouldn't apply because we can't even resolve UnknownTrait 868 // The blanket impl currently applies because we ignore the unresolved where clause
869 let t = type_at( 869 let t = type_at(
870 r#" 870 r#"
871//- /main.rs 871//- /main.rs
@@ -875,7 +875,7 @@ impl<T> Trait for T where T: UnknownTrait {}
875fn test() { (&S).foo()<|>; } 875fn test() { (&S).foo()<|>; }
876"#, 876"#,
877 ); 877 );
878 assert_eq!(t, "{unknown}"); 878 assert_eq!(t, "u128");
879} 879}
880 880
881#[test] 881#[test]
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 76e2198b6..0bc72644a 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -38,6 +38,63 @@ mod future {
38} 38}
39 39
40#[test] 40#[test]
41fn infer_async() {
42 let (db, pos) = TestDB::with_position(
43 r#"
44//- /main.rs crate:main deps:std
45
46async fn foo() -> u64 {
47 128
48}
49
50fn test() {
51 let r = foo();
52 let v = r.await;
53 v<|>;
54}
55
56//- /std.rs crate:std
57#[prelude_import] use future::*;
58mod future {
59 trait Future {
60 type Output;
61 }
62}
63
64"#,
65 );
66 assert_eq!("u64", type_at_pos(&db, pos));
67}
68
69#[test]
70fn infer_desugar_async() {
71 let (db, pos) = TestDB::with_position(
72 r#"
73//- /main.rs crate:main deps:std
74
75async fn foo() -> u64 {
76 128
77}
78
79fn test() {
80 let r = foo();
81 r<|>;
82}
83
84//- /std.rs crate:std
85#[prelude_import] use future::*;
86mod future {
87 trait Future {
88 type Output;
89 }
90}
91
92"#,
93 );
94 assert_eq!("impl Future<Output = u64>", type_at_pos(&db, pos));
95}
96
97#[test]
41fn infer_try() { 98fn infer_try() {
42 let (db, pos) = TestDB::with_position( 99 let (db, pos) = TestDB::with_position(
43 r#" 100 r#"
@@ -959,6 +1016,23 @@ fn test() {
959} 1016}
960 1017
961#[test] 1018#[test]
1019fn error_bound_chalk() {
1020 let t = type_at(
1021 r#"
1022//- /main.rs
1023trait Trait {
1024 fn foo(&self) -> u32 {}
1025}
1026
1027fn test(x: (impl Trait + UnknownTrait)) {
1028 x.foo()<|>;
1029}
1030"#,
1031 );
1032 assert_eq!(t, "u32");
1033}
1034
1035#[test]
962fn assoc_type_bindings() { 1036fn assoc_type_bindings() {
963 assert_snapshot!( 1037 assert_snapshot!(
964 infer(r#" 1038 infer(r#"
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index d49f8fb4b..c4dc857bc 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -1,7 +1,7 @@
1//! Trait solving using Chalk. 1//! Trait solving using Chalk.
2use std::sync::{Arc, Mutex}; 2use std::sync::{Arc, Mutex};
3 3
4use chalk_ir::{cast::Cast, family::ChalkIr}; 4use chalk_ir::cast::Cast;
5use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId}; 5use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId};
6use log::debug; 6use log::debug;
7use ra_db::{impl_intern_key, salsa, CrateId}; 7use ra_db::{impl_intern_key, salsa, CrateId};
@@ -12,7 +12,7 @@ use crate::db::HirDatabase;
12 12
13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
14 14
15use self::chalk::{from_chalk, ToChalk}; 15use self::chalk::{from_chalk, ToChalk, TypeFamily};
16 16
17pub(crate) mod chalk; 17pub(crate) mod chalk;
18mod builtin; 18mod builtin;
@@ -20,7 +20,7 @@ mod builtin;
20#[derive(Debug, Clone)] 20#[derive(Debug, Clone)]
21pub struct TraitSolver { 21pub struct TraitSolver {
22 krate: CrateId, 22 krate: CrateId,
23 inner: Arc<Mutex<chalk_solve::Solver<ChalkIr>>>, 23 inner: Arc<Mutex<chalk_solve::Solver<TypeFamily>>>,
24} 24}
25 25
26/// We need eq for salsa 26/// We need eq for salsa
@@ -36,8 +36,8 @@ impl TraitSolver {
36 fn solve( 36 fn solve(
37 &self, 37 &self,
38 db: &impl HirDatabase, 38 db: &impl HirDatabase,
39 goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<ChalkIr>>>, 39 goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<TypeFamily>>>,
40 ) -> Option<chalk_solve::Solution<ChalkIr>> { 40 ) -> Option<chalk_solve::Solution<TypeFamily>> {
41 let context = ChalkContext { db, krate: self.krate }; 41 let context = ChalkContext { db, krate: self.krate };
42 debug!("solve goal: {:?}", goal); 42 debug!("solve goal: {:?}", goal);
43 let mut solver = match self.inner.lock() { 43 let mut solver = match self.inner.lock() {
@@ -201,17 +201,17 @@ pub(crate) fn trait_solve_query(
201 201
202fn solution_from_chalk( 202fn solution_from_chalk(
203 db: &impl HirDatabase, 203 db: &impl HirDatabase,
204 solution: chalk_solve::Solution<ChalkIr>, 204 solution: chalk_solve::Solution<TypeFamily>,
205) -> Solution { 205) -> Solution {
206 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<ChalkIr>>| { 206 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<TypeFamily>>| {
207 let value = subst 207 let value = subst
208 .value 208 .value
209 .parameters 209 .parameters
210 .into_iter() 210 .into_iter()
211 .map(|p| { 211 .map(|p| {
212 let ty = match p { 212 let ty = match p.ty() {
213 chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty), 213 Some(ty) => from_chalk(db, ty.clone()),
214 chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(), 214 None => unimplemented!(),
215 }; 215 };
216 ty 216 ty
217 }) 217 })
@@ -291,7 +291,7 @@ impl FnTrait {
291 } 291 }
292} 292}
293 293
294#[derive(Debug, Clone, PartialEq, Eq, Hash)] 294#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
295pub struct ClosureFnTraitImplData { 295pub struct ClosureFnTraitImplData {
296 def: DefWithBodyId, 296 def: DefWithBodyId,
297 expr: ExprId, 297 expr: ExprId,
@@ -300,7 +300,7 @@ pub struct ClosureFnTraitImplData {
300 300
301/// An impl. Usually this comes from an impl block, but some built-in types get 301/// An impl. Usually this comes from an impl block, but some built-in types get
302/// synthetic impls. 302/// synthetic impls.
303#[derive(Debug, Clone, PartialEq, Eq, Hash)] 303#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
304pub enum Impl { 304pub enum Impl {
305 /// A normal impl from an impl block. 305 /// A normal impl from an impl block.
306 ImplBlock(ImplId), 306 ImplBlock(ImplId),
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs
index cd587a338..dd41176f0 100644
--- a/crates/ra_hir_ty/src/traits/builtin.rs
+++ b/crates/ra_hir_ty/src/traits/builtin.rs
@@ -28,24 +28,24 @@ pub(super) fn get_builtin_impls(
28 trait_: TraitId, 28 trait_: TraitId,
29 mut callback: impl FnMut(Impl), 29 mut callback: impl FnMut(Impl),
30) { 30) {
31 // Note: since impl_datum needs to be infallible, we need to make sure here
32 // that we have all prerequisites to build the respective impls.
31 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty { 33 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty {
32 for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() 34 for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter()
33 { 35 {
34 if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) { 36 if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) {
35 if trait_ == actual_trait { 37 if trait_ == actual_trait {
36 let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait }; 38 let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait };
37 callback(Impl::ClosureFnTraitImpl(impl_)); 39 if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) {
40 callback(Impl::ClosureFnTraitImpl(impl_));
41 }
38 } 42 }
39 } 43 }
40 } 44 }
41 } 45 }
42} 46}
43 47
44pub(super) fn impl_datum( 48pub(super) fn impl_datum(db: &impl HirDatabase, krate: CrateId, impl_: Impl) -> BuiltinImplData {
45 db: &impl HirDatabase,
46 krate: CrateId,
47 impl_: Impl,
48) -> Option<BuiltinImplData> {
49 match impl_ { 49 match impl_ {
50 Impl::ImplBlock(_) => unreachable!(), 50 Impl::ImplBlock(_) => unreachable!(),
51 Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), 51 Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data),
@@ -65,21 +65,38 @@ pub(super) fn associated_ty_value(
65 } 65 }
66} 66}
67 67
68fn check_closure_fn_trait_impl_prerequisites(
69 db: &impl HirDatabase,
70 krate: CrateId,
71 data: super::ClosureFnTraitImplData,
72) -> bool {
73 // the respective Fn/FnOnce/FnMut trait needs to exist
74 if get_fn_trait(db, krate, data.fn_trait).is_none() {
75 return false;
76 }
77
78 // FIXME: there are more assumptions that we should probably check here:
79 // the traits having no type params, FnOnce being a supertrait
80
81 // the FnOnce trait needs to exist and have an assoc type named Output
82 let fn_once_trait = match get_fn_trait(db, krate, super::FnTrait::FnOnce) {
83 Some(t) => t,
84 None => return false,
85 };
86 db.trait_data(fn_once_trait).associated_type_by_name(&name![Output]).is_some()
87}
88
68fn closure_fn_trait_impl_datum( 89fn closure_fn_trait_impl_datum(
69 db: &impl HirDatabase, 90 db: &impl HirDatabase,
70 krate: CrateId, 91 krate: CrateId,
71 data: super::ClosureFnTraitImplData, 92 data: super::ClosureFnTraitImplData,
72) -> Option<BuiltinImplData> { 93) -> BuiltinImplData {
73 // for some closure |X, Y| -> Z: 94 // for some closure |X, Y| -> Z:
74 // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V } 95 // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V }
75 96
76 let trait_ = get_fn_trait(db, krate, data.fn_trait)?; // get corresponding fn trait 97 let trait_ = get_fn_trait(db, krate, data.fn_trait) // get corresponding fn trait
77 98 // the existence of the Fn trait has been checked before
78 // validate FnOnce trait, since we need it in the assoc ty value definition 99 .expect("fn trait for closure impl missing");
79 // and don't want to return a valid value only to find out later that FnOnce
80 // is broken
81 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
82 let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
83 100
84 let num_args: u16 = match &db.body(data.def.into())[data.expr] { 101 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
85 Expr::Lambda { args, .. } => args.len() as u16, 102 Expr::Lambda { args, .. } => args.len() as u16,
@@ -107,12 +124,12 @@ fn closure_fn_trait_impl_datum(
107 124
108 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()); 125 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone());
109 126
110 Some(BuiltinImplData { 127 BuiltinImplData {
111 num_vars: num_args as usize + 1, 128 num_vars: num_args as usize + 1,
112 trait_ref, 129 trait_ref,
113 where_clauses: Vec::new(), 130 where_clauses: Vec::new(),
114 assoc_ty_values: vec![output_ty_id], 131 assoc_ty_values: vec![output_ty_id],
115 }) 132 }
116} 133}
117 134
118fn closure_fn_trait_output_assoc_ty_value( 135fn closure_fn_trait_output_assoc_ty_value(
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 5eb032d86..555930c9b 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -1,17 +1,11 @@
1//! Conversion code from/to Chalk. 1//! Conversion code from/to Chalk.
2use std::sync::Arc; 2use std::{fmt, sync::Arc};
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{ 6use chalk_ir::{cast::Cast, Parameter, PlaceholderIndex, TypeName, UniverseIndex};
7 cast::Cast, family::ChalkIr, Identifier, Parameter, PlaceholderIndex, TypeId, TypeKindId,
8 TypeName, UniverseIndex,
9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11 7
12use hir_def::{ 8use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
13 AssocContainerId, AssocItemId, GenericDefId, HasModule, ImplId, Lookup, TraitId, TypeAliasId,
14};
15use ra_db::{ 9use ra_db::{
16 salsa::{InternId, InternKey}, 10 salsa::{InternId, InternKey},
17 CrateId, 11 CrateId,
@@ -23,9 +17,83 @@ use crate::{
23 ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 17 ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
24}; 18};
25 19
26/// This represents a trait whose name we could not resolve. 20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
27const UNKNOWN_TRAIT: chalk_ir::TraitId = 21pub struct TypeFamily {}
28 chalk_ir::TraitId(chalk_ir::RawId { index: u32::max_value() }); 22
23impl chalk_ir::family::TypeFamily for TypeFamily {
24 type InternedType = Box<chalk_ir::TyData<Self>>;
25 type InternedLifetime = chalk_ir::LifetimeData<Self>;
26 type InternedParameter = chalk_ir::ParameterData<Self>;
27 type DefId = InternId;
28
29 // FIXME: implement these
30 fn debug_struct_id(
31 _type_kind_id: chalk_ir::StructId<Self>,
32 _fmt: &mut fmt::Formatter<'_>,
33 ) -> Option<fmt::Result> {
34 None
35 }
36
37 fn debug_trait_id(
38 _type_kind_id: chalk_ir::TraitId<Self>,
39 _fmt: &mut fmt::Formatter<'_>,
40 ) -> Option<fmt::Result> {
41 None
42 }
43
44 fn debug_assoc_type_id(
45 _id: chalk_ir::AssocTypeId<Self>,
46 _fmt: &mut fmt::Formatter<'_>,
47 ) -> Option<fmt::Result> {
48 None
49 }
50
51 fn debug_projection(
52 _projection: &chalk_ir::ProjectionTy<Self>,
53 _fmt: &mut fmt::Formatter<'_>,
54 ) -> Option<fmt::Result> {
55 None
56 }
57
58 fn intern_ty(ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> {
59 Box::new(ty)
60 }
61
62 fn ty_data(ty: &Box<chalk_ir::TyData<Self>>) -> &chalk_ir::TyData<Self> {
63 ty
64 }
65
66 fn intern_lifetime(lifetime: chalk_ir::LifetimeData<Self>) -> chalk_ir::LifetimeData<Self> {
67 lifetime
68 }
69
70 fn lifetime_data(lifetime: &chalk_ir::LifetimeData<Self>) -> &chalk_ir::LifetimeData<Self> {
71 lifetime
72 }
73
74 fn intern_parameter(parameter: chalk_ir::ParameterData<Self>) -> chalk_ir::ParameterData<Self> {
75 parameter
76 }
77
78 fn parameter_data(parameter: &chalk_ir::ParameterData<Self>) -> &chalk_ir::ParameterData<Self> {
79 parameter
80 }
81}
82
83impl chalk_ir::family::HasTypeFamily for TypeFamily {
84 type TypeFamily = Self;
85}
86
87pub type AssocTypeId = chalk_ir::AssocTypeId<TypeFamily>;
88pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<TypeFamily>;
89pub type TraitId = chalk_ir::TraitId<TypeFamily>;
90pub type TraitDatum = chalk_rust_ir::TraitDatum<TypeFamily>;
91pub type StructId = chalk_ir::StructId<TypeFamily>;
92pub type StructDatum = chalk_rust_ir::StructDatum<TypeFamily>;
93pub type ImplId = chalk_ir::ImplId<TypeFamily>;
94pub type ImplDatum = chalk_rust_ir::ImplDatum<TypeFamily>;
95pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId;
96pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<TypeFamily>;
29 97
30pub(super) trait ToChalk { 98pub(super) trait ToChalk {
31 type Chalk; 99 type Chalk;
@@ -41,21 +109,11 @@ where
41} 109}
42 110
43impl ToChalk for Ty { 111impl ToChalk for Ty {
44 type Chalk = chalk_ir::Ty<ChalkIr>; 112 type Chalk = chalk_ir::Ty<TypeFamily>;
45 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<ChalkIr> { 113 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<TypeFamily> {
46 match self { 114 match self {
47 Ty::Apply(apply_ty) => { 115 Ty::Apply(apply_ty) => {
48 let name = match apply_ty.ctor { 116 let name = apply_ty.ctor.to_chalk(db);
49 TypeCtor::AssociatedType(type_alias) => {
50 let type_id = type_alias.to_chalk(db);
51 TypeName::AssociatedType(type_id)
52 }
53 _ => {
54 // other TypeCtors get interned and turned into a chalk StructId
55 let struct_id = apply_ty.ctor.to_chalk(db);
56 TypeName::TypeKindId(struct_id.into())
57 }
58 };
59 let parameters = apply_ty.parameters.to_chalk(db); 117 let parameters = apply_ty.parameters.to_chalk(db);
60 chalk_ir::ApplicationTy { name, parameters }.cast().intern() 118 chalk_ir::ApplicationTy { name, parameters }.cast().intern()
61 } 119 }
@@ -65,17 +123,30 @@ impl ToChalk for Ty {
65 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast().intern() 123 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast().intern()
66 } 124 }
67 Ty::Param { idx, .. } => { 125 Ty::Param { idx, .. } => {
68 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty::<ChalkIr>() 126 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }
127 .to_ty::<TypeFamily>()
69 } 128 }
70 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), 129 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(),
71 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 130 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
72 Ty::Dyn(predicates) => { 131 Ty::Dyn(predicates) => {
73 let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); 132 let where_clauses = predicates
74 chalk_ir::TyData::Dyn(make_binders(where_clauses, 1)).intern() 133 .iter()
134 .filter(|p| !p.is_error())
135 .cloned()
136 .map(|p| p.to_chalk(db))
137 .collect();
138 let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) };
139 chalk_ir::TyData::Dyn(bounded_ty).intern()
75 } 140 }
76 Ty::Opaque(predicates) => { 141 Ty::Opaque(predicates) => {
77 let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); 142 let where_clauses = predicates
78 chalk_ir::TyData::Opaque(make_binders(where_clauses, 1)).intern() 143 .iter()
144 .filter(|p| !p.is_error())
145 .cloned()
146 .map(|p| p.to_chalk(db))
147 .collect();
148 let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) };
149 chalk_ir::TyData::Opaque(bounded_ty).intern()
79 } 150 }
80 Ty::Unknown => { 151 Ty::Unknown => {
81 let parameters = Vec::new(); 152 let parameters = Vec::new();
@@ -84,30 +155,19 @@ impl ToChalk for Ty {
84 } 155 }
85 } 156 }
86 } 157 }
87 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<ChalkIr>) -> Self { 158 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<TypeFamily>) -> Self {
88 match chalk.data().clone() { 159 match chalk.data().clone() {
89 chalk_ir::TyData::Apply(apply_ty) => { 160 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
90 // FIXME this is kind of hacky due to the fact that 161 TypeName::Error => Ty::Unknown,
91 // TypeName::Placeholder is a Ty::Param on our side 162 _ => {
92 match apply_ty.name { 163 let ctor = from_chalk(db, apply_ty.name);
93 TypeName::TypeKindId(TypeKindId::StructId(struct_id)) => { 164 let parameters = from_chalk(db, apply_ty.parameters);
94 let ctor = from_chalk(db, struct_id); 165 Ty::Apply(ApplicationTy { ctor, parameters })
95 let parameters = from_chalk(db, apply_ty.parameters);
96 Ty::Apply(ApplicationTy { ctor, parameters })
97 }
98 TypeName::AssociatedType(type_id) => {
99 let ctor = TypeCtor::AssociatedType(from_chalk(db, type_id));
100 let parameters = from_chalk(db, apply_ty.parameters);
101 Ty::Apply(ApplicationTy { ctor, parameters })
102 }
103 TypeName::Error => Ty::Unknown,
104 // FIXME handle TypeKindId::Trait/Type here
105 TypeName::TypeKindId(_) => unimplemented!(),
106 TypeName::Placeholder(idx) => {
107 assert_eq!(idx.ui, UniverseIndex::ROOT);
108 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() }
109 }
110 } 166 }
167 },
168 chalk_ir::TyData::Placeholder(idx) => {
169 assert_eq!(idx.ui, UniverseIndex::ROOT);
170 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() }
111 } 171 }
112 chalk_ir::TyData::Projection(proj) => { 172 chalk_ir::TyData::Projection(proj) => {
113 let associated_ty = from_chalk(db, proj.associated_ty_id); 173 let associated_ty = from_chalk(db, proj.associated_ty_id);
@@ -118,15 +178,15 @@ impl ToChalk for Ty {
118 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32), 178 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32),
119 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, 179 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
120 chalk_ir::TyData::Dyn(where_clauses) => { 180 chalk_ir::TyData::Dyn(where_clauses) => {
121 assert_eq!(where_clauses.binders.len(), 1); 181 assert_eq!(where_clauses.bounds.binders.len(), 1);
122 let predicates = 182 let predicates =
123 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); 183 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect();
124 Ty::Dyn(predicates) 184 Ty::Dyn(predicates)
125 } 185 }
126 chalk_ir::TyData::Opaque(where_clauses) => { 186 chalk_ir::TyData::Opaque(where_clauses) => {
127 assert_eq!(where_clauses.binders.len(), 1); 187 assert_eq!(where_clauses.bounds.binders.len(), 1);
128 let predicates = 188 let predicates =
129 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); 189 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect();
130 Ty::Opaque(predicates) 190 Ty::Opaque(predicates)
131 } 191 }
132 } 192 }
@@ -134,18 +194,21 @@ impl ToChalk for Ty {
134} 194}
135 195
136impl ToChalk for Substs { 196impl ToChalk for Substs {
137 type Chalk = Vec<chalk_ir::Parameter<ChalkIr>>; 197 type Chalk = Vec<chalk_ir::Parameter<TypeFamily>>;
138 198
139 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<ChalkIr>> { 199 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<TypeFamily>> {
140 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() 200 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect()
141 } 201 }
142 202
143 fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter<ChalkIr>>) -> Substs { 203 fn from_chalk(
204 db: &impl HirDatabase,
205 parameters: Vec<chalk_ir::Parameter<TypeFamily>>,
206 ) -> Substs {
144 let tys = parameters 207 let tys = parameters
145 .into_iter() 208 .into_iter()
146 .map(|p| match p { 209 .map(|p| match p.ty() {
147 chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty), 210 Some(ty) => from_chalk(db, ty.clone()),
148 chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(), 211 None => unimplemented!(),
149 }) 212 })
150 .collect(); 213 .collect();
151 Substs(tys) 214 Substs(tys)
@@ -153,88 +216,102 @@ impl ToChalk for Substs {
153} 216}
154 217
155impl ToChalk for TraitRef { 218impl ToChalk for TraitRef {
156 type Chalk = chalk_ir::TraitRef<ChalkIr>; 219 type Chalk = chalk_ir::TraitRef<TypeFamily>;
157 220
158 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<ChalkIr> { 221 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<TypeFamily> {
159 let trait_id = self.trait_.to_chalk(db); 222 let trait_id = self.trait_.to_chalk(db);
160 let parameters = self.substs.to_chalk(db); 223 let parameters = self.substs.to_chalk(db);
161 chalk_ir::TraitRef { trait_id, parameters } 224 chalk_ir::TraitRef { trait_id, parameters }
162 } 225 }
163 226
164 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<ChalkIr>) -> Self { 227 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<TypeFamily>) -> Self {
165 let trait_ = from_chalk(db, trait_ref.trait_id); 228 let trait_ = from_chalk(db, trait_ref.trait_id);
166 let substs = from_chalk(db, trait_ref.parameters); 229 let substs = from_chalk(db, trait_ref.parameters);
167 TraitRef { trait_, substs } 230 TraitRef { trait_, substs }
168 } 231 }
169} 232}
170 233
171impl ToChalk for TraitId { 234impl ToChalk for hir_def::TraitId {
172 type Chalk = chalk_ir::TraitId; 235 type Chalk = TraitId;
173 236
174 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { 237 fn to_chalk(self, _db: &impl HirDatabase) -> TraitId {
175 chalk_ir::TraitId(id_to_chalk(self)) 238 chalk_ir::TraitId(self.as_intern_id())
176 } 239 }
177 240
178 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId { 241 fn from_chalk(_db: &impl HirDatabase, trait_id: TraitId) -> hir_def::TraitId {
179 id_from_chalk(trait_id.0) 242 InternKey::from_intern_id(trait_id.0)
180 } 243 }
181} 244}
182 245
183impl ToChalk for TypeCtor { 246impl ToChalk for TypeCtor {
184 type Chalk = chalk_ir::StructId; 247 type Chalk = TypeName<TypeFamily>;
185 248
186 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::StructId { 249 fn to_chalk(self, db: &impl HirDatabase) -> TypeName<TypeFamily> {
187 db.intern_type_ctor(self).into() 250 match self {
251 TypeCtor::AssociatedType(type_alias) => {
252 let type_id = type_alias.to_chalk(db);
253 TypeName::AssociatedType(type_id)
254 }
255 _ => {
256 // other TypeCtors get interned and turned into a chalk StructId
257 let struct_id = db.intern_type_ctor(self).into();
258 TypeName::Struct(struct_id)
259 }
260 }
188 } 261 }
189 262
190 fn from_chalk(db: &impl HirDatabase, struct_id: chalk_ir::StructId) -> TypeCtor { 263 fn from_chalk(db: &impl HirDatabase, type_name: TypeName<TypeFamily>) -> TypeCtor {
191 db.lookup_intern_type_ctor(struct_id.into()) 264 match type_name {
265 TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
266 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
267 TypeName::Error => {
268 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
269 unreachable!()
270 }
271 }
192 } 272 }
193} 273}
194 274
195impl ToChalk for Impl { 275impl ToChalk for Impl {
196 type Chalk = chalk_ir::ImplId; 276 type Chalk = ImplId;
197 277
198 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ImplId { 278 fn to_chalk(self, db: &impl HirDatabase) -> ImplId {
199 db.intern_chalk_impl(self).into() 279 db.intern_chalk_impl(self).into()
200 } 280 }
201 281
202 fn from_chalk(db: &impl HirDatabase, impl_id: chalk_ir::ImplId) -> Impl { 282 fn from_chalk(db: &impl HirDatabase, impl_id: ImplId) -> Impl {
203 db.lookup_intern_chalk_impl(impl_id.into()) 283 db.lookup_intern_chalk_impl(impl_id.into())
204 } 284 }
205} 285}
206 286
207impl ToChalk for TypeAliasId { 287impl ToChalk for TypeAliasId {
208 type Chalk = chalk_ir::TypeId; 288 type Chalk = AssocTypeId;
209 289
210 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { 290 fn to_chalk(self, _db: &impl HirDatabase) -> AssocTypeId {
211 chalk_ir::TypeId(id_to_chalk(self)) 291 chalk_ir::AssocTypeId(self.as_intern_id())
212 } 292 }
213 293
214 fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAliasId { 294 fn from_chalk(_db: &impl HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId {
215 id_from_chalk(type_alias_id.0) 295 InternKey::from_intern_id(type_alias_id.0)
216 } 296 }
217} 297}
218 298
219impl ToChalk for AssocTyValue { 299impl ToChalk for AssocTyValue {
220 type Chalk = chalk_rust_ir::AssociatedTyValueId; 300 type Chalk = AssociatedTyValueId;
221 301
222 fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::AssociatedTyValueId { 302 fn to_chalk(self, db: &impl HirDatabase) -> AssociatedTyValueId {
223 db.intern_assoc_ty_value(self).into() 303 db.intern_assoc_ty_value(self).into()
224 } 304 }
225 305
226 fn from_chalk( 306 fn from_chalk(db: &impl HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue {
227 db: &impl HirDatabase,
228 assoc_ty_value_id: chalk_rust_ir::AssociatedTyValueId,
229 ) -> AssocTyValue {
230 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into()) 307 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into())
231 } 308 }
232} 309}
233 310
234impl ToChalk for GenericPredicate { 311impl ToChalk for GenericPredicate {
235 type Chalk = chalk_ir::QuantifiedWhereClause<ChalkIr>; 312 type Chalk = chalk_ir::QuantifiedWhereClause<TypeFamily>;
236 313
237 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<ChalkIr> { 314 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<TypeFamily> {
238 match self { 315 match self {
239 GenericPredicate::Implemented(trait_ref) => { 316 GenericPredicate::Implemented(trait_ref) => {
240 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 317 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
@@ -246,26 +323,16 @@ impl ToChalk for GenericPredicate {
246 }), 323 }),
247 0, 324 0,
248 ), 325 ),
249 GenericPredicate::Error => { 326 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
250 let impossible_trait_ref = chalk_ir::TraitRef {
251 trait_id: UNKNOWN_TRAIT,
252 parameters: vec![Ty::Unknown.to_chalk(db).cast()],
253 };
254 make_binders(chalk_ir::WhereClause::Implemented(impossible_trait_ref), 0)
255 }
256 } 327 }
257 } 328 }
258 329
259 fn from_chalk( 330 fn from_chalk(
260 db: &impl HirDatabase, 331 db: &impl HirDatabase,
261 where_clause: chalk_ir::QuantifiedWhereClause<ChalkIr>, 332 where_clause: chalk_ir::QuantifiedWhereClause<TypeFamily>,
262 ) -> GenericPredicate { 333 ) -> GenericPredicate {
263 match where_clause.value { 334 match where_clause.value {
264 chalk_ir::WhereClause::Implemented(tr) => { 335 chalk_ir::WhereClause::Implemented(tr) => {
265 if tr.trait_id == UNKNOWN_TRAIT {
266 // FIXME we need an Error enum on the Chalk side to avoid this
267 return GenericPredicate::Error;
268 }
269 GenericPredicate::Implemented(from_chalk(db, tr)) 336 GenericPredicate::Implemented(from_chalk(db, tr))
270 } 337 }
271 chalk_ir::WhereClause::ProjectionEq(projection_eq) => { 338 chalk_ir::WhereClause::ProjectionEq(projection_eq) => {
@@ -278,9 +345,9 @@ impl ToChalk for GenericPredicate {
278} 345}
279 346
280impl ToChalk for ProjectionTy { 347impl ToChalk for ProjectionTy {
281 type Chalk = chalk_ir::ProjectionTy<ChalkIr>; 348 type Chalk = chalk_ir::ProjectionTy<TypeFamily>;
282 349
283 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<ChalkIr> { 350 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<TypeFamily> {
284 chalk_ir::ProjectionTy { 351 chalk_ir::ProjectionTy {
285 associated_ty_id: self.associated_ty.to_chalk(db), 352 associated_ty_id: self.associated_ty.to_chalk(db),
286 parameters: self.parameters.to_chalk(db), 353 parameters: self.parameters.to_chalk(db),
@@ -289,7 +356,7 @@ impl ToChalk for ProjectionTy {
289 356
290 fn from_chalk( 357 fn from_chalk(
291 db: &impl HirDatabase, 358 db: &impl HirDatabase,
292 projection_ty: chalk_ir::ProjectionTy<ChalkIr>, 359 projection_ty: chalk_ir::ProjectionTy<TypeFamily>,
293 ) -> ProjectionTy { 360 ) -> ProjectionTy {
294 ProjectionTy { 361 ProjectionTy {
295 associated_ty: from_chalk(db, projection_ty.associated_ty_id), 362 associated_ty: from_chalk(db, projection_ty.associated_ty_id),
@@ -299,31 +366,31 @@ impl ToChalk for ProjectionTy {
299} 366}
300 367
301impl ToChalk for super::ProjectionPredicate { 368impl ToChalk for super::ProjectionPredicate {
302 type Chalk = chalk_ir::Normalize<ChalkIr>; 369 type Chalk = chalk_ir::Normalize<TypeFamily>;
303 370
304 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<ChalkIr> { 371 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<TypeFamily> {
305 chalk_ir::Normalize { 372 chalk_ir::Normalize {
306 projection: self.projection_ty.to_chalk(db), 373 projection: self.projection_ty.to_chalk(db),
307 ty: self.ty.to_chalk(db), 374 ty: self.ty.to_chalk(db),
308 } 375 }
309 } 376 }
310 377
311 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<ChalkIr>) -> Self { 378 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<TypeFamily>) -> Self {
312 unimplemented!() 379 unimplemented!()
313 } 380 }
314} 381}
315 382
316impl ToChalk for Obligation { 383impl ToChalk for Obligation {
317 type Chalk = chalk_ir::DomainGoal<ChalkIr>; 384 type Chalk = chalk_ir::DomainGoal<TypeFamily>;
318 385
319 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<ChalkIr> { 386 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<TypeFamily> {
320 match self { 387 match self {
321 Obligation::Trait(tr) => tr.to_chalk(db).cast(), 388 Obligation::Trait(tr) => tr.to_chalk(db).cast(),
322 Obligation::Projection(pr) => pr.to_chalk(db).cast(), 389 Obligation::Projection(pr) => pr.to_chalk(db).cast(),
323 } 390 }
324 } 391 }
325 392
326 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<ChalkIr>) -> Self { 393 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<TypeFamily>) -> Self {
327 unimplemented!() 394 unimplemented!()
328 } 395 }
329} 396}
@@ -347,16 +414,17 @@ where
347} 414}
348 415
349impl ToChalk for Arc<super::TraitEnvironment> { 416impl ToChalk for Arc<super::TraitEnvironment> {
350 type Chalk = chalk_ir::Environment<ChalkIr>; 417 type Chalk = chalk_ir::Environment<TypeFamily>;
351 418
352 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<ChalkIr> { 419 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<TypeFamily> {
353 let mut clauses = Vec::new(); 420 let mut clauses = Vec::new();
354 for pred in &self.predicates { 421 for pred in &self.predicates {
355 if pred.is_error() { 422 if pred.is_error() {
356 // for env, we just ignore errors 423 // for env, we just ignore errors
357 continue; 424 continue;
358 } 425 }
359 let program_clause: chalk_ir::ProgramClause<ChalkIr> = pred.clone().to_chalk(db).cast(); 426 let program_clause: chalk_ir::ProgramClause<TypeFamily> =
427 pred.clone().to_chalk(db).cast();
360 clauses.push(program_clause.into_from_env_clause()); 428 clauses.push(program_clause.into_from_env_clause());
361 } 429 }
362 chalk_ir::Environment::new().add_clauses(clauses) 430 chalk_ir::Environment::new().add_clauses(clauses)
@@ -364,7 +432,7 @@ impl ToChalk for Arc<super::TraitEnvironment> {
364 432
365 fn from_chalk( 433 fn from_chalk(
366 _db: &impl HirDatabase, 434 _db: &impl HirDatabase,
367 _env: chalk_ir::Environment<ChalkIr>, 435 _env: chalk_ir::Environment<TypeFamily>,
368 ) -> Arc<super::TraitEnvironment> { 436 ) -> Arc<super::TraitEnvironment> {
369 unimplemented!() 437 unimplemented!()
370 } 438 }
@@ -372,7 +440,7 @@ impl ToChalk for Arc<super::TraitEnvironment> {
372 440
373impl<T: ToChalk> ToChalk for super::InEnvironment<T> 441impl<T: ToChalk> ToChalk for super::InEnvironment<T>
374where 442where
375 T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = ChalkIr>, 443 T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = TypeFamily>,
376{ 444{
377 type Chalk = chalk_ir::InEnvironment<T::Chalk>; 445 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
378 446
@@ -395,9 +463,9 @@ where
395} 463}
396 464
397impl ToChalk for builtin::BuiltinImplData { 465impl ToChalk for builtin::BuiltinImplData {
398 type Chalk = chalk_rust_ir::ImplDatum<ChalkIr>; 466 type Chalk = ImplDatum;
399 467
400 fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::ImplDatum<ChalkIr> { 468 fn to_chalk(self, db: &impl HirDatabase) -> ImplDatum {
401 let impl_type = chalk_rust_ir::ImplType::External; 469 let impl_type = chalk_rust_ir::ImplType::External;
402 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect(); 470 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect();
403 471
@@ -413,15 +481,15 @@ impl ToChalk for builtin::BuiltinImplData {
413 } 481 }
414 } 482 }
415 483
416 fn from_chalk(_db: &impl HirDatabase, _data: chalk_rust_ir::ImplDatum<ChalkIr>) -> Self { 484 fn from_chalk(_db: &impl HirDatabase, _data: ImplDatum) -> Self {
417 unimplemented!() 485 unimplemented!()
418 } 486 }
419} 487}
420 488
421impl ToChalk for builtin::BuiltinImplAssocTyValueData { 489impl ToChalk for builtin::BuiltinImplAssocTyValueData {
422 type Chalk = chalk_rust_ir::AssociatedTyValue<ChalkIr>; 490 type Chalk = AssociatedTyValue;
423 491
424 fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::AssociatedTyValue<ChalkIr> { 492 fn to_chalk(self, db: &impl HirDatabase) -> AssociatedTyValue {
425 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: self.value.to_chalk(db) }; 493 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: self.value.to_chalk(db) };
426 494
427 chalk_rust_ir::AssociatedTyValue { 495 chalk_rust_ir::AssociatedTyValue {
@@ -433,7 +501,7 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData {
433 501
434 fn from_chalk( 502 fn from_chalk(
435 _db: &impl HirDatabase, 503 _db: &impl HirDatabase,
436 _data: chalk_rust_ir::AssociatedTyValue<ChalkIr>, 504 _data: AssociatedTyValue,
437 ) -> builtin::BuiltinImplAssocTyValueData { 505 ) -> builtin::BuiltinImplAssocTyValueData {
438 unimplemented!() 506 unimplemented!()
439 } 507 }
@@ -450,46 +518,46 @@ fn convert_where_clauses(
450 db: &impl HirDatabase, 518 db: &impl HirDatabase,
451 def: GenericDefId, 519 def: GenericDefId,
452 substs: &Substs, 520 substs: &Substs,
453) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> { 521) -> Vec<chalk_ir::QuantifiedWhereClause<TypeFamily>> {
454 let generic_predicates = db.generic_predicates(def); 522 let generic_predicates = db.generic_predicates(def);
455 let mut result = Vec::with_capacity(generic_predicates.len()); 523 let mut result = Vec::with_capacity(generic_predicates.len());
456 for pred in generic_predicates.iter() { 524 for pred in generic_predicates.iter() {
457 if pred.is_error() { 525 if pred.is_error() {
458 // HACK: Return just the single predicate (which is always false 526 // skip errored predicates completely
459 // anyway), otherwise Chalk can easily get into slow situations 527 continue;
460 return vec![pred.clone().subst(substs).to_chalk(db)];
461 } 528 }
462 result.push(pred.clone().subst(substs).to_chalk(db)); 529 result.push(pred.clone().subst(substs).to_chalk(db));
463 } 530 }
464 result 531 result
465} 532}
466 533
467impl<'a, DB> chalk_solve::RustIrDatabase<ChalkIr> for ChalkContext<'a, DB> 534impl<'a, DB> chalk_solve::RustIrDatabase<TypeFamily> for ChalkContext<'a, DB>
468where 535where
469 DB: HirDatabase, 536 DB: HirDatabase,
470{ 537{
471 fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum<ChalkIr>> { 538 fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> {
472 self.db.associated_ty_data(id) 539 self.db.associated_ty_data(id)
473 } 540 }
474 fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum<ChalkIr>> { 541 fn trait_datum(&self, trait_id: TraitId) -> Arc<TraitDatum> {
475 self.db.trait_datum(self.krate, trait_id) 542 self.db.trait_datum(self.krate, trait_id)
476 } 543 }
477 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum<ChalkIr>> { 544 fn struct_datum(&self, struct_id: StructId) -> Arc<StructDatum> {
478 self.db.struct_datum(self.krate, struct_id) 545 self.db.struct_datum(self.krate, struct_id)
479 } 546 }
480 fn impl_datum(&self, impl_id: chalk_ir::ImplId) -> Arc<ImplDatum<ChalkIr>> { 547 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
481 self.db.impl_datum(self.krate, impl_id) 548 self.db.impl_datum(self.krate, impl_id)
482 } 549 }
483 fn impls_for_trait( 550 fn impls_for_trait(
484 &self, 551 &self,
485 trait_id: chalk_ir::TraitId, 552 trait_id: TraitId,
486 parameters: &[Parameter<ChalkIr>], 553 parameters: &[Parameter<TypeFamily>],
487 ) -> Vec<chalk_ir::ImplId> { 554 ) -> Vec<ImplId> {
488 debug!("impls_for_trait {:?}", trait_id); 555 debug!("impls_for_trait {:?}", trait_id);
489 if trait_id == UNKNOWN_TRAIT { 556 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
490 return Vec::new(); 557
491 } 558 // Note: Since we're using impls_for_trait, only impls where the trait
492 let trait_: TraitId = from_chalk(self.db, trait_id); 559 // can be resolved should ever reach Chalk. `impl_datum` relies on that
560 // and will panic if the trait can't be resolved.
493 let mut result: Vec<_> = self 561 let mut result: Vec<_> = self
494 .db 562 .db
495 .impls_for_trait(self.krate, trait_.into()) 563 .impls_for_trait(self.krate, trait_.into())
@@ -508,39 +576,32 @@ where
508 debug!("impls_for_trait returned {} impls", result.len()); 576 debug!("impls_for_trait returned {} impls", result.len());
509 result 577 result
510 } 578 }
511 fn impl_provided_for( 579 fn impl_provided_for(&self, auto_trait_id: TraitId, struct_id: StructId) -> bool {
512 &self,
513 auto_trait_id: chalk_ir::TraitId,
514 struct_id: chalk_ir::StructId,
515 ) -> bool {
516 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id); 580 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id);
517 false // FIXME 581 false // FIXME
518 } 582 }
519 fn type_name(&self, _id: TypeKindId) -> Identifier { 583 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
520 unimplemented!()
521 }
522 fn associated_ty_value(
523 &self,
524 id: chalk_rust_ir::AssociatedTyValueId,
525 ) -> Arc<AssociatedTyValue<ChalkIr>> {
526 self.db.associated_ty_value(self.krate.into(), id) 584 self.db.associated_ty_value(self.krate.into(), id)
527 } 585 }
528 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> { 586 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<TypeFamily>> {
529 vec![] 587 vec![]
530 } 588 }
531 fn local_impls_to_coherence_check( 589 fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec<ImplId> {
532 &self,
533 _trait_id: chalk_ir::TraitId,
534 ) -> Vec<chalk_ir::ImplId> {
535 // We don't do coherence checking (yet) 590 // We don't do coherence checking (yet)
536 unimplemented!() 591 unimplemented!()
537 } 592 }
593 fn as_struct_id(&self, id: &TypeName<TypeFamily>) -> Option<StructId> {
594 match id {
595 TypeName::Struct(struct_id) => Some(*struct_id),
596 _ => None,
597 }
598 }
538} 599}
539 600
540pub(crate) fn associated_ty_data_query( 601pub(crate) fn associated_ty_data_query(
541 db: &impl HirDatabase, 602 db: &impl HirDatabase,
542 id: TypeId, 603 id: AssocTypeId,
543) -> Arc<AssociatedTyDatum<ChalkIr>> { 604) -> Arc<AssociatedTyDatum> {
544 debug!("associated_ty_data {:?}", id); 605 debug!("associated_ty_data {:?}", id);
545 let type_alias: TypeAliasId = from_chalk(db, id); 606 let type_alias: TypeAliasId = from_chalk(db, id);
546 let trait_ = match type_alias.lookup(db).container { 607 let trait_ = match type_alias.lookup(db).container {
@@ -565,28 +626,10 @@ pub(crate) fn associated_ty_data_query(
565pub(crate) fn trait_datum_query( 626pub(crate) fn trait_datum_query(
566 db: &impl HirDatabase, 627 db: &impl HirDatabase,
567 krate: CrateId, 628 krate: CrateId,
568 trait_id: chalk_ir::TraitId, 629 trait_id: TraitId,
569) -> Arc<TraitDatum<ChalkIr>> { 630) -> Arc<TraitDatum> {
570 debug!("trait_datum {:?}", trait_id); 631 debug!("trait_datum {:?}", trait_id);
571 if trait_id == UNKNOWN_TRAIT { 632 let trait_: hir_def::TraitId = from_chalk(db, trait_id);
572 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses: Vec::new() };
573
574 let flags = chalk_rust_ir::TraitFlags {
575 auto: false,
576 marker: false,
577 upstream: true,
578 fundamental: false,
579 non_enumerable: true,
580 coinductive: false,
581 };
582 return Arc::new(TraitDatum {
583 id: trait_id,
584 binders: make_binders(trait_datum_bound, 1),
585 flags,
586 associated_ty_ids: vec![],
587 });
588 }
589 let trait_: TraitId = from_chalk(db, trait_id);
590 let trait_data = db.trait_data(trait_); 633 let trait_data = db.trait_data(trait_);
591 debug!("trait {:?} = {:?}", trait_id, trait_data.name); 634 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
592 let generic_params = generics(db, trait_.into()); 635 let generic_params = generics(db, trait_.into());
@@ -616,10 +659,10 @@ pub(crate) fn trait_datum_query(
616pub(crate) fn struct_datum_query( 659pub(crate) fn struct_datum_query(
617 db: &impl HirDatabase, 660 db: &impl HirDatabase,
618 krate: CrateId, 661 krate: CrateId,
619 struct_id: chalk_ir::StructId, 662 struct_id: StructId,
620) -> Arc<StructDatum<ChalkIr>> { 663) -> Arc<StructDatum> {
621 debug!("struct_datum {:?}", struct_id); 664 debug!("struct_datum {:?}", struct_id);
622 let type_ctor: TypeCtor = from_chalk(db, struct_id); 665 let type_ctor: TypeCtor = from_chalk(db, TypeName::Struct(struct_id));
623 debug!("struct {:?} = {:?}", struct_id, type_ctor); 666 debug!("struct {:?} = {:?}", struct_id, type_ctor);
624 let num_params = type_ctor.num_ty_params(db); 667 let num_params = type_ctor.num_ty_params(db);
625 let upstream = type_ctor.krate(db) != Some(krate); 668 let upstream = type_ctor.krate(db) != Some(krate);
@@ -648,25 +691,27 @@ pub(crate) fn struct_datum_query(
648pub(crate) fn impl_datum_query( 691pub(crate) fn impl_datum_query(
649 db: &impl HirDatabase, 692 db: &impl HirDatabase,
650 krate: CrateId, 693 krate: CrateId,
651 impl_id: chalk_ir::ImplId, 694 impl_id: ImplId,
652) -> Arc<ImplDatum<ChalkIr>> { 695) -> Arc<ImplDatum> {
653 let _p = ra_prof::profile("impl_datum"); 696 let _p = ra_prof::profile("impl_datum");
654 debug!("impl_datum {:?}", impl_id); 697 debug!("impl_datum {:?}", impl_id);
655 let impl_: Impl = from_chalk(db, impl_id); 698 let impl_: Impl = from_chalk(db, impl_id);
656 match impl_ { 699 match impl_ {
657 Impl::ImplBlock(impl_block) => impl_block_datum(db, krate, impl_id, impl_block), 700 Impl::ImplBlock(impl_block) => impl_block_datum(db, krate, impl_id, impl_block),
658 _ => builtin::impl_datum(db, krate, impl_).map(|d| Arc::new(d.to_chalk(db))), 701 _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)),
659 } 702 }
660 .unwrap_or_else(invalid_impl_datum)
661} 703}
662 704
663fn impl_block_datum( 705fn impl_block_datum(
664 db: &impl HirDatabase, 706 db: &impl HirDatabase,
665 krate: CrateId, 707 krate: CrateId,
666 chalk_id: chalk_ir::ImplId, 708 chalk_id: ImplId,
667 impl_id: ImplId, 709 impl_id: hir_def::ImplId,
668) -> Option<Arc<ImplDatum<ChalkIr>>> { 710) -> Arc<ImplDatum> {
669 let trait_ref = db.impl_trait(impl_id)?; 711 let trait_ref = db
712 .impl_trait(impl_id)
713 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk
714 .expect("invalid impl passed to Chalk");
670 let impl_data = db.impl_data(impl_id); 715 let impl_data = db.impl_data(impl_id);
671 716
672 let generic_params = generics(db, impl_id.into()); 717 let generic_params = generics(db, impl_id.into());
@@ -718,29 +763,14 @@ fn impl_block_datum(
718 polarity, 763 polarity,
719 associated_ty_value_ids, 764 associated_ty_value_ids,
720 }; 765 };
721 Some(Arc::new(impl_datum))
722}
723
724fn invalid_impl_datum() -> Arc<ImplDatum<ChalkIr>> {
725 let trait_ref = chalk_ir::TraitRef {
726 trait_id: UNKNOWN_TRAIT,
727 parameters: vec![chalk_ir::TyData::BoundVar(0).cast().intern().cast()],
728 };
729 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses: Vec::new() };
730 let impl_datum = ImplDatum {
731 binders: make_binders(impl_datum_bound, 1),
732 impl_type: chalk_rust_ir::ImplType::External,
733 polarity: chalk_rust_ir::Polarity::Positive,
734 associated_ty_value_ids: Vec::new(),
735 };
736 Arc::new(impl_datum) 766 Arc::new(impl_datum)
737} 767}
738 768
739pub(crate) fn associated_ty_value_query( 769pub(crate) fn associated_ty_value_query(
740 db: &impl HirDatabase, 770 db: &impl HirDatabase,
741 krate: CrateId, 771 krate: CrateId,
742 id: chalk_rust_ir::AssociatedTyValueId, 772 id: AssociatedTyValueId,
743) -> Arc<chalk_rust_ir::AssociatedTyValue<ChalkIr>> { 773) -> Arc<AssociatedTyValue> {
744 let data: AssocTyValue = from_chalk(db, id); 774 let data: AssocTyValue = from_chalk(db, id);
745 match data { 775 match data {
746 AssocTyValue::TypeAlias(type_alias) => { 776 AssocTyValue::TypeAlias(type_alias) => {
@@ -754,7 +784,7 @@ fn type_alias_associated_ty_value(
754 db: &impl HirDatabase, 784 db: &impl HirDatabase,
755 _krate: CrateId, 785 _krate: CrateId,
756 type_alias: TypeAliasId, 786 type_alias: TypeAliasId,
757) -> Arc<AssociatedTyValue<ChalkIr>> { 787) -> Arc<AssociatedTyValue> {
758 let type_alias_data = db.type_alias_data(type_alias); 788 let type_alias_data = db.type_alias_data(type_alias);
759 let impl_id = match type_alias.lookup(db).container { 789 let impl_id = match type_alias.lookup(db).container {
760 AssocContainerId::ImplId(it) => it, 790 AssocContainerId::ImplId(it) => it,
@@ -786,27 +816,27 @@ fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId {
786 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } 816 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() }
787} 817}
788 818
789impl From<chalk_ir::StructId> for crate::TypeCtorId { 819impl From<StructId> for crate::TypeCtorId {
790 fn from(struct_id: chalk_ir::StructId) -> Self { 820 fn from(struct_id: StructId) -> Self {
791 id_from_chalk(struct_id.0) 821 InternKey::from_intern_id(struct_id.0)
792 } 822 }
793} 823}
794 824
795impl From<crate::TypeCtorId> for chalk_ir::StructId { 825impl From<crate::TypeCtorId> for StructId {
796 fn from(type_ctor_id: crate::TypeCtorId) -> Self { 826 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
797 chalk_ir::StructId(id_to_chalk(type_ctor_id)) 827 chalk_ir::StructId(type_ctor_id.as_intern_id())
798 } 828 }
799} 829}
800 830
801impl From<chalk_ir::ImplId> for crate::traits::GlobalImplId { 831impl From<ImplId> for crate::traits::GlobalImplId {
802 fn from(impl_id: chalk_ir::ImplId) -> Self { 832 fn from(impl_id: ImplId) -> Self {
803 id_from_chalk(impl_id.0) 833 InternKey::from_intern_id(impl_id.0)
804 } 834 }
805} 835}
806 836
807impl From<crate::traits::GlobalImplId> for chalk_ir::ImplId { 837impl From<crate::traits::GlobalImplId> for ImplId {
808 fn from(impl_id: crate::traits::GlobalImplId) -> Self { 838 fn from(impl_id: crate::traits::GlobalImplId) -> Self {
809 chalk_ir::ImplId(id_to_chalk(impl_id)) 839 chalk_ir::ImplId(impl_id.as_intern_id())
810 } 840 }
811} 841}
812 842
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml
index e826c10ef..030e9033c 100644
--- a/crates/ra_lsp_server/Cargo.toml
+++ b/crates/ra_lsp_server/Cargo.toml
@@ -14,7 +14,7 @@ serde_json = "1.0.34"
14serde = { version = "1.0.83", features = ["derive"] } 14serde = { version = "1.0.83", features = ["derive"] }
15crossbeam-channel = "0.4" 15crossbeam-channel = "0.4"
16log = "0.4.3" 16log = "0.4.3"
17lsp-types = { version = "0.65.0", features = ["proposed"] } 17lsp-types = { version = "0.67.0", features = ["proposed"] }
18rustc-hash = "1.0" 18rustc-hash = "1.0"
19parking_lot = "0.10.0" 19parking_lot = "0.10.0"
20jod-thread = "0.1.0" 20jod-thread = "0.1.0"
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs
index eeca67ee1..ceb4c4259 100644
--- a/crates/ra_lsp_server/src/caps.rs
+++ b/crates/ra_lsp_server/src/caps.rs
@@ -46,6 +46,7 @@ pub fn server_capabilities() -> ServerCapabilities {
46 more_trigger_character: Some(vec![".".to_string(), ">".to_string()]), 46 more_trigger_character: Some(vec![".".to_string(), ">".to_string()]),
47 }), 47 }),
48 selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)), 48 selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
49 semantic_highlighting: None,
49 folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)), 50 folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
50 rename_provider: Some(RenameProviderCapability::Options(RenameOptions { 51 rename_provider: Some(RenameProviderCapability::Options(RenameOptions {
51 prepare_provider: Some(true), 52 prepare_provider: Some(true),
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index a8f625176..baaef3023 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -221,6 +221,10 @@ impl ast::FnDef {
221 .and_then(|it| it.into_token()) 221 .and_then(|it| it.into_token())
222 .filter(|it| it.kind() == T![;]) 222 .filter(|it| it.kind() == T![;])
223 } 223 }
224
225 pub fn is_async(&self) -> bool {
226 self.syntax().children_with_tokens().any(|it| it.kind() == T![async])
227 }
224} 228}
225 229
226impl ast::LetStmt { 230impl ast::LetStmt {
diff --git a/docs/user/assists.md b/docs/user/assists.md
index 334ba450f..ecf206f71 100644
--- a/docs/user/assists.md
+++ b/docs/user/assists.md
@@ -98,26 +98,26 @@ Adds scaffold for overriding default impl members.
98 98
99```rust 99```rust
100// BEFORE 100// BEFORE
101trait T { 101trait Trait {
102 Type X; 102 Type X;
103 fn foo(&self); 103 fn foo(&self);
104 fn bar(&self) {} 104 fn bar(&self) {}
105} 105}
106 106
107impl T for () { 107impl Trait for () {
108 Type X = (); 108 Type X = ();
109 fn foo(&self) {}┃ 109 fn foo(&self) {}┃
110 110
111} 111}
112 112
113// AFTER 113// AFTER
114trait T { 114trait Trait {
115 Type X; 115 Type X;
116 fn foo(&self); 116 fn foo(&self);
117 fn bar(&self) {} 117 fn bar(&self) {}
118} 118}
119 119
120impl T for () { 120impl Trait for () {
121 Type X = (); 121 Type X = ();
122 fn foo(&self) {} 122 fn foo(&self) {}
123 fn bar(&self) {} 123 fn bar(&self) {}
@@ -131,25 +131,25 @@ Adds scaffold for required impl members.
131 131
132```rust 132```rust
133// BEFORE 133// BEFORE
134trait T { 134trait Trait<T> {
135 Type X; 135 Type X;
136 fn foo(&self); 136 fn foo(&self) -> T;
137 fn bar(&self) {} 137 fn bar(&self) {}
138} 138}
139 139
140impl T for () {┃ 140impl Trait<u32> for () {┃
141 141
142} 142}
143 143
144// AFTER 144// AFTER
145trait T { 145trait Trait<T> {
146 Type X; 146 Type X;
147 fn foo(&self); 147 fn foo(&self) -> T;
148 fn bar(&self) {} 148 fn bar(&self) {}
149} 149}
150 150
151impl T for () { 151impl Trait<u32> for () {
152 fn foo(&self) { unimplemented!() } 152 fn foo(&self) -> u32 { unimplemented!() }
153 153
154} 154}
155``` 155```
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 4201c6a6a..9cefad925 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -226,7 +226,7 @@ fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> {
226 if !str::from_utf8(&output.stdout)?.contains("ra-lsp") { 226 if !str::from_utf8(&output.stdout)?.contains("ra-lsp") {
227 anyhow::bail!( 227 anyhow::bail!(
228 "Could not install the Visual Studio Code extension. \ 228 "Could not install the Visual Studio Code extension. \
229 Please make sure you have at least NodeJS 10.x installed and try again." 229 Please make sure you have at least NodeJS 10.x together with the latest version of VS Code installed and try again."
230 ); 230 );
231 } 231 }
232 232