diff options
85 files changed, 2736 insertions, 2330 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dddc82f80..b5160eaa3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md | |||
@@ -13,12 +13,9 @@ Forum for questions: https://users.rust-lang.org/c/ide/14 | |||
13 | 13 | ||
14 | Before submitting, please make sure that you're not running into one of these known issues: | 14 | Before submitting, please make sure that you're not running into one of these known issues: |
15 | 15 | ||
16 | 1. local imports (`use` statements) don't work: #1165 | 16 | 1. on-the-fly diagnostics are mostly unimplemented (`cargo check` diagnostics will be shown when saving a file) |
17 | 2. local items don't work: #1559 | 17 | 2. some settings are required for procedural macro and build script support (`rust-analyzer.cargo.loadOutDirsFromCheck`, `rust-analyzer.procMacro.enable`): #6448 |
18 | 3. on-the-fly diagnostics are mostly unimplemented (`cargo check` diagnostics will be shown when saving a file) | 18 | 3. some platform-specific imports are not resolved: #6038 |
19 | 4. some settings are required for procedural macro and build script support (`rust-analyzer.cargo.loadOutDirsFromCheck`, `rust-analyzer.procMacro.enable`): #6448 | ||
20 | 5. some platform-specific imports are not resolved: #6038 | ||
21 | 6. the official `rust-lang.rust` VS Code extension conflicts with `rust-analyzer`: #6463 | ||
22 | 19 | ||
23 | Otherwise please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3. | 20 | Otherwise please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3. |
24 | --> | 21 | --> |
diff --git a/Cargo.lock b/Cargo.lock index 3d2bf8f05..ec5aecfa0 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -13,9 +13,9 @@ dependencies = [ | |||
13 | 13 | ||
14 | [[package]] | 14 | [[package]] |
15 | name = "adler" | 15 | name = "adler" |
16 | version = "1.0.1" | 16 | version = "1.0.2" |
17 | source = "registry+https://github.com/rust-lang/crates.io-index" | 17 | source = "registry+https://github.com/rust-lang/crates.io-index" |
18 | checksum = "bedc89c5c7b5550ffb9372eb5c5ffc7f9f705cc3f4a128bd4669b9745f555093" | 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" |
19 | 19 | ||
20 | [[package]] | 20 | [[package]] |
21 | name = "always-assert" | 21 | name = "always-assert" |
@@ -112,6 +112,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
112 | checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" | 112 | checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" |
113 | 113 | ||
114 | [[package]] | 114 | [[package]] |
115 | name = "camino" | ||
116 | version = "1.0.1" | ||
117 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
118 | checksum = "9bb47ab72bdba43021afa16dc1ef4d80c980d366b17ed37ea8d2ebe2087075b9" | ||
119 | dependencies = [ | ||
120 | "serde", | ||
121 | ] | ||
122 | |||
123 | [[package]] | ||
115 | name = "cargo-platform" | 124 | name = "cargo-platform" |
116 | version = "0.1.1" | 125 | version = "0.1.1" |
117 | source = "registry+https://github.com/rust-lang/crates.io-index" | 126 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -122,10 +131,11 @@ dependencies = [ | |||
122 | 131 | ||
123 | [[package]] | 132 | [[package]] |
124 | name = "cargo_metadata" | 133 | name = "cargo_metadata" |
125 | version = "0.12.3" | 134 | version = "0.13.1" |
126 | source = "registry+https://github.com/rust-lang/crates.io-index" | 135 | source = "registry+https://github.com/rust-lang/crates.io-index" |
127 | checksum = "7714a157da7991e23d90686b9524b9e12e0407a108647f52e9328f4b3d51ac7f" | 136 | checksum = "081e3f0755c1f380c2d010481b6fa2e02973586d5f2b24eebb7a2a1d98b143d8" |
128 | dependencies = [ | 137 | dependencies = [ |
138 | "camino", | ||
129 | "cargo-platform", | 139 | "cargo-platform", |
130 | "semver", | 140 | "semver", |
131 | "semver-parser", | 141 | "semver-parser", |
@@ -158,9 +168,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | |||
158 | 168 | ||
159 | [[package]] | 169 | [[package]] |
160 | name = "chalk-derive" | 170 | name = "chalk-derive" |
161 | version = "0.58.0" | 171 | version = "0.59.0" |
162 | source = "registry+https://github.com/rust-lang/crates.io-index" | 172 | source = "registry+https://github.com/rust-lang/crates.io-index" |
163 | checksum = "e625b7c688272783140509a0de8f7aa9000217cb0982c9b10606a12b0b747ba8" | 173 | checksum = "4b9000fbcb67353dc8973ab9fd136277d321d85b79bd36b8756bb3ae0979a94a" |
164 | dependencies = [ | 174 | dependencies = [ |
165 | "proc-macro2", | 175 | "proc-macro2", |
166 | "quote", | 176 | "quote", |
@@ -170,9 +180,9 @@ dependencies = [ | |||
170 | 180 | ||
171 | [[package]] | 181 | [[package]] |
172 | name = "chalk-ir" | 182 | name = "chalk-ir" |
173 | version = "0.58.0" | 183 | version = "0.59.0" |
174 | source = "registry+https://github.com/rust-lang/crates.io-index" | 184 | source = "registry+https://github.com/rust-lang/crates.io-index" |
175 | checksum = "c220d870128959d7d56667060d556ffdebd490f32ee0fc9f4060a76c1193f206" | 185 | checksum = "b23528d61b3557c676eccf508fa0771a38453b379f0b780154eaa7f70afe8dfc" |
176 | dependencies = [ | 186 | dependencies = [ |
177 | "bitflags", | 187 | "bitflags", |
178 | "chalk-derive", | 188 | "chalk-derive", |
@@ -181,9 +191,9 @@ dependencies = [ | |||
181 | 191 | ||
182 | [[package]] | 192 | [[package]] |
183 | name = "chalk-recursive" | 193 | name = "chalk-recursive" |
184 | version = "0.58.0" | 194 | version = "0.59.0" |
185 | source = "registry+https://github.com/rust-lang/crates.io-index" | 195 | source = "registry+https://github.com/rust-lang/crates.io-index" |
186 | checksum = "7d8cd81a15aa936215378e695a8907b9f1af8626a27a32ee22e97a50984960da" | 196 | checksum = "a8bdd37afc666b771de8b4429fe014363d0e74aae5cc26f320f60a3eab34d744" |
187 | dependencies = [ | 197 | dependencies = [ |
188 | "chalk-derive", | 198 | "chalk-derive", |
189 | "chalk-ir", | 199 | "chalk-ir", |
@@ -194,14 +204,14 @@ dependencies = [ | |||
194 | 204 | ||
195 | [[package]] | 205 | [[package]] |
196 | name = "chalk-solve" | 206 | name = "chalk-solve" |
197 | version = "0.58.0" | 207 | version = "0.59.0" |
198 | source = "registry+https://github.com/rust-lang/crates.io-index" | 208 | source = "registry+https://github.com/rust-lang/crates.io-index" |
199 | checksum = "55571250dfe096a4c899be88c81418284c952ce1c8a06aa16afb5781b298e9c9" | 209 | checksum = "4182c42ca319cb71c89898ebc3d2671d1fa7d928123b171b66f1797a2000b9c8" |
200 | dependencies = [ | 210 | dependencies = [ |
201 | "chalk-derive", | 211 | "chalk-derive", |
202 | "chalk-ir", | 212 | "chalk-ir", |
203 | "ena", | 213 | "ena", |
204 | "itertools 0.9.0", | 214 | "itertools", |
205 | "petgraph", | 215 | "petgraph", |
206 | "rustc-hash", | 216 | "rustc-hash", |
207 | "tracing", | 217 | "tracing", |
@@ -475,7 +485,7 @@ dependencies = [ | |||
475 | "hir_def", | 485 | "hir_def", |
476 | "hir_expand", | 486 | "hir_expand", |
477 | "hir_ty", | 487 | "hir_ty", |
478 | "itertools 0.10.0", | 488 | "itertools", |
479 | "log", | 489 | "log", |
480 | "profile", | 490 | "profile", |
481 | "rustc-hash", | 491 | "rustc-hash", |
@@ -497,7 +507,7 @@ dependencies = [ | |||
497 | "fst", | 507 | "fst", |
498 | "hir_expand", | 508 | "hir_expand", |
499 | "indexmap", | 509 | "indexmap", |
500 | "itertools 0.10.0", | 510 | "itertools", |
501 | "la-arena", | 511 | "la-arena", |
502 | "log", | 512 | "log", |
503 | "mbe", | 513 | "mbe", |
@@ -541,7 +551,7 @@ dependencies = [ | |||
541 | "expect-test", | 551 | "expect-test", |
542 | "hir_def", | 552 | "hir_def", |
543 | "hir_expand", | 553 | "hir_expand", |
544 | "itertools 0.10.0", | 554 | "itertools", |
545 | "la-arena", | 555 | "la-arena", |
546 | "log", | 556 | "log", |
547 | "once_cell", | 557 | "once_cell", |
@@ -579,7 +589,7 @@ dependencies = [ | |||
579 | "ide_db", | 589 | "ide_db", |
580 | "ide_ssr", | 590 | "ide_ssr", |
581 | "indexmap", | 591 | "indexmap", |
582 | "itertools 0.10.0", | 592 | "itertools", |
583 | "log", | 593 | "log", |
584 | "oorandom", | 594 | "oorandom", |
585 | "profile", | 595 | "profile", |
@@ -601,7 +611,7 @@ dependencies = [ | |||
601 | "expect-test", | 611 | "expect-test", |
602 | "hir", | 612 | "hir", |
603 | "ide_db", | 613 | "ide_db", |
604 | "itertools 0.10.0", | 614 | "itertools", |
605 | "profile", | 615 | "profile", |
606 | "rustc-hash", | 616 | "rustc-hash", |
607 | "stdx", | 617 | "stdx", |
@@ -619,7 +629,7 @@ dependencies = [ | |||
619 | "expect-test", | 629 | "expect-test", |
620 | "hir", | 630 | "hir", |
621 | "ide_db", | 631 | "ide_db", |
622 | "itertools 0.10.0", | 632 | "itertools", |
623 | "log", | 633 | "log", |
624 | "profile", | 634 | "profile", |
625 | "rustc-hash", | 635 | "rustc-hash", |
@@ -638,7 +648,7 @@ dependencies = [ | |||
638 | "expect-test", | 648 | "expect-test", |
639 | "fst", | 649 | "fst", |
640 | "hir", | 650 | "hir", |
641 | "itertools 0.10.0", | 651 | "itertools", |
642 | "log", | 652 | "log", |
643 | "once_cell", | 653 | "once_cell", |
644 | "profile", | 654 | "profile", |
@@ -657,7 +667,7 @@ dependencies = [ | |||
657 | "expect-test", | 667 | "expect-test", |
658 | "hir", | 668 | "hir", |
659 | "ide_db", | 669 | "ide_db", |
660 | "itertools 0.10.0", | 670 | "itertools", |
661 | "rustc-hash", | 671 | "rustc-hash", |
662 | "syntax", | 672 | "syntax", |
663 | "test_utils", | 673 | "test_utils", |
@@ -716,15 +726,6 @@ dependencies = [ | |||
716 | 726 | ||
717 | [[package]] | 727 | [[package]] |
718 | name = "itertools" | 728 | name = "itertools" |
719 | version = "0.9.0" | ||
720 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
721 | checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" | ||
722 | dependencies = [ | ||
723 | "either", | ||
724 | ] | ||
725 | |||
726 | [[package]] | ||
727 | name = "itertools" | ||
728 | version = "0.10.0" | 729 | version = "0.10.0" |
729 | source = "registry+https://github.com/rust-lang/crates.io-index" | 730 | source = "registry+https://github.com/rust-lang/crates.io-index" |
730 | checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" | 731 | checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" |
@@ -788,9 +789,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | |||
788 | 789 | ||
789 | [[package]] | 790 | [[package]] |
790 | name = "libc" | 791 | name = "libc" |
791 | version = "0.2.86" | 792 | version = "0.2.87" |
792 | source = "registry+https://github.com/rust-lang/crates.io-index" | 793 | source = "registry+https://github.com/rust-lang/crates.io-index" |
793 | checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" | 794 | checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213" |
794 | 795 | ||
795 | [[package]] | 796 | [[package]] |
796 | name = "libloading" | 797 | name = "libloading" |
@@ -1015,9 +1016,9 @@ checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" | |||
1015 | 1016 | ||
1016 | [[package]] | 1017 | [[package]] |
1017 | name = "once_cell" | 1018 | name = "once_cell" |
1018 | version = "1.7.0" | 1019 | version = "1.7.1" |
1019 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1020 | checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a" | 1021 | checksum = "ea78b9742c52ac729753c1590e9adc5248ea9bdaf974597efd46c74cfaa5fb54" |
1021 | 1022 | ||
1022 | [[package]] | 1023 | [[package]] |
1023 | name = "oorandom" | 1024 | name = "oorandom" |
@@ -1125,16 +1126,10 @@ dependencies = [ | |||
1125 | ] | 1126 | ] |
1126 | 1127 | ||
1127 | [[package]] | 1128 | [[package]] |
1128 | name = "pico-args" | ||
1129 | version = "0.4.0" | ||
1130 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1131 | checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6" | ||
1132 | |||
1133 | [[package]] | ||
1134 | name = "pin-project-lite" | 1129 | name = "pin-project-lite" |
1135 | version = "0.2.4" | 1130 | version = "0.2.5" |
1136 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1137 | checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" | 1132 | checksum = "0cf491442e4b033ed1c722cb9f0df5fcfcf4de682466c46469c36bc47dc5548a" |
1138 | 1133 | ||
1139 | [[package]] | 1134 | [[package]] |
1140 | name = "proc-macro-hack" | 1135 | name = "proc-macro-hack" |
@@ -1207,7 +1202,7 @@ dependencies = [ | |||
1207 | "base_db", | 1202 | "base_db", |
1208 | "cargo_metadata", | 1203 | "cargo_metadata", |
1209 | "cfg", | 1204 | "cfg", |
1210 | "itertools 0.10.0", | 1205 | "itertools", |
1211 | "la-arena", | 1206 | "la-arena", |
1212 | "log", | 1207 | "log", |
1213 | "paths", | 1208 | "paths", |
@@ -1339,7 +1334,7 @@ dependencies = [ | |||
1339 | "ide", | 1334 | "ide", |
1340 | "ide_db", | 1335 | "ide_db", |
1341 | "ide_ssr", | 1336 | "ide_ssr", |
1342 | "itertools 0.10.0", | 1337 | "itertools", |
1343 | "jemallocator", | 1338 | "jemallocator", |
1344 | "jod-thread", | 1339 | "jod-thread", |
1345 | "log", | 1340 | "log", |
@@ -1349,7 +1344,6 @@ dependencies = [ | |||
1349 | "mimalloc", | 1344 | "mimalloc", |
1350 | "oorandom", | 1345 | "oorandom", |
1351 | "parking_lot", | 1346 | "parking_lot", |
1352 | "pico-args", | ||
1353 | "proc_macro_srv", | 1347 | "proc_macro_srv", |
1354 | "profile", | 1348 | "profile", |
1355 | "project_model", | 1349 | "project_model", |
@@ -1371,6 +1365,7 @@ dependencies = [ | |||
1371 | "vfs", | 1365 | "vfs", |
1372 | "vfs-notify", | 1366 | "vfs-notify", |
1373 | "winapi", | 1367 | "winapi", |
1368 | "xflags", | ||
1374 | ] | 1369 | ] |
1375 | 1370 | ||
1376 | [[package]] | 1371 | [[package]] |
@@ -1491,9 +1486,9 @@ dependencies = [ | |||
1491 | 1486 | ||
1492 | [[package]] | 1487 | [[package]] |
1493 | name = "serde_json" | 1488 | name = "serde_json" |
1494 | version = "1.0.62" | 1489 | version = "1.0.64" |
1495 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1496 | checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" | 1491 | checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" |
1497 | dependencies = [ | 1492 | dependencies = [ |
1498 | "indexmap", | 1493 | "indexmap", |
1499 | "itoa", | 1494 | "itoa", |
@@ -1594,7 +1589,7 @@ dependencies = [ | |||
1594 | "arrayvec", | 1589 | "arrayvec", |
1595 | "expect-test", | 1590 | "expect-test", |
1596 | "indexmap", | 1591 | "indexmap", |
1597 | "itertools 0.10.0", | 1592 | "itertools", |
1598 | "once_cell", | 1593 | "once_cell", |
1599 | "parser", | 1594 | "parser", |
1600 | "profile", | 1595 | "profile", |
@@ -1923,19 +1918,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1923 | checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3" | 1918 | checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3" |
1924 | 1919 | ||
1925 | [[package]] | 1920 | [[package]] |
1921 | name = "xflags" | ||
1922 | version = "0.1.3" | ||
1923 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1924 | checksum = "ddb4b07c0db813f8e2b5e1b2189ef56fcddb27a6f9ef71314dbf8cc50096a5db" | ||
1925 | dependencies = [ | ||
1926 | "xflags-macros", | ||
1927 | ] | ||
1928 | |||
1929 | [[package]] | ||
1930 | name = "xflags-macros" | ||
1931 | version = "0.1.3" | ||
1932 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1933 | checksum = "f8e168a99d6ce9d5dd0d0913f1bded279377843952dd8ff83f81b862a1dad0e1" | ||
1934 | dependencies = [ | ||
1935 | "proc-macro2", | ||
1936 | ] | ||
1937 | |||
1938 | [[package]] | ||
1926 | name = "xshell" | 1939 | name = "xshell" |
1927 | version = "0.1.8" | 1940 | version = "0.1.9" |
1928 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1941 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1929 | checksum = "ed373ede30cea03e8c0af22f48ee1ba80efbf06fec8b4746977e6ee703878de0" | 1942 | checksum = "6f18102278453c8f70ea5c514ac78cb4c73a0ef72a8273d17094b52f9584c0c1" |
1930 | dependencies = [ | 1943 | dependencies = [ |
1931 | "xshell-macros", | 1944 | "xshell-macros", |
1932 | ] | 1945 | ] |
1933 | 1946 | ||
1934 | [[package]] | 1947 | [[package]] |
1935 | name = "xshell-macros" | 1948 | name = "xshell-macros" |
1936 | version = "0.1.8" | 1949 | version = "0.1.9" |
1937 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1950 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1938 | checksum = "7f6af9f8119104697b0105989a73c578ce33f922d9d6f3dae0e8ae3d538db321" | 1951 | checksum = "6093c460064572007f885facc70bb0ca5e40a83ea7ff8b16c1abbee56fd2e767" |
1939 | 1952 | ||
1940 | [[package]] | 1953 | [[package]] |
1941 | name = "xtask" | 1954 | name = "xtask" |
@@ -1943,11 +1956,11 @@ version = "0.1.0" | |||
1943 | dependencies = [ | 1956 | dependencies = [ |
1944 | "anyhow", | 1957 | "anyhow", |
1945 | "flate2", | 1958 | "flate2", |
1946 | "pico-args", | ||
1947 | "proc-macro2", | 1959 | "proc-macro2", |
1948 | "quote", | 1960 | "quote", |
1949 | "ungrammar", | 1961 | "ungrammar", |
1950 | "walkdir", | 1962 | "walkdir", |
1951 | "write-json", | 1963 | "write-json", |
1964 | "xflags", | ||
1952 | "xshell", | 1965 | "xshell", |
1953 | ] | 1966 | ] |
diff --git a/crates/flycheck/Cargo.toml b/crates/flycheck/Cargo.toml index 1d19c7886..2a1a21b28 100644 --- a/crates/flycheck/Cargo.toml +++ b/crates/flycheck/Cargo.toml | |||
@@ -12,9 +12,9 @@ doctest = false | |||
12 | [dependencies] | 12 | [dependencies] |
13 | crossbeam-channel = "0.5.0" | 13 | crossbeam-channel = "0.5.0" |
14 | log = "0.4.8" | 14 | log = "0.4.8" |
15 | cargo_metadata = "0.12.2" | 15 | cargo_metadata = "0.13" |
16 | serde_json = "1.0.48" | 16 | serde_json = "1.0.48" |
17 | jod-thread = "0.1.1" | 17 | jod-thread = "0.1.1" |
18 | 18 | ||
19 | toolchain = { path = "../toolchain", version = "0.0.0" } | 19 | toolchain = { path = "../toolchain", version = "0.0.0" } |
20 | stdx = { path = "../stdx", version = "0.0.0" } | 20 | stdx = { path = "../stdx", version = "0.0.0" } |
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs index e04208006..e2a59497a 100644 --- a/crates/flycheck/src/lib.rs +++ b/crates/flycheck/src/lib.rs | |||
@@ -194,7 +194,7 @@ impl FlycheckActor { | |||
194 | cargo_metadata::Message::BuildScriptExecuted(_) | 194 | cargo_metadata::Message::BuildScriptExecuted(_) |
195 | | cargo_metadata::Message::BuildFinished(_) | 195 | | cargo_metadata::Message::BuildFinished(_) |
196 | | cargo_metadata::Message::TextLine(_) | 196 | | cargo_metadata::Message::TextLine(_) |
197 | | cargo_metadata::Message::Unknown => {} | 197 | | _ => {} |
198 | }, | 198 | }, |
199 | } | 199 | } |
200 | } | 200 | } |
@@ -329,8 +329,7 @@ impl CargoActor { | |||
329 | // Skip certain kinds of messages to only spend time on what's useful | 329 | // Skip certain kinds of messages to only spend time on what's useful |
330 | match &message { | 330 | match &message { |
331 | cargo_metadata::Message::CompilerArtifact(artifact) if artifact.fresh => (), | 331 | cargo_metadata::Message::CompilerArtifact(artifact) if artifact.fresh => (), |
332 | cargo_metadata::Message::BuildScriptExecuted(_) | 332 | cargo_metadata::Message::BuildScriptExecuted(_) => (), |
333 | | cargo_metadata::Message::Unknown => (), | ||
334 | _ => self.sender.send(message).unwrap(), | 333 | _ => self.sender.send(message).unwrap(), |
335 | } | 334 | } |
336 | } | 335 | } |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index b3218833d..fc1a74641 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -14,7 +14,7 @@ use hir_def::{ | |||
14 | per_ns::PerNs, | 14 | per_ns::PerNs, |
15 | resolver::{HasResolver, Resolver}, | 15 | resolver::{HasResolver, Resolver}, |
16 | src::HasSource as _, | 16 | src::HasSource as _, |
17 | type_ref::{Mutability, TypeRef}, | 17 | type_ref::TypeRef, |
18 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, | 18 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, |
19 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, | 19 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, |
20 | LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, | 20 | LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, |
@@ -31,9 +31,9 @@ use hir_ty::{ | |||
31 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, | 31 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, |
32 | method_resolution, | 32 | method_resolution, |
33 | traits::{FnTrait, Solution, SolutionVariables}, | 33 | traits::{FnTrait, Solution, SolutionVariables}, |
34 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, | 34 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, |
35 | InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty, | 35 | InEnvironment, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, |
36 | TyDefId, TyKind, TypeCtor, | 36 | TraitEnvironment, Ty, TyDefId, TyVariableKind, |
37 | }; | 37 | }; |
38 | use rustc_hash::FxHashSet; | 38 | use rustc_hash::FxHashSet; |
39 | use stdx::{format_to, impl_from}; | 39 | use stdx::{format_to, impl_from}; |
@@ -836,7 +836,7 @@ pub enum Access { | |||
836 | impl From<Mutability> for Access { | 836 | impl From<Mutability> for Access { |
837 | fn from(mutability: Mutability) -> Access { | 837 | fn from(mutability: Mutability) -> Access { |
838 | match mutability { | 838 | match mutability { |
839 | Mutability::Shared => Access::Shared, | 839 | Mutability::Not => Access::Shared, |
840 | Mutability::Mut => Access::Exclusive, | 840 | Mutability::Mut => Access::Exclusive, |
841 | } | 841 | } |
842 | } | 842 | } |
@@ -865,7 +865,10 @@ impl SelfParam { | |||
865 | .params | 865 | .params |
866 | .first() | 866 | .first() |
867 | .map(|param| match *param { | 867 | .map(|param| match *param { |
868 | TypeRef::Reference(.., mutability) => mutability.into(), | 868 | TypeRef::Reference(.., mutability) => match mutability { |
869 | hir_def::type_ref::Mutability::Shared => Access::Shared, | ||
870 | hir_def::type_ref::Mutability::Mut => Access::Exclusive, | ||
871 | }, | ||
869 | _ => Access::Owned, | 872 | _ => Access::Owned, |
870 | }) | 873 | }) |
871 | .unwrap_or(Access::Owned) | 874 | .unwrap_or(Access::Owned) |
@@ -1547,25 +1550,19 @@ impl Type { | |||
1547 | } | 1550 | } |
1548 | 1551 | ||
1549 | pub fn is_unit(&self) -> bool { | 1552 | pub fn is_unit(&self) -> bool { |
1550 | matches!( | 1553 | matches!(self.ty.value, Ty::Tuple(0, ..)) |
1551 | self.ty.value, | ||
1552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. }) | ||
1553 | ) | ||
1554 | } | 1554 | } |
1555 | pub fn is_bool(&self) -> bool { | 1555 | pub fn is_bool(&self) -> bool { |
1556 | matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) | 1556 | matches!(self.ty.value, Ty::Scalar(Scalar::Bool)) |
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | pub fn is_mutable_reference(&self) -> bool { | 1559 | pub fn is_mutable_reference(&self) -> bool { |
1560 | matches!( | 1560 | matches!(self.ty.value, Ty::Ref(Mutability::Mut, ..)) |
1561 | self.ty.value, | ||
1562 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(Mutability::Mut), .. }) | ||
1563 | ) | ||
1564 | } | 1561 | } |
1565 | 1562 | ||
1566 | pub fn remove_ref(&self) -> Option<Type> { | 1563 | pub fn remove_ref(&self) -> Option<Type> { |
1567 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_), .. }) = self.ty.value { | 1564 | if let Ty::Ref(.., substs) = &self.ty.value { |
1568 | self.ty.value.substs().map(|substs| self.derived(substs[0].clone())) | 1565 | Some(self.derived(substs[0].clone())) |
1569 | } else { | 1566 | } else { |
1570 | None | 1567 | None |
1571 | } | 1568 | } |
@@ -1654,14 +1651,14 @@ impl Type { | |||
1654 | .build(); | 1651 | .build(); |
1655 | let predicate = ProjectionPredicate { | 1652 | let predicate = ProjectionPredicate { |
1656 | projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, | 1653 | projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, |
1657 | ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)), | 1654 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)), |
1658 | }; | 1655 | }; |
1659 | let goal = Canonical { | 1656 | let goal = Canonical { |
1660 | value: InEnvironment::new( | 1657 | value: InEnvironment::new( |
1661 | self.ty.environment.clone(), | 1658 | self.ty.environment.clone(), |
1662 | Obligation::Projection(predicate), | 1659 | Obligation::Projection(predicate), |
1663 | ), | 1660 | ), |
1664 | kinds: Arc::new([TyKind::General]), | 1661 | kinds: Arc::new([TyVariableKind::General]), |
1665 | }; | 1662 | }; |
1666 | 1663 | ||
1667 | match db.trait_solve(self.krate, goal)? { | 1664 | match db.trait_solve(self.krate, goal)? { |
@@ -1685,7 +1682,7 @@ impl Type { | |||
1685 | 1682 | ||
1686 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { | 1683 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { |
1687 | let def = match self.ty.value { | 1684 | let def = match self.ty.value { |
1688 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def), | 1685 | Ty::FnDef(def, _) => Some(def), |
1689 | _ => None, | 1686 | _ => None, |
1690 | }; | 1687 | }; |
1691 | 1688 | ||
@@ -1694,20 +1691,16 @@ impl Type { | |||
1694 | } | 1691 | } |
1695 | 1692 | ||
1696 | pub fn is_closure(&self) -> bool { | 1693 | pub fn is_closure(&self) -> bool { |
1697 | matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) | 1694 | matches!(&self.ty.value, Ty::Closure { .. }) |
1698 | } | 1695 | } |
1699 | 1696 | ||
1700 | pub fn is_fn(&self) -> bool { | 1697 | pub fn is_fn(&self) -> bool { |
1701 | matches!( | 1698 | matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. }) |
1702 | &self.ty.value, | ||
1703 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) | ||
1704 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. }) | ||
1705 | ) | ||
1706 | } | 1699 | } |
1707 | 1700 | ||
1708 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1701 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1709 | let adt_id = match self.ty.value { | 1702 | let adt_id = match self.ty.value { |
1710 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_id), .. }) => adt_id, | 1703 | Ty::Adt(adt_id, ..) => adt_id, |
1711 | _ => return false, | 1704 | _ => return false, |
1712 | }; | 1705 | }; |
1713 | 1706 | ||
@@ -1719,7 +1712,7 @@ impl Type { | |||
1719 | } | 1712 | } |
1720 | 1713 | ||
1721 | pub fn is_raw_ptr(&self) -> bool { | 1714 | pub fn is_raw_ptr(&self) -> bool { |
1722 | matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. })) | 1715 | matches!(&self.ty.value, Ty::Raw(..)) |
1723 | } | 1716 | } |
1724 | 1717 | ||
1725 | pub fn contains_unknown(&self) -> bool { | 1718 | pub fn contains_unknown(&self) -> bool { |
@@ -1728,44 +1721,34 @@ impl Type { | |||
1728 | fn go(ty: &Ty) -> bool { | 1721 | fn go(ty: &Ty) -> bool { |
1729 | match ty { | 1722 | match ty { |
1730 | Ty::Unknown => true, | 1723 | Ty::Unknown => true, |
1731 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), | 1724 | _ => ty.substs().map_or(false, |substs| substs.iter().any(go)), |
1732 | _ => false, | ||
1733 | } | 1725 | } |
1734 | } | 1726 | } |
1735 | } | 1727 | } |
1736 | 1728 | ||
1737 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1729 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1738 | if let Ty::Apply(a_ty) = &self.ty.value { | 1730 | let (variant_id, substs) = match self.ty.value { |
1739 | let variant_id = match a_ty.ctor { | 1731 | Ty::Adt(AdtId::StructId(s), ref substs) => (s.into(), substs), |
1740 | TypeCtor::Adt(AdtId::StructId(s)) => s.into(), | 1732 | Ty::Adt(AdtId::UnionId(u), ref substs) => (u.into(), substs), |
1741 | TypeCtor::Adt(AdtId::UnionId(u)) => u.into(), | 1733 | _ => return Vec::new(), |
1742 | _ => return Vec::new(), | ||
1743 | }; | ||
1744 | |||
1745 | return db | ||
1746 | .field_types(variant_id) | ||
1747 | .iter() | ||
1748 | .map(|(local_id, ty)| { | ||
1749 | let def = Field { parent: variant_id.into(), id: local_id }; | ||
1750 | let ty = ty.clone().subst(&a_ty.parameters); | ||
1751 | (def, self.derived(ty)) | ||
1752 | }) | ||
1753 | .collect(); | ||
1754 | }; | 1734 | }; |
1755 | Vec::new() | 1735 | |
1736 | db.field_types(variant_id) | ||
1737 | .iter() | ||
1738 | .map(|(local_id, ty)| { | ||
1739 | let def = Field { parent: variant_id.into(), id: local_id }; | ||
1740 | let ty = ty.clone().subst(substs); | ||
1741 | (def, self.derived(ty)) | ||
1742 | }) | ||
1743 | .collect() | ||
1756 | } | 1744 | } |
1757 | 1745 | ||
1758 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1746 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1759 | let mut res = Vec::new(); | 1747 | if let Ty::Tuple(_, substs) = &self.ty.value { |
1760 | if let Ty::Apply(a_ty) = &self.ty.value { | 1748 | substs.iter().map(|ty| self.derived(ty.clone())).collect() |
1761 | if let TypeCtor::Tuple { .. } = a_ty.ctor { | 1749 | } else { |
1762 | for ty in a_ty.parameters.iter() { | 1750 | Vec::new() |
1763 | let ty = ty.clone(); | 1751 | } |
1764 | res.push(self.derived(ty)); | ||
1765 | } | ||
1766 | } | ||
1767 | }; | ||
1768 | res | ||
1769 | } | 1752 | } |
1770 | 1753 | ||
1771 | pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { | 1754 | pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { |
@@ -1802,15 +1785,13 @@ impl Type { | |||
1802 | } | 1785 | } |
1803 | 1786 | ||
1804 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { | 1787 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { |
1805 | let ty = self.ty.value.strip_references(); | 1788 | self.ty |
1806 | let substs = match ty { | 1789 | .value |
1807 | Ty::Apply(apply_ty) => &apply_ty.parameters, | 1790 | .strip_references() |
1808 | Ty::Opaque(opaque_ty) => &opaque_ty.parameters, | 1791 | .substs() |
1809 | _ => return Either::Left(iter::empty()), | 1792 | .into_iter() |
1810 | }; | 1793 | .flat_map(|substs| substs.iter()) |
1811 | 1794 | .map(move |ty| self.derived(ty.clone())) | |
1812 | let iter = substs.iter().map(move |ty| self.derived(ty.clone())); | ||
1813 | Either::Right(iter) | ||
1814 | } | 1795 | } |
1815 | 1796 | ||
1816 | pub fn iterate_method_candidates<T>( | 1797 | pub fn iterate_method_candidates<T>( |
@@ -1900,17 +1881,8 @@ impl Type { | |||
1900 | 1881 | ||
1901 | // FIXME: provide required accessors such that it becomes implementable from outside. | 1882 | // FIXME: provide required accessors such that it becomes implementable from outside. |
1902 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | 1883 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { |
1903 | match (&self.ty.value, &other.ty.value) { | 1884 | let rref = other.remove_ref(); |
1904 | (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor | 1885 | self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value)) |
1905 | { | ||
1906 | TypeCtor::Ref(..) => match parameters.as_single() { | ||
1907 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, | ||
1908 | _ => false, | ||
1909 | }, | ||
1910 | _ => a_original_ty.ctor == *ctor, | ||
1911 | }, | ||
1912 | _ => false, | ||
1913 | } | ||
1914 | } | 1886 | } |
1915 | 1887 | ||
1916 | fn derived(&self, ty: Ty) -> Type { | 1888 | fn derived(&self, ty: Ty) -> Type { |
@@ -1955,28 +1927,20 @@ impl Type { | |||
1955 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 1927 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
1956 | let ty = type_.ty.value.strip_references(); | 1928 | let ty = type_.ty.value.strip_references(); |
1957 | match ty { | 1929 | match ty { |
1958 | Ty::Apply(ApplicationTy { ctor, parameters }) => { | 1930 | Ty::Adt(..) => { |
1959 | match ctor { | 1931 | cb(type_.derived(ty.clone())); |
1960 | TypeCtor::Adt(_) => { | 1932 | } |
1961 | cb(type_.derived(ty.clone())); | 1933 | Ty::AssociatedType(..) => { |
1962 | } | 1934 | if let Some(_) = ty.associated_type_parent_trait(db) { |
1963 | TypeCtor::AssociatedType(_) => { | 1935 | cb(type_.derived(ty.clone())); |
1964 | if let Some(_) = ty.associated_type_parent_trait(db) { | ||
1965 | cb(type_.derived(ty.clone())); | ||
1966 | } | ||
1967 | } | ||
1968 | TypeCtor::OpaqueType(..) => { | ||
1969 | if let Some(bounds) = ty.impl_trait_bounds(db) { | ||
1970 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | ||
1971 | } | ||
1972 | } | ||
1973 | _ => (), | ||
1974 | } | 1936 | } |
1975 | |||
1976 | // adt params, tuples, etc... | ||
1977 | walk_substs(db, type_, parameters, cb); | ||
1978 | } | 1937 | } |
1979 | Ty::Opaque(opaque_ty) => { | 1938 | Ty::OpaqueType(..) => { |
1939 | if let Some(bounds) = ty.impl_trait_bounds(db) { | ||
1940 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | ||
1941 | } | ||
1942 | } | ||
1943 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | ||
1980 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 1944 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1981 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 1945 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1982 | } | 1946 | } |
@@ -1992,7 +1956,10 @@ impl Type { | |||
1992 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); | 1956 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); |
1993 | } | 1957 | } |
1994 | 1958 | ||
1995 | _ => (), | 1959 | _ => {} |
1960 | } | ||
1961 | if let Some(substs) = ty.substs() { | ||
1962 | walk_substs(db, type_, &substs, cb); | ||
1996 | } | 1963 | } |
1997 | } | 1964 | } |
1998 | 1965 | ||
@@ -2010,7 +1977,7 @@ impl HirDisplay for Type { | |||
2010 | #[derive(Debug)] | 1977 | #[derive(Debug)] |
2011 | pub struct Callable { | 1978 | pub struct Callable { |
2012 | ty: Type, | 1979 | ty: Type, |
2013 | sig: FnSig, | 1980 | sig: CallableSig, |
2014 | def: Option<CallableDefId>, | 1981 | def: Option<CallableDefId>, |
2015 | pub(crate) is_bound_method: bool, | 1982 | pub(crate) is_bound_method: bool, |
2016 | } | 1983 | } |
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index dc21f6051..64ce4add1 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -20,7 +20,7 @@ use hir_def::{ | |||
20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; | 20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; |
21 | use hir_ty::{ | 21 | use hir_ty::{ |
22 | diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, | 22 | diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, |
23 | InferenceResult, Substs, Ty, | 23 | InferenceResult, Substs, |
24 | }; | 24 | }; |
25 | use syntax::{ | 25 | use syntax::{ |
26 | ast::{self, AstNode}, | 26 | ast::{self, AstNode}, |
@@ -299,14 +299,11 @@ impl SourceAnalyzer { | |||
299 | let infer = self.infer.as_ref()?; | 299 | let infer = self.infer.as_ref()?; |
300 | 300 | ||
301 | let expr_id = self.expr_id(db, &literal.clone().into())?; | 301 | let expr_id = self.expr_id(db, &literal.clone().into())?; |
302 | let substs = match &infer.type_of_expr[expr_id] { | 302 | let substs = infer.type_of_expr[expr_id].substs()?; |
303 | Ty::Apply(a_ty) => &a_ty.parameters, | ||
304 | _ => return None, | ||
305 | }; | ||
306 | 303 | ||
307 | let (variant, missing_fields, _exhaustive) = | 304 | let (variant, missing_fields, _exhaustive) = |
308 | record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?; | 305 | record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?; |
309 | let res = self.missing_fields(db, krate, substs, variant, missing_fields); | 306 | let res = self.missing_fields(db, krate, &substs, variant, missing_fields); |
310 | Some(res) | 307 | Some(res) |
311 | } | 308 | } |
312 | 309 | ||
@@ -320,14 +317,11 @@ impl SourceAnalyzer { | |||
320 | let infer = self.infer.as_ref()?; | 317 | let infer = self.infer.as_ref()?; |
321 | 318 | ||
322 | let pat_id = self.pat_id(&pattern.clone().into())?; | 319 | let pat_id = self.pat_id(&pattern.clone().into())?; |
323 | let substs = match &infer.type_of_pat[pat_id] { | 320 | let substs = infer.type_of_pat[pat_id].substs()?; |
324 | Ty::Apply(a_ty) => &a_ty.parameters, | ||
325 | _ => return None, | ||
326 | }; | ||
327 | 321 | ||
328 | let (variant, missing_fields, _exhaustive) = | 322 | let (variant, missing_fields, _exhaustive) = |
329 | record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; | 323 | record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; |
330 | let res = self.missing_fields(db, krate, substs, variant, missing_fields); | 324 | let res = self.missing_fields(db, krate, &substs, variant, missing_fields); |
331 | Some(res) | 325 | Some(res) |
332 | } | 326 | } |
333 | 327 | ||
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index c18001e15..40beb2f7a 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -24,7 +24,7 @@ use test_utils::mark; | |||
24 | use crate::{ | 24 | use crate::{ |
25 | adt::StructKind, | 25 | adt::StructKind, |
26 | body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, | 26 | body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, |
27 | builtin_type::{BuiltinFloat, BuiltinInt}, | 27 | builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, |
28 | db::DefDatabase, | 28 | db::DefDatabase, |
29 | diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, | 29 | diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, |
30 | expr::{ | 30 | expr::{ |
@@ -1065,11 +1065,16 @@ impl From<ast::LiteralKind> for Literal { | |||
1065 | fn from(ast_lit_kind: ast::LiteralKind) -> Self { | 1065 | fn from(ast_lit_kind: ast::LiteralKind) -> Self { |
1066 | match ast_lit_kind { | 1066 | match ast_lit_kind { |
1067 | LiteralKind::IntNumber(lit) => { | 1067 | LiteralKind::IntNumber(lit) => { |
1068 | if let Some(float_suffix) = lit.suffix().and_then(BuiltinFloat::from_suffix) { | 1068 | if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) { |
1069 | return Literal::Float(Default::default(), Some(float_suffix)); | 1069 | return Literal::Float(Default::default(), builtin); |
1070 | } else if let builtin @ Some(_) = | ||
1071 | lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it)) | ||
1072 | { | ||
1073 | Literal::Int(Default::default(), builtin) | ||
1074 | } else { | ||
1075 | let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it)); | ||
1076 | Literal::Uint(Default::default(), builtin) | ||
1070 | } | 1077 | } |
1071 | let ty = lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it)); | ||
1072 | Literal::Int(Default::default(), ty) | ||
1073 | } | 1078 | } |
1074 | LiteralKind::FloatNumber(lit) => { | 1079 | LiteralKind::FloatNumber(lit) => { |
1075 | let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it)); | 1080 | let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it)); |
@@ -1077,7 +1082,7 @@ impl From<ast::LiteralKind> for Literal { | |||
1077 | } | 1082 | } |
1078 | LiteralKind::ByteString(_) => Literal::ByteString(Default::default()), | 1083 | LiteralKind::ByteString(_) => Literal::ByteString(Default::default()), |
1079 | LiteralKind::String(_) => Literal::String(Default::default()), | 1084 | LiteralKind::String(_) => Literal::String(Default::default()), |
1080 | LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), | 1085 | LiteralKind::Byte => Literal::Uint(Default::default(), Some(BuiltinUint::U8)), |
1081 | LiteralKind::Bool(val) => Literal::Bool(val), | 1086 | LiteralKind::Bool(val) => Literal::Bool(val), |
1082 | LiteralKind::Char => Literal::Char(Default::default()), | 1087 | LiteralKind::Char => Literal::Char(Default::default()), |
1083 | } | 1088 | } |
diff --git a/crates/hir_def/src/builtin_type.rs b/crates/hir_def/src/builtin_type.rs index 0f872b5c0..7cbaf30b8 100644 --- a/crates/hir_def/src/builtin_type.rs +++ b/crates/hir_def/src/builtin_type.rs | |||
@@ -6,38 +6,32 @@ | |||
6 | use std::fmt; | 6 | use std::fmt; |
7 | 7 | ||
8 | use hir_expand::name::{name, AsName, Name}; | 8 | use hir_expand::name::{name, AsName, Name}; |
9 | 9 | /// Different signed int types. | |
10 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | 10 | #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
11 | pub enum Signedness { | 11 | pub enum BuiltinInt { |
12 | Signed, | 12 | Isize, |
13 | Unsigned, | 13 | I8, |
14 | } | 14 | I16, |
15 | 15 | I32, | |
16 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | 16 | I64, |
17 | pub enum IntBitness { | 17 | I128, |
18 | Xsize, | ||
19 | X8, | ||
20 | X16, | ||
21 | X32, | ||
22 | X64, | ||
23 | X128, | ||
24 | } | ||
25 | |||
26 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | ||
27 | pub enum FloatBitness { | ||
28 | X32, | ||
29 | X64, | ||
30 | } | 18 | } |
31 | 19 | ||
32 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 20 | /// Different unsigned int types. |
33 | pub struct BuiltinInt { | 21 | #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
34 | pub signedness: Signedness, | 22 | pub enum BuiltinUint { |
35 | pub bitness: IntBitness, | 23 | Usize, |
24 | U8, | ||
25 | U16, | ||
26 | U32, | ||
27 | U64, | ||
28 | U128, | ||
36 | } | 29 | } |
37 | 30 | ||
38 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 31 | #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
39 | pub struct BuiltinFloat { | 32 | pub enum BuiltinFloat { |
40 | pub bitness: FloatBitness, | 33 | F32, |
34 | F64, | ||
41 | } | 35 | } |
42 | 36 | ||
43 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 37 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -46,6 +40,7 @@ pub enum BuiltinType { | |||
46 | Bool, | 40 | Bool, |
47 | Str, | 41 | Str, |
48 | Int(BuiltinInt), | 42 | Int(BuiltinInt), |
43 | Uint(BuiltinUint), | ||
49 | Float(BuiltinFloat), | 44 | Float(BuiltinFloat), |
50 | } | 45 | } |
51 | 46 | ||
@@ -56,19 +51,19 @@ impl BuiltinType { | |||
56 | (name![bool], BuiltinType::Bool), | 51 | (name![bool], BuiltinType::Bool), |
57 | (name![str], BuiltinType::Str), | 52 | (name![str], BuiltinType::Str), |
58 | 53 | ||
59 | (name![isize], BuiltinType::Int(BuiltinInt::ISIZE)), | 54 | (name![isize], BuiltinType::Int(BuiltinInt::Isize)), |
60 | (name![i8], BuiltinType::Int(BuiltinInt::I8)), | 55 | (name![i8], BuiltinType::Int(BuiltinInt::I8)), |
61 | (name![i16], BuiltinType::Int(BuiltinInt::I16)), | 56 | (name![i16], BuiltinType::Int(BuiltinInt::I16)), |
62 | (name![i32], BuiltinType::Int(BuiltinInt::I32)), | 57 | (name![i32], BuiltinType::Int(BuiltinInt::I32)), |
63 | (name![i64], BuiltinType::Int(BuiltinInt::I64)), | 58 | (name![i64], BuiltinType::Int(BuiltinInt::I64)), |
64 | (name![i128], BuiltinType::Int(BuiltinInt::I128)), | 59 | (name![i128], BuiltinType::Int(BuiltinInt::I128)), |
65 | 60 | ||
66 | (name![usize], BuiltinType::Int(BuiltinInt::USIZE)), | 61 | (name![usize], BuiltinType::Uint(BuiltinUint::Usize)), |
67 | (name![u8], BuiltinType::Int(BuiltinInt::U8)), | 62 | (name![u8], BuiltinType::Uint(BuiltinUint::U8)), |
68 | (name![u16], BuiltinType::Int(BuiltinInt::U16)), | 63 | (name![u16], BuiltinType::Uint(BuiltinUint::U16)), |
69 | (name![u32], BuiltinType::Int(BuiltinInt::U32)), | 64 | (name![u32], BuiltinType::Uint(BuiltinUint::U32)), |
70 | (name![u64], BuiltinType::Int(BuiltinInt::U64)), | 65 | (name![u64], BuiltinType::Uint(BuiltinUint::U64)), |
71 | (name![u128], BuiltinType::Int(BuiltinInt::U128)), | 66 | (name![u128], BuiltinType::Uint(BuiltinUint::U128)), |
72 | 67 | ||
73 | (name![f32], BuiltinType::Float(BuiltinFloat::F32)), | 68 | (name![f32], BuiltinType::Float(BuiltinFloat::F32)), |
74 | (name![f64], BuiltinType::Float(BuiltinFloat::F64)), | 69 | (name![f64], BuiltinType::Float(BuiltinFloat::F64)), |
@@ -81,24 +76,25 @@ impl AsName for BuiltinType { | |||
81 | BuiltinType::Char => name![char], | 76 | BuiltinType::Char => name![char], |
82 | BuiltinType::Bool => name![bool], | 77 | BuiltinType::Bool => name![bool], |
83 | BuiltinType::Str => name![str], | 78 | BuiltinType::Str => name![str], |
84 | BuiltinType::Int(BuiltinInt { signedness, bitness }) => match (signedness, bitness) { | 79 | BuiltinType::Int(it) => match it { |
85 | (Signedness::Signed, IntBitness::Xsize) => name![isize], | 80 | BuiltinInt::Isize => name![isize], |
86 | (Signedness::Signed, IntBitness::X8) => name![i8], | 81 | BuiltinInt::I8 => name![i8], |
87 | (Signedness::Signed, IntBitness::X16) => name![i16], | 82 | BuiltinInt::I16 => name![i16], |
88 | (Signedness::Signed, IntBitness::X32) => name![i32], | 83 | BuiltinInt::I32 => name![i32], |
89 | (Signedness::Signed, IntBitness::X64) => name![i64], | 84 | BuiltinInt::I64 => name![i64], |
90 | (Signedness::Signed, IntBitness::X128) => name![i128], | 85 | BuiltinInt::I128 => name![i128], |
91 | 86 | }, | |
92 | (Signedness::Unsigned, IntBitness::Xsize) => name![usize], | 87 | BuiltinType::Uint(it) => match it { |
93 | (Signedness::Unsigned, IntBitness::X8) => name![u8], | 88 | BuiltinUint::Usize => name![usize], |
94 | (Signedness::Unsigned, IntBitness::X16) => name![u16], | 89 | BuiltinUint::U8 => name![u8], |
95 | (Signedness::Unsigned, IntBitness::X32) => name![u32], | 90 | BuiltinUint::U16 => name![u16], |
96 | (Signedness::Unsigned, IntBitness::X64) => name![u64], | 91 | BuiltinUint::U32 => name![u32], |
97 | (Signedness::Unsigned, IntBitness::X128) => name![u128], | 92 | BuiltinUint::U64 => name![u64], |
93 | BuiltinUint::U128 => name![u128], | ||
98 | }, | 94 | }, |
99 | BuiltinType::Float(BuiltinFloat { bitness }) => match bitness { | 95 | BuiltinType::Float(it) => match it { |
100 | FloatBitness::X32 => name![f32], | 96 | BuiltinFloat::F32 => name![f32], |
101 | FloatBitness::X64 => name![f64], | 97 | BuiltinFloat::F64 => name![f64], |
102 | }, | 98 | }, |
103 | } | 99 | } |
104 | } | 100 | } |
@@ -113,31 +109,26 @@ impl fmt::Display for BuiltinType { | |||
113 | 109 | ||
114 | #[rustfmt::skip] | 110 | #[rustfmt::skip] |
115 | impl BuiltinInt { | 111 | impl BuiltinInt { |
116 | pub const ISIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::Xsize }; | ||
117 | pub const I8 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X8 }; | ||
118 | pub const I16 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X16 }; | ||
119 | pub const I32 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X32 }; | ||
120 | pub const I64 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X64 }; | ||
121 | pub const I128 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X128 }; | ||
122 | |||
123 | pub const USIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize }; | ||
124 | pub const U8 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X8 }; | ||
125 | pub const U16 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X16 }; | ||
126 | pub const U32 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X32 }; | ||
127 | pub const U64 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X64 }; | ||
128 | pub const U128 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X128 }; | ||
129 | |||
130 | |||
131 | pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> { | 112 | pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> { |
132 | let res = match suffix { | 113 | let res = match suffix { |
133 | "isize" => Self::ISIZE, | 114 | "isize" => Self::Isize, |
134 | "i8" => Self::I8, | 115 | "i8" => Self::I8, |
135 | "i16" => Self::I16, | 116 | "i16" => Self::I16, |
136 | "i32" => Self::I32, | 117 | "i32" => Self::I32, |
137 | "i64" => Self::I64, | 118 | "i64" => Self::I64, |
138 | "i128" => Self::I128, | 119 | "i128" => Self::I128, |
139 | 120 | ||
140 | "usize" => Self::USIZE, | 121 | _ => return None, |
122 | }; | ||
123 | Some(res) | ||
124 | } | ||
125 | } | ||
126 | |||
127 | #[rustfmt::skip] | ||
128 | impl BuiltinUint { | ||
129 | pub fn from_suffix(suffix: &str) -> Option<BuiltinUint> { | ||
130 | let res = match suffix { | ||
131 | "usize" => Self::Usize, | ||
141 | "u8" => Self::U8, | 132 | "u8" => Self::U8, |
142 | "u16" => Self::U16, | 133 | "u16" => Self::U16, |
143 | "u32" => Self::U32, | 134 | "u32" => Self::U32, |
@@ -152,9 +143,6 @@ impl BuiltinInt { | |||
152 | 143 | ||
153 | #[rustfmt::skip] | 144 | #[rustfmt::skip] |
154 | impl BuiltinFloat { | 145 | impl BuiltinFloat { |
155 | pub const F32: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X32 }; | ||
156 | pub const F64: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X64 }; | ||
157 | |||
158 | pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> { | 146 | pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> { |
159 | let res = match suffix { | 147 | let res = match suffix { |
160 | "f32" => BuiltinFloat::F32, | 148 | "f32" => BuiltinFloat::F32, |
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs index 4d72eaeaf..24be93773 100644 --- a/crates/hir_def/src/expr.rs +++ b/crates/hir_def/src/expr.rs | |||
@@ -17,7 +17,7 @@ use la_arena::{Idx, RawIdx}; | |||
17 | use syntax::ast::RangeOp; | 17 | use syntax::ast::RangeOp; |
18 | 18 | ||
19 | use crate::{ | 19 | use crate::{ |
20 | builtin_type::{BuiltinFloat, BuiltinInt}, | 20 | builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, |
21 | path::{GenericArgs, Path}, | 21 | path::{GenericArgs, Path}, |
22 | type_ref::{Mutability, Rawness, TypeRef}, | 22 | type_ref::{Mutability, Rawness, TypeRef}, |
23 | BlockId, | 23 | BlockId, |
@@ -43,6 +43,7 @@ pub enum Literal { | |||
43 | Char(char), | 43 | Char(char), |
44 | Bool(bool), | 44 | Bool(bool), |
45 | Int(u64, Option<BuiltinInt>), | 45 | Int(u64, Option<BuiltinInt>), |
46 | Uint(u64, Option<BuiltinUint>), | ||
46 | Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq | 47 | Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq |
47 | } | 48 | } |
48 | 49 | ||
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index 5e2a711b8..3e19a7702 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | //! An algorithm to find a path to refer to a certain item. | 1 | //! An algorithm to find a path to refer to a certain item. |
2 | 2 | ||
3 | use std::iter; | ||
4 | |||
3 | use hir_expand::name::{known, AsName, Name}; | 5 | use hir_expand::name::{known, AsName, Name}; |
4 | use rustc_hash::FxHashSet; | 6 | use rustc_hash::FxHashSet; |
5 | use test_utils::mark; | 7 | use test_utils::mark; |
@@ -95,7 +97,7 @@ fn find_path_inner( | |||
95 | item: ItemInNs, | 97 | item: ItemInNs, |
96 | from: ModuleId, | 98 | from: ModuleId, |
97 | max_len: usize, | 99 | max_len: usize, |
98 | prefixed: Option<PrefixKind>, | 100 | mut prefixed: Option<PrefixKind>, |
99 | ) -> Option<ModPath> { | 101 | ) -> Option<ModPath> { |
100 | if max_len == 0 { | 102 | if max_len == 0 { |
101 | return None; | 103 | return None; |
@@ -114,8 +116,9 @@ fn find_path_inner( | |||
114 | } | 116 | } |
115 | 117 | ||
116 | // - if the item is the crate root, return `crate` | 118 | // - if the item is the crate root, return `crate` |
117 | let root = def_map.module_id(def_map.root()); | 119 | let root = def_map.crate_root(db); |
118 | if item == ItemInNs::Types(ModuleDefId::ModuleId(root)) && def_map.block_id().is_none() { | 120 | if item == ItemInNs::Types(ModuleDefId::ModuleId(root)) && def_map.block_id().is_none() { |
121 | // FIXME: the `block_id()` check should be unnecessary, but affects the result | ||
119 | return Some(ModPath::from_segments(PathKind::Crate, Vec::new())); | 122 | return Some(ModPath::from_segments(PathKind::Crate, Vec::new())); |
120 | } | 123 | } |
121 | 124 | ||
@@ -165,7 +168,7 @@ fn find_path_inner( | |||
165 | 168 | ||
166 | // - otherwise, look for modules containing (reexporting) it and import it from one of those | 169 | // - otherwise, look for modules containing (reexporting) it and import it from one of those |
167 | 170 | ||
168 | let crate_root = def_map.module_id(def_map.root()); | 171 | let crate_root = def_map.crate_root(db); |
169 | let crate_attrs = db.attrs(crate_root.into()); | 172 | let crate_attrs = db.attrs(crate_root.into()); |
170 | let prefer_no_std = crate_attrs.by_key("no_std").exists(); | 173 | let prefer_no_std = crate_attrs.by_key("no_std").exists(); |
171 | let mut best_path = None; | 174 | let mut best_path = None; |
@@ -228,12 +231,16 @@ fn find_path_inner( | |||
228 | } | 231 | } |
229 | } | 232 | } |
230 | 233 | ||
231 | if let Some(mut prefix) = prefixed.map(PrefixKind::prefix) { | 234 | // If the item is declared inside a block expression, don't use a prefix, as we don't handle |
232 | if matches!(prefix, PathKind::Crate | PathKind::Super(0)) && def_map.block_id().is_some() { | 235 | // that correctly (FIXME). |
233 | // Inner items cannot be referred to via `crate::` or `self::` paths. | 236 | if let Some(item_module) = item.as_module_def_id().and_then(|did| did.module(db)) { |
234 | prefix = PathKind::Plain; | 237 | if item_module.def_map(db).block_id().is_some() && prefixed.is_some() { |
238 | mark::hit!(prefixed_in_block_expression); | ||
239 | prefixed = Some(PrefixKind::Plain); | ||
235 | } | 240 | } |
241 | } | ||
236 | 242 | ||
243 | if let Some(prefix) = prefixed.map(PrefixKind::prefix) { | ||
237 | best_path.or_else(|| { | 244 | best_path.or_else(|| { |
238 | scope_name.map(|scope_name| ModPath::from_segments(prefix, vec![scope_name])) | 245 | scope_name.map(|scope_name| ModPath::from_segments(prefix, vec![scope_name])) |
239 | }) | 246 | }) |
@@ -285,12 +292,12 @@ fn find_local_import_locations( | |||
285 | let data = &def_map[from.local_id]; | 292 | let data = &def_map[from.local_id]; |
286 | let mut worklist = | 293 | let mut worklist = |
287 | data.children.values().map(|child| def_map.module_id(*child)).collect::<Vec<_>>(); | 294 | data.children.values().map(|child| def_map.module_id(*child)).collect::<Vec<_>>(); |
288 | let mut parent = data.parent; | 295 | for ancestor in iter::successors(from.containing_module(db), |m| m.containing_module(db)) { |
289 | while let Some(p) = parent { | 296 | worklist.push(ancestor); |
290 | worklist.push(def_map.module_id(p)); | ||
291 | parent = def_map[p].parent; | ||
292 | } | 297 | } |
293 | 298 | ||
299 | let def_map = def_map.crate_root(db).def_map(db); | ||
300 | |||
294 | let mut seen: FxHashSet<_> = FxHashSet::default(); | 301 | let mut seen: FxHashSet<_> = FxHashSet::default(); |
295 | 302 | ||
296 | let mut locations = Vec::new(); | 303 | let mut locations = Vec::new(); |
@@ -301,7 +308,14 @@ fn find_local_import_locations( | |||
301 | 308 | ||
302 | let ext_def_map; | 309 | let ext_def_map; |
303 | let data = if module.krate == from.krate { | 310 | let data = if module.krate == from.krate { |
304 | &def_map[module.local_id] | 311 | if module.block.is_some() { |
312 | // Re-query the block's DefMap | ||
313 | ext_def_map = module.def_map(db); | ||
314 | &ext_def_map[module.local_id] | ||
315 | } else { | ||
316 | // Reuse the root DefMap | ||
317 | &def_map[module.local_id] | ||
318 | } | ||
305 | } else { | 319 | } else { |
306 | // The crate might reexport a module defined in another crate. | 320 | // The crate might reexport a module defined in another crate. |
307 | ext_def_map = module.def_map(db); | 321 | ext_def_map = module.def_map(db); |
@@ -828,6 +842,7 @@ mod tests { | |||
828 | 842 | ||
829 | #[test] | 843 | #[test] |
830 | fn inner_items_from_inner_module() { | 844 | fn inner_items_from_inner_module() { |
845 | mark::check!(prefixed_in_block_expression); | ||
831 | check_found_path( | 846 | check_found_path( |
832 | r#" | 847 | r#" |
833 | fn main() { | 848 | fn main() { |
@@ -869,4 +884,24 @@ mod tests { | |||
869 | "super::Struct", | 884 | "super::Struct", |
870 | ); | 885 | ); |
871 | } | 886 | } |
887 | |||
888 | #[test] | ||
889 | fn outer_items_with_inner_items_present() { | ||
890 | check_found_path( | ||
891 | r#" | ||
892 | mod module { | ||
893 | pub struct CompleteMe; | ||
894 | } | ||
895 | |||
896 | fn main() { | ||
897 | fn inner() {} | ||
898 | $0 | ||
899 | } | ||
900 | "#, | ||
901 | "module::CompleteMe", | ||
902 | "module::CompleteMe", | ||
903 | "crate::module::CompleteMe", | ||
904 | "self::module::CompleteMe", | ||
905 | ) | ||
906 | } | ||
872 | } | 907 | } |
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index ee46c3330..4e5daa2ff 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs | |||
@@ -12,8 +12,8 @@ use stdx::format_to; | |||
12 | use test_utils::mark; | 12 | use test_utils::mark; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId, | 15 | db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, ImplId, |
16 | LocalModuleId, Lookup, MacroDefId, ModuleDefId, ModuleId, TraitId, | 16 | LocalModuleId, MacroDefId, ModuleDefId, ModuleId, TraitId, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | #[derive(Copy, Clone)] | 19 | #[derive(Copy, Clone)] |
@@ -375,19 +375,9 @@ impl ItemInNs { | |||
375 | 375 | ||
376 | /// Returns the crate defining this item (or `None` if `self` is built-in). | 376 | /// Returns the crate defining this item (or `None` if `self` is built-in). |
377 | pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> { | 377 | pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> { |
378 | Some(match self { | 378 | match self { |
379 | ItemInNs::Types(did) | ItemInNs::Values(did) => match did { | 379 | ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate), |
380 | ModuleDefId::ModuleId(id) => id.krate, | 380 | ItemInNs::Macros(id) => Some(id.krate), |
381 | ModuleDefId::FunctionId(id) => id.lookup(db).module(db).krate, | 381 | } |
382 | ModuleDefId::AdtId(id) => id.module(db).krate, | ||
383 | ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container.module(db).krate, | ||
384 | ModuleDefId::ConstId(id) => id.lookup(db).container.module(db).krate, | ||
385 | ModuleDefId::StaticId(id) => id.lookup(db).container.module(db).krate, | ||
386 | ModuleDefId::TraitId(id) => id.lookup(db).container.module(db).krate, | ||
387 | ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db).krate, | ||
388 | ModuleDefId::BuiltinType(_) => return None, | ||
389 | }, | ||
390 | ItemInNs::Macros(id) => return Some(id.krate), | ||
391 | }) | ||
392 | } | 382 | } |
393 | } | 383 | } |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 6802bc250..4498d94bb 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -97,6 +97,10 @@ impl ModuleId { | |||
97 | pub fn krate(&self) -> CrateId { | 97 | pub fn krate(&self) -> CrateId { |
98 | self.krate | 98 | self.krate |
99 | } | 99 | } |
100 | |||
101 | pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> { | ||
102 | self.def_map(db).containing_module(self.local_id) | ||
103 | } | ||
100 | } | 104 | } |
101 | 105 | ||
102 | /// An ID of a module, **local** to a specific crate | 106 | /// An ID of a module, **local** to a specific crate |
@@ -529,6 +533,25 @@ impl HasModule for StaticLoc { | |||
529 | } | 533 | } |
530 | } | 534 | } |
531 | 535 | ||
536 | impl ModuleDefId { | ||
537 | /// Returns the module containing `self` (or `self`, if `self` is itself a module). | ||
538 | /// | ||
539 | /// Returns `None` if `self` refers to a primitive type. | ||
540 | pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> { | ||
541 | Some(match self { | ||
542 | ModuleDefId::ModuleId(id) => *id, | ||
543 | ModuleDefId::FunctionId(id) => id.lookup(db).module(db), | ||
544 | ModuleDefId::AdtId(id) => id.module(db), | ||
545 | ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container.module(db), | ||
546 | ModuleDefId::ConstId(id) => id.lookup(db).container.module(db), | ||
547 | ModuleDefId::StaticId(id) => id.lookup(db).container.module(db), | ||
548 | ModuleDefId::TraitId(id) => id.lookup(db).container.module(db), | ||
549 | ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db), | ||
550 | ModuleDefId::BuiltinType(_) => return None, | ||
551 | }) | ||
552 | } | ||
553 | } | ||
554 | |||
532 | impl AttrDefId { | 555 | impl AttrDefId { |
533 | pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId { | 556 | pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId { |
534 | match self { | 557 | match self { |
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 6a3456f2e..003d668ca 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs | |||
@@ -343,6 +343,18 @@ impl DefMap { | |||
343 | Some(self.block?.parent) | 343 | Some(self.block?.parent) |
344 | } | 344 | } |
345 | 345 | ||
346 | /// Returns the module containing `local_mod`, either the parent `mod`, or the module containing | ||
347 | /// the block, if `self` corresponds to a block expression. | ||
348 | pub fn containing_module(&self, local_mod: LocalModuleId) -> Option<ModuleId> { | ||
349 | match &self[local_mod].parent { | ||
350 | Some(parent) => Some(self.module_id(*parent)), | ||
351 | None => match &self.block { | ||
352 | Some(block) => Some(block.parent), | ||
353 | None => None, | ||
354 | }, | ||
355 | } | ||
356 | } | ||
357 | |||
346 | // FIXME: this can use some more human-readable format (ideally, an IR | 358 | // FIXME: this can use some more human-readable format (ideally, an IR |
347 | // even), as this should be a great debugging aid. | 359 | // even), as this should be a great debugging aid. |
348 | pub fn dump(&self, db: &dyn DefDatabase) -> String { | 360 | pub fn dump(&self, db: &dyn DefDatabase) -> String { |
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index a469546c1..505493a74 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs | |||
@@ -101,8 +101,12 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
101 | break; | 101 | break; |
102 | } | 102 | } |
103 | ast::PathSegmentKind::SelfKw => { | 103 | ast::PathSegmentKind::SelfKw => { |
104 | kind = PathKind::Super(0); | 104 | // don't break out if `self` is the last segment of a path, this mean we got an |
105 | break; | 105 | // use tree like `foo::{self}` which we want to resolve as `foo` |
106 | if !segments.is_empty() { | ||
107 | kind = PathKind::Super(0); | ||
108 | break; | ||
109 | } | ||
106 | } | 110 | } |
107 | ast::PathSegmentKind::SuperKw => { | 111 | ast::PathSegmentKind::SuperKw => { |
108 | let nested_super_count = if let PathKind::Super(n) = kind { n } else { 0 }; | 112 | let nested_super_count = if let PathKind::Super(n) = kind { n } else { 0 }; |
@@ -117,6 +121,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
117 | segments.reverse(); | 121 | segments.reverse(); |
118 | generic_args.reverse(); | 122 | generic_args.reverse(); |
119 | 123 | ||
124 | if segments.is_empty() && kind == PathKind::Plain && type_anchor.is_none() { | ||
125 | // plain empty paths don't exist, this means we got a single `self` segment as our path | ||
126 | kind = PathKind::Super(0); | ||
127 | } | ||
128 | |||
120 | // handle local_inner_macros : | 129 | // handle local_inner_macros : |
121 | // Basically, even in rustc it is quite hacky: | 130 | // Basically, even in rustc it is quite hacky: |
122 | // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 | 131 | // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 |
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index 6ef9d1e7e..d1302d749 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -17,9 +17,9 @@ ena = "0.14.0" | |||
17 | log = "0.4.8" | 17 | log = "0.4.8" |
18 | rustc-hash = "1.1.0" | 18 | rustc-hash = "1.1.0" |
19 | scoped-tls = "1" | 19 | scoped-tls = "1" |
20 | chalk-solve = { version = "0.58", default-features = false } | 20 | chalk-solve = { version = "0.59", default-features = false } |
21 | chalk-ir = "0.58" | 21 | chalk-ir = "0.59" |
22 | chalk-recursive = "0.58" | 22 | chalk-recursive = "0.59" |
23 | la-arena = { version = "0.2.0", path = "../../lib/arena" } | 23 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
24 | 24 | ||
25 | stdx = { path = "../stdx", version = "0.0.0" } | 25 | stdx = { path = "../stdx", version = "0.0.0" } |
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index ece68183e..be1fd1f13 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -81,7 +81,7 @@ fn deref_by_trait( | |||
81 | 81 | ||
82 | // Now do the assoc type projection | 82 | // Now do the assoc type projection |
83 | let projection = super::traits::ProjectionPredicate { | 83 | let projection = super::traits::ProjectionPredicate { |
84 | ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), | 84 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), |
85 | projection_ty: super::ProjectionTy { associated_ty: target, parameters }, | 85 | projection_ty: super::ProjectionTy { associated_ty: target, parameters }, |
86 | }; | 86 | }; |
87 | 87 | ||
@@ -89,8 +89,10 @@ fn deref_by_trait( | |||
89 | 89 | ||
90 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; | 90 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; |
91 | 91 | ||
92 | let canonical = | 92 | let canonical = Canonical::new( |
93 | Canonical::new(in_env, ty.value.kinds.iter().copied().chain(Some(super::TyKind::General))); | 93 | in_env, |
94 | ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)), | ||
95 | ); | ||
94 | 96 | ||
95 | let solution = db.trait_solve(krate, canonical)?; | 97 | let solution = db.trait_solve(krate, canonical)?; |
96 | 98 | ||
@@ -112,7 +114,8 @@ fn deref_by_trait( | |||
112 | // new variables in that case | 114 | // new variables in that case |
113 | 115 | ||
114 | for i in 1..vars.0.kinds.len() { | 116 | for i in 1..vars.0.kinds.len() { |
115 | if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) | 117 | if vars.0.value[i - 1] |
118 | != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) | ||
116 | { | 119 | { |
117 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); | 120 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); |
118 | return None; | 121 | return None; |
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index d740b7265..66a88e2b6 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | MissingPatFields, RemoveThisSemicolon, | 17 | MissingPatFields, RemoveThisSemicolon, |
18 | }, | 18 | }, |
19 | utils::variant_data, | 19 | utils::variant_data, |
20 | ApplicationTy, InferenceResult, Ty, TypeCtor, | 20 | InferenceResult, Ty, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | pub(crate) use hir_def::{ | 23 | pub(crate) use hir_def::{ |
@@ -381,14 +381,11 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
381 | _ => return, | 381 | _ => return, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); | 384 | let (params, required) = match mismatch.expected { |
385 | let core_option_ctor = TypeCtor::Adt(AdtId::EnumId(core_option_enum)); | 385 | Ty::Adt(AdtId::EnumId(enum_id), ref parameters) if enum_id == core_result_enum => { |
386 | |||
387 | let (params, required) = match &mismatch.expected { | ||
388 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => { | ||
389 | (parameters, "Ok".to_string()) | 386 | (parameters, "Ok".to_string()) |
390 | } | 387 | } |
391 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_option_ctor => { | 388 | Ty::Adt(AdtId::EnumId(enum_id), ref parameters) if enum_id == core_option_enum => { |
392 | (parameters, "Some".to_string()) | 389 | (parameters, "Some".to_string()) |
393 | } | 390 | } |
394 | _ => return, | 391 | _ => return, |
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs index 1c1423fbf..86fee0050 100644 --- a/crates/hir_ty/src/diagnostics/match_check.rs +++ b/crates/hir_ty/src/diagnostics/match_check.rs | |||
@@ -227,7 +227,7 @@ use hir_def::{ | |||
227 | use la_arena::Idx; | 227 | use la_arena::Idx; |
228 | use smallvec::{smallvec, SmallVec}; | 228 | use smallvec::{smallvec, SmallVec}; |
229 | 229 | ||
230 | use crate::{db::HirDatabase, ApplicationTy, InferenceResult, Ty, TypeCtor}; | 230 | use crate::{db::HirDatabase, InferenceResult, Ty}; |
231 | 231 | ||
232 | #[derive(Debug, Clone, Copy)] | 232 | #[derive(Debug, Clone, Copy)] |
233 | /// Either a pattern from the source code being analyzed, represented as | 233 | /// Either a pattern from the source code being analyzed, represented as |
@@ -627,14 +627,12 @@ pub(super) fn is_useful( | |||
627 | // - `!` type | 627 | // - `!` type |
628 | // In those cases, no match arm is useful. | 628 | // In those cases, no match arm is useful. |
629 | match cx.infer[cx.match_expr].strip_references() { | 629 | match cx.infer[cx.match_expr].strip_references() { |
630 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) => { | 630 | Ty::Adt(AdtId::EnumId(enum_id), ..) => { |
631 | if cx.db.enum_data(*enum_id).variants.is_empty() { | 631 | if cx.db.enum_data(*enum_id).variants.is_empty() { |
632 | return Ok(Usefulness::NotUseful); | 632 | return Ok(Usefulness::NotUseful); |
633 | } | 633 | } |
634 | } | 634 | } |
635 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) => { | 635 | Ty::Never => return Ok(Usefulness::NotUseful), |
636 | return Ok(Usefulness::NotUseful); | ||
637 | } | ||
638 | _ => (), | 636 | _ => (), |
639 | } | 637 | } |
640 | 638 | ||
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs index 9c506112d..e77a20fea 100644 --- a/crates/hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs | |||
@@ -11,9 +11,7 @@ use hir_def::{ | |||
11 | }; | 11 | }; |
12 | use hir_expand::diagnostics::DiagnosticSink; | 12 | use hir_expand::diagnostics::DiagnosticSink; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty}; |
15 | db::HirDatabase, diagnostics::MissingUnsafe, ApplicationTy, InferenceResult, Ty, TypeCtor, | ||
16 | }; | ||
17 | 15 | ||
18 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { | 16 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { |
19 | owner: DefWithBodyId, | 17 | owner: DefWithBodyId, |
@@ -112,7 +110,7 @@ fn walk_unsafe( | |||
112 | } | 110 | } |
113 | } | 111 | } |
114 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { | 112 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { |
115 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }) = &infer[*expr] { | 113 | if let Ty::Raw(..) = &infer[*expr] { |
116 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); | 114 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); |
117 | } | 115 | } |
118 | } | 116 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 271fcbfaf..d4a8b48e6 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -3,10 +3,12 @@ | |||
3 | use std::{borrow::Cow, fmt}; | 3 | use std::{borrow::Cow, fmt}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, | 6 | db::HirDatabase, primitive, utils::generics, AliasTy, CallableDefId, CallableSig, |
7 | Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 7 | GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, |
8 | TraitRef, Ty, | ||
8 | }; | 9 | }; |
9 | use arrayvec::ArrayVec; | 10 | use arrayvec::ArrayVec; |
11 | use chalk_ir::Mutability; | ||
10 | use hir_def::{ | 12 | use hir_def::{ |
11 | db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, | 13 | db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, |
12 | AssocContainerId, HasModule, Lookup, ModuleId, TraitId, | 14 | AssocContainerId, HasModule, Lookup, ModuleId, TraitId, |
@@ -234,39 +236,79 @@ impl HirDisplay for &Ty { | |||
234 | } | 236 | } |
235 | } | 237 | } |
236 | 238 | ||
237 | impl HirDisplay for ApplicationTy { | 239 | impl HirDisplay for ProjectionTy { |
238 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 240 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
239 | if f.should_truncate() { | 241 | if f.should_truncate() { |
240 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 242 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
241 | } | 243 | } |
242 | 244 | ||
243 | match self.ctor { | 245 | let trait_ = f.db.trait_data(self.trait_(f.db)); |
244 | TypeCtor::Bool => write!(f, "bool")?, | 246 | let first_parameter = self.parameters[0].into_displayable( |
245 | TypeCtor::Char => write!(f, "char")?, | 247 | f.db, |
246 | TypeCtor::Int(t) => write!(f, "{}", t)?, | 248 | f.max_size, |
247 | TypeCtor::Float(t) => write!(f, "{}", t)?, | 249 | f.omit_verbose_types, |
248 | TypeCtor::Str => write!(f, "str")?, | 250 | f.display_target, |
249 | TypeCtor::Slice => { | 251 | ); |
250 | let t = self.parameters.as_single(); | 252 | write!(f, "<{} as {}", first_parameter, trait_.name)?; |
253 | if self.parameters.len() > 1 { | ||
254 | write!(f, "<")?; | ||
255 | f.write_joined(&self.parameters[1..], ", ")?; | ||
256 | write!(f, ">")?; | ||
257 | } | ||
258 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; | ||
259 | Ok(()) | ||
260 | } | ||
261 | } | ||
262 | |||
263 | impl HirDisplay for Ty { | ||
264 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
265 | if f.should_truncate() { | ||
266 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
267 | } | ||
268 | |||
269 | match self { | ||
270 | Ty::Never => write!(f, "!")?, | ||
271 | Ty::Str => write!(f, "str")?, | ||
272 | Ty::Scalar(Scalar::Bool) => write!(f, "bool")?, | ||
273 | Ty::Scalar(Scalar::Char) => write!(f, "char")?, | ||
274 | &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, | ||
275 | &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, | ||
276 | &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, | ||
277 | Ty::Slice(parameters) => { | ||
278 | let t = parameters.as_single(); | ||
251 | write!(f, "[")?; | 279 | write!(f, "[")?; |
252 | t.hir_fmt(f)?; | 280 | t.hir_fmt(f)?; |
253 | write!(f, "]")?; | 281 | write!(f, "]")?; |
254 | } | 282 | } |
255 | TypeCtor::Array => { | 283 | Ty::Array(parameters) => { |
256 | let t = self.parameters.as_single(); | 284 | let t = parameters.as_single(); |
257 | write!(f, "[")?; | 285 | write!(f, "[")?; |
258 | t.hir_fmt(f)?; | 286 | t.hir_fmt(f)?; |
259 | write!(f, "; _]")?; | 287 | write!(f, "; _]")?; |
260 | } | 288 | } |
261 | TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { | 289 | Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => { |
262 | let t = self.parameters.as_single(); | 290 | let t = parameters.as_single(); |
263 | let ty_display = | 291 | let ty_display = |
264 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); | 292 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); |
265 | 293 | ||
266 | if matches!(self.ctor, TypeCtor::RawPtr(_)) { | 294 | if matches!(self, Ty::Raw(..)) { |
267 | write!(f, "*{}", m.as_keyword_for_ptr())?; | 295 | write!( |
296 | f, | ||
297 | "*{}", | ||
298 | match m { | ||
299 | Mutability::Not => "const ", | ||
300 | Mutability::Mut => "mut ", | ||
301 | } | ||
302 | )?; | ||
268 | } else { | 303 | } else { |
269 | write!(f, "&{}", m.as_keyword_for_ref())?; | 304 | write!( |
305 | f, | ||
306 | "&{}", | ||
307 | match m { | ||
308 | Mutability::Not => "", | ||
309 | Mutability::Mut => "mut ", | ||
310 | } | ||
311 | )?; | ||
270 | } | 312 | } |
271 | 313 | ||
272 | let datas; | 314 | let datas; |
@@ -274,10 +316,10 @@ impl HirDisplay for ApplicationTy { | |||
274 | Ty::Dyn(predicates) if predicates.len() > 1 => { | 316 | Ty::Dyn(predicates) if predicates.len() > 1 => { |
275 | Cow::Borrowed(predicates.as_ref()) | 317 | Cow::Borrowed(predicates.as_ref()) |
276 | } | 318 | } |
277 | &Ty::Opaque(OpaqueTy { | 319 | &Ty::Alias(AliasTy::Opaque(OpaqueTy { |
278 | opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), | 320 | opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), |
279 | ref parameters, | 321 | ref parameters, |
280 | }) => { | 322 | })) => { |
281 | datas = | 323 | datas = |
282 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 324 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
283 | let data = (*datas) | 325 | let data = (*datas) |
@@ -304,25 +346,24 @@ impl HirDisplay for ApplicationTy { | |||
304 | write!(f, "{}", ty_display)?; | 346 | write!(f, "{}", ty_display)?; |
305 | } | 347 | } |
306 | } | 348 | } |
307 | TypeCtor::Never => write!(f, "!")?, | 349 | Ty::Tuple(_, substs) => { |
308 | TypeCtor::Tuple { .. } => { | 350 | if substs.len() == 1 { |
309 | let ts = &self.parameters; | ||
310 | if ts.len() == 1 { | ||
311 | write!(f, "(")?; | 351 | write!(f, "(")?; |
312 | ts[0].hir_fmt(f)?; | 352 | substs[0].hir_fmt(f)?; |
313 | write!(f, ",)")?; | 353 | write!(f, ",)")?; |
314 | } else { | 354 | } else { |
315 | write!(f, "(")?; | 355 | write!(f, "(")?; |
316 | f.write_joined(&*ts.0, ", ")?; | 356 | f.write_joined(&*substs.0, ", ")?; |
317 | write!(f, ")")?; | 357 | write!(f, ")")?; |
318 | } | 358 | } |
319 | } | 359 | } |
320 | TypeCtor::FnPtr { is_varargs, .. } => { | 360 | Ty::Function(fn_ptr) => { |
321 | let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); | 361 | let sig = CallableSig::from_fn_ptr(fn_ptr); |
322 | sig.hir_fmt(f)?; | 362 | sig.hir_fmt(f)?; |
323 | } | 363 | } |
324 | TypeCtor::FnDef(def) => { | 364 | Ty::FnDef(def, parameters) => { |
325 | let sig = f.db.callable_item_signature(def).subst(&self.parameters); | 365 | let def = *def; |
366 | let sig = f.db.callable_item_signature(def).subst(parameters); | ||
326 | match def { | 367 | match def { |
327 | CallableDefId::FunctionId(ff) => { | 368 | CallableDefId::FunctionId(ff) => { |
328 | write!(f, "fn {}", f.db.function_data(ff).name)? | 369 | write!(f, "fn {}", f.db.function_data(ff).name)? |
@@ -332,7 +373,7 @@ impl HirDisplay for ApplicationTy { | |||
332 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? | 373 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? |
333 | } | 374 | } |
334 | }; | 375 | }; |
335 | if self.parameters.len() > 0 { | 376 | if parameters.len() > 0 { |
336 | let generics = generics(f.db.upcast(), def.into()); | 377 | let generics = generics(f.db.upcast(), def.into()); |
337 | let (parent_params, self_param, type_params, _impl_trait_params) = | 378 | let (parent_params, self_param, type_params, _impl_trait_params) = |
338 | generics.provenance_split(); | 379 | generics.provenance_split(); |
@@ -340,7 +381,7 @@ impl HirDisplay for ApplicationTy { | |||
340 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? | 381 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? |
341 | if total_len > 0 { | 382 | if total_len > 0 { |
342 | write!(f, "<")?; | 383 | write!(f, "<")?; |
343 | f.write_joined(&self.parameters.0[..total_len], ", ")?; | 384 | f.write_joined(¶meters.0[..total_len], ", ")?; |
344 | write!(f, ">")?; | 385 | write!(f, ">")?; |
345 | } | 386 | } |
346 | } | 387 | } |
@@ -359,10 +400,10 @@ impl HirDisplay for ApplicationTy { | |||
359 | write!(f, " -> {}", ret_display)?; | 400 | write!(f, " -> {}", ret_display)?; |
360 | } | 401 | } |
361 | } | 402 | } |
362 | TypeCtor::Adt(def_id) => { | 403 | Ty::Adt(def_id, parameters) => { |
363 | match f.display_target { | 404 | match f.display_target { |
364 | DisplayTarget::Diagnostics | DisplayTarget::Test => { | 405 | DisplayTarget::Diagnostics | DisplayTarget::Test => { |
365 | let name = match def_id { | 406 | let name = match *def_id { |
366 | AdtId::StructId(it) => f.db.struct_data(it).name.clone(), | 407 | AdtId::StructId(it) => f.db.struct_data(it).name.clone(), |
367 | AdtId::UnionId(it) => f.db.union_data(it).name.clone(), | 408 | AdtId::UnionId(it) => f.db.union_data(it).name.clone(), |
368 | AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), | 409 | AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), |
@@ -372,7 +413,7 @@ impl HirDisplay for ApplicationTy { | |||
372 | DisplayTarget::SourceCode { module_id } => { | 413 | DisplayTarget::SourceCode { module_id } => { |
373 | if let Some(path) = find_path::find_path( | 414 | if let Some(path) = find_path::find_path( |
374 | f.db.upcast(), | 415 | f.db.upcast(), |
375 | ItemInNs::Types(def_id.into()), | 416 | ItemInNs::Types((*def_id).into()), |
376 | module_id, | 417 | module_id, |
377 | ) { | 418 | ) { |
378 | write!(f, "{}", path)?; | 419 | write!(f, "{}", path)?; |
@@ -384,19 +425,18 @@ impl HirDisplay for ApplicationTy { | |||
384 | } | 425 | } |
385 | } | 426 | } |
386 | 427 | ||
387 | if self.parameters.len() > 0 { | 428 | if parameters.len() > 0 { |
388 | let parameters_to_write = | 429 | let parameters_to_write = |
389 | if f.display_target.is_source_code() || f.omit_verbose_types() { | 430 | if f.display_target.is_source_code() || f.omit_verbose_types() { |
390 | match self | 431 | match self |
391 | .ctor | ||
392 | .as_generic_def() | 432 | .as_generic_def() |
393 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 433 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
394 | .filter(|defaults| !defaults.is_empty()) | 434 | .filter(|defaults| !defaults.is_empty()) |
395 | { | 435 | { |
396 | None => self.parameters.0.as_ref(), | 436 | None => parameters.0.as_ref(), |
397 | Some(default_parameters) => { | 437 | Some(default_parameters) => { |
398 | let mut default_from = 0; | 438 | let mut default_from = 0; |
399 | for (i, parameter) in self.parameters.iter().enumerate() { | 439 | for (i, parameter) in parameters.iter().enumerate() { |
400 | match (parameter, default_parameters.get(i)) { | 440 | match (parameter, default_parameters.get(i)) { |
401 | (&Ty::Unknown, _) | (_, None) => { | 441 | (&Ty::Unknown, _) | (_, None) => { |
402 | default_from = i + 1; | 442 | default_from = i + 1; |
@@ -404,18 +444,18 @@ impl HirDisplay for ApplicationTy { | |||
404 | (_, Some(default_parameter)) => { | 444 | (_, Some(default_parameter)) => { |
405 | let actual_default = default_parameter | 445 | let actual_default = default_parameter |
406 | .clone() | 446 | .clone() |
407 | .subst(&self.parameters.prefix(i)); | 447 | .subst(¶meters.prefix(i)); |
408 | if parameter != &actual_default { | 448 | if parameter != &actual_default { |
409 | default_from = i + 1; | 449 | default_from = i + 1; |
410 | } | 450 | } |
411 | } | 451 | } |
412 | } | 452 | } |
413 | } | 453 | } |
414 | &self.parameters.0[0..default_from] | 454 | ¶meters.0[0..default_from] |
415 | } | 455 | } |
416 | } | 456 | } |
417 | } else { | 457 | } else { |
418 | self.parameters.0.as_ref() | 458 | parameters.0.as_ref() |
419 | }; | 459 | }; |
420 | if !parameters_to_write.is_empty() { | 460 | if !parameters_to_write.is_empty() { |
421 | write!(f, "<")?; | 461 | write!(f, "<")?; |
@@ -424,61 +464,54 @@ impl HirDisplay for ApplicationTy { | |||
424 | } | 464 | } |
425 | } | 465 | } |
426 | } | 466 | } |
427 | TypeCtor::AssociatedType(type_alias) => { | 467 | Ty::AssociatedType(type_alias, parameters) => { |
428 | let trait_ = match type_alias.lookup(f.db.upcast()).container { | 468 | let trait_ = match type_alias.lookup(f.db.upcast()).container { |
429 | AssocContainerId::TraitId(it) => it, | 469 | AssocContainerId::TraitId(it) => it, |
430 | _ => panic!("not an associated type"), | 470 | _ => panic!("not an associated type"), |
431 | }; | 471 | }; |
432 | let trait_ = f.db.trait_data(trait_); | 472 | let trait_ = f.db.trait_data(trait_); |
433 | let type_alias_data = f.db.type_alias_data(type_alias); | 473 | let type_alias_data = f.db.type_alias_data(*type_alias); |
434 | 474 | ||
435 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) | 475 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) |
436 | if f.display_target.is_test() { | 476 | if f.display_target.is_test() { |
437 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; | 477 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; |
438 | if self.parameters.len() > 0 { | 478 | if parameters.len() > 0 { |
439 | write!(f, "<")?; | 479 | write!(f, "<")?; |
440 | f.write_joined(&*self.parameters.0, ", ")?; | 480 | f.write_joined(&*parameters.0, ", ")?; |
441 | write!(f, ">")?; | 481 | write!(f, ">")?; |
442 | } | 482 | } |
443 | } else { | 483 | } else { |
444 | let projection_ty = ProjectionTy { | 484 | let projection_ty = |
445 | associated_ty: type_alias, | 485 | ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() }; |
446 | parameters: self.parameters.clone(), | ||
447 | }; | ||
448 | 486 | ||
449 | projection_ty.hir_fmt(f)?; | 487 | projection_ty.hir_fmt(f)?; |
450 | } | 488 | } |
451 | } | 489 | } |
452 | TypeCtor::ForeignType(type_alias) => { | 490 | Ty::ForeignType(type_alias) => { |
453 | let type_alias = f.db.type_alias_data(type_alias); | 491 | let type_alias = f.db.type_alias_data(*type_alias); |
454 | write!(f, "{}", type_alias.name)?; | 492 | write!(f, "{}", type_alias.name)?; |
455 | if self.parameters.len() > 0 { | ||
456 | write!(f, "<")?; | ||
457 | f.write_joined(&*self.parameters.0, ", ")?; | ||
458 | write!(f, ">")?; | ||
459 | } | ||
460 | } | 493 | } |
461 | TypeCtor::OpaqueType(opaque_ty_id) => { | 494 | Ty::OpaqueType(opaque_ty_id, parameters) => { |
462 | match opaque_ty_id { | 495 | match opaque_ty_id { |
463 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 496 | &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
464 | let datas = | 497 | let datas = |
465 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 498 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
466 | let data = (*datas) | 499 | let data = (*datas) |
467 | .as_ref() | 500 | .as_ref() |
468 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 501 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
469 | let bounds = data.subst(&self.parameters); | 502 | let bounds = data.subst(¶meters); |
470 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 503 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; |
471 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution | 504 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
472 | } | 505 | } |
473 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 506 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { |
474 | write!(f, "impl Future<Output = ")?; | 507 | write!(f, "impl Future<Output = ")?; |
475 | self.parameters[0].hir_fmt(f)?; | 508 | parameters[0].hir_fmt(f)?; |
476 | write!(f, ">")?; | 509 | write!(f, ">")?; |
477 | } | 510 | } |
478 | } | 511 | } |
479 | } | 512 | } |
480 | TypeCtor::Closure { .. } => { | 513 | Ty::Closure(.., substs) => { |
481 | let sig = self.parameters[0].callable_sig(f.db); | 514 | let sig = substs[0].callable_sig(f.db); |
482 | if let Some(sig) = sig { | 515 | if let Some(sig) = sig { |
483 | if sig.params().is_empty() { | 516 | if sig.params().is_empty() { |
484 | write!(f, "||")?; | 517 | write!(f, "||")?; |
@@ -501,44 +534,6 @@ impl HirDisplay for ApplicationTy { | |||
501 | write!(f, "{{closure}}")?; | 534 | write!(f, "{{closure}}")?; |
502 | } | 535 | } |
503 | } | 536 | } |
504 | } | ||
505 | Ok(()) | ||
506 | } | ||
507 | } | ||
508 | |||
509 | impl HirDisplay for ProjectionTy { | ||
510 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
511 | if f.should_truncate() { | ||
512 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
513 | } | ||
514 | |||
515 | let trait_ = f.db.trait_data(self.trait_(f.db)); | ||
516 | let first_parameter = self.parameters[0].into_displayable( | ||
517 | f.db, | ||
518 | f.max_size, | ||
519 | f.omit_verbose_types, | ||
520 | f.display_target, | ||
521 | ); | ||
522 | write!(f, "<{} as {}", first_parameter, trait_.name)?; | ||
523 | if self.parameters.len() > 1 { | ||
524 | write!(f, "<")?; | ||
525 | f.write_joined(&self.parameters[1..], ", ")?; | ||
526 | write!(f, ">")?; | ||
527 | } | ||
528 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; | ||
529 | Ok(()) | ||
530 | } | ||
531 | } | ||
532 | |||
533 | impl HirDisplay for Ty { | ||
534 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
535 | if f.should_truncate() { | ||
536 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
537 | } | ||
538 | |||
539 | match self { | ||
540 | Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, | ||
541 | Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, | ||
542 | Ty::Placeholder(id) => { | 537 | Ty::Placeholder(id) => { |
543 | let generics = generics(f.db.upcast(), id.parent); | 538 | let generics = generics(f.db.upcast(), id.parent); |
544 | let param_data = &generics.params.types[id.local_id]; | 539 | let param_data = &generics.params.types[id.local_id]; |
@@ -557,11 +552,12 @@ impl HirDisplay for Ty { | |||
557 | } | 552 | } |
558 | } | 553 | } |
559 | } | 554 | } |
560 | Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, | 555 | Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, |
561 | Ty::Dyn(predicates) => { | 556 | Ty::Dyn(predicates) => { |
562 | write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; | 557 | write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; |
563 | } | 558 | } |
564 | Ty::Opaque(opaque_ty) => { | 559 | Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, |
560 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | ||
565 | match opaque_ty.opaque_ty_id { | 561 | match opaque_ty.opaque_ty_id { |
566 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 562 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
567 | let datas = | 563 | let datas = |
@@ -585,13 +581,13 @@ impl HirDisplay for Ty { | |||
585 | } | 581 | } |
586 | write!(f, "{{unknown}}")?; | 582 | write!(f, "{{unknown}}")?; |
587 | } | 583 | } |
588 | Ty::Infer(..) => write!(f, "_")?, | 584 | Ty::InferenceVar(..) => write!(f, "_")?, |
589 | } | 585 | } |
590 | Ok(()) | 586 | Ok(()) |
591 | } | 587 | } |
592 | } | 588 | } |
593 | 589 | ||
594 | impl HirDisplay for FnSig { | 590 | impl HirDisplay for CallableSig { |
595 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 591 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
596 | write!(f, "fn(")?; | 592 | write!(f, "fn(")?; |
597 | f.write_joined(self.params(), ", ")?; | 593 | f.write_joined(self.params(), ", ")?; |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 4b683c5a7..4d771a91e 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -18,6 +18,7 @@ use std::mem; | |||
18 | use std::ops::Index; | 18 | use std::ops::Index; |
19 | use std::sync::Arc; | 19 | use std::sync::Arc; |
20 | 20 | ||
21 | use chalk_ir::Mutability; | ||
21 | use hir_def::{ | 22 | use hir_def::{ |
22 | body::Body, | 23 | body::Body, |
23 | data::{ConstData, FunctionData, StaticData}, | 24 | data::{ConstData, FunctionData, StaticData}, |
@@ -25,7 +26,7 @@ use hir_def::{ | |||
25 | lang_item::LangItemTarget, | 26 | lang_item::LangItemTarget, |
26 | path::{path, Path}, | 27 | path::{path, Path}, |
27 | resolver::{HasResolver, Resolver, TypeNs}, | 28 | resolver::{HasResolver, Resolver, TypeNs}, |
28 | type_ref::{Mutability, TypeRef}, | 29 | type_ref::TypeRef, |
29 | AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId, | 30 | AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId, |
30 | TypeAliasId, VariantId, | 31 | TypeAliasId, VariantId, |
31 | }; | 32 | }; |
@@ -36,25 +37,15 @@ use stdx::impl_from; | |||
36 | use syntax::SmolStr; | 37 | use syntax::SmolStr; |
37 | 38 | ||
38 | use super::{ | 39 | use super::{ |
39 | primitive::{FloatTy, IntTy}, | ||
40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, | 41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, |
42 | }; | 42 | }; |
43 | use crate::{ | 43 | use crate::{ |
44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, | 44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | pub(crate) use unify::unify; | 47 | pub(crate) use unify::unify; |
48 | 48 | ||
49 | macro_rules! ty_app { | ||
50 | ($ctor:pat, $param:pat) => { | ||
51 | crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param }) | ||
52 | }; | ||
53 | ($ctor:pat) => { | ||
54 | ty_app!($ctor, _) | ||
55 | }; | ||
56 | } | ||
57 | |||
58 | mod unify; | 49 | mod unify; |
59 | mod path; | 50 | mod path; |
60 | mod expr; | 51 | mod expr; |
@@ -97,7 +88,7 @@ impl BindingMode { | |||
97 | fn convert(annotation: BindingAnnotation) -> BindingMode { | 88 | fn convert(annotation: BindingAnnotation) -> BindingMode { |
98 | match annotation { | 89 | match annotation { |
99 | BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, | 90 | BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, |
100 | BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), | 91 | BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not), |
101 | BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut), | 92 | BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut), |
102 | } | 93 | } |
103 | } | 94 | } |
@@ -405,7 +396,7 @@ impl<'a> InferenceContext<'a> { | |||
405 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { | 396 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { |
406 | let ty = self.resolve_ty_as_possible(ty); | 397 | let ty = self.resolve_ty_as_possible(ty); |
407 | ty.fold(&mut |ty| match ty { | 398 | ty.fold(&mut |ty| match ty { |
408 | Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), | 399 | Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty), |
409 | _ => ty, | 400 | _ => ty, |
410 | }) | 401 | }) |
411 | } | 402 | } |
@@ -664,30 +655,17 @@ impl<'a> InferenceContext<'a> { | |||
664 | /// two are used for inference of literal values (e.g. `100` could be one of | 655 | /// two are used for inference of literal values (e.g. `100` could be one of |
665 | /// several integer types). | 656 | /// several integer types). |
666 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | 657 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] |
667 | pub enum InferTy { | 658 | pub struct InferenceVar { |
668 | TypeVar(unify::TypeVarId), | 659 | index: u32, |
669 | IntVar(unify::TypeVarId), | ||
670 | FloatVar(unify::TypeVarId), | ||
671 | MaybeNeverTypeVar(unify::TypeVarId), | ||
672 | } | 660 | } |
673 | 661 | ||
674 | impl InferTy { | 662 | impl InferenceVar { |
675 | fn to_inner(self) -> unify::TypeVarId { | 663 | fn to_inner(self) -> unify::TypeVarId { |
676 | match self { | 664 | unify::TypeVarId(self.index) |
677 | InferTy::TypeVar(ty) | ||
678 | | InferTy::IntVar(ty) | ||
679 | | InferTy::FloatVar(ty) | ||
680 | | InferTy::MaybeNeverTypeVar(ty) => ty, | ||
681 | } | ||
682 | } | 665 | } |
683 | 666 | ||
684 | fn fallback_value(self) -> Ty { | 667 | fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self { |
685 | match self { | 668 | InferenceVar { index } |
686 | InferTy::TypeVar(..) => Ty::Unknown, | ||
687 | InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())), | ||
688 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())), | ||
689 | InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), | ||
690 | } | ||
691 | } | 669 | } |
692 | } | 670 | } |
693 | 671 | ||
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 32c7c57cd..cf0a3add4 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -4,12 +4,13 @@ | |||
4 | //! | 4 | //! |
5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html | 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html |
6 | 6 | ||
7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; | 7 | use chalk_ir::{Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | ||
8 | use test_utils::mark; | 9 | use test_utils::mark; |
9 | 10 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; | 11 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; |
11 | 12 | ||
12 | use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; | 13 | use super::{InEnvironment, InferenceContext}; |
13 | 14 | ||
14 | impl<'a> InferenceContext<'a> { | 15 | impl<'a> InferenceContext<'a> { |
15 | /// Unify two types, but may coerce the first one to the second one | 16 | /// Unify two types, but may coerce the first one to the second one |
@@ -33,7 +34,7 @@ impl<'a> InferenceContext<'a> { | |||
33 | } else if self.coerce(ty2, ty1) { | 34 | } else if self.coerce(ty2, ty1) { |
34 | ty1.clone() | 35 | ty1.clone() |
35 | } else { | 36 | } else { |
36 | if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { | 37 | if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { |
37 | mark::hit!(coerce_fn_reification); | 38 | mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 39 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 40 | // pointers to have a chance at getting a match. See |
@@ -53,12 +54,11 @@ impl<'a> InferenceContext<'a> { | |||
53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 54 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
54 | match (&from_ty, to_ty) { | 55 | match (&from_ty, to_ty) { |
55 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 56 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
56 | (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { | 57 | (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { |
57 | let var = self.table.new_maybe_never_type_var(); | 58 | self.table.type_variable_table.set_diverging(*tv, true); |
58 | self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var)); | ||
59 | return true; | 59 | return true; |
60 | } | 60 | } |
61 | (ty_app!(TypeCtor::Never), _) => return true, | 61 | (Ty::Never, _) => return true, |
62 | 62 | ||
63 | // Trivial cases, this should go after `never` check to | 63 | // Trivial cases, this should go after `never` check to |
64 | // avoid infer result type to be never | 64 | // avoid infer result type to be never |
@@ -71,38 +71,33 @@ impl<'a> InferenceContext<'a> { | |||
71 | 71 | ||
72 | // Pointer weakening and function to pointer | 72 | // Pointer weakening and function to pointer |
73 | match (&mut from_ty, to_ty) { | 73 | match (&mut from_ty, to_ty) { |
74 | // `*mut T`, `&mut T, `&T`` -> `*const T` | 74 | // `*mut T` -> `*const T` |
75 | // `&mut T` -> `&T` | 75 | // `&mut T` -> `&T` |
76 | // `&mut T` -> `*mut T` | 76 | (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) |
77 | (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) | 77 | | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { |
78 | | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) | 78 | *m1 = *m2; |
79 | | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::Ref(Mutability::Shared))) | 79 | } |
80 | | (ty_app!(c1@TypeCtor::Ref(Mutability::Mut)), ty_app!(c2@TypeCtor::RawPtr(_))) => { | 80 | // `&T` -> `*const T` |
81 | *c1 = *c2; | 81 | // `&mut T` -> `*mut T`/`*const T` |
82 | (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) | ||
83 | | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { | ||
84 | from_ty = Ty::Raw(m2, substs.clone()); | ||
82 | } | 85 | } |
83 | 86 | ||
84 | // Illegal mutablity conversion | 87 | // Illegal mutability conversion |
85 | ( | 88 | (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) |
86 | ty_app!(TypeCtor::RawPtr(Mutability::Shared)), | 89 | | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, |
87 | ty_app!(TypeCtor::RawPtr(Mutability::Mut)), | ||
88 | ) | ||
89 | | ( | ||
90 | ty_app!(TypeCtor::Ref(Mutability::Shared)), | ||
91 | ty_app!(TypeCtor::Ref(Mutability::Mut)), | ||
92 | ) => return false, | ||
93 | 90 | ||
94 | // `{function_type}` -> `fn()` | 91 | // `{function_type}` -> `fn()` |
95 | (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { | 92 | (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { |
96 | match from_ty.callable_sig(self.db) { | 93 | None => return false, |
97 | None => return false, | 94 | Some(sig) => { |
98 | Some(sig) => { | 95 | from_ty = Ty::fn_ptr(sig); |
99 | from_ty = Ty::fn_ptr(sig); | ||
100 | } | ||
101 | } | 96 | } |
102 | } | 97 | }, |
103 | 98 | ||
104 | (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { | 99 | (Ty::Closure(.., substs), Ty::Function { .. }) => { |
105 | from_ty = params[0].clone(); | 100 | from_ty = substs[0].clone(); |
106 | } | 101 | } |
107 | 102 | ||
108 | _ => {} | 103 | _ => {} |
@@ -115,9 +110,7 @@ impl<'a> InferenceContext<'a> { | |||
115 | // Auto Deref if cannot coerce | 110 | // Auto Deref if cannot coerce |
116 | match (&from_ty, to_ty) { | 111 | match (&from_ty, to_ty) { |
117 | // FIXME: DerefMut | 112 | // FIXME: DerefMut |
118 | (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { | 113 | (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), |
119 | self.unify_autoderef_behind_ref(&st1[0], &st2[0]) | ||
120 | } | ||
121 | 114 | ||
122 | // Otherwise, normal unify | 115 | // Otherwise, normal unify |
123 | _ => self.unify(&from_ty, to_ty), | 116 | _ => self.unify(&from_ty, to_ty), |
@@ -178,17 +171,17 @@ impl<'a> InferenceContext<'a> { | |||
178 | }, | 171 | }, |
179 | ) { | 172 | ) { |
180 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); | 173 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); |
181 | match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { | 174 | let from_ty = self.resolve_ty_shallow(&derefed_ty); |
182 | // Stop when constructor matches. | 175 | // Stop when constructor matches. |
183 | (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { | 176 | if from_ty.equals_ctor(&to_ty) { |
184 | // It will not recurse to `coerce`. | 177 | // It will not recurse to `coerce`. |
185 | return self.table.unify_substs(st1, st2, 0); | 178 | return match (from_ty.substs(), to_ty.substs()) { |
186 | } | 179 | (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0), |
187 | _ => { | 180 | (None, None) => true, |
188 | if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { | 181 | _ => false, |
189 | return true; | 182 | }; |
190 | } | 183 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { |
191 | } | 184 | return true; |
192 | } | 185 | } |
193 | } | 186 | } |
194 | 187 | ||
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index cb59a6937..cf1f1038a 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -3,8 +3,8 @@ | |||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::iter::{repeat, repeat_with}; |
4 | use std::{mem, sync::Arc}; | 4 | use std::{mem, sync::Arc}; |
5 | 5 | ||
6 | use chalk_ir::{Mutability, TyVariableKind}; | ||
6 | use hir_def::{ | 7 | use hir_def::{ |
7 | builtin_type::Signedness, | ||
8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
9 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
10 | resolver::resolver_for_expr, | 10 | resolver::resolver_for_expr, |
@@ -15,11 +15,14 @@ use syntax::ast::RangeOp; | |||
15 | use test_utils::mark; | 15 | use test_utils::mark; |
16 | 16 | ||
17 | use crate::{ | 17 | use crate::{ |
18 | autoderef, method_resolution, op, | 18 | autoderef, |
19 | lower::lower_to_chalk_mutability, | ||
20 | method_resolution, op, | ||
21 | primitive::{self, UintTy}, | ||
19 | traits::{FnTrait, InEnvironment}, | 22 | traits::{FnTrait, InEnvironment}, |
20 | utils::{generics, variant_data, Generics}, | 23 | utils::{generics, variant_data, Generics}, |
21 | ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, | 24 | Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, Substs, |
22 | Rawness, Substs, TraitRef, Ty, TypeCtor, | 25 | TraitRef, Ty, |
23 | }; | 26 | }; |
24 | 27 | ||
25 | use super::{ | 28 | use super::{ |
@@ -82,10 +85,7 @@ impl<'a> InferenceContext<'a> { | |||
82 | arg_tys.push(arg); | 85 | arg_tys.push(arg); |
83 | } | 86 | } |
84 | let parameters = param_builder.build(); | 87 | let parameters = param_builder.build(); |
85 | let arg_ty = Ty::Apply(ApplicationTy { | 88 | let arg_ty = Ty::Tuple(num_args, parameters); |
86 | ctor: TypeCtor::Tuple { cardinality: num_args as u16 }, | ||
87 | parameters, | ||
88 | }); | ||
89 | let substs = | 89 | let substs = |
90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
91 | 91 | ||
@@ -120,7 +120,7 @@ impl<'a> InferenceContext<'a> { | |||
120 | Expr::Missing => Ty::Unknown, | 120 | Expr::Missing => Ty::Unknown, |
121 | Expr::If { condition, then_branch, else_branch } => { | 121 | Expr::If { condition, then_branch, else_branch } => { |
122 | // if let is desugared to match, so this is always simple if | 122 | // if let is desugared to match, so this is always simple if |
123 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 123 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
124 | 124 | ||
125 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 125 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
126 | let mut both_arms_diverge = Diverges::Always; | 126 | let mut both_arms_diverge = Diverges::Always; |
@@ -175,7 +175,7 @@ impl<'a> InferenceContext<'a> { | |||
175 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 175 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
176 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 176 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
177 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 177 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); |
178 | Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) | 178 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) |
179 | } | 179 | } |
180 | Expr::Loop { body, label } => { | 180 | Expr::Loop { body, label } => { |
181 | self.breakables.push(BreakableContext { | 181 | self.breakables.push(BreakableContext { |
@@ -193,7 +193,7 @@ impl<'a> InferenceContext<'a> { | |||
193 | if ctxt.may_break { | 193 | if ctxt.may_break { |
194 | ctxt.break_ty | 194 | ctxt.break_ty |
195 | } else { | 195 | } else { |
196 | Ty::simple(TypeCtor::Never) | 196 | Ty::Never |
197 | } | 197 | } |
198 | } | 198 | } |
199 | Expr::While { condition, body, label } => { | 199 | Expr::While { condition, body, label } => { |
@@ -203,7 +203,7 @@ impl<'a> InferenceContext<'a> { | |||
203 | label: label.map(|label| self.body[label].name.clone()), | 203 | label: label.map(|label| self.body[label].name.clone()), |
204 | }); | 204 | }); |
205 | // while let is desugared to a match loop, so this is always simple while | 205 | // while let is desugared to a match loop, so this is always simple while |
206 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 206 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
207 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 207 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
208 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 208 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
209 | // the body may not run, so it diverging doesn't mean we diverge | 209 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -250,12 +250,12 @@ impl<'a> InferenceContext<'a> { | |||
250 | None => self.table.new_type_var(), | 250 | None => self.table.new_type_var(), |
251 | }; | 251 | }; |
252 | sig_tys.push(ret_ty.clone()); | 252 | sig_tys.push(ret_ty.clone()); |
253 | let sig_ty = Ty::apply( | 253 | let sig_ty = Ty::Function(FnPointer { |
254 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, | 254 | num_args: sig_tys.len() - 1, |
255 | Substs(sig_tys.clone().into()), | 255 | sig: FnSig { variadic: false }, |
256 | ); | 256 | substs: Substs(sig_tys.clone().into()), |
257 | let closure_ty = | 257 | }); |
258 | Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); | 258 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); |
259 | 259 | ||
260 | // Eagerly try to relate the closure type with the expected | 260 | // Eagerly try to relate the closure type with the expected |
261 | // type, otherwise we often won't have enough information to | 261 | // type, otherwise we often won't have enough information to |
@@ -306,11 +306,8 @@ impl<'a> InferenceContext<'a> { | |||
306 | Expr::Match { expr, arms } => { | 306 | Expr::Match { expr, arms } => { |
307 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 307 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
308 | 308 | ||
309 | let mut result_ty = if arms.is_empty() { | 309 | let mut result_ty = |
310 | Ty::simple(TypeCtor::Never) | 310 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; |
311 | } else { | ||
312 | self.table.new_type_var() | ||
313 | }; | ||
314 | 311 | ||
315 | let matchee_diverges = self.diverges; | 312 | let matchee_diverges = self.diverges; |
316 | let mut all_arms_diverge = Diverges::Always; | 313 | let mut all_arms_diverge = Diverges::Always; |
@@ -321,7 +318,7 @@ impl<'a> InferenceContext<'a> { | |||
321 | if let Some(guard_expr) = arm.guard { | 318 | if let Some(guard_expr) = arm.guard { |
322 | self.infer_expr( | 319 | self.infer_expr( |
323 | guard_expr, | 320 | guard_expr, |
324 | &Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 321 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
325 | ); | 322 | ); |
326 | } | 323 | } |
327 | 324 | ||
@@ -339,7 +336,7 @@ impl<'a> InferenceContext<'a> { | |||
339 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 336 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); |
340 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 337 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
341 | } | 338 | } |
342 | Expr::Continue { .. } => Ty::simple(TypeCtor::Never), | 339 | Expr::Continue { .. } => Ty::Never, |
343 | Expr::Break { expr, label } => { | 340 | Expr::Break { expr, label } => { |
344 | let val_ty = if let Some(expr) = expr { | 341 | let val_ty = if let Some(expr) = expr { |
345 | self.infer_expr(*expr, &Expectation::none()) | 342 | self.infer_expr(*expr, &Expectation::none()) |
@@ -364,8 +361,7 @@ impl<'a> InferenceContext<'a> { | |||
364 | expr: tgt_expr, | 361 | expr: tgt_expr, |
365 | }); | 362 | }); |
366 | } | 363 | } |
367 | 364 | Ty::Never | |
368 | Ty::simple(TypeCtor::Never) | ||
369 | } | 365 | } |
370 | Expr::Return { expr } => { | 366 | Expr::Return { expr } => { |
371 | if let Some(expr) = expr { | 367 | if let Some(expr) = expr { |
@@ -374,14 +370,14 @@ impl<'a> InferenceContext<'a> { | |||
374 | let unit = Ty::unit(); | 370 | let unit = Ty::unit(); |
375 | self.coerce(&unit, &self.return_ty.clone()); | 371 | self.coerce(&unit, &self.return_ty.clone()); |
376 | } | 372 | } |
377 | Ty::simple(TypeCtor::Never) | 373 | Ty::Never |
378 | } | 374 | } |
379 | Expr::Yield { expr } => { | 375 | Expr::Yield { expr } => { |
380 | // FIXME: track yield type for coercion | 376 | // FIXME: track yield type for coercion |
381 | if let Some(expr) = expr { | 377 | if let Some(expr) = expr { |
382 | self.infer_expr(*expr, &Expectation::none()); | 378 | self.infer_expr(*expr, &Expectation::none()); |
383 | } | 379 | } |
384 | Ty::simple(TypeCtor::Never) | 380 | Ty::Never |
385 | } | 381 | } |
386 | Expr::RecordLit { path, fields, spread } => { | 382 | Expr::RecordLit { path, fields, spread } => { |
387 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 383 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -391,7 +387,7 @@ impl<'a> InferenceContext<'a> { | |||
391 | 387 | ||
392 | self.unify(&ty, &expected.ty); | 388 | self.unify(&ty, &expected.ty); |
393 | 389 | ||
394 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 390 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
395 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 391 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
396 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 392 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
397 | for (field_idx, field) in fields.iter().enumerate() { | 393 | for (field_idx, field) in fields.iter().enumerate() { |
@@ -430,30 +426,23 @@ impl<'a> InferenceContext<'a> { | |||
430 | }, | 426 | }, |
431 | ) | 427 | ) |
432 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 428 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
433 | Ty::Apply(a_ty) => match a_ty.ctor { | 429 | Ty::Tuple(_, substs) => { |
434 | TypeCtor::Tuple { .. } => name | 430 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
435 | .as_tuple_index() | 431 | } |
436 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 432 | Ty::Adt(AdtId::StructId(s), parameters) => { |
437 | TypeCtor::Adt(AdtId::StructId(s)) => { | 433 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { |
438 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 434 | let field = FieldId { parent: s.into(), local_id }; |
439 | let field = FieldId { parent: s.into(), local_id }; | 435 | self.write_field_resolution(tgt_expr, field); |
440 | self.write_field_resolution(tgt_expr, field); | 436 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) |
441 | self.db.field_types(s.into())[field.local_id] | 437 | }) |
442 | .clone() | 438 | } |
443 | .subst(&a_ty.parameters) | 439 | Ty::Adt(AdtId::UnionId(u), parameters) => { |
444 | }) | 440 | self.db.union_data(u).variant_data.field(name).map(|local_id| { |
445 | } | 441 | let field = FieldId { parent: u.into(), local_id }; |
446 | TypeCtor::Adt(AdtId::UnionId(u)) => { | 442 | self.write_field_resolution(tgt_expr, field); |
447 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 443 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) |
448 | let field = FieldId { parent: u.into(), local_id }; | 444 | }) |
449 | self.write_field_resolution(tgt_expr, field); | 445 | } |
450 | self.db.field_types(u.into())[field.local_id] | ||
451 | .clone() | ||
452 | .subst(&a_ty.parameters) | ||
453 | }) | ||
454 | } | ||
455 | _ => None, | ||
456 | }, | ||
457 | _ => None, | 446 | _ => None, |
458 | }) | 447 | }) |
459 | .unwrap_or(Ty::Unknown); | 448 | .unwrap_or(Ty::Unknown); |
@@ -475,10 +464,11 @@ impl<'a> InferenceContext<'a> { | |||
475 | cast_ty | 464 | cast_ty |
476 | } | 465 | } |
477 | Expr::Ref { expr, rawness, mutability } => { | 466 | Expr::Ref { expr, rawness, mutability } => { |
467 | let mutability = lower_to_chalk_mutability(*mutability); | ||
478 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = | 468 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = |
479 | &expected.ty.as_reference_or_ptr() | 469 | &expected.ty.as_reference_or_ptr() |
480 | { | 470 | { |
481 | if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { | 471 | if *exp_mutability == Mutability::Mut && mutability == Mutability::Not { |
482 | // FIXME: throw type error - expected mut reference but found shared ref, | 472 | // FIXME: throw type error - expected mut reference but found shared ref, |
483 | // which cannot be coerced | 473 | // which cannot be coerced |
484 | } | 474 | } |
@@ -491,19 +481,24 @@ impl<'a> InferenceContext<'a> { | |||
491 | Expectation::none() | 481 | Expectation::none() |
492 | }; | 482 | }; |
493 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 483 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
494 | let ty = match rawness { | 484 | match rawness { |
495 | Rawness::RawPtr => TypeCtor::RawPtr(*mutability), | 485 | Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), |
496 | Rawness::Ref => TypeCtor::Ref(*mutability), | 486 | Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), |
497 | }; | 487 | } |
498 | Ty::apply_one(ty, inner_ty) | ||
499 | } | 488 | } |
500 | Expr::Box { expr } => { | 489 | Expr::Box { expr } => { |
501 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 490 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
502 | if let Some(box_) = self.resolve_boxed_box() { | 491 | if let Some(box_) = self.resolve_boxed_box() { |
503 | let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); | 492 | let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); |
504 | sb = sb.push(inner_ty); | 493 | sb = sb.push(inner_ty); |
494 | match self.db.generic_defaults(box_.into()).as_ref() { | ||
495 | [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { | ||
496 | sb = sb.push(alloc_ty.value.clone()); | ||
497 | } | ||
498 | _ => (), | ||
499 | } | ||
505 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 500 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
506 | Ty::apply(TypeCtor::Adt(box_), sb.build()) | 501 | Ty::Adt(box_, sb.build()) |
507 | } else { | 502 | } else { |
508 | Ty::Unknown | 503 | Ty::Unknown |
509 | } | 504 | } |
@@ -533,13 +528,11 @@ impl<'a> InferenceContext<'a> { | |||
533 | UnaryOp::Neg => { | 528 | UnaryOp::Neg => { |
534 | match &inner_ty { | 529 | match &inner_ty { |
535 | // Fast path for builtins | 530 | // Fast path for builtins |
536 | Ty::Apply(ApplicationTy { | 531 | Ty::Scalar(Scalar::Int(_)) |
537 | ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), | 532 | | Ty::Scalar(Scalar::Uint(_)) |
538 | .. | 533 | | Ty::Scalar(Scalar::Float(_)) |
539 | }) | 534 | | Ty::InferenceVar(_, TyVariableKind::Integer) |
540 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) | 535 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
541 | | Ty::Infer(InferTy::IntVar(..)) | ||
542 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | ||
543 | // Otherwise we resolve via the std::ops::Neg trait | 536 | // Otherwise we resolve via the std::ops::Neg trait |
544 | _ => self | 537 | _ => self |
545 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 538 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
@@ -548,9 +541,10 @@ impl<'a> InferenceContext<'a> { | |||
548 | UnaryOp::Not => { | 541 | UnaryOp::Not => { |
549 | match &inner_ty { | 542 | match &inner_ty { |
550 | // Fast path for builtins | 543 | // Fast path for builtins |
551 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) | 544 | Ty::Scalar(Scalar::Bool) |
552 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) | 545 | | Ty::Scalar(Scalar::Int(_)) |
553 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 546 | | Ty::Scalar(Scalar::Uint(_)) |
547 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | ||
554 | // Otherwise we resolve via the std::ops::Not trait | 548 | // Otherwise we resolve via the std::ops::Not trait |
555 | _ => self | 549 | _ => self |
556 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 550 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -561,7 +555,7 @@ impl<'a> InferenceContext<'a> { | |||
561 | Expr::BinaryOp { lhs, rhs, op } => match op { | 555 | Expr::BinaryOp { lhs, rhs, op } => match op { |
562 | Some(op) => { | 556 | Some(op) => { |
563 | let lhs_expectation = match op { | 557 | let lhs_expectation = match op { |
564 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 558 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
565 | _ => Expectation::none(), | 559 | _ => Expectation::none(), |
566 | }; | 560 | }; |
567 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 561 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -592,31 +586,31 @@ impl<'a> InferenceContext<'a> { | |||
592 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | 586 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); |
593 | match (range_type, lhs_ty, rhs_ty) { | 587 | match (range_type, lhs_ty, rhs_ty) { |
594 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 588 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
595 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | 589 | Some(adt) => Ty::Adt(adt, Substs::empty()), |
596 | None => Ty::Unknown, | 590 | None => Ty::Unknown, |
597 | }, | 591 | }, |
598 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 592 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
599 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 593 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
600 | None => Ty::Unknown, | 594 | None => Ty::Unknown, |
601 | }, | 595 | }, |
602 | (RangeOp::Inclusive, None, Some(ty)) => { | 596 | (RangeOp::Inclusive, None, Some(ty)) => { |
603 | match self.resolve_range_to_inclusive() { | 597 | match self.resolve_range_to_inclusive() { |
604 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 598 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
605 | None => Ty::Unknown, | 599 | None => Ty::Unknown, |
606 | } | 600 | } |
607 | } | 601 | } |
608 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 602 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
609 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 603 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
610 | None => Ty::Unknown, | 604 | None => Ty::Unknown, |
611 | }, | 605 | }, |
612 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 606 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
613 | match self.resolve_range_inclusive() { | 607 | match self.resolve_range_inclusive() { |
614 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 608 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
615 | None => Ty::Unknown, | 609 | None => Ty::Unknown, |
616 | } | 610 | } |
617 | } | 611 | } |
618 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 612 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
619 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 613 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
620 | None => Ty::Unknown, | 614 | None => Ty::Unknown, |
621 | }, | 615 | }, |
622 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 616 | (RangeOp::Inclusive, _, None) => Ty::Unknown, |
@@ -650,7 +644,7 @@ impl<'a> InferenceContext<'a> { | |||
650 | } | 644 | } |
651 | Expr::Tuple { exprs } => { | 645 | Expr::Tuple { exprs } => { |
652 | let mut tys = match &expected.ty { | 646 | let mut tys = match &expected.ty { |
653 | ty_app!(TypeCtor::Tuple { .. }, st) => st | 647 | Ty::Tuple(_, substs) => substs |
654 | .iter() | 648 | .iter() |
655 | .cloned() | 649 | .cloned() |
656 | .chain(repeat_with(|| self.table.new_type_var())) | 650 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -663,15 +657,11 @@ impl<'a> InferenceContext<'a> { | |||
663 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 657 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
664 | } | 658 | } |
665 | 659 | ||
666 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) | 660 | Ty::Tuple(tys.len(), Substs(tys.into())) |
667 | } | 661 | } |
668 | Expr::Array(array) => { | 662 | Expr::Array(array) => { |
669 | let elem_ty = match &expected.ty { | 663 | let elem_ty = match &expected.ty { |
670 | // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed | 664 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), |
671 | #[allow(unreachable_patterns)] | ||
672 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { | ||
673 | st.as_single().clone() | ||
674 | } | ||
675 | _ => self.table.new_type_var(), | 665 | _ => self.table.new_type_var(), |
676 | }; | 666 | }; |
677 | 667 | ||
@@ -688,30 +678,38 @@ impl<'a> InferenceContext<'a> { | |||
688 | ); | 678 | ); |
689 | self.infer_expr( | 679 | self.infer_expr( |
690 | *repeat, | 680 | *repeat, |
691 | &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), | 681 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), |
692 | ); | 682 | ); |
693 | } | 683 | } |
694 | } | 684 | } |
695 | 685 | ||
696 | Ty::apply_one(TypeCtor::Array, elem_ty) | 686 | Ty::Array(Substs::single(elem_ty)) |
697 | } | 687 | } |
698 | Expr::Literal(lit) => match lit { | 688 | Expr::Literal(lit) => match lit { |
699 | Literal::Bool(..) => Ty::simple(TypeCtor::Bool), | 689 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), |
700 | Literal::String(..) => { | 690 | Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), |
701 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | ||
702 | } | ||
703 | Literal::ByteString(..) => { | 691 | Literal::ByteString(..) => { |
704 | let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); | 692 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); |
705 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 693 | let array_type = Ty::Array(Substs::single(byte_type)); |
706 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 694 | Ty::Ref(Mutability::Not, Substs::single(array_type)) |
707 | } | 695 | } |
708 | Literal::Char(..) => Ty::simple(TypeCtor::Char), | 696 | Literal::Char(..) => Ty::Scalar(Scalar::Char), |
709 | Literal::Int(_v, ty) => match ty { | 697 | Literal::Int(_v, ty) => match ty { |
710 | Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), | 698 | Some(int_ty) => { |
699 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) | ||
700 | } | ||
701 | None => self.table.new_integer_var(), | ||
702 | }, | ||
703 | Literal::Uint(_v, ty) => match ty { | ||
704 | Some(int_ty) => { | ||
705 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) | ||
706 | } | ||
711 | None => self.table.new_integer_var(), | 707 | None => self.table.new_integer_var(), |
712 | }, | 708 | }, |
713 | Literal::Float(_v, ty) => match ty { | 709 | Literal::Float(_v, ty) => match ty { |
714 | Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), | 710 | Some(float_ty) => { |
711 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) | ||
712 | } | ||
715 | None => self.table.new_float_var(), | 713 | None => self.table.new_float_var(), |
716 | }, | 714 | }, |
717 | }, | 715 | }, |
@@ -767,7 +765,7 @@ impl<'a> InferenceContext<'a> { | |||
767 | // `!`). | 765 | // `!`). |
768 | if self.diverges.is_always() { | 766 | if self.diverges.is_always() { |
769 | // we don't even make an attempt at coercion | 767 | // we don't even make an attempt at coercion |
770 | self.table.new_maybe_never_type_var() | 768 | self.table.new_maybe_never_var() |
771 | } else { | 769 | } else { |
772 | self.coerce(&Ty::unit(), expected.coercion_target()); | 770 | self.coerce(&Ty::unit(), expected.coercion_target()); |
773 | Ty::unit() | 771 | Ty::unit() |
@@ -824,7 +822,7 @@ impl<'a> InferenceContext<'a> { | |||
824 | // Apply autoref so the below unification works correctly | 822 | // Apply autoref so the below unification works correctly |
825 | // FIXME: return correct autorefs from lookup_method | 823 | // FIXME: return correct autorefs from lookup_method |
826 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 824 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
827 | Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), | 825 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), |
828 | _ => derefed_receiver_ty, | 826 | _ => derefed_receiver_ty, |
829 | }; | 827 | }; |
830 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 828 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -901,30 +899,26 @@ impl<'a> InferenceContext<'a> { | |||
901 | } | 899 | } |
902 | 900 | ||
903 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 901 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
904 | if let Ty::Apply(a_ty) = callable_ty { | 902 | if let &Ty::FnDef(def, ref parameters) = callable_ty { |
905 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 903 | let generic_predicates = self.db.generic_predicates(def.into()); |
906 | let generic_predicates = self.db.generic_predicates(def.into()); | 904 | for predicate in generic_predicates.iter() { |
907 | for predicate in generic_predicates.iter() { | 905 | let predicate = predicate.clone().subst(parameters); |
908 | let predicate = predicate.clone().subst(&a_ty.parameters); | 906 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
909 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 907 | self.obligations.push(obligation); |
910 | self.obligations.push(obligation); | ||
911 | } | ||
912 | } | 908 | } |
913 | // add obligation for trait implementation, if this is a trait method | 909 | } |
914 | match def { | 910 | // add obligation for trait implementation, if this is a trait method |
915 | CallableDefId::FunctionId(f) => { | 911 | match def { |
916 | if let AssocContainerId::TraitId(trait_) = | 912 | CallableDefId::FunctionId(f) => { |
917 | f.lookup(self.db.upcast()).container | 913 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
918 | { | 914 | { |
919 | // construct a TraitDef | 915 | // construct a TraitDef |
920 | let substs = a_ty | 916 | let substs = |
921 | .parameters | 917 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); |
922 | .prefix(generics(self.db.upcast(), trait_.into()).len()); | 918 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
923 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); | ||
924 | } | ||
925 | } | 919 | } |
926 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
927 | } | 920 | } |
921 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
928 | } | 922 | } |
929 | } | 923 | } |
930 | } | 924 | } |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index d974f805b..eb099311c 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -3,17 +3,17 @@ | |||
3 | use std::iter::repeat; | 3 | use std::iter::repeat; |
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use chalk_ir::Mutability; | ||
6 | use hir_def::{ | 7 | use hir_def::{ |
7 | expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, | 8 | expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, |
8 | path::Path, | 9 | path::Path, |
9 | type_ref::Mutability, | ||
10 | FieldId, | 10 | FieldId, |
11 | }; | 11 | }; |
12 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
13 | use test_utils::mark; | 13 | use test_utils::mark; |
14 | 14 | ||
15 | use super::{BindingMode, Expectation, InferenceContext}; | 15 | use super::{BindingMode, Expectation, InferenceContext}; |
16 | use crate::{utils::variant_data, Substs, Ty, TypeCtor}; | 16 | use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty}; |
17 | 17 | ||
18 | impl<'a> InferenceContext<'a> { | 18 | impl<'a> InferenceContext<'a> { |
19 | fn infer_tuple_struct_pat( | 19 | fn infer_tuple_struct_pat( |
@@ -32,7 +32,7 @@ impl<'a> InferenceContext<'a> { | |||
32 | } | 32 | } |
33 | self.unify(&ty, expected); | 33 | self.unify(&ty, expected); |
34 | 34 | ||
35 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 35 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
36 | 36 | ||
37 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 37 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
38 | let (pre, post) = match ellipsis { | 38 | let (pre, post) = match ellipsis { |
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> { | |||
71 | 71 | ||
72 | self.unify(&ty, expected); | 72 | self.unify(&ty, expected); |
73 | 73 | ||
74 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 74 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
75 | 75 | ||
76 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 76 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
77 | for subpat in subpats { | 77 | for subpat in subpats { |
@@ -103,7 +103,7 @@ impl<'a> InferenceContext<'a> { | |||
103 | expected = inner; | 103 | expected = inner; |
104 |