aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md9
-rw-r--r--Cargo.lock119
-rw-r--r--crates/flycheck/Cargo.toml4
-rw-r--r--crates/flycheck/src/lib.rs5
-rw-r--r--crates/hir/src/code_model.rs165
-rw-r--r--crates/hir/src/source_analyzer.rs16
-rw-r--r--crates/hir_def/src/body/lower.rs17
-rw-r--r--crates/hir_def/src/builtin_type.rs132
-rw-r--r--crates/hir_def/src/expr.rs3
-rw-r--r--crates/hir_def/src/find_path.rs59
-rw-r--r--crates/hir_def/src/item_scope.rs22
-rw-r--r--crates/hir_def/src/lib.rs23
-rw-r--r--crates/hir_def/src/nameres.rs12
-rw-r--r--crates/hir_def/src/path/lower.rs13
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/autoderef.rs11
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs11
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs8
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
-rw-r--r--crates/hir_ty/src/display.rs206
-rw-r--r--crates/hir_ty/src/infer.rs46
-rw-r--r--crates/hir_ty/src/infer/coerce.rs87
-rw-r--r--crates/hir_ty/src/infer/expr.rs236
-rw-r--r--crates/hir_ty/src/infer/pat.rs34
-rw-r--r--crates/hir_ty/src/infer/unify.rs200
-rw-r--r--crates/hir_ty/src/lib.rs607
-rw-r--r--crates/hir_ty/src/lower.rs88
-rw-r--r--crates/hir_ty/src/method_resolution.rs167
-rw-r--r--crates/hir_ty/src/op.rs50
-rw-r--r--crates/hir_ty/src/primitive.rs160
-rw-r--r--crates/hir_ty/src/tests/simple.rs55
-rw-r--r--crates/hir_ty/src/traits.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk.rs24
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs332
-rw-r--r--crates/ide/src/hover.rs29
-rw-r--r--crates/ide/src/references.rs9
-rw-r--r--crates/ide/src/references/rename.rs9
-rw-r--r--crates/ide_assists/src/handlers/convert_comment_block.rs419
-rw-r--r--crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs (renamed from crates/ide_assists/src/handlers/convert_for_to_iter_for_each.rs)38
-rw-r--r--crates/ide_assists/src/handlers/replace_let_with_if_let.rs2
-rw-r--r--crates/ide_assists/src/lib.rs14
-rw-r--r--crates/ide_assists/src/tests.rs2
-rw-r--r--crates/ide_assists/src/tests/generated.rs46
-rw-r--r--crates/mbe/Cargo.toml3
-rw-r--r--crates/mbe/src/benchmark.rs2
-rw-r--r--crates/proc_macro_srv/Cargo.toml2
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs40
-rw-r--r--crates/proc_macro_srv/src/tests/utils.rs3
-rw-r--r--crates/project_model/Cargo.toml10
-rw-r--r--crates/project_model/src/build_data.rs23
-rw-r--r--crates/project_model/src/cargo_workspace.rs9
-rw-r--r--crates/rust-analyzer/Cargo.toml2
-rw-r--r--crates/rust-analyzer/src/bin/args.rs274
-rw-r--r--crates/rust-analyzer/src/bin/flags.rs251
-rw-r--r--crates/rust-analyzer/src/bin/main.rs85
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs3
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs2
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs3
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs9
-rw-r--r--crates/rust-analyzer/src/cli/ssr.rs4
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs2
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/main.rs18
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/support.rs12
-rw-r--r--crates/syntax/src/ast/edit.rs11
-rw-r--r--crates/syntax/src/ast/token_ext.rs3
-rw-r--r--docs/dev/README.md2
-rw-r--r--editors/code/README.md70
-rw-r--r--xtask/Cargo.toml5
-rw-r--r--xtask/src/codegen.rs14
-rw-r--r--xtask/src/codegen/gen_assists_docs.rs4
-rw-r--r--xtask/src/codegen/gen_diagnostic_docs.rs2
-rw-r--r--xtask/src/codegen/gen_feature_docs.rs2
-rw-r--r--xtask/src/codegen/gen_lint_completions.rs2
-rw-r--r--xtask/src/codegen/gen_parser_tests.rs2
-rw-r--r--xtask/src/codegen/gen_syntax.rs2
-rw-r--r--xtask/src/dist.rs8
-rw-r--r--xtask/src/flags.rs139
-rw-r--r--xtask/src/install.rs18
-rw-r--r--xtask/src/lib.rs131
-rw-r--r--xtask/src/main.rs273
-rw-r--r--xtask/src/metrics.rs10
-rw-r--r--xtask/src/pre_cache.rs6
-rw-r--r--xtask/src/pre_commit.rs38
-rw-r--r--xtask/src/release.rs18
-rw-r--r--xtask/src/tidy.rs (renamed from xtask/tests/tidy.rs)46
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
14Before submitting, please make sure that you're not running into one of these known issues: 14Before 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
23Otherwise please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3. 20Otherwise 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]]
15name = "adler" 15name = "adler"
16version = "1.0.1" 16version = "1.0.2"
17source = "registry+https://github.com/rust-lang/crates.io-index" 17source = "registry+https://github.com/rust-lang/crates.io-index"
18checksum = "bedc89c5c7b5550ffb9372eb5c5ffc7f9f705cc3f4a128bd4669b9745f555093" 18checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
19 19
20[[package]] 20[[package]]
21name = "always-assert" 21name = "always-assert"
@@ -112,6 +112,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
112checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" 112checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
113 113
114[[package]] 114[[package]]
115name = "camino"
116version = "1.0.1"
117source = "registry+https://github.com/rust-lang/crates.io-index"
118checksum = "9bb47ab72bdba43021afa16dc1ef4d80c980d366b17ed37ea8d2ebe2087075b9"
119dependencies = [
120 "serde",
121]
122
123[[package]]
115name = "cargo-platform" 124name = "cargo-platform"
116version = "0.1.1" 125version = "0.1.1"
117source = "registry+https://github.com/rust-lang/crates.io-index" 126source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -122,10 +131,11 @@ dependencies = [
122 131
123[[package]] 132[[package]]
124name = "cargo_metadata" 133name = "cargo_metadata"
125version = "0.12.3" 134version = "0.13.1"
126source = "registry+https://github.com/rust-lang/crates.io-index" 135source = "registry+https://github.com/rust-lang/crates.io-index"
127checksum = "7714a157da7991e23d90686b9524b9e12e0407a108647f52e9328f4b3d51ac7f" 136checksum = "081e3f0755c1f380c2d010481b6fa2e02973586d5f2b24eebb7a2a1d98b143d8"
128dependencies = [ 137dependencies = [
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]]
160name = "chalk-derive" 170name = "chalk-derive"
161version = "0.58.0" 171version = "0.59.0"
162source = "registry+https://github.com/rust-lang/crates.io-index" 172source = "registry+https://github.com/rust-lang/crates.io-index"
163checksum = "e625b7c688272783140509a0de8f7aa9000217cb0982c9b10606a12b0b747ba8" 173checksum = "4b9000fbcb67353dc8973ab9fd136277d321d85b79bd36b8756bb3ae0979a94a"
164dependencies = [ 174dependencies = [
165 "proc-macro2", 175 "proc-macro2",
166 "quote", 176 "quote",
@@ -170,9 +180,9 @@ dependencies = [
170 180
171[[package]] 181[[package]]
172name = "chalk-ir" 182name = "chalk-ir"
173version = "0.58.0" 183version = "0.59.0"
174source = "registry+https://github.com/rust-lang/crates.io-index" 184source = "registry+https://github.com/rust-lang/crates.io-index"
175checksum = "c220d870128959d7d56667060d556ffdebd490f32ee0fc9f4060a76c1193f206" 185checksum = "b23528d61b3557c676eccf508fa0771a38453b379f0b780154eaa7f70afe8dfc"
176dependencies = [ 186dependencies = [
177 "bitflags", 187 "bitflags",
178 "chalk-derive", 188 "chalk-derive",
@@ -181,9 +191,9 @@ dependencies = [
181 191
182[[package]] 192[[package]]
183name = "chalk-recursive" 193name = "chalk-recursive"
184version = "0.58.0" 194version = "0.59.0"
185source = "registry+https://github.com/rust-lang/crates.io-index" 195source = "registry+https://github.com/rust-lang/crates.io-index"
186checksum = "7d8cd81a15aa936215378e695a8907b9f1af8626a27a32ee22e97a50984960da" 196checksum = "a8bdd37afc666b771de8b4429fe014363d0e74aae5cc26f320f60a3eab34d744"
187dependencies = [ 197dependencies = [
188 "chalk-derive", 198 "chalk-derive",
189 "chalk-ir", 199 "chalk-ir",
@@ -194,14 +204,14 @@ dependencies = [
194 204
195[[package]] 205[[package]]
196name = "chalk-solve" 206name = "chalk-solve"
197version = "0.58.0" 207version = "0.59.0"
198source = "registry+https://github.com/rust-lang/crates.io-index" 208source = "registry+https://github.com/rust-lang/crates.io-index"
199checksum = "55571250dfe096a4c899be88c81418284c952ce1c8a06aa16afb5781b298e9c9" 209checksum = "4182c42ca319cb71c89898ebc3d2671d1fa7d928123b171b66f1797a2000b9c8"
200dependencies = [ 210dependencies = [
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]]
718name = "itertools" 728name = "itertools"
719version = "0.9.0"
720source = "registry+https://github.com/rust-lang/crates.io-index"
721checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
722dependencies = [
723 "either",
724]
725
726[[package]]
727name = "itertools"
728version = "0.10.0" 729version = "0.10.0"
729source = "registry+https://github.com/rust-lang/crates.io-index" 730source = "registry+https://github.com/rust-lang/crates.io-index"
730checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" 731checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
@@ -788,9 +789,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
788 789
789[[package]] 790[[package]]
790name = "libc" 791name = "libc"
791version = "0.2.86" 792version = "0.2.87"
792source = "registry+https://github.com/rust-lang/crates.io-index" 793source = "registry+https://github.com/rust-lang/crates.io-index"
793checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" 794checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213"
794 795
795[[package]] 796[[package]]
796name = "libloading" 797name = "libloading"
@@ -1015,9 +1016,9 @@ checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
1015 1016
1016[[package]] 1017[[package]]
1017name = "once_cell" 1018name = "once_cell"
1018version = "1.7.0" 1019version = "1.7.1"
1019source = "registry+https://github.com/rust-lang/crates.io-index" 1020source = "registry+https://github.com/rust-lang/crates.io-index"
1020checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a" 1021checksum = "ea78b9742c52ac729753c1590e9adc5248ea9bdaf974597efd46c74cfaa5fb54"
1021 1022
1022[[package]] 1023[[package]]
1023name = "oorandom" 1024name = "oorandom"
@@ -1125,16 +1126,10 @@ dependencies = [
1125] 1126]
1126 1127
1127[[package]] 1128[[package]]
1128name = "pico-args"
1129version = "0.4.0"
1130source = "registry+https://github.com/rust-lang/crates.io-index"
1131checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6"
1132
1133[[package]]
1134name = "pin-project-lite" 1129name = "pin-project-lite"
1135version = "0.2.4" 1130version = "0.2.5"
1136source = "registry+https://github.com/rust-lang/crates.io-index" 1131source = "registry+https://github.com/rust-lang/crates.io-index"
1137checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" 1132checksum = "0cf491442e4b033ed1c722cb9f0df5fcfcf4de682466c46469c36bc47dc5548a"
1138 1133
1139[[package]] 1134[[package]]
1140name = "proc-macro-hack" 1135name = "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]]
1493name = "serde_json" 1488name = "serde_json"
1494version = "1.0.62" 1489version = "1.0.64"
1495source = "registry+https://github.com/rust-lang/crates.io-index" 1490source = "registry+https://github.com/rust-lang/crates.io-index"
1496checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" 1491checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
1497dependencies = [ 1492dependencies = [
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"
1923checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3" 1918checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3"
1924 1919
1925[[package]] 1920[[package]]
1921name = "xflags"
1922version = "0.1.3"
1923source = "registry+https://github.com/rust-lang/crates.io-index"
1924checksum = "ddb4b07c0db813f8e2b5e1b2189ef56fcddb27a6f9ef71314dbf8cc50096a5db"
1925dependencies = [
1926 "xflags-macros",
1927]
1928
1929[[package]]
1930name = "xflags-macros"
1931version = "0.1.3"
1932source = "registry+https://github.com/rust-lang/crates.io-index"
1933checksum = "f8e168a99d6ce9d5dd0d0913f1bded279377843952dd8ff83f81b862a1dad0e1"
1934dependencies = [
1935 "proc-macro2",
1936]
1937
1938[[package]]
1926name = "xshell" 1939name = "xshell"
1927version = "0.1.8" 1940version = "0.1.9"
1928source = "registry+https://github.com/rust-lang/crates.io-index" 1941source = "registry+https://github.com/rust-lang/crates.io-index"
1929checksum = "ed373ede30cea03e8c0af22f48ee1ba80efbf06fec8b4746977e6ee703878de0" 1942checksum = "6f18102278453c8f70ea5c514ac78cb4c73a0ef72a8273d17094b52f9584c0c1"
1930dependencies = [ 1943dependencies = [
1931 "xshell-macros", 1944 "xshell-macros",
1932] 1945]
1933 1946
1934[[package]] 1947[[package]]
1935name = "xshell-macros" 1948name = "xshell-macros"
1936version = "0.1.8" 1949version = "0.1.9"
1937source = "registry+https://github.com/rust-lang/crates.io-index" 1950source = "registry+https://github.com/rust-lang/crates.io-index"
1938checksum = "7f6af9f8119104697b0105989a73c578ce33f922d9d6f3dae0e8ae3d538db321" 1951checksum = "6093c460064572007f885facc70bb0ca5e40a83ea7ff8b16c1abbee56fd2e767"
1939 1952
1940[[package]] 1953[[package]]
1941name = "xtask" 1954name = "xtask"
@@ -1943,11 +1956,11 @@ version = "0.1.0"
1943dependencies = [ 1956dependencies = [
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]
13crossbeam-channel = "0.5.0" 13crossbeam-channel = "0.5.0"
14log = "0.4.8" 14log = "0.4.8"
15cargo_metadata = "0.12.2" 15cargo_metadata = "0.13"
16serde_json = "1.0.48" 16serde_json = "1.0.48"
17jod-thread = "0.1.1" 17jod-thread = "0.1.1"
18 18
19toolchain = { path = "../toolchain", version = "0.0.0" } 19toolchain = { path = "../toolchain", version = "0.0.0" }
20stdx = { path = "../stdx", version = "0.0.0" } 20stdx = { 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};
38use rustc_hash::FxHashSet; 38use rustc_hash::FxHashSet;
39use stdx::{format_to, impl_from}; 39use stdx::{format_to, impl_from};
@@ -836,7 +836,7 @@ pub enum Access {
836impl From<Mutability> for Access { 836impl 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)]
2011pub struct Callable { 1978pub 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::{
20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; 20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
21use hir_ty::{ 21use 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};
25use syntax::{ 25use 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;
24use crate::{ 24use 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 @@
6use std::fmt; 6use std::fmt;
7 7
8use hir_expand::name::{name, AsName, Name}; 8use 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)]
11pub enum Signedness { 11pub 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,
17pub 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)]
27pub enum FloatBitness {
28 X32,
29 X64,
30} 18}
31 19
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 20/// Different unsigned int types.
33pub struct BuiltinInt { 21#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
34 pub signedness: Signedness, 22pub 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)]
39pub struct BuiltinFloat { 32pub 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]
115impl BuiltinInt { 111impl 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]
128impl 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]
154impl BuiltinFloat { 145impl 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};
17use syntax::ast::RangeOp; 17use syntax::ast::RangeOp;
18 18
19use crate::{ 19use 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
3use std::iter;
4
3use hir_expand::name::{known, AsName, Name}; 5use hir_expand::name::{known, AsName, Name};
4use rustc_hash::FxHashSet; 6use rustc_hash::FxHashSet;
5use test_utils::mark; 7use 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;
12use test_utils::mark; 12use test_utils::mark;
13 13
14use crate::{ 14use 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
536impl 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
532impl AttrDefId { 555impl 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"
17log = "0.4.8" 17log = "0.4.8"
18rustc-hash = "1.1.0" 18rustc-hash = "1.1.0"
19scoped-tls = "1" 19scoped-tls = "1"
20chalk-solve = { version = "0.58", default-features = false } 20chalk-solve = { version = "0.59", default-features = false }
21chalk-ir = "0.58" 21chalk-ir = "0.59"
22chalk-recursive = "0.58" 22chalk-recursive = "0.59"
23la-arena = { version = "0.2.0", path = "../../lib/arena" } 23la-arena = { version = "0.2.0", path = "../../lib/arena" }
24 24
25stdx = { path = "../stdx", version = "0.0.0" } 25stdx = { 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
23pub(crate) use hir_def::{ 23pub(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::{
227use la_arena::Idx; 227use la_arena::Idx;
228use smallvec::{smallvec, SmallVec}; 228use smallvec::{smallvec, SmallVec};
229 229
230use crate::{db::HirDatabase, ApplicationTy, InferenceResult, Ty, TypeCtor}; 230use 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};
12use hir_expand::diagnostics::DiagnosticSink; 12use hir_expand::diagnostics::DiagnosticSink;
13 13
14use crate::{ 14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty};
15 db::HirDatabase, diagnostics::MissingUnsafe, ApplicationTy, InferenceResult, Ty, TypeCtor,
16};
17 15
18pub(super) struct UnsafeValidator<'a, 'b: 'a> { 16pub(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 @@
3use std::{borrow::Cow, fmt}; 3use std::{borrow::Cow, fmt};
4 4
5use crate::{ 5use 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};
9use arrayvec::ArrayVec; 10use arrayvec::ArrayVec;
11use chalk_ir::Mutability;
10use hir_def::{ 12use 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
237impl HirDisplay for ApplicationTy { 239impl 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
263impl 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(&parameters.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(&parameters.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 &parameters.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(&parameters);
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
509impl 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
533impl 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
594impl HirDisplay for FnSig { 590impl 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;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use chalk_ir::Mutability;
21use hir_def::{ 22use 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;
36use syntax::SmolStr; 37use syntax::SmolStr;
37 38
38use super::{ 39use 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};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy,
45}; 45};
46 46
47pub(crate) use unify::unify; 47pub(crate) use unify::unify;
48 48
49macro_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
58mod unify; 49mod unify;
59mod path; 50mod path;
60mod expr; 51mod 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)]
667pub enum InferTy { 658pub 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
674impl InferTy { 662impl 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
7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; 7use chalk_ir::{Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget;
8use test_utils::mark; 9use test_utils::mark;
9 10
10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; 11use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty};
11 12
12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; 13use super::{InEnvironment, InferenceContext};
13 14
14impl<'a> InferenceContext<'a> { 15impl<'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 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{Mutability, TyVariableKind};
6use hir_def::{ 7use 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;
15use test_utils::mark; 15use test_utils::mark;
16 16
17use crate::{ 17use 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
25use super::{ 28use 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(&parameters)
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(&parameters)
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 @@
3use std::iter::repeat; 3use std::iter::repeat;
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use chalk_ir::Mutability;
6use hir_def::{ 7use 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};
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13use test_utils::mark; 13use test_utils::mark;
14 14
15use super::{BindingMode, Expectation, InferenceContext}; 15use super::{BindingMode, Expectation, InferenceContext};
16use crate::{utils::variant_data, Substs, Ty, TypeCtor}; 16use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty};
17 17
18impl<'a> InferenceContext<'a> { 18impl<'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