aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes4
-rw-r--r--Cargo.lock194
-rw-r--r--crates/ra_assists/src/handlers/change_return_type_to_result.rs2
-rw-r--r--crates/ra_assists/src/handlers/extract_variable.rs103
-rw-r--r--crates/ra_assists/src/handlers/fix_visibility.rs90
-rw-r--r--crates/ra_hir/src/db.rs2
-rw-r--r--crates/ra_hir_def/src/item_scope.rs29
-rw-r--r--crates/ra_hir_def/src/nameres.rs2
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs72
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs130
-rw-r--r--crates/ra_hir_def/src/visibility.rs41
-rw-r--r--crates/ra_hir_expand/src/db.rs19
-rw-r--r--crates/ra_hir_expand/src/lib.rs6
-rw-r--r--crates/ra_hir_ty/Cargo.toml7
-rw-r--r--crates/ra_hir_ty/src/display.rs22
-rw-r--r--crates/ra_hir_ty/src/tests.rs4
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs620
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs1150
-rw-r--r--crates/ra_hir_ty/src/tests/patterns.rs1102
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs1172
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs3413
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs3296
-rw-r--r--crates/ra_ide/src/inlay_hints.rs2
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs59
-rw-r--r--crates/ra_ide/test_data/highlight_doctest.html24
-rw-r--r--crates/ra_ide/test_data/highlight_injection.html2
-rw-r--r--crates/ra_ide/test_data/highlight_strings.html30
-rw-r--r--crates/ra_ide/test_data/highlight_unsafe.html8
-rw-r--r--crates/ra_ide/test_data/highlighting.html46
-rw-r--r--crates/ra_ide/test_data/rainbow_highlighting.html12
-rw-r--r--crates/ra_ide_db/Cargo.toml3
-rw-r--r--crates/ra_ide_db/src/change.rs4
-rw-r--r--crates/ra_ide_db/src/line_index.rs8
-rw-r--r--crates/ra_prof/Cargo.toml10
-rw-r--r--crates/ra_prof/src/lib.rs10
-rw-r--r--crates/ra_prof/src/memory_usage.rs21
-rw-r--r--crates/ra_syntax/Cargo.toml2
-rw-r--r--crates/ra_syntax/src/lib.rs4
-rw-r--r--crates/ra_syntax/src/syntax_node.rs4
-rw-r--r--crates/rust-analyzer/Cargo.toml7
-rw-r--r--crates/rust-analyzer/src/bin/args.rs4
-rw-r--r--crates/rust-analyzer/src/bin/main.rs4
-rw-r--r--crates/rust-analyzer/src/global_state.rs13
-rw-r--r--crates/rust-analyzer/src/handlers.rs22
-rw-r--r--crates/rust-analyzer/src/main_loop.rs67
-rw-r--r--crates/rust-analyzer/src/to_proto.rs7
-rw-r--r--crates/stdx/src/lib.rs30
-rw-r--r--docs/dev/README.md8
-rw-r--r--docs/dev/architecture.md3
-rw-r--r--docs/dev/lsp-extensions.md8
-rw-r--r--docs/user/manual.adoc4
-rw-r--r--editors/code/package.json12
-rw-r--r--editors/code/src/client.ts1
-rw-r--r--editors/code/src/snippets.ts4
-rw-r--r--xtask/src/dist.rs2
-rw-r--r--xtask/src/install.rs2
-rw-r--r--xtask/src/main.rs12
-rw-r--r--xtask/tests/tidy.rs1
58 files changed, 6104 insertions, 5836 deletions
diff --git a/.gitattributes b/.gitattributes
index e749e1dc9..4cd50e481 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,6 @@
1* text=auto eol=lf 1* text=auto eol=lf
2crates/ra_syntax/test_data/** -text eof=LF 2crates/ra_syntax/test_data/** -text eof=LF
3# Older git versions try to fix line endings on images, this prevents it.
4*.png binary
5*.jpg binary
6*.ico binary
diff --git a/Cargo.lock b/Cargo.lock
index e0ba7b688..029698808 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -126,9 +126,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
126 126
127[[package]] 127[[package]]
128name = "chalk-derive" 128name = "chalk-derive"
129version = "0.17.0" 129version = "0.18.0"
130source = "registry+https://github.com/rust-lang/crates.io-index" 130source = "registry+https://github.com/rust-lang/crates.io-index"
131checksum = "9396f12a23b1a40d5019aa81bc0cbd7ccd2c9736d6bc4afc95868533c2346dcb" 131checksum = "eea3a22f0c30b2504ac4ab58934dac0d00b92a4d7788df32795cabca24c3f929"
132dependencies = [ 132dependencies = [
133 "proc-macro2", 133 "proc-macro2",
134 "quote", 134 "quote",
@@ -138,9 +138,9 @@ dependencies = [
138 138
139[[package]] 139[[package]]
140name = "chalk-ir" 140name = "chalk-ir"
141version = "0.17.0" 141version = "0.18.0"
142source = "registry+https://github.com/rust-lang/crates.io-index" 142source = "registry+https://github.com/rust-lang/crates.io-index"
143checksum = "87e9c67d500717d65ede27affb7ae40efe240d86fbefff1006fe0ffb62d4caf9" 143checksum = "fb617b643e145e3b151502799e91a9625dd5daf1cf05dc2cb821bc75ae0c9cbd"
144dependencies = [ 144dependencies = [
145 "chalk-derive", 145 "chalk-derive",
146 "lazy_static", 146 "lazy_static",
@@ -148,9 +148,9 @@ dependencies = [
148 148
149[[package]] 149[[package]]
150name = "chalk-recursive" 150name = "chalk-recursive"
151version = "0.17.0" 151version = "0.18.0"
152source = "registry+https://github.com/rust-lang/crates.io-index" 152source = "registry+https://github.com/rust-lang/crates.io-index"
153checksum = "a8fd2ac0fc06c857b95614d229bbe8ea317d1d94a7e8b9442a3f05c9a2c2d5f4" 153checksum = "d280565c8eefbf9b2bc615df49c7dfd971faad37774bf65734e626fd23864bd6"
154dependencies = [ 154dependencies = [
155 "chalk-derive", 155 "chalk-derive",
156 "chalk-ir", 156 "chalk-ir",
@@ -161,9 +161,9 @@ dependencies = [
161 161
162[[package]] 162[[package]]
163name = "chalk-solve" 163name = "chalk-solve"
164version = "0.17.0" 164version = "0.18.0"
165source = "registry+https://github.com/rust-lang/crates.io-index" 165source = "registry+https://github.com/rust-lang/crates.io-index"
166checksum = "2a79166f2405c1e51eadcc1344f5ee833c7b391532dd78f64a0731a9a123cc58" 166checksum = "be906fbca3f3077dce0e76d9864771d0f450c946af0d86b569fb9504148a065a"
167dependencies = [ 167dependencies = [
168 "chalk-derive", 168 "chalk-derive",
169 "chalk-ir", 169 "chalk-ir",
@@ -206,20 +206,6 @@ dependencies = [
206] 206]
207 207
208[[package]] 208[[package]]
209name = "console"
210version = "0.11.3"
211source = "registry+https://github.com/rust-lang/crates.io-index"
212checksum = "8c0994e656bba7b922d8dd1245db90672ffb701e684e45be58f20719d69abc5a"
213dependencies = [
214 "encode_unicode",
215 "lazy_static",
216 "libc",
217 "terminal_size",
218 "termios",
219 "winapi 0.3.9",
220]
221
222[[package]]
223name = "crc32fast" 209name = "crc32fast"
224version = "1.2.0" 210version = "1.2.0"
225source = "registry+https://github.com/rust-lang/crates.io-index" 211source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -230,12 +216,12 @@ dependencies = [
230 216
231[[package]] 217[[package]]
232name = "crossbeam-channel" 218name = "crossbeam-channel"
233version = "0.4.2" 219version = "0.4.3"
234source = "registry+https://github.com/rust-lang/crates.io-index" 220source = "registry+https://github.com/rust-lang/crates.io-index"
235checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" 221checksum = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6"
236dependencies = [ 222dependencies = [
223 "cfg-if",
237 "crossbeam-utils", 224 "crossbeam-utils",
238 "maybe-uninit",
239] 225]
240 226
241[[package]] 227[[package]]
@@ -299,12 +285,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
299checksum = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f" 285checksum = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f"
300 286
301[[package]] 287[[package]]
302name = "dtoa"
303version = "0.4.6"
304source = "registry+https://github.com/rust-lang/crates.io-index"
305checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
306
307[[package]]
308name = "either" 288name = "either"
309version = "1.5.3" 289version = "1.5.3"
310source = "registry+https://github.com/rust-lang/crates.io-index" 290source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -320,12 +300,6 @@ dependencies = [
320] 300]
321 301
322[[package]] 302[[package]]
323name = "encode_unicode"
324version = "0.3.6"
325source = "registry+https://github.com/rust-lang/crates.io-index"
326checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
327
328[[package]]
329name = "env_logger" 303name = "env_logger"
330version = "0.7.1" 304version = "0.7.1"
331source = "registry+https://github.com/rust-lang/crates.io-index" 305source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -386,12 +360,6 @@ dependencies = [
386] 360]
387 361
388[[package]] 362[[package]]
389name = "fs_extra"
390version = "1.1.0"
391source = "registry+https://github.com/rust-lang/crates.io-index"
392checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
393
394[[package]]
395name = "fsevent" 363name = "fsevent"
396version = "2.0.2" 364version = "2.0.2"
397source = "registry+https://github.com/rust-lang/crates.io-index" 365source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -538,20 +506,6 @@ dependencies = [
538] 506]
539 507
540[[package]] 508[[package]]
541name = "insta"
542version = "0.16.1"
543source = "registry+https://github.com/rust-lang/crates.io-index"
544checksum = "617e921abc813f96a3b00958c079e7bf1e2db998f8a04f1546dd967373a418ee"
545dependencies = [
546 "console",
547 "difference",
548 "lazy_static",
549 "serde",
550 "serde_json",
551 "serde_yaml",
552]
553
554[[package]]
555name = "instant" 509name = "instant"
556version = "0.1.6" 510version = "0.1.6"
557source = "registry+https://github.com/rust-lang/crates.io-index" 511source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -582,38 +536,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
582checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" 536checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
583 537
584[[package]] 538[[package]]
585name = "jemalloc-ctl"
586version = "0.3.3"
587source = "registry+https://github.com/rust-lang/crates.io-index"
588checksum = "c502a5ff9dd2924f1ed32ba96e3b65735d837b4bfd978d3161b1702e66aca4b7"
589dependencies = [
590 "jemalloc-sys",
591 "libc",
592 "paste",
593]
594
595[[package]]
596name = "jemalloc-sys"
597version = "0.3.2"
598source = "registry+https://github.com/rust-lang/crates.io-index"
599checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45"
600dependencies = [
601 "cc",
602 "fs_extra",
603 "libc",
604]
605
606[[package]]
607name = "jemallocator"
608version = "0.3.2"
609source = "registry+https://github.com/rust-lang/crates.io-index"
610checksum = "43ae63fcfc45e99ab3d1b29a46782ad679e98436c3169d15a167a1108a724b69"
611dependencies = [
612 "jemalloc-sys",
613 "libc",
614]
615
616[[package]]
617name = "jod-thread" 539name = "jod-thread"
618version = "0.1.2" 540version = "0.1.2"
619source = "registry+https://github.com/rust-lang/crates.io-index" 541source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -666,12 +588,6 @@ dependencies = [
666] 588]
667 589
668[[package]] 590[[package]]
669name = "linked-hash-map"
670version = "0.5.3"
671source = "registry+https://github.com/rust-lang/crates.io-index"
672checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
673
674[[package]]
675name = "lock_api" 591name = "lock_api"
676version = "0.4.1" 592version = "0.4.1"
677source = "registry+https://github.com/rust-lang/crates.io-index" 593source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -703,9 +619,9 @@ dependencies = [
703 619
704[[package]] 620[[package]]
705name = "lsp-types" 621name = "lsp-types"
706version = "0.77.0" 622version = "0.78.0"
707source = "registry+https://github.com/rust-lang/crates.io-index" 623source = "registry+https://github.com/rust-lang/crates.io-index"
708checksum = "897c6c8930fbf12b67deffc83729287bb379dd5e5a4bd0ae2d81eff8d6503db6" 624checksum = "d2e6cf68e3492cfa2035f0382c1da1b6ab045db0320feca505b86b4f13d66c27"
709dependencies = [ 625dependencies = [
710 "base64", 626 "base64",
711 "bitflags", 627 "bitflags",
@@ -921,25 +837,6 @@ dependencies = [
921] 837]
922 838
923[[package]] 839[[package]]
924name = "paste"
925version = "0.1.18"
926source = "registry+https://github.com/rust-lang/crates.io-index"
927checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
928dependencies = [
929 "paste-impl",
930 "proc-macro-hack",
931]
932
933[[package]]
934name = "paste-impl"
935version = "0.1.18"
936source = "registry+https://github.com/rust-lang/crates.io-index"
937checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
938dependencies = [
939 "proc-macro-hack",
940]
941
942[[package]]
943name = "paths" 840name = "paths"
944version = "0.1.0" 841version = "0.1.0"
945 842
@@ -978,12 +875,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
978checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" 875checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
979 876
980[[package]] 877[[package]]
981name = "proc-macro-hack"
982version = "0.5.16"
983source = "registry+https://github.com/rust-lang/crates.io-index"
984checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
985
986[[package]]
987name = "proc-macro2" 878name = "proc-macro2"
988version = "1.0.19" 879version = "1.0.19"
989source = "registry+https://github.com/rust-lang/crates.io-index" 880source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1128,7 +1019,6 @@ dependencies = [
1128 "chalk-solve", 1019 "chalk-solve",
1129 "ena", 1020 "ena",
1130 "expect", 1021 "expect",
1131 "insta",
1132 "itertools", 1022 "itertools",
1133 "log", 1023 "log",
1134 "ra_arena", 1024 "ra_arena",
@@ -1187,7 +1077,7 @@ dependencies = [
1187 "ra_text_edit", 1077 "ra_text_edit",
1188 "rayon", 1078 "rayon",
1189 "rustc-hash", 1079 "rustc-hash",
1190 "superslice", 1080 "stdx",
1191 "test_utils", 1081 "test_utils",
1192] 1082]
1193 1083
@@ -1245,9 +1135,8 @@ name = "ra_prof"
1245version = "0.1.0" 1135version = "0.1.0"
1246dependencies = [ 1136dependencies = [
1247 "backtrace", 1137 "backtrace",
1248 "jemalloc-ctl", 1138 "cfg-if",
1249 "jemallocator", 1139 "libc",
1250 "mimalloc",
1251 "once_cell", 1140 "once_cell",
1252 "ra_arena", 1141 "ra_arena",
1253] 1142]
@@ -1472,6 +1361,7 @@ dependencies = [
1472 "log", 1361 "log",
1473 "lsp-server", 1362 "lsp-server",
1474 "lsp-types", 1363 "lsp-types",
1364 "mimalloc",
1475 "parking_lot", 1365 "parking_lot",
1476 "pico-args", 1366 "pico-args",
1477 "ra_cfg", 1367 "ra_cfg",
@@ -1506,9 +1396,9 @@ dependencies = [
1506 1396
1507[[package]] 1397[[package]]
1508name = "rustc-ap-rustc_lexer" 1398name = "rustc-ap-rustc_lexer"
1509version = "666.0.0" 1399version = "669.0.0"
1510source = "registry+https://github.com/rust-lang/crates.io-index" 1400source = "registry+https://github.com/rust-lang/crates.io-index"
1511checksum = "4e00c526f9f8430ea4cd2178d25b02bfc7debe6677350c57292f92f50e65d2fe" 1401checksum = "456af5f09c006cf6c22c1a433ee0232c4bb74bdc6c647a010166a47c94ed2a63"
1512dependencies = [ 1402dependencies = [
1513 "unicode-xid", 1403 "unicode-xid",
1514] 1404]
@@ -1660,18 +1550,6 @@ dependencies = [
1660] 1550]
1661 1551
1662[[package]] 1552[[package]]
1663name = "serde_yaml"
1664version = "0.8.13"
1665source = "registry+https://github.com/rust-lang/crates.io-index"
1666checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5"
1667dependencies = [
1668 "dtoa",
1669 "linked-hash-map",
1670 "serde",
1671 "yaml-rust",
1672]
1673
1674[[package]]
1675name = "sharded-slab" 1553name = "sharded-slab"
1676version = "0.0.9" 1554version = "0.0.9"
1677source = "registry+https://github.com/rust-lang/crates.io-index" 1555source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1706,12 +1584,6 @@ name = "stdx"
1706version = "0.1.0" 1584version = "0.1.0"
1707 1585
1708[[package]] 1586[[package]]
1709name = "superslice"
1710version = "1.0.0"
1711source = "registry+https://github.com/rust-lang/crates.io-index"
1712checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
1713
1714[[package]]
1715name = "syn" 1587name = "syn"
1716version = "1.0.35" 1588version = "1.0.35"
1717source = "registry+https://github.com/rust-lang/crates.io-index" 1589source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1758,25 +1630,6 @@ dependencies = [
1758] 1630]
1759 1631
1760[[package]] 1632[[package]]
1761name = "terminal_size"
1762version = "0.1.13"
1763source = "registry+https://github.com/rust-lang/crates.io-index"
1764checksum = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13"
1765dependencies = [
1766 "libc",
1767 "winapi 0.3.9",
1768]
1769
1770[[package]]
1771name = "termios"
1772version = "0.3.2"
1773source = "registry+https://github.com/rust-lang/crates.io-index"
1774checksum = "6f0fcee7b24a25675de40d5bb4de6e41b0df07bc9856295e7e2b3a3600c400c2"
1775dependencies = [
1776 "libc",
1777]
1778
1779[[package]]
1780name = "test_utils" 1633name = "test_utils"
1781version = "0.1.0" 1634version = "0.1.0"
1782dependencies = [ 1635dependencies = [
@@ -2065,12 +1918,3 @@ dependencies = [
2065 "quote", 1918 "quote",
2066 "walkdir", 1919 "walkdir",
2067] 1920]
2068
2069[[package]]
2070name = "yaml-rust"
2071version = "0.4.4"
2072source = "registry+https://github.com/rust-lang/crates.io-index"
2073checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d"
2074dependencies = [
2075 "linked-hash-map",
2076]
diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
index 24e5f6963..def00f7d8 100644
--- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs
+++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
@@ -36,7 +36,7 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex
36 36
37 acc.add( 37 acc.add(
38 AssistId("change_return_type_to_result", AssistKind::RefactorRewrite), 38 AssistId("change_return_type_to_result", AssistKind::RefactorRewrite),
39 "Change return type to Result", 39 "Wrap return type in Result",
40 type_ref.syntax().text_range(), 40 type_ref.syntax().text_range(),
41 |builder| { 41 |builder| {
42 let mut tail_return_expr_collector = TailReturnCollector::new(); 42 let mut tail_return_expr_collector = TailReturnCollector::new();
diff --git a/crates/ra_assists/src/handlers/extract_variable.rs b/crates/ra_assists/src/handlers/extract_variable.rs
index 481baf1a4..098adf078 100644
--- a/crates/ra_assists/src/handlers/extract_variable.rs
+++ b/crates/ra_assists/src/handlers/extract_variable.rs
@@ -2,7 +2,6 @@ use ra_syntax::{
2 ast::{self, AstNode}, 2 ast::{self, AstNode},
3 SyntaxKind::{ 3 SyntaxKind::{
4 BLOCK_EXPR, BREAK_EXPR, COMMENT, LAMBDA_EXPR, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR, 4 BLOCK_EXPR, BREAK_EXPR, COMMENT, LAMBDA_EXPR, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR,
5 WHITESPACE,
6 }, 5 },
7 SyntaxNode, 6 SyntaxNode,
8}; 7};
@@ -36,22 +35,20 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
36 mark::hit!(extract_var_in_comment_is_not_applicable); 35 mark::hit!(extract_var_in_comment_is_not_applicable);
37 return None; 36 return None;
38 } 37 }
39 let expr = node.ancestors().find_map(valid_target_expr)?; 38 let to_extract = node.ancestors().find_map(valid_target_expr)?;
40 let (anchor_stmt, wrap_in_block) = anchor_stmt(expr.clone())?; 39 let anchor = Anchor::from(&to_extract)?;
41 let indent = anchor_stmt.prev_sibling_or_token()?.as_token()?.clone(); 40 let indent = anchor.syntax().prev_sibling_or_token()?.as_token()?.clone();
42 if indent.kind() != WHITESPACE { 41 let target = to_extract.syntax().text_range();
43 return None;
44 }
45 let target = expr.syntax().text_range();
46 acc.add( 42 acc.add(
47 AssistId("extract_variable", AssistKind::RefactorExtract), 43 AssistId("extract_variable", AssistKind::RefactorExtract),
48 "Extract into variable", 44 "Extract into variable",
49 target, 45 target,
50 move |edit| { 46 move |edit| {
51 let field_shorthand = match expr.syntax().parent().and_then(ast::RecordField::cast) { 47 let field_shorthand =
52 Some(field) => field.name_ref(), 48 match to_extract.syntax().parent().and_then(ast::RecordField::cast) {
53 None => None, 49 Some(field) => field.name_ref(),
54 }; 50 None => None,
51 };
55 52
56 let mut buf = String::new(); 53 let mut buf = String::new();
57 54
@@ -60,26 +57,20 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
60 None => "var_name".to_string(), 57 None => "var_name".to_string(),
61 }; 58 };
62 let expr_range = match &field_shorthand { 59 let expr_range = match &field_shorthand {
63 Some(it) => it.syntax().text_range().cover(expr.syntax().text_range()), 60 Some(it) => it.syntax().text_range().cover(to_extract.syntax().text_range()),
64 None => expr.syntax().text_range(), 61 None => to_extract.syntax().text_range(),
65 }; 62 };
66 63
67 if wrap_in_block { 64 if let Anchor::WrapInBlock(_) = anchor {
68 format_to!(buf, "{{ let {} = ", var_name); 65 format_to!(buf, "{{ let {} = ", var_name);
69 } else { 66 } else {
70 format_to!(buf, "let {} = ", var_name); 67 format_to!(buf, "let {} = ", var_name);
71 }; 68 };
72 format_to!(buf, "{}", expr.syntax()); 69 format_to!(buf, "{}", to_extract.syntax());
73 70
74 let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone()); 71 if let Anchor::Replace(stmt) = anchor {
75 let is_full_stmt = if let Some(expr_stmt) = &full_stmt {
76 Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone())
77 } else {
78 false
79 };
80 if is_full_stmt {
81 mark::hit!(test_extract_var_expr_stmt); 72 mark::hit!(test_extract_var_expr_stmt);
82 if full_stmt.unwrap().semicolon_token().is_none() { 73 if stmt.semicolon_token().is_none() {
83 buf.push_str(";"); 74 buf.push_str(";");
84 } 75 }
85 match ctx.config.snippet_cap { 76 match ctx.config.snippet_cap {
@@ -107,7 +98,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
107 } 98 }
108 99
109 edit.replace(expr_range, var_name.clone()); 100 edit.replace(expr_range, var_name.clone());
110 let offset = anchor_stmt.text_range().start(); 101 let offset = anchor.syntax().text_range().start();
111 match ctx.config.snippet_cap { 102 match ctx.config.snippet_cap {
112 Some(cap) => { 103 Some(cap) => {
113 let snip = 104 let snip =
@@ -117,8 +108,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
117 None => edit.insert(offset, buf), 108 None => edit.insert(offset, buf),
118 } 109 }
119 110
120 if wrap_in_block { 111 if let Anchor::WrapInBlock(_) = anchor {
121 edit.insert(anchor_stmt.text_range().end(), " }"); 112 edit.insert(anchor.syntax().text_range().end(), " }");
122 } 113 }
123 }, 114 },
124 ) 115 )
@@ -138,32 +129,48 @@ fn valid_target_expr(node: SyntaxNode) -> Option<ast::Expr> {
138 } 129 }
139} 130}
140 131
141/// Returns the syntax node which will follow the freshly extractd var 132enum Anchor {
142/// and a boolean indicating whether we have to wrap it within a { } block 133 Before(SyntaxNode),
143/// to produce correct code. 134 Replace(ast::ExprStmt),
144/// It can be a statement, the last in a block expression or a wanna be block 135 WrapInBlock(SyntaxNode),
145/// expression like a lambda or match arm. 136}
146fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { 137
147 expr.syntax().ancestors().find_map(|node| { 138impl Anchor {
148 if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) { 139 fn from(to_extract: &ast::Expr) -> Option<Anchor> {
149 if expr.syntax() == &node { 140 to_extract.syntax().ancestors().find_map(|node| {
150 mark::hit!(test_extract_var_last_expr); 141 if let Some(expr) =
151 return Some((node, false)); 142 node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr())
143 {
144 if expr.syntax() == &node {
145 mark::hit!(test_extract_var_last_expr);
146 return Some(Anchor::Before(node));
147 }
152 } 148 }
153 }
154 149
155 if let Some(parent) = node.parent() { 150 if let Some(parent) = node.parent() {
156 if parent.kind() == MATCH_ARM || parent.kind() == LAMBDA_EXPR { 151 if parent.kind() == MATCH_ARM || parent.kind() == LAMBDA_EXPR {
157 return Some((node, true)); 152 return Some(Anchor::WrapInBlock(node));
153 }
158 } 154 }
159 }
160 155
161 if ast::Stmt::cast(node.clone()).is_some() { 156 if let Some(stmt) = ast::Stmt::cast(node.clone()) {
162 return Some((node, false)); 157 if let ast::Stmt::ExprStmt(stmt) = stmt {
163 } 158 if stmt.expr().as_ref() == Some(to_extract) {
159 return Some(Anchor::Replace(stmt));
160 }
161 }
162 return Some(Anchor::Before(node));
163 }
164 None
165 })
166 }
164 167
165 None 168 fn syntax(&self) -> &SyntaxNode {
166 }) 169 match self {
170 Anchor::Before(it) | Anchor::WrapInBlock(it) => it,
171 Anchor::Replace(stmt) => stmt.syntax(),
172 }
173 }
167} 174}
168 175
169#[cfg(test)] 176#[cfg(test)]
diff --git a/crates/ra_assists/src/handlers/fix_visibility.rs b/crates/ra_assists/src/handlers/fix_visibility.rs
index e212557c8..1d3ed3c6a 100644
--- a/crates/ra_assists/src/handlers/fix_visibility.rs
+++ b/crates/ra_assists/src/handlers/fix_visibility.rs
@@ -3,6 +3,7 @@ use ra_db::FileId;
3use ra_syntax::{ast, AstNode, TextRange, TextSize}; 3use ra_syntax::{ast, AstNode, TextRange, TextSize};
4 4
5use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists}; 5use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists};
6use ast::VisibilityOwner;
6 7
7// FIXME: this really should be a fix for diagnostic, rather than an assist. 8// FIXME: this really should be a fix for diagnostic, rather than an assist.
8 9
@@ -48,7 +49,8 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> O
48 return None; 49 return None;
49 }; 50 };
50 51
51 let (offset, target, target_file, target_name) = target_data_for_def(ctx.db(), def)?; 52 let (offset, current_visibility, target, target_file, target_name) =
53 target_data_for_def(ctx.db(), def)?;
52 54
53 let missing_visibility = 55 let missing_visibility =
54 if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" }; 56 if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
@@ -61,8 +63,20 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> O
61 acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| { 63 acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
62 builder.edit_file(target_file); 64 builder.edit_file(target_file);
63 match ctx.config.snippet_cap { 65 match ctx.config.snippet_cap {
64 Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)), 66 Some(cap) => match current_visibility {
65 None => builder.insert(offset, format!("{} ", missing_visibility)), 67 Some(current_visibility) => builder.replace_snippet(
68 cap,
69 current_visibility.syntax().text_range(),
70 format!("$0{}", missing_visibility),
71 ),
72 None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
73 },
74 None => match current_visibility {
75 Some(current_visibility) => {
76 builder.replace(current_visibility.syntax().text_range(), missing_visibility)
77 }
78 None => builder.insert(offset, format!("{} ", missing_visibility)),
79 },
66 } 80 }
67 }) 81 })
68} 82}
@@ -82,14 +96,14 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) ->
82 let target_module = parent.module(ctx.db()); 96 let target_module = parent.module(ctx.db());
83 97
84 let in_file_source = record_field_def.source(ctx.db()); 98 let in_file_source = record_field_def.source(ctx.db());
85 let (offset, target) = match in_file_source.value { 99 let (offset, current_visibility, target) = match in_file_source.value {
86 hir::FieldSource::Named(it) => { 100 hir::FieldSource::Named(it) => {
87 let s = it.syntax(); 101 let s = it.syntax();
88 (vis_offset(s), s.text_range()) 102 (vis_offset(s), it.visibility(), s.text_range())
89 } 103 }
90 hir::FieldSource::Pos(it) => { 104 hir::FieldSource::Pos(it) => {
91 let s = it.syntax(); 105 let s = it.syntax();
92 (vis_offset(s), s.text_range()) 106 (vis_offset(s), it.visibility(), s.text_range())
93 } 107 }
94 }; 108 };
95 109
@@ -104,8 +118,20 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) ->
104 acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| { 118 acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
105 builder.edit_file(target_file); 119 builder.edit_file(target_file);
106 match ctx.config.snippet_cap { 120 match ctx.config.snippet_cap {
107 Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)), 121 Some(cap) => match current_visibility {
108 None => builder.insert(offset, format!("{} ", missing_visibility)), 122 Some(current_visibility) => builder.replace_snippet(
123 cap,
124 dbg!(current_visibility.syntax()).text_range(),
125 format!("$0{}", missing_visibility),
126 ),
127 None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
128 },
129 None => match current_visibility {
130 Some(current_visibility) => {
131 builder.replace(current_visibility.syntax().text_range(), missing_visibility)
132 }
133 None => builder.insert(offset, format!("{} ", missing_visibility)),
134 },
109 } 135 }
110 }) 136 })
111} 137}
@@ -113,24 +139,30 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) ->
113fn target_data_for_def( 139fn target_data_for_def(
114 db: &dyn HirDatabase, 140 db: &dyn HirDatabase,
115 def: hir::ModuleDef, 141 def: hir::ModuleDef,
116) -> Option<(TextSize, TextRange, FileId, Option<hir::Name>)> { 142) -> Option<(TextSize, Option<ast::Visibility>, TextRange, FileId, Option<hir::Name>)> {
117 fn offset_target_and_file_id<S, Ast>( 143 fn offset_target_and_file_id<S, Ast>(
118 db: &dyn HirDatabase, 144 db: &dyn HirDatabase,
119 x: S, 145 x: S,
120 ) -> (TextSize, TextRange, FileId) 146 ) -> (TextSize, Option<ast::Visibility>, TextRange, FileId)
121 where 147 where
122 S: HasSource<Ast = Ast>, 148 S: HasSource<Ast = Ast>,
123 Ast: AstNode, 149 Ast: AstNode + ast::VisibilityOwner,
124 { 150 {
125 let source = x.source(db); 151 let source = x.source(db);
126 let in_file_syntax = source.syntax(); 152 let in_file_syntax = source.syntax();
127 let file_id = in_file_syntax.file_id; 153 let file_id = in_file_syntax.file_id;
128 let syntax = in_file_syntax.value; 154 let syntax = in_file_syntax.value;
129 (vis_offset(syntax), syntax.text_range(), file_id.original_file(db.upcast())) 155 let current_visibility = source.value.visibility();
156 (
157 vis_offset(syntax),
158 current_visibility,
159 syntax.text_range(),
160 file_id.original_file(db.upcast()),
161 )
130 } 162 }
131 163
132 let target_name; 164 let target_name;
133 let (offset, target, target_file) = match def { 165 let (offset, current_visibility, target, target_file) = match def {
134 hir::ModuleDef::Function(f) => { 166 hir::ModuleDef::Function(f) => {
135 target_name = Some(f.name(db)); 167 target_name = Some(f.name(db));
136 offset_target_and_file_id(db, f) 168 offset_target_and_file_id(db, f)
@@ -164,13 +196,13 @@ fn target_data_for_def(
164 let in_file_source = m.declaration_source(db)?; 196 let in_file_source = m.declaration_source(db)?;
165 let file_id = in_file_source.file_id.original_file(db.upcast()); 197 let file_id = in_file_source.file_id.original_file(db.upcast());
166 let syntax = in_file_source.value.syntax(); 198 let syntax = in_file_source.value.syntax();
167 (vis_offset(syntax), syntax.text_range(), file_id) 199 (vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id)
168 } 200 }
169 // Enum variants can't be private, we can't modify builtin types 201 // Enum variants can't be private, we can't modify builtin types
170 hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None, 202 hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None,
171 }; 203 };
172 204
173 Some((offset, target, target_file, target_name)) 205 Some((offset, current_visibility, target, target_file, target_name))
174} 206}
175 207
176#[cfg(test)] 208#[cfg(test)]
@@ -523,6 +555,34 @@ struct Bar;
523 } 555 }
524 556
525 #[test] 557 #[test]
558 fn replaces_pub_crate_with_pub() {
559 check_assist(
560 fix_visibility,
561 r"
562//- /main.rs crate:a deps:foo
563foo::Bar<|>
564//- /lib.rs crate:foo
565pub(crate) struct Bar;
566",
567 r"$0pub struct Bar;
568",
569 );
570 check_assist(
571 fix_visibility,
572 r"
573//- /main.rs crate:a deps:foo
574fn main() {
575 foo::Foo { <|>bar: () };
576}
577//- /lib.rs crate:foo
578pub struct Foo { pub(crate) bar: () }
579",
580 r"pub struct Foo { $0pub bar: () }
581",
582 );
583 }
584
585 #[test]
526 #[ignore] 586 #[ignore]
527 // FIXME handle reexports properly 587 // FIXME handle reexports properly
528 fn fix_visibility_of_reexport() { 588 fn fix_visibility_of_reexport() {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 1ad92a1f8..a2b9f3e35 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -11,7 +11,7 @@ pub use hir_def::db::{
11}; 11};
12pub use hir_expand::db::{ 12pub use hir_expand::db::{
13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery, 13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery,
14 MacroArgQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery, 14 MacroArgTextQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery,
15}; 15};
16pub use hir_ty::db::{ 16pub use hir_ty::db::{
17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery, 17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery,
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
index beeb98559..8fee4b15e 100644
--- a/crates/ra_hir_def/src/item_scope.rs
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -36,6 +36,8 @@ pub struct ItemScope {
36 36
37 defs: Vec<ModuleDefId>, 37 defs: Vec<ModuleDefId>,
38 impls: Vec<ImplId>, 38 impls: Vec<ImplId>,
39 /// Traits imported via `use Trait as _;`.
40 unnamed_trait_imports: FxHashMap<TraitId, Visibility>,
39 /// Macros visible in current module in legacy textual scope 41 /// Macros visible in current module in legacy textual scope
40 /// 42 ///
41 /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first. 43 /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first.
@@ -126,10 +128,13 @@ impl ItemScope {
126 } 128 }
127 129
128 pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a { 130 pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
129 self.types.values().filter_map(|(def, _)| match def { 131 self.types
130 ModuleDefId::TraitId(t) => Some(*t), 132 .values()
131 _ => None, 133 .filter_map(|(def, _)| match def {
132 }) 134 ModuleDefId::TraitId(t) => Some(*t),
135 _ => None,
136 })
137 .chain(self.unnamed_trait_imports.keys().copied())
133 } 138 }
134 139
135 pub(crate) fn define_def(&mut self, def: ModuleDefId) { 140 pub(crate) fn define_def(&mut self, def: ModuleDefId) {
@@ -148,6 +153,14 @@ impl ItemScope {
148 self.legacy_macros.insert(name, mac); 153 self.legacy_macros.insert(name, mac);
149 } 154 }
150 155
156 pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> {
157 self.unnamed_trait_imports.get(&tr).copied()
158 }
159
160 pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
161 self.unnamed_trait_imports.insert(tr, vis);
162 }
163
151 pub(crate) fn push_res(&mut self, name: Name, def: PerNs) -> bool { 164 pub(crate) fn push_res(&mut self, name: Name, def: PerNs) -> bool {
152 let mut changed = false; 165 let mut changed = false;
153 166
@@ -241,8 +254,12 @@ impl ItemScope {
241 changed 254 changed
242 } 255 }
243 256
244 pub(crate) fn resolutions<'a>(&'a self) -> impl Iterator<Item = (Name, PerNs)> + 'a { 257 pub(crate) fn resolutions<'a>(&'a self) -> impl Iterator<Item = (Option<Name>, PerNs)> + 'a {
245 self.entries().map(|(name, res)| (name.clone(), res)) 258 self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
259 self.unnamed_trait_imports
260 .iter()
261 .map(|(tr, vis)| (None, PerNs::types(ModuleDefId::TraitId(*tr), *vis))),
262 )
246 } 263 }
247 264
248 pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> { 265 pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> {
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 5a9de3d3e..3d9b55a73 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -239,7 +239,7 @@ impl CrateDefMap {
239 entries.sort_by_key(|(name, _)| name.clone()); 239 entries.sort_by_key(|(name, _)| name.clone());
240 240
241 for (name, def) in entries { 241 for (name, def) in entries {
242 format_to!(buf, "{}:", name); 242 format_to!(buf, "{}:", name.map_or("_".to_string(), |name| name.to_string()));
243 243
244 if def.types.is_some() { 244 if def.types.is_some() {
245 buf.push_str(" t"); 245 buf.push_str(" t");
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index d85a86c0a..a030cab47 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -310,7 +310,7 @@ impl DefCollector<'_> {
310 if export { 310 if export {
311 self.update( 311 self.update(
312 self.def_map.root, 312 self.def_map.root,
313 &[(name, PerNs::macros(macro_, Visibility::Public))], 313 &[(Some(name), PerNs::macros(macro_, Visibility::Public))],
314 Visibility::Public, 314 Visibility::Public,
315 ImportType::Named, 315 ImportType::Named,
316 ); 316 );
@@ -336,7 +336,7 @@ impl DefCollector<'_> {
336 fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) { 336 fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) {
337 self.update( 337 self.update(
338 self.def_map.root, 338 self.def_map.root,
339 &[(name, PerNs::macros(macro_, Visibility::Public))], 339 &[(Some(name), PerNs::macros(macro_, Visibility::Public))],
340 Visibility::Public, 340 Visibility::Public,
341 ImportType::Named, 341 ImportType::Named,
342 ); 342 );
@@ -534,7 +534,7 @@ impl DefCollector<'_> {
534 let name = variant_data.name.clone(); 534 let name = variant_data.name.clone();
535 let variant = EnumVariantId { parent: e, local_id }; 535 let variant = EnumVariantId { parent: e, local_id };
536 let res = PerNs::both(variant.into(), variant.into(), vis); 536 let res = PerNs::both(variant.into(), variant.into(), vis);
537 (name, res) 537 (Some(name), res)
538 }) 538 })
539 .collect::<Vec<_>>(); 539 .collect::<Vec<_>>();
540 self.update(module_id, &resolutions, vis, ImportType::Glob); 540 self.update(module_id, &resolutions, vis, ImportType::Glob);
@@ -550,15 +550,15 @@ impl DefCollector<'_> {
550 match import.path.segments.last() { 550 match import.path.segments.last() {
551 Some(last_segment) => { 551 Some(last_segment) => {
552 let name = match &import.alias { 552 let name = match &import.alias {
553 Some(ImportAlias::Alias(name)) => name.clone(), 553 Some(ImportAlias::Alias(name)) => Some(name.clone()),
554 Some(ImportAlias::Underscore) => last_segment.clone(), // FIXME rust-analyzer#2736 554 Some(ImportAlias::Underscore) => None,
555 None => last_segment.clone(), 555 None => Some(last_segment.clone()),
556 }; 556 };
557 log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); 557 log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
558 558
559 // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 559 // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
560 if import.is_extern_crate && module_id == self.def_map.root { 560 if import.is_extern_crate && module_id == self.def_map.root {
561 if let Some(def) = def.take_types() { 561 if let (Some(def), Some(name)) = (def.take_types(), name.as_ref()) {
562 self.def_map.extern_prelude.insert(name.clone(), def); 562 self.def_map.extern_prelude.insert(name.clone(), def);
563 } 563 }
564 } 564 }
@@ -573,7 +573,7 @@ impl DefCollector<'_> {
573 fn update( 573 fn update(
574 &mut self, 574 &mut self,
575 module_id: LocalModuleId, 575 module_id: LocalModuleId,
576 resolutions: &[(Name, PerNs)], 576 resolutions: &[(Option<Name>, PerNs)],
577 vis: Visibility, 577 vis: Visibility,
578 import_type: ImportType, 578 import_type: ImportType,
579 ) { 579 ) {
@@ -584,7 +584,7 @@ impl DefCollector<'_> {
584 fn update_recursive( 584 fn update_recursive(
585 &mut self, 585 &mut self,
586 module_id: LocalModuleId, 586 module_id: LocalModuleId,
587 resolutions: &[(Name, PerNs)], 587 resolutions: &[(Option<Name>, PerNs)],
588 // All resolutions are imported with this visibility; the visibilies in 588 // All resolutions are imported with this visibility; the visibilies in
589 // the `PerNs` values are ignored and overwritten 589 // the `PerNs` values are ignored and overwritten
590 vis: Visibility, 590 vis: Visibility,
@@ -595,15 +595,51 @@ impl DefCollector<'_> {
595 // prevent stack overflows (but this shouldn't be possible) 595 // prevent stack overflows (but this shouldn't be possible)
596 panic!("infinite recursion in glob imports!"); 596 panic!("infinite recursion in glob imports!");
597 } 597 }
598 let scope = &mut self.def_map.modules[module_id].scope;
599 let mut changed = false; 598 let mut changed = false;
599
600 for (name, res) in resolutions { 600 for (name, res) in resolutions {
601 changed |= scope.push_res_with_import( 601 match name {
602 &mut self.from_glob_import, 602 Some(name) => {
603 (module_id, name.clone()), 603 let scope = &mut self.def_map.modules[module_id].scope;
604 res.with_visibility(vis), 604 changed |= scope.push_res_with_import(
605 import_type, 605 &mut self.from_glob_import,
606 ); 606 (module_id, name.clone()),
607 res.with_visibility(vis),
608 import_type,
609 );
610 }
611 None => {
612 let tr = match res.take_types() {
613 Some(ModuleDefId::TraitId(tr)) => tr,
614 Some(other) => {
615 log::debug!("non-trait `_` import of {:?}", other);
616 continue;
617 }
618 None => continue,
619 };
620 let old_vis = self.def_map.modules[module_id].scope.unnamed_trait_vis(tr);
621 let should_update = match old_vis {
622 None => true,
623 Some(old_vis) => {
624 let max_vis = old_vis.max(vis, &self.def_map).unwrap_or_else(|| {
625 panic!("`Tr as _` imports with unrelated visibilities {:?} and {:?} (trait {:?})", old_vis, vis, tr);
626 });
627
628 if max_vis == old_vis {
629 false
630 } else {
631 mark::hit!(upgrade_underscore_visibility);
632 true
633 }
634 }
635 };
636
637 if should_update {
638 changed = true;
639 self.def_map.modules[module_id].scope.push_unnamed_trait(tr, vis);
640 }
641 }
642 }
607 } 643 }
608 644
609 if !changed { 645 if !changed {
@@ -950,7 +986,7 @@ impl ModCollector<'_, '_> {
950 .unwrap_or(Visibility::Public); 986 .unwrap_or(Visibility::Public);
951 self.def_collector.update( 987 self.def_collector.update(
952 self.module_id, 988 self.module_id,
953 &[(name.clone(), PerNs::from_def(id, vis, has_constructor))], 989 &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
954 vis, 990 vis,
955 ImportType::Named, 991 ImportType::Named,
956 ) 992 )
@@ -1057,7 +1093,7 @@ impl ModCollector<'_, '_> {
1057 self.def_collector.def_map.modules[self.module_id].scope.define_def(def); 1093 self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
1058 self.def_collector.update( 1094 self.def_collector.update(
1059 self.module_id, 1095 self.module_id,
1060 &[(name, PerNs::from_def(def, vis, false))], 1096 &[(Some(name), PerNs::from_def(def, vis, false))],
1061 vis, 1097 vis,
1062 ImportType::Named, 1098 ImportType::Named,
1063 ); 1099 );
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 205d3528b..839b1de57 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -558,3 +558,133 @@ mod b {
558 "#]], 558 "#]],
559 ); 559 );
560} 560}
561
562#[test]
563fn underscore_import() {
564 check(
565 r#"
566//- /main.rs
567use tr::Tr as _;
568use tr::Tr2 as _;
569
570mod tr {
571 pub trait Tr {}
572 pub trait Tr2 {}
573}
574 "#,
575 expect![[r#"
576 crate
577 _: t
578 _: t
579 tr: t
580
581 crate::tr
582 Tr: t
583 Tr2: t
584 "#]],
585 );
586}
587
588#[test]
589fn underscore_reexport() {
590 check(
591 r#"
592//- /main.rs
593mod tr {
594 pub trait PubTr {}
595 pub trait PrivTr {}
596}
597mod reex {
598 use crate::tr::PrivTr as _;
599 pub use crate::tr::PubTr as _;
600}
601use crate::reex::*;
602 "#,
603 expect![[r#"
604 crate
605 _: t
606 reex: t
607 tr: t
608
609 crate::tr
610 PrivTr: t
611 PubTr: t
612
613 crate::reex
614 _: t
615 _: t
616 "#]],
617 );
618}
619
620#[test]
621fn underscore_pub_crate_reexport() {
622 mark::check!(upgrade_underscore_visibility);
623 check(
624 r#"
625//- /main.rs crate:main deps:lib
626use lib::*;
627
628//- /lib.rs crate:lib
629use tr::Tr as _;
630pub use tr::Tr as _;
631
632mod tr {
633 pub trait Tr {}
634}
635 "#,
636 expect![[r#"
637 crate
638 _: t
639 "#]],
640 );
641}
642
643#[test]
644fn underscore_nontrait() {
645 check(
646 r#"
647//- /main.rs
648mod m {
649 pub struct Struct;
650 pub enum Enum {}
651 pub const CONST: () = ();
652}
653use crate::m::{Struct as _, Enum as _, CONST as _};
654 "#,
655 expect![[r#"
656 crate
657 m: t
658
659 crate::m
660 CONST: v
661 Enum: t
662 Struct: t v
663 "#]],
664 );
665}
666
667#[test]
668fn underscore_name_conflict() {
669 check(
670 r#"
671//- /main.rs
672struct Tr;
673
674use tr::Tr as _;
675
676mod tr {
677 pub trait Tr {}
678}
679 "#,
680 expect![[r#"
681 crate
682 _: t
683 Tr: t v
684 tr: t
685
686 crate::tr
687 Tr: t
688 "#]],
689 );
690}
diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs
index 8136cb50c..1abffb4c3 100644
--- a/crates/ra_hir_def/src/visibility.rs
+++ b/crates/ra_hir_def/src/visibility.rs
@@ -5,6 +5,7 @@ use ra_syntax::ast;
5 5
6use crate::{ 6use crate::{
7 db::DefDatabase, 7 db::DefDatabase,
8 nameres::CrateDefMap,
8 path::{ModPath, PathKind}, 9 path::{ModPath, PathKind},
9 ModuleId, 10 ModuleId,
10}; 11};
@@ -115,7 +116,7 @@ impl Visibility {
115 116
116 pub(crate) fn is_visible_from_def_map( 117 pub(crate) fn is_visible_from_def_map(
117 self, 118 self,
118 def_map: &crate::nameres::CrateDefMap, 119 def_map: &CrateDefMap,
119 from_module: crate::LocalModuleId, 120 from_module: crate::LocalModuleId,
120 ) -> bool { 121 ) -> bool {
121 let to_module = match self { 122 let to_module = match self {
@@ -129,4 +130,42 @@ impl Visibility {
129 }); 130 });
130 ancestors.any(|m| m == to_module.local_id) 131 ancestors.any(|m| m == to_module.local_id)
131 } 132 }
133
134 /// Returns the most permissive visibility of `self` and `other`.
135 ///
136 /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only
137 /// visible in unrelated modules).
138 pub(crate) fn max(self, other: Visibility, def_map: &CrateDefMap) -> Option<Visibility> {
139 match (self, other) {
140 (Visibility::Module(_), Visibility::Public)
141 | (Visibility::Public, Visibility::Module(_))
142 | (Visibility::Public, Visibility::Public) => Some(Visibility::Public),
143 (Visibility::Module(mod_a), Visibility::Module(mod_b)) => {
144 if mod_a.krate != mod_b.krate {
145 return None;
146 }
147
148 let mut a_ancestors = std::iter::successors(Some(mod_a.local_id), |m| {
149 let parent_id = def_map[*m].parent?;
150 Some(parent_id)
151 });
152 let mut b_ancestors = std::iter::successors(Some(mod_b.local_id), |m| {
153 let parent_id = def_map[*m].parent?;
154 Some(parent_id)
155 });
156
157 if a_ancestors.any(|m| m == mod_b.local_id) {
158 // B is above A
159 return Some(Visibility::Module(mod_b));
160 }
161
162 if b_ancestors.any(|m| m == mod_a.local_id) {
163 // A is above B
164 return Some(Visibility::Module(mod_a));
165 }
166
167 None
168 }
169 }
170 }
132} 171}
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index bf30d7151..e0ad1567f 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -6,7 +6,7 @@ use mbe::{ExpandResult, MacroRules};
6use ra_db::{salsa, SourceDatabase}; 6use ra_db::{salsa, SourceDatabase};
7use ra_parser::FragmentKind; 7use ra_parser::FragmentKind;
8use ra_prof::profile; 8use ra_prof::profile;
9use ra_syntax::{algo::diff, AstNode, Parse, SyntaxKind::*, SyntaxNode}; 9use ra_syntax::{algo::diff, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode};
10 10
11use crate::{ 11use crate::{
12 ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, 12 ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId,
@@ -72,6 +72,8 @@ pub trait AstDatabase: SourceDatabase {
72 72
73 #[salsa::interned] 73 #[salsa::interned]
74 fn intern_macro(&self, macro_call: MacroCallLoc) -> LazyMacroId; 74 fn intern_macro(&self, macro_call: MacroCallLoc) -> LazyMacroId;
75 fn macro_arg_text(&self, id: MacroCallId) -> Option<GreenNode>;
76 #[salsa::transparent]
75 fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>; 77 fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>;
76 fn macro_def(&self, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>>; 78 fn macro_def(&self, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>>;
77 fn parse_macro(&self, macro_file: MacroFile) 79 fn parse_macro(&self, macro_file: MacroFile)
@@ -148,10 +150,7 @@ pub(crate) fn macro_def(
148 } 150 }
149} 151}
150 152
151pub(crate) fn macro_arg( 153pub(crate) fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> {
152 db: &dyn AstDatabase,
153 id: MacroCallId,
154) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> {
155 let id = match id { 154 let id = match id {
156 MacroCallId::LazyMacro(id) => id, 155 MacroCallId::LazyMacro(id) => id,
157 MacroCallId::EagerMacro(_id) => { 156 MacroCallId::EagerMacro(_id) => {
@@ -161,7 +160,15 @@ pub(crate) fn macro_arg(
161 }; 160 };
162 let loc = db.lookup_intern_macro(id); 161 let loc = db.lookup_intern_macro(id);
163 let arg = loc.kind.arg(db)?; 162 let arg = loc.kind.arg(db)?;
164 let (tt, tmap) = mbe::syntax_node_to_token_tree(&arg)?; 163 Some(arg.green().clone())
164}
165
166pub(crate) fn macro_arg(
167 db: &dyn AstDatabase,
168 id: MacroCallId,
169) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> {
170 let arg = db.macro_arg_text(id)?;
171 let (tt, tmap) = mbe::syntax_node_to_token_tree(&SyntaxNode::new_root(arg))?;
165 Some(Arc::new((tt, tmap))) 172 Some(Arc::new((tt, tmap)))
166} 173}
167 174
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 1cf6c1ba9..d9e31ac20 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -262,14 +262,14 @@ pub enum MacroCallKind {
262} 262}
263 263
264impl MacroCallKind { 264impl MacroCallKind {
265 pub fn file_id(&self) -> HirFileId { 265 fn file_id(&self) -> HirFileId {
266 match self { 266 match self {
267 MacroCallKind::FnLike(ast_id) => ast_id.file_id, 267 MacroCallKind::FnLike(ast_id) => ast_id.file_id,
268 MacroCallKind::Attr(ast_id, _) => ast_id.file_id, 268 MacroCallKind::Attr(ast_id, _) => ast_id.file_id,
269 } 269 }
270 } 270 }
271 271
272 pub fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> { 272 fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> {
273 match self { 273 match self {
274 MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()), 274 MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()),
275 MacroCallKind::Attr(ast_id, _) => { 275 MacroCallKind::Attr(ast_id, _) => {
@@ -278,7 +278,7 @@ impl MacroCallKind {
278 } 278 }
279 } 279 }
280 280
281 pub fn arg(&self, db: &dyn db::AstDatabase) -> Option<SyntaxNode> { 281 fn arg(&self, db: &dyn db::AstDatabase) -> Option<SyntaxNode> {
282 match self { 282 match self {
283 MacroCallKind::FnLike(ast_id) => { 283 MacroCallKind::FnLike(ast_id) => {
284 Some(ast_id.to_node(db).token_tree()?.syntax().clone()) 284 Some(ast_id.to_node(db).token_tree()?.syntax().clone())
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 78f5e55bb..cdabb359f 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -28,12 +28,11 @@ test_utils = { path = "../test_utils" }
28 28
29scoped-tls = "1" 29scoped-tls = "1"
30 30
31chalk-solve = { version = "0.17.0" } 31chalk-solve = { version = "0.18.0" }
32chalk-ir = { version = "0.17.0" } 32chalk-ir = { version = "0.18.0" }
33chalk-recursive = { version = "0.17.0" } 33chalk-recursive = { version = "0.18.0" }
34 34
35[dev-dependencies] 35[dev-dependencies]
36insta = "0.16.0"
37expect = { path = "../expect" } 36expect = { path = "../expect" }
38 37
39tracing = "0.1" 38tracing = "0.1"
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs
index 758d5f5ac..19770e609 100644
--- a/crates/ra_hir_ty/src/display.rs
+++ b/crates/ra_hir_ty/src/display.rs
@@ -257,7 +257,12 @@ impl HirDisplay for ApplicationTy {
257 write!(f, ")")?; 257 write!(f, ")")?;
258 let ret = sig.ret(); 258 let ret = sig.ret();
259 if *ret != Ty::unit() { 259 if *ret != Ty::unit() {
260 write!(f, " -> {}", ret.display(f.db))?; 260 let ret_display = if f.omit_verbose_types() {
261 ret.display_truncated(f.db, f.max_size)
262 } else {
263 ret.display(f.db)
264 };
265 write!(f, " -> {}", ret_display)?;
261 } 266 }
262 } 267 }
263 TypeCtor::FnDef(def) => { 268 TypeCtor::FnDef(def) => {
@@ -288,7 +293,12 @@ impl HirDisplay for ApplicationTy {
288 write!(f, ")")?; 293 write!(f, ")")?;
289 let ret = sig.ret(); 294 let ret = sig.ret();
290 if *ret != Ty::unit() { 295 if *ret != Ty::unit() {
291 write!(f, " -> {}", ret.display(f.db))?; 296 let ret_display = if f.omit_verbose_types() {
297 ret.display_truncated(f.db, f.max_size)
298 } else {
299 ret.display(f.db)
300 };
301 write!(f, " -> {}", ret_display)?;
292 } 302 }
293 } 303 }
294 TypeCtor::Adt(def_id) => { 304 TypeCtor::Adt(def_id) => {
@@ -397,7 +407,13 @@ impl HirDisplay for ApplicationTy {
397 f.write_joined(sig.params(), ", ")?; 407 f.write_joined(sig.params(), ", ")?;
398 write!(f, "|")?; 408 write!(f, "|")?;
399 }; 409 };
400 write!(f, " -> {}", sig.ret().display(f.db))?; 410
411 let ret_display = if f.omit_verbose_types() {
412 sig.ret().display_truncated(f.db, f.max_size)
413 } else {
414 sig.ret().display(f.db)
415 };
416 write!(f, " -> {}", ret_display)?;
401 } else { 417 } else {
402 write!(f, "{{closure}}")?; 418 write!(f, "{{closure}}")?;
403 } 419 }
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index 59a21092e..45bc14c37 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -34,8 +34,8 @@ use crate::{
34}; 34};
35 35
36// These tests compare the inference results for all expressions in a file 36// These tests compare the inference results for all expressions in a file
37// against snapshots of the expected results using insta. Use cargo-insta to 37// against snapshots of the expected results using expect. Use
38// update the snapshots. 38// `env UPDATE_EXPECT=1 cargo test -p ra_hir_ty` to update the snapshots.
39 39
40fn setup_tracing() -> tracing::subscriber::DefaultGuard { 40fn setup_tracing() -> tracing::subscriber::DefaultGuard {
41 use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; 41 use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs
index 45c4e309e..24c53eb02 100644
--- a/crates/ra_hir_ty/src/tests/macros.rs
+++ b/crates/ra_hir_ty/src/tests/macros.rs
@@ -1,9 +1,9 @@
1use std::fs; 1use std::fs;
2 2
3use insta::assert_snapshot; 3use expect::expect;
4use test_utils::project_dir; 4use test_utils::project_dir;
5 5
6use super::{check_types, infer}; 6use super::{check_infer, check_types};
7 7
8#[test] 8#[test]
9fn cfg_impl_def() { 9fn cfg_impl_def() {
@@ -46,204 +46,204 @@ impl S {
46 46
47#[test] 47#[test]
48fn infer_macros_expanded() { 48fn infer_macros_expanded() {
49 assert_snapshot!( 49 check_infer(
50 infer(r#" 50 r#"
51struct Foo(Vec<i32>); 51 struct Foo(Vec<i32>);
52 52
53macro_rules! foo { 53 macro_rules! foo {
54 ($($item:expr),*) => { 54 ($($item:expr),*) => {
55 { 55 {
56 Foo(vec![$($item,)*]) 56 Foo(vec![$($item,)*])
57 } 57 }
58 }; 58 };
59} 59 }
60 60
61fn main() { 61 fn main() {
62 let x = foo!(1,2); 62 let x = foo!(1,2);
63} 63 }
64"#), 64 "#,
65 @r###" 65 expect![[r#"
66 !0..17 '{Foo(v...,2,])}': Foo 66 !0..17 '{Foo(v...,2,])}': Foo
67 !1..4 'Foo': Foo({unknown}) -> Foo 67 !1..4 'Foo': Foo({unknown}) -> Foo
68 !1..16 'Foo(vec![1,2,])': Foo 68 !1..16 'Foo(vec![1,2,])': Foo
69 !5..15 'vec![1,2,]': {unknown} 69 !5..15 'vec![1,2,]': {unknown}
70 155..181 '{ ...,2); }': () 70 155..181 '{ ...,2); }': ()
71 165..166 'x': Foo 71 165..166 'x': Foo
72 "### 72 "#]],
73 ); 73 );
74} 74}
75 75
76#[test] 76#[test]
77fn infer_legacy_textual_scoped_macros_expanded() { 77fn infer_legacy_textual_scoped_macros_expanded() {
78 assert_snapshot!( 78 check_infer(
79 infer(r#" 79 r#"
80struct Foo(Vec<i32>); 80 struct Foo(Vec<i32>);
81 81
82#[macro_use] 82 #[macro_use]
83mod m { 83 mod m {
84 macro_rules! foo { 84 macro_rules! foo {
85 ($($item:expr),*) => { 85 ($($item:expr),*) => {
86 { 86 {
87 Foo(vec![$($item,)*]) 87 Foo(vec![$($item,)*])
88 }
89 };
88 } 90 }
89 }; 91 }
90 }
91}
92 92
93fn main() { 93 fn main() {
94 let x = foo!(1,2); 94 let x = foo!(1,2);
95 let y = crate::foo!(1,2); 95 let y = crate::foo!(1,2);
96} 96 }
97"#), 97 "#,
98 @r###" 98 expect![[r#"
99 !0..17 '{Foo(v...,2,])}': Foo 99 !0..17 '{Foo(v...,2,])}': Foo
100 !1..4 'Foo': Foo({unknown}) -> Foo 100 !1..4 'Foo': Foo({unknown}) -> Foo
101 !1..16 'Foo(vec![1,2,])': Foo 101 !1..16 'Foo(vec![1,2,])': Foo
102 !5..15 'vec![1,2,]': {unknown} 102 !5..15 'vec![1,2,]': {unknown}
103 194..250 '{ ...,2); }': () 103 194..250 '{ ...,2); }': ()
104 204..205 'x': Foo 104 204..205 'x': Foo
105 227..228 'y': {unknown} 105 227..228 'y': {unknown}
106 231..247 'crate:...!(1,2)': {unknown} 106 231..247 'crate:...!(1,2)': {unknown}
107 "### 107 "#]],
108 ); 108 );
109} 109}
110 110
111#[test] 111#[test]
112fn infer_path_qualified_macros_expanded() { 112fn infer_path_qualified_macros_expanded() {
113 assert_snapshot!( 113 check_infer(
114 infer(r#" 114 r#"
115#[macro_export] 115 #[macro_export]
116macro_rules! foo { 116 macro_rules! foo {
117 () => { 42i32 } 117 () => { 42i32 }
118} 118 }
119 119
120mod m { 120 mod m {
121 pub use super::foo as bar; 121 pub use super::foo as bar;
122} 122 }
123 123
124fn main() { 124 fn main() {
125 let x = crate::foo!(); 125 let x = crate::foo!();
126 let y = m::bar!(); 126 let y = m::bar!();
127} 127 }
128"#), 128 "#,
129 @r###" 129 expect![[r#"
130 !0..5 '42i32': i32 130 !0..5 '42i32': i32
131 !0..5 '42i32': i32 131 !0..5 '42i32': i32
132 110..163 '{ ...!(); }': () 132 110..163 '{ ...!(); }': ()
133 120..121 'x': i32 133 120..121 'x': i32
134 147..148 'y': i32 134 147..148 'y': i32
135 "### 135 "#]],
136 ); 136 );
137} 137}
138 138
139#[test] 139#[test]
140fn expr_macro_expanded_in_various_places() { 140fn expr_macro_expanded_in_various_places() {
141 assert_snapshot!( 141 check_infer(
142 infer(r#" 142 r#"
143macro_rules! spam { 143 macro_rules! spam {
144 () => (1isize); 144 () => (1isize);
145} 145 }
146 146
147fn spam() { 147 fn spam() {
148 spam!(); 148 spam!();
149 (spam!()); 149 (spam!());
150 spam!().spam(spam!()); 150 spam!().spam(spam!());
151 for _ in spam!() {} 151 for _ in spam!() {}
152 || spam!(); 152 || spam!();
153 while spam!() {} 153 while spam!() {}
154 break spam!(); 154 break spam!();
155 return spam!(); 155 return spam!();
156 match spam!() { 156 match spam!() {
157 _ if spam!() => spam!(), 157 _ if spam!() => spam!(),
158 } 158 }
159 spam!()(spam!()); 159 spam!()(spam!());
160 Spam { spam: spam!() }; 160 Spam { spam: spam!() };
161 spam!()[spam!()]; 161 spam!()[spam!()];
162 await spam!(); 162 await spam!();
163 spam!() as usize; 163 spam!() as usize;
164 &spam!(); 164 &spam!();
165 -spam!(); 165 -spam!();
166 spam!()..spam!(); 166 spam!()..spam!();
167 spam!() + spam!(); 167 spam!() + spam!();
168} 168 }
169"#), 169 "#,
170 @r###" 170 expect![[r#"
171 !0..6 '1isize': isize 171 !0..6 '1isize': isize
172 !0..6 '1isize': isize 172 !0..6 '1isize': isize
173 !0..6 '1isize': isize 173 !0..6 '1isize': isize
174 !0..6 '1isize': isize 174 !0..6 '1isize': isize
175 !0..6 '1isize': isize 175 !0..6 '1isize': isize
176 !0..6 '1isize': isize 176 !0..6 '1isize': isize
177 !0..6 '1isize': isize 177 !0..6 '1isize': isize
178 !0..6 '1isize': isize 178 !0..6 '1isize': isize
179 !0..6 '1isize': isize 179 !0..6 '1isize': isize
180 !0..6 '1isize': isize 180 !0..6 '1isize': isize
181 !0..6 '1isize': isize 181 !0..6 '1isize': isize
182 !0..6 '1isize': isize 182 !0..6 '1isize': isize
183 !0..6 '1isize': isize 183 !0..6 '1isize': isize
184 !0..6 '1isize': isize 184 !0..6 '1isize': isize
185 !0..6 '1isize': isize 185 !0..6 '1isize': isize
186 !0..6 '1isize': isize 186 !0..6 '1isize': isize
187 !0..6 '1isize': isize 187 !0..6 '1isize': isize
188 !0..6 '1isize': isize 188 !0..6 '1isize': isize
189 !0..6 '1isize': isize 189 !0..6 '1isize': isize
190 !0..6 '1isize': isize 190 !0..6 '1isize': isize
191 !0..6 '1isize': isize 191 !0..6 '1isize': isize
192 !0..6 '1isize': isize 192 !0..6 '1isize': isize
193 !0..6 '1isize': isize 193 !0..6 '1isize': isize
194 !0..6 '1isize': isize 194 !0..6 '1isize': isize
195 !0..6 '1isize': isize 195 !0..6 '1isize': isize
196 53..456 '{ ...!(); }': () 196 53..456 '{ ...!(); }': ()
197 87..108 'spam!(...am!())': {unknown} 197 87..108 'spam!(...am!())': {unknown}
198 114..133 'for _ ...!() {}': () 198 114..133 'for _ ...!() {}': ()
199 118..119 '_': {unknown} 199 118..119 '_': {unknown}
200 131..133 '{}': () 200 131..133 '{}': ()
201 138..148 '|| spam!()': || -> isize 201 138..148 '|| spam!()': || -> isize
202 154..170 'while ...!() {}': () 202 154..170 'while ...!() {}': ()
203 168..170 '{}': () 203 168..170 '{}': ()
204 175..188 'break spam!()': ! 204 175..188 'break spam!()': !
205 194..208 'return spam!()': ! 205 194..208 'return spam!()': !
206 214..268 'match ... }': isize 206 214..268 'match ... }': isize
207 238..239 '_': isize 207 238..239 '_': isize
208 273..289 'spam!(...am!())': {unknown} 208 273..289 'spam!(...am!())': {unknown}
209 295..317 'Spam {...m!() }': {unknown} 209 295..317 'Spam {...m!() }': {unknown}
210 323..339 'spam!(...am!()]': {unknown} 210 323..339 'spam!(...am!()]': {unknown}
211 364..380 'spam!(... usize': usize 211 364..380 'spam!(... usize': usize
212 386..394 '&spam!()': &isize 212 386..394 '&spam!()': &isize
213 400..408 '-spam!()': isize 213 400..408 '-spam!()': isize
214 414..430 'spam!(...pam!()': {unknown} 214 414..430 'spam!(...pam!()': {unknown}
215 436..453 'spam!(...pam!()': isize 215 436..453 'spam!(...pam!()': isize
216 "### 216 "#]],
217 ); 217 );
218} 218}
219 219
220#[test] 220#[test]
221fn infer_type_value_macro_having_same_name() { 221fn infer_type_value_macro_having_same_name() {
222 assert_snapshot!( 222 check_infer(
223 infer(r#" 223 r#"
224#[macro_export] 224 #[macro_export]
225macro_rules! foo { 225 macro_rules! foo {
226 () => { 226 () => {
227 mod foo { 227 mod foo {
228 pub use super::foo; 228 pub use super::foo;
229 }
230 };
231 ($x:tt) => {
232 $x
233 };
229 } 234 }
230 };
231 ($x:tt) => {
232 $x
233 };
234}
235 235
236foo!(); 236 foo!();
237 237
238fn foo() { 238 fn foo() {
239 let foo = foo::foo!(42i32); 239 let foo = foo::foo!(42i32);
240} 240 }
241"#), 241 "#,
242 @r###" 242 expect![[r#"
243 !0..5 '42i32': i32 243 !0..5 '42i32': i32
244 170..205 '{ ...32); }': () 244 170..205 '{ ...32); }': ()
245 180..183 'foo': i32 245 180..183 'foo': i32
246 "### 246 "#]],
247 ); 247 );
248} 248}
249 249
@@ -372,50 +372,50 @@ expand!();
372 372
373#[test] 373#[test]
374fn infer_type_value_non_legacy_macro_use_as() { 374fn infer_type_value_non_legacy_macro_use_as() {
375 assert_snapshot!( 375 check_infer(
376 infer(r#" 376 r#"
377mod m { 377 mod m {
378 macro_rules! _foo { 378 macro_rules! _foo {
379 ($x:ident) => { type $x = u64; } 379 ($x:ident) => { type $x = u64; }
380 } 380 }
381 pub(crate) use _foo as foo; 381 pub(crate) use _foo as foo;
382} 382 }
383 383
384m::foo!(foo); 384 m::foo!(foo);
385use foo as bar; 385 use foo as bar;
386fn f() -> bar { 0 } 386 fn f() -> bar { 0 }
387fn main() { 387 fn main() {
388 let _a = f(); 388 let _a = f();
389} 389 }
390"#), 390 "#,
391 @r###" 391 expect![[r#"
392 158..163 '{ 0 }': u64 392 158..163 '{ 0 }': u64
393 160..161 '0': u64 393 160..161 '0': u64
394 174..196 '{ ...f(); }': () 394 174..196 '{ ...f(); }': ()
395 184..186 '_a': u64 395 184..186 '_a': u64
396 190..191 'f': fn f() -> u64 396 190..191 'f': fn f() -> u64
397 190..193 'f()': u64 397 190..193 'f()': u64
398 "### 398 "#]],
399 ); 399 );
400} 400}
401 401
402#[test] 402#[test]
403fn infer_local_macro() { 403fn infer_local_macro() {
404 assert_snapshot!( 404 check_infer(
405 infer(r#" 405 r#"
406fn main() { 406 fn main() {
407 macro_rules! foo { 407 macro_rules! foo {
408 () => { 1usize } 408 () => { 1usize }
409 } 409 }
410 let _a = foo!(); 410 let _a = foo!();
411} 411 }
412"#), 412 "#,
413 @r###" 413 expect![[r#"
414 !0..6 '1usize': usize 414 !0..6 '1usize': usize
415 10..89 '{ ...!(); }': () 415 10..89 '{ ...!(); }': ()
416 16..65 'macro_... }': {unknown} 416 16..65 'macro_... }': {unknown}
417 74..76 '_a': usize 417 74..76 '_a': usize
418 "### 418 "#]],
419 ); 419 );
420} 420}
421 421
@@ -446,77 +446,77 @@ macro_rules! bar {
446 446
447#[test] 447#[test]
448fn infer_builtin_macros_line() { 448fn infer_builtin_macros_line() {
449 assert_snapshot!( 449 check_infer(
450 infer(r#" 450 r#"
451#[rustc_builtin_macro] 451 #[rustc_builtin_macro]
452macro_rules! line {() => {}} 452 macro_rules! line {() => {}}
453 453
454fn main() { 454 fn main() {
455 let x = line!(); 455 let x = line!();
456} 456 }
457"#), 457 "#,
458 @r###" 458 expect![[r#"
459 !0..1 '0': i32 459 !0..1 '0': i32
460 63..87 '{ ...!(); }': () 460 63..87 '{ ...!(); }': ()
461 73..74 'x': i32 461 73..74 'x': i32
462 "### 462 "#]],
463 ); 463 );
464} 464}
465 465
466#[test] 466#[test]
467fn infer_builtin_macros_file() { 467fn infer_builtin_macros_file() {
468 assert_snapshot!( 468 check_infer(
469 infer(r#" 469 r#"
470#[rustc_builtin_macro] 470 #[rustc_builtin_macro]
471macro_rules! file {() => {}} 471 macro_rules! file {() => {}}
472 472
473fn main() { 473 fn main() {
474 let x = file!(); 474 let x = file!();
475} 475 }
476"#), 476 "#,
477 @r###" 477 expect![[r#"
478 !0..2 '""': &str 478 !0..2 '""': &str
479 63..87 '{ ...!(); }': () 479 63..87 '{ ...!(); }': ()
480 73..74 'x': &str 480 73..74 'x': &str
481 "### 481 "#]],
482 ); 482 );
483} 483}
484 484
485#[test] 485#[test]
486fn infer_builtin_macros_column() { 486fn infer_builtin_macros_column() {
487 assert_snapshot!( 487 check_infer(
488 infer(r#" 488 r#"
489#[rustc_builtin_macro] 489 #[rustc_builtin_macro]
490macro_rules! column {() => {}} 490 macro_rules! column {() => {}}
491 491
492fn main() { 492 fn main() {
493 let x = column!(); 493 let x = column!();
494} 494 }
495"#), 495 "#,
496 @r###" 496 expect![[r#"
497 !0..1 '0': i32 497 !0..1 '0': i32
498 65..91 '{ ...!(); }': () 498 65..91 '{ ...!(); }': ()
499 75..76 'x': i32 499 75..76 'x': i32
500 "### 500 "#]],
501 ); 501 );
502} 502}
503 503
504#[test] 504#[test]
505fn infer_builtin_macros_concat() { 505fn infer_builtin_macros_concat() {
506 assert_snapshot!( 506 check_infer(
507 infer(r#" 507 r#"
508#[rustc_builtin_macro] 508 #[rustc_builtin_macro]
509macro_rules! concat {() => {}} 509 macro_rules! concat {() => {}}
510 510
511fn main() { 511 fn main() {
512 let x = concat!("hello", concat!("world", "!")); 512 let x = concat!("hello", concat!("world", "!"));
513} 513 }
514"#), 514 "#,
515 @r###" 515 expect![[r#"
516 !0..13 '"helloworld!"': &str 516 !0..13 '"helloworld!"': &str
517 65..121 '{ ...")); }': () 517 65..121 '{ ...")); }': ()
518 75..76 'x': &str 518 75..76 'x': &str
519 "### 519 "#]],
520 ); 520 );
521} 521}
522 522
@@ -622,7 +622,7 @@ macro_rules! include {() => {}}
622include!("main.rs"); 622include!("main.rs");
623 623
624fn main() { 624fn main() {
625 0 625 0
626} //^ i32 626} //^ i32
627"#, 627"#,
628 ); 628 );
@@ -630,42 +630,42 @@ fn main() {
630 630
631#[test] 631#[test]
632fn infer_builtin_macros_concat_with_lazy() { 632fn infer_builtin_macros_concat_with_lazy() {
633 assert_snapshot!( 633 check_infer(
634 infer(r#" 634 r#"
635macro_rules! hello {() => {"hello"}} 635 macro_rules! hello {() => {"hello"}}
636 636
637#[rustc_builtin_macro] 637 #[rustc_builtin_macro]
638macro_rules! concat {() => {}} 638 macro_rules! concat {() => {}}
639 639
640fn main() { 640 fn main() {
641 let x = concat!(hello!(), concat!("world", "!")); 641 let x = concat!(hello!(), concat!("world", "!"));
642} 642 }
643"#), 643 "#,
644 @r###" 644 expect![[r#"
645 !0..13 '"helloworld!"': &str 645 !0..13 '"helloworld!"': &str
646 103..160 '{ ...")); }': () 646 103..160 '{ ...")); }': ()
647 113..114 'x': &str 647 113..114 'x': &str
648 "### 648 "#]],
649 ); 649 );
650} 650}
651 651
652#[test] 652#[test]
653fn infer_builtin_macros_env() { 653fn infer_builtin_macros_env() {
654 assert_snapshot!( 654 check_infer(
655 infer(r#" 655 r#"
656//- /main.rs env:foo=bar 656 //- /main.rs env:foo=bar
657#[rustc_builtin_macro] 657 #[rustc_builtin_macro]
658macro_rules! env {() => {}} 658 macro_rules! env {() => {}}
659 659
660fn main() { 660 fn main() {
661 let x = env!("foo"); 661 let x = env!("foo");
662} 662 }
663"#), 663 "#,
664 @r###" 664 expect![[r#"
665 !0..22 '"__RA_...TED__"': &str 665 !0..22 '"__RA_...TED__"': &str
666 62..90 '{ ...o"); }': () 666 62..90 '{ ...o"); }': ()
667 72..73 'x': &str 667 72..73 'x': &str
668 "### 668 "#]],
669 ); 669 );
670} 670}
671 671
@@ -763,25 +763,25 @@ fn test() {
763 763
764#[test] 764#[test]
765fn macro_in_arm() { 765fn macro_in_arm() {
766 assert_snapshot!( 766 check_infer(
767 infer(r#" 767 r#"
768macro_rules! unit { 768 macro_rules! unit {
769 () => { () }; 769 () => { () };
770} 770 }
771 771
772fn main() { 772 fn main() {
773 let x = match () { 773 let x = match () {
774 unit!() => 92u32, 774 unit!() => 92u32,
775 }; 775 };
776} 776 }
777"#), 777 "#,
778 @r###" 778 expect![[r#"
779 51..110 '{ ... }; }': () 779 51..110 '{ ... }; }': ()
780 61..62 'x': u32 780 61..62 'x': u32
781 65..107 'match ... }': u32 781 65..107 'match ... }': u32
782 71..73 '()': () 782 71..73 '()': ()
783 84..91 'unit!()': () 783 84..91 'unit!()': ()
784 95..100 '92u32': u32 784 95..100 '92u32': u32
785 "### 785 "#]],
786 ); 786 );
787} 787}
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index 9c8f22314..fa68355aa 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -1,245 +1,245 @@
1use insta::assert_snapshot; 1use expect::expect;
2 2
3use super::{check_types, infer}; 3use super::{check_infer, check_types};
4 4
5#[test] 5#[test]
6fn infer_slice_method() { 6fn infer_slice_method() {
7 assert_snapshot!( 7 check_infer(
8 infer(r#" 8 r#"
9#[lang = "slice"] 9 #[lang = "slice"]
10impl<T> [T] { 10 impl<T> [T] {
11 fn foo(&self) -> T { 11 fn foo(&self) -> T {
12 loop {} 12 loop {}
13 } 13 }
14} 14 }
15 15
16#[lang = "slice_alloc"] 16 #[lang = "slice_alloc"]
17impl<T> [T] {} 17 impl<T> [T] {}
18 18
19fn test(x: &[u8]) { 19 fn test(x: &[u8]) {
20 <[_]>::foo(x); 20 <[_]>::foo(x);
21} 21 }
22"#), 22 "#,
23 @r###" 23 expect![[r#"
24 44..48 'self': &[T] 24 44..48 'self': &[T]
25 55..78 '{ ... }': T 25 55..78 '{ ... }': T
26 65..72 'loop {}': ! 26 65..72 'loop {}': !
27 70..72 '{}': () 27 70..72 '{}': ()
28 130..131 'x': &[u8] 28 130..131 'x': &[u8]
29 140..162 '{ ...(x); }': () 29 140..162 '{ ...(x); }': ()
30 146..156 '<[_]>::foo': fn foo<u8>(&[u8]) -> u8 30 146..156 '<[_]>::foo': fn foo<u8>(&[u8]) -> u8
31 146..159 '<[_]>::foo(x)': u8 31 146..159 '<[_]>::foo(x)': u8
32 157..158 'x': &[u8] 32 157..158 'x': &[u8]
33 "### 33 "#]],
34 ); 34 );
35} 35}
36 36
37#[test] 37#[test]
38fn infer_associated_method_struct() { 38fn infer_associated_method_struct() {
39 assert_snapshot!( 39 check_infer(
40 infer(r#" 40 r#"
41struct A { x: u32 } 41 struct A { x: u32 }
42 42
43impl A { 43 impl A {
44 fn new() -> A { 44 fn new() -> A {
45 A { x: 0 } 45 A { x: 0 }
46 } 46 }
47} 47 }
48fn test() { 48 fn test() {
49 let a = A::new(); 49 let a = A::new();
50 a.x; 50 a.x;
51} 51 }
52"#), 52 "#,
53 @r###" 53 expect![[r#"
54 48..74 '{ ... }': A 54 48..74 '{ ... }': A
55 58..68 'A { x: 0 }': A 55 58..68 'A { x: 0 }': A
56 65..66 '0': u32 56 65..66 '0': u32
57 87..121 '{ ...a.x; }': () 57 87..121 '{ ...a.x; }': ()
58 97..98 'a': A 58 97..98 'a': A
59 101..107 'A::new': fn new() -> A 59 101..107 'A::new': fn new() -> A
60 101..109 'A::new()': A 60 101..109 'A::new()': A
61 115..116 'a': A 61 115..116 'a': A
62 115..118 'a.x': u32 62 115..118 'a.x': u32
63 "### 63 "#]],
64 ); 64 );
65} 65}
66 66
67#[test] 67#[test]
68fn infer_associated_method_enum() { 68fn infer_associated_method_enum() {
69 assert_snapshot!( 69 check_infer(
70 infer(r#" 70 r#"
71enum A { B, C } 71 enum A { B, C }
72 72
73impl A { 73 impl A {
74 pub fn b() -> A { 74 pub fn b() -> A {
75 A::B 75 A::B
76 } 76 }
77 pub fn c() -> A { 77 pub fn c() -> A {
78 A::C 78 A::C
79 } 79 }
80} 80 }
81fn test() { 81 fn test() {
82 let a = A::b(); 82 let a = A::b();
83 a; 83 a;
84 let c = A::c(); 84 let c = A::c();
85 c; 85 c;
86} 86 }
87"#), 87 "#,
88 @r###" 88 expect![[r#"
89 46..66 '{ ... }': A 89 46..66 '{ ... }': A
90 56..60 'A::B': A 90 56..60 'A::B': A
91 87..107 '{ ... }': A 91 87..107 '{ ... }': A
92 97..101 'A::C': A 92 97..101 'A::C': A
93 120..177 '{ ... c; }': () 93 120..177 '{ ... c; }': ()
94 130..131 'a': A 94 130..131 'a': A
95 134..138 'A::b': fn b() -> A 95 134..138 'A::b': fn b() -> A
96 134..140 'A::b()': A 96 134..140 'A::b()': A
97 146..147 'a': A 97 146..147 'a': A
98 157..158 'c': A 98 157..158 'c': A
99 161..165 'A::c': fn c() -> A 99 161..165 'A::c': fn c() -> A
100 161..167 'A::c()': A 100 161..167 'A::c()': A
101 173..174 'c': A 101 173..174 'c': A
102 "### 102 "#]],
103 ); 103 );
104} 104}
105 105
106#[test] 106#[test]
107fn infer_associated_method_with_modules() { 107fn infer_associated_method_with_modules() {
108 assert_snapshot!( 108 check_infer(
109 infer(r#" 109 r#"
110mod a { 110 mod a {
111 struct A; 111 struct A;
112 impl A { pub fn thing() -> A { A {} }} 112 impl A { pub fn thing() -> A { A {} }}
113} 113 }
114 114
115mod b { 115 mod b {
116 struct B; 116 struct B;
117 impl B { pub fn thing() -> u32 { 99 }} 117 impl B { pub fn thing() -> u32 { 99 }}
118 118
119 mod c { 119 mod c {
120 struct C; 120 struct C;
121 impl C { pub fn thing() -> C { C {} }} 121 impl C { pub fn thing() -> C { C {} }}
122 } 122 }
123} 123 }
124use b::c; 124 use b::c;
125 125
126fn test() { 126 fn test() {
127 let x = a::A::thing(); 127 let x = a::A::thing();
128 let y = b::B::thing(); 128 let y = b::B::thing();
129 let z = c::C::thing(); 129 let z = c::C::thing();
130} 130 }
131"#), 131 "#,
132 @r###" 132 expect![[r#"
133 55..63 '{ A {} }': A 133 55..63 '{ A {} }': A
134 57..61 'A {}': A 134 57..61 'A {}': A
135 125..131 '{ 99 }': u32 135 125..131 '{ 99 }': u32
136 127..129 '99': u32 136 127..129 '99': u32
137 201..209 '{ C {} }': C 137 201..209 '{ C {} }': C
138 203..207 'C {}': C 138 203..207 'C {}': C
139 240..324 '{ ...g(); }': () 139 240..324 '{ ...g(); }': ()
140 250..251 'x': A 140 250..251 'x': A
141 254..265 'a::A::thing': fn thing() -> A 141 254..265 'a::A::thing': fn thing() -> A
142 254..267 'a::A::thing()': A 142 254..267 'a::A::thing()': A
143 277..278 'y': u32 143 277..278 'y': u32
144 281..292 'b::B::thing': fn thing() -> u32 144 281..292 'b::B::thing': fn thing() -> u32
145 281..294 'b::B::thing()': u32 145 281..294 'b::B::thing()': u32
146 304..305 'z': C 146 304..305 'z': C
147 308..319 'c::C::thing': fn thing() -> C 147 308..319 'c::C::thing': fn thing() -> C
148 308..321 'c::C::thing()': C 148 308..321 'c::C::thing()': C
149 "### 149 "#]],
150 ); 150 );
151} 151}
152 152
153#[test] 153#[test]
154fn infer_associated_method_generics() { 154fn infer_associated_method_generics() {
155 assert_snapshot!( 155 check_infer(
156 infer(r#" 156 r#"
157struct Gen<T> { 157 struct Gen<T> {
158 val: T 158 val: T
159} 159 }
160 160
161impl<T> Gen<T> { 161 impl<T> Gen<T> {
162 pub fn make(val: T) -> Gen<T> { 162 pub fn make(val: T) -> Gen<T> {
163 Gen { val } 163 Gen { val }
164 } 164 }
165} 165 }
166 166
167fn test() { 167 fn test() {
168 let a = Gen::make(0u32); 168 let a = Gen::make(0u32);
169} 169 }
170"#), 170 "#,
171 @r###" 171 expect![[r#"
172 63..66 'val': T 172 63..66 'val': T
173 81..108 '{ ... }': Gen<T> 173 81..108 '{ ... }': Gen<T>
174 91..102 'Gen { val }': Gen<T> 174 91..102 'Gen { val }': Gen<T>
175 97..100 'val': T 175 97..100 'val': T
176 122..154 '{ ...32); }': () 176 122..154 '{ ...32); }': ()
177 132..133 'a': Gen<u32> 177 132..133 'a': Gen<u32>
178 136..145 'Gen::make': fn make<u32>(u32) -> Gen<u32> 178 136..145 'Gen::make': fn make<u32>(u32) -> Gen<u32>
179 136..151 'Gen::make(0u32)': Gen<u32> 179 136..151 'Gen::make(0u32)': Gen<u32>
180 146..150 '0u32': u32 180 146..150 '0u32': u32
181 "### 181 "#]],
182 ); 182 );
183} 183}
184 184
185#[test] 185#[test]
186fn infer_associated_method_generics_without_args() { 186fn infer_associated_method_generics_without_args() {
187 assert_snapshot!( 187 check_infer(
188 infer(r#" 188 r#"
189struct Gen<T> { 189 struct Gen<T> {
190 val: T 190 val: T
191} 191 }
192 192
193impl<T> Gen<T> { 193 impl<T> Gen<T> {
194 pub fn make() -> Gen<T> { 194 pub fn make() -> Gen<T> {
195 loop { } 195 loop { }
196 } 196 }
197} 197 }
198 198
199fn test() { 199 fn test() {
200 let a = Gen::<u32>::make(); 200 let a = Gen::<u32>::make();
201} 201 }
202"#), 202 "#,
203 @r###" 203 expect![[r#"
204 75..99 '{ ... }': Gen<T> 204 75..99 '{ ... }': Gen<T>
205 85..93 'loop { }': ! 205 85..93 'loop { }': !
206 90..93 '{ }': () 206 90..93 '{ }': ()
207 113..148 '{ ...e(); }': () 207 113..148 '{ ...e(); }': ()
208 123..124 'a': Gen<u32> 208 123..124 'a': Gen<u32>
209 127..143 'Gen::<...::make': fn make<u32>() -> Gen<u32> 209 127..143 'Gen::<...::make': fn make<u32>() -> Gen<u32>
210 127..145 'Gen::<...make()': Gen<u32> 210 127..145 'Gen::<...make()': Gen<u32>
211 "### 211 "#]],
212 ); 212 );
213} 213}
214 214
215#[test] 215#[test]
216fn infer_associated_method_generics_2_type_params_without_args() { 216fn infer_associated_method_generics_2_type_params_without_args() {
217 assert_snapshot!( 217 check_infer(
218 infer(r#" 218 r#"
219struct Gen<T, U> { 219 struct Gen<T, U> {
220 val: T, 220 val: T,
221 val2: U, 221 val2: U,
222} 222 }
223 223
224impl<T> Gen<u32, T> { 224 impl<T> Gen<u32, T> {
225 pub fn make() -> Gen<u32,T> { 225 pub fn make() -> Gen<u32,T> {
226 loop { } 226 loop { }
227 } 227 }
228} 228 }
229 229
230fn test() { 230 fn test() {
231 let a = Gen::<u32, u64>::make(); 231 let a = Gen::<u32, u64>::make();
232} 232 }
233"#), 233 "#,
234 @r###" 234 expect![[r#"
235 101..125 '{ ... }': Gen<u32, T> 235 101..125 '{ ... }': Gen<u32, T>
236 111..119 'loop { }': ! 236 111..119 'loop { }': !
237 116..119 '{ }': () 237 116..119 '{ }': ()
238 139..179 '{ ...e(); }': () 238 139..179 '{ ...e(); }': ()
239 149..150 'a': Gen<u32, u64> 239 149..150 'a': Gen<u32, u64>
240 153..174 'Gen::<...::make': fn make<u64>() -> Gen<u32, u64> 240 153..174 'Gen::<...::make': fn make<u64>() -> Gen<u32, u64>
241 153..176 'Gen::<...make()': Gen<u32, u64> 241 153..176 'Gen::<...make()': Gen<u32, u64>
242 "### 242 "#]],
243 ); 243 );
244} 244}
245 245
@@ -267,416 +267,416 @@ mod foo {
267#[test] 267#[test]
268fn infer_trait_method_simple() { 268fn infer_trait_method_simple() {
269 // the trait implementation is intentionally incomplete -- it shouldn't matter 269 // the trait implementation is intentionally incomplete -- it shouldn't matter
270 assert_snapshot!( 270 check_infer(
271 infer(r#" 271 r#"
272trait Trait1 { 272 trait Trait1 {
273 fn method(&self) -> u32; 273 fn method(&self) -> u32;
274} 274 }
275struct S1; 275 struct S1;
276impl Trait1 for S1 {} 276 impl Trait1 for S1 {}
277trait Trait2 { 277 trait Trait2 {
278 fn method(&self) -> i128; 278 fn method(&self) -> i128;
279} 279 }
280struct S2; 280 struct S2;
281impl Trait2 for S2 {} 281 impl Trait2 for S2 {}
282fn test() { 282 fn test() {
283 S1.method(); // -> u32 283 S1.method(); // -> u32
284 S2.method(); // -> i128 284 S2.method(); // -> i128
285} 285 }
286"#), 286 "#,
287 @r###" 287 expect![[r#"
288 30..34 'self': &Self 288 30..34 'self': &Self
289 109..113 'self': &Self 289 109..113 'self': &Self
290 169..227 '{ ...i128 }': () 290 169..227 '{ ...i128 }': ()
291 175..177 'S1': S1 291 175..177 'S1': S1
292 175..186 'S1.method()': u32 292 175..186 'S1.method()': u32
293 202..204 'S2': S2 293 202..204 'S2': S2
294 202..213 'S2.method()': i128 294 202..213 'S2.method()': i128
295 "### 295 "#]],
296 ); 296 );
297} 297}
298 298
299#[test] 299#[test]
300fn infer_trait_method_scoped() { 300fn infer_trait_method_scoped() {
301 // the trait implementation is intentionally incomplete -- it shouldn't matter 301 // the trait implementation is intentionally incomplete -- it shouldn't matter
302 assert_snapshot!( 302 check_infer(
303 infer(r#" 303 r#"
304struct S; 304 struct S;
305mod foo { 305 mod foo {
306 pub trait Trait1 { 306 pub trait Trait1 {
307 fn method(&self) -> u32; 307 fn method(&self) -> u32;
308 } 308 }
309 impl Trait1 for super::S {} 309 impl Trait1 for super::S {}
310} 310 }
311mod bar { 311 mod bar {
312 pub trait Trait2 { 312 pub trait Trait2 {
313 fn method(&self) -> i128; 313 fn method(&self) -> i128;
314 } 314 }
315 impl Trait2 for super::S {} 315 impl Trait2 for super::S {}
316} 316 }
317 317
318mod foo_test { 318 mod foo_test {
319 use super::S; 319 use super::S;
320 use super::foo::Trait1; 320 use super::foo::Trait1;
321 fn test() { 321 fn test() {
322 S.method(); // -> u32 322 S.method(); // -> u32
323 } 323 }
324} 324 }
325 325
326mod bar_test { 326 mod bar_test {
327 use super::S; 327 use super::S;
328 use super::bar::Trait2; 328 use super::bar::Trait2;
329 fn test() { 329 fn test() {
330 S.method(); // -> i128 330 S.method(); // -> i128
331 } 331 }
332} 332 }
333"#), 333 "#,
334 @r###" 334 expect![[r#"
335 62..66 'self': &Self 335 62..66 'self': &Self
336 168..172 'self': &Self 336 168..172 'self': &Self
337 299..336 '{ ... }': () 337 299..336 '{ ... }': ()
338 309..310 'S': S 338 309..310 'S': S
339 309..319 'S.method()': u32 339 309..319 'S.method()': u32
340 415..453 '{ ... }': () 340 415..453 '{ ... }': ()
341 425..426 'S': S 341 425..426 'S': S
342 425..435 'S.method()': i128 342 425..435 'S.method()': i128
343 "### 343 "#]],
344 ); 344 );
345} 345}
346 346
347#[test] 347#[test]
348fn infer_trait_method_generic_1() { 348fn infer_trait_method_generic_1() {
349 // the trait implementation is intentionally incomplete -- it shouldn't matter 349 // the trait implementation is intentionally incomplete -- it shouldn't matter
350 assert_snapshot!( 350 check_infer(
351 infer(r#" 351 r#"
352trait Trait<T> { 352 trait Trait<T> {
353 fn method(&self) -> T; 353 fn method(&self) -> T;
354} 354 }
355struct S; 355 struct S;
356impl Trait<u32> for S {} 356 impl Trait<u32> for S {}
357fn test() { 357 fn test() {
358 S.method(); 358 S.method();
359} 359 }
360"#), 360 "#,
361 @r###" 361 expect![[r#"
362 32..36 'self': &Self 362 32..36 'self': &Self
363 91..110 '{ ...d(); }': () 363 91..110 '{ ...d(); }': ()
364 97..98 'S': S 364 97..98 'S': S
365 97..107 'S.method()': u32 365 97..107 'S.method()': u32
366 "### 366 "#]],
367 ); 367 );
368} 368}
369 369
370#[test] 370#[test]
371fn infer_trait_method_generic_more_params() { 371fn infer_trait_method_generic_more_params() {
372 // the trait implementation is intentionally incomplete -- it shouldn't matter 372 // the trait implementation is intentionally incomplete -- it shouldn't matter
373 assert_snapshot!( 373 check_infer(
374 infer(r#" 374 r#"
375trait Trait<T1, T2, T3> { 375 trait Trait<T1, T2, T3> {
376 fn method1(&self) -> (T1, T2, T3); 376 fn method1(&self) -> (T1, T2, T3);
377 fn method2(&self) -> (T3, T2, T1); 377 fn method2(&self) -> (T3, T2, T1);
378} 378 }
379struct S1; 379 struct S1;
380impl Trait<u8, u16, u32> for S1 {} 380 impl Trait<u8, u16, u32> for S1 {}
381struct S2; 381 struct S2;
382impl<T> Trait<i8, i16, T> for S2 {} 382 impl<T> Trait<i8, i16, T> for S2 {}
383fn test() { 383 fn test() {
384 S1.method1(); // u8, u16, u32 384 S1.method1(); // u8, u16, u32
385 S1.method2(); // u32, u16, u8 385 S1.method2(); // u32, u16, u8
386 S2.method1(); // i8, i16, {unknown} 386 S2.method1(); // i8, i16, {unknown}
387 S2.method2(); // {unknown}, i16, i8 387 S2.method2(); // {unknown}, i16, i8
388} 388 }
389"#), 389 "#,
390 @r###" 390 expect![[r#"
391 42..46 'self': &Self 391 42..46 'self': &Self
392 81..85 'self': &Self 392 81..85 'self': &Self
393 209..360 '{ ..., i8 }': () 393 209..360 '{ ..., i8 }': ()
394 215..217 'S1': S1 394 215..217 'S1': S1
395 215..227 'S1.method1()': (u8, u16, u32) 395 215..227 'S1.method1()': (u8, u16, u32)
396 249..251 'S1': S1 396 249..251 'S1': S1
397 249..261 'S1.method2()': (u32, u16, u8) 397 249..261 'S1.method2()': (u32, u16, u8)
398 283..285 'S2': S2 398 283..285 'S2': S2
399 283..295 'S2.method1()': (i8, i16, {unknown}) 399 283..295 'S2.method1()': (i8, i16, {unknown})
400 323..325 'S2': S2 400 323..325 'S2': S2
401 323..335 'S2.method2()': ({unknown}, i16, i8) 401 323..335 'S2.method2()': ({unknown}, i16, i8)
402 "### 402 "#]],
403 ); 403 );
404} 404}
405 405
406#[test] 406#[test]
407fn infer_trait_method_generic_2() { 407fn infer_trait_method_generic_2() {
408 // the trait implementation is intentionally incomplete -- it shouldn't matter 408 // the trait implementation is intentionally incomplete -- it shouldn't matter
409 assert_snapshot!( 409 check_infer(
410 infer(r#" 410 r#"
411trait Trait<T> { 411 trait Trait<T> {
412 fn method(&self) -> T; 412 fn method(&self) -> T;
413} 413 }
414struct S<T>(T); 414 struct S<T>(T);
415impl<U> Trait<U> for S<U> {} 415 impl<U> Trait<U> for S<U> {}
416fn test() { 416 fn test() {
417 S(1u32).method(); 417 S(1u32).method();
418} 418 }
419"#), 419 "#,
420 @r###" 420 expect![[r#"
421 32..36 'self': &Self 421 32..36 'self': &Self
422 101..126 '{ ...d(); }': () 422 101..126 '{ ...d(); }': ()
423 107..108 'S': S<u32>(u32) -> S<u32> 423 107..108 'S': S<u32>(u32) -> S<u32>
424 107..114 'S(1u32)': S<u32> 424 107..114 'S(1u32)': S<u32>
425 107..123 'S(1u32...thod()': u32 425 107..123 'S(1u32...thod()': u32
426 109..113 '1u32': u32 426 109..113 '1u32': u32
427 "### 427 "#]],
428 ); 428 );
429} 429}
430 430
431#[test] 431#[test]
432fn infer_trait_assoc_method() { 432fn infer_trait_assoc_method() {
433 assert_snapshot!( 433 check_infer(
434 infer(r#" 434 r#"
435trait Default { 435 trait Default {
436 fn default() -> Self; 436 fn default() -> Self;
437} 437 }
438struct S; 438 struct S;
439impl Default for S {} 439 impl Default for S {}
440fn test() { 440 fn test() {
441 let s1: S = Default::default(); 441 let s1: S = Default::default();
442 let s2 = S::default(); 442 let s2 = S::default();
443 let s3 = <S as Default>::default(); 443 let s3 = <S as Default>::default();
444} 444 }
445"#), 445 "#,
446 @r###" 446 expect![[r#"
447 86..192 '{ ...t(); }': () 447 86..192 '{ ...t(); }': ()
448 96..98 's1': S 448 96..98 's1': S
449 104..120 'Defaul...efault': fn default<S>() -> S 449 104..120 'Defaul...efault': fn default<S>() -> S
450 104..122 'Defaul...ault()': S 450 104..122 'Defaul...ault()': S
451 132..134 's2': S 451 132..134 's2': S
452 137..147 'S::default': fn default<S>() -> S 452 137..147 'S::default': fn default<S>() -> S
453 137..149 'S::default()': S 453 137..149 'S::default()': S
454 159..161 's3': S 454 159..161 's3': S
455 164..187 '<S as ...efault': fn default<S>() -> S 455 164..187 '<S as ...efault': fn default<S>() -> S
456 164..189 '<S as ...ault()': S 456 164..189 '<S as ...ault()': S
457 "### 457 "#]],
458 ); 458 );
459} 459}
460 460
461#[test] 461#[test]
462fn infer_trait_assoc_method_generics_1() { 462fn infer_trait_assoc_method_generics_1() {
463 assert_snapshot!( 463 check_infer(
464 infer(r#" 464 r#"
465trait Trait<T> { 465 trait Trait<T> {
466 fn make() -> T; 466 fn make() -> T;
467} 467 }
468struct S; 468 struct S;
469impl Trait<u32> for S {} 469 impl Trait<u32> for S {}
470struct G<T>; 470 struct G<T>;
471impl<T> Trait<T> for G<T> {} 471 impl<T> Trait<T> for G<T> {}
472fn test() { 472 fn test() {
473 let a = S::make(); 473 let a = S::make();
474 let b = G::<u64>::make(); 474 let b = G::<u64>::make();
475 let c: f64 = G::make(); 475 let c: f64 = G::make();
476} 476 }
477"#), 477 "#,
478 @r###" 478 expect![[r#"
479 126..210 '{ ...e(); }': () 479 126..210 '{ ...e(); }': ()
480 136..137 'a': u32 480 136..137 'a': u32
481 140..147 'S::make': fn make<S, u32>() -> u32 481 140..147 'S::make': fn make<S, u32>() -> u32
482 140..149 'S::make()': u32 482 140..149 'S::make()': u32
483 159..160 'b': u64 483 159..160 'b': u64
484 163..177 'G::<u64>::make': fn make<G<u64>, u64>() -> u64 484 163..177 'G::<u64>::make': fn make<G<u64>, u64>() -> u64
485 163..179 'G::<u6...make()': u64 485 163..179 'G::<u6...make()': u64
486 189..190 'c': f64 486 189..190 'c': f64
487 198..205 'G::make': fn make<G<f64>, f64>() -> f64 487 198..205 'G::make': fn make<G<f64>, f64>() -> f64
488 198..207 'G::make()': f64 488 198..207 'G::make()': f64
489 "### 489 "#]],
490 ); 490 );
491} 491}
492 492
493#[test] 493#[test]
494fn infer_trait_assoc_method_generics_2() { 494fn infer_trait_assoc_method_generics_2() {
495 assert_snapshot!( 495 check_infer(
496 infer(r#" 496 r#"
497trait Trait<T> { 497 trait Trait<T> {
498 fn make<U>() -> (T, U); 498 fn make<U>() -> (T, U);
499} 499 }
500struct S; 500 struct S;
501impl Trait<u32> for S {} 501 impl Trait<u32> for S {}
502struct G<T>; 502 struct G<T>;
503impl<T> Trait<T> for G<T> {} 503 impl<T> Trait<T> for G<T> {}
504fn test() { 504 fn test() {
505 let a = S::make::<i64>(); 505 let a = S::make::<i64>();
506 let b: (_, i64) = S::make(); 506 let b: (_, i64) = S::make();
507 let c = G::<u32>::make::<i64>(); 507 let c = G::<u32>::make::<i64>();
508 let d: (u32, _) = G::make::<i64>(); 508 let d: (u32, _) = G::make::<i64>();
509 let e: (u32, i64) = G::make(); 509 let e: (u32, i64) = G::make();
510} 510 }
511"#), 511 "#,
512 @r###" 512 expect![[r#"
513 134..312 '{ ...e(); }': () 513 134..312 '{ ...e(); }': ()
514 144..145 'a': (u32, i64) 514 144..145 'a': (u32, i64)
515 148..162 'S::make::<i64>': fn make<S, u32, i64>() -> (u32, i64) 515 148..162 'S::make::<i64>': fn make<S, u32, i64>() -> (u32, i64)
516 148..164 'S::mak...i64>()': (u32, i64) 516 148..164 'S::mak...i64>()': (u32, i64)
517 174..175 'b': (u32, i64) 517 174..175 'b': (u32, i64)
518 188..195 'S::make': fn make<S, u32, i64>() -> (u32, i64) 518 188..195 'S::make': fn make<S, u32, i64>() -> (u32, i64)
519 188..197 'S::make()': (u32, i64) 519 188..197 'S::make()': (u32, i64)
520 207..208 'c': (u32, i64) 520 207..208 'c': (u32, i64)
521 211..232 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64) 521 211..232 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64)
522 211..234 'G::<u3...i64>()': (u32, i64) 522 211..234 'G::<u3...i64>()': (u32, i64)
523 244..245 'd': (u32, i64) 523 244..245 'd': (u32, i64)
524 258..272 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64) 524 258..272 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64)
525 258..274 'G::mak...i64>()': (u32, i64) 525 258..274 'G::mak...i64>()': (u32, i64)
526 284..285 'e': (u32, i64) 526 284..285 'e': (u32, i64)
527 300..307 'G::make': fn make<G<u32>, u32, i64>() -> (u32, i64) 527 300..307 'G::make': fn make<G<u32>, u32, i64>() -> (u32, i64)
528 300..309 'G::make()': (u32, i64) 528 300..309 'G::make()': (u32, i64)
529 "### 529 "#]],
530 ); 530 );
531} 531}
532 532
533#[test] 533#[test]
534fn infer_trait_assoc_method_generics_3() { 534fn infer_trait_assoc_method_generics_3() {
535 assert_snapshot!( 535 check_infer(
536 infer(r#" 536 r#"
537trait Trait<T> { 537 trait Trait<T> {
538 fn make() -> (Self, T); 538 fn make() -> (Self, T);
539} 539 }
540struct S<T>; 540 struct S<T>;
541impl Trait<i64> for S<i32> {} 541 impl Trait<i64> for S<i32> {}
542fn test() { 542 fn test() {
543 let a = S::make(); 543 let a = S::make();
544} 544 }
545"#), 545 "#,
546 @r###" 546 expect![[r#"
547 100..126 '{ ...e(); }': () 547 100..126 '{ ...e(); }': ()
548 110..111 'a': (S<i32>, i64) 548 110..111 'a': (S<i32>, i64)
549 114..121 'S::make': fn make<S<i32>, i64>() -> (S<i32>, i64) 549 114..121 'S::make': fn make<S<i32>, i64>() -> (S<i32>, i64)
550 114..123 'S::make()': (S<i32>, i64) 550 114..123 'S::make()': (S<i32>, i64)
551 "### 551 "#]],
552 ); 552 );
553} 553}
554 554
555#[test] 555#[test]
556fn infer_trait_assoc_method_generics_4() { 556fn infer_trait_assoc_method_generics_4() {
557 assert_snapshot!( 557 check_infer(
558 infer(r#" 558 r#"
559trait Trait<T> { 559 trait Trait<T> {
560 fn make() -> (Self, T); 560 fn make() -> (Self, T);
561} 561 }
562struct S<T>; 562 struct S<T>;
563impl Trait<i64> for S<u64> {} 563 impl Trait<i64> for S<u64> {}
564impl Trait<i32> for S<u32> {} 564 impl Trait<i32> for S<u32> {}
565fn test() { 565 fn test() {
566 let a: (S<u64>, _) = S::make(); 566 let a: (S<u64>, _) = S::make();
567 let b: (_, i32) = S::make(); 567 let b: (_, i32) = S::make();
568} 568 }
569"#), 569 "#,
570 @r###" 570 expect![[r#"
571 130..202 '{ ...e(); }': () 571 130..202 '{ ...e(); }': ()
572 140..141 'a': (S<u64>, i64) 572 140..141 'a': (S<u64>, i64)
573 157..164 'S::make': fn make<S<u64>, i64>() -> (S<u64>, i64) 573 157..164 'S::make': fn make<S<u64>, i64>() -> (S<u64>, i64)
574 157..166 'S::make()': (S<u64>, i64) 574 157..166 'S::make()': (S<u64>, i64)
575 176..177 'b': (S<u32>, i32) 575 176..177 'b': (S<u32>, i32)
576 190..197 'S::make': fn make<S<u32>, i32>() -> (S<u32>, i32) 576 190..197 'S::make': fn make<S<u32>, i32>() -> (S<u32>, i32)
577 190..199 'S::make()': (S<u32>, i32) 577 190..199 'S::make()': (S<u32>, i32)
578 "### 578 "#]],
579 ); 579 );
580} 580}
581 581
582#[test] 582#[test]
583fn infer_trait_assoc_method_generics_5() { 583fn infer_trait_assoc_method_generics_5() {
584 assert_snapshot!( 584 check_infer(
585 infer(r#" 585 r#"
586trait Trait<T> { 586 trait Trait<T> {
587 fn make<U>() -> (Self, T, U); 587 fn make<U>() -> (Self, T, U);
588} 588 }
589struct S<T>; 589 struct S<T>;
590impl Trait<i64> for S<u64> {} 590 impl Trait<i64> for S<u64> {}
591fn test() { 591 fn test() {
592 let a = <S as Trait<i64>>::make::<u8>(); 592 let a = <S as Trait<i64>>::make::<u8>();
593 let b: (S<u64>, _, _) = Trait::<i64>::make::<u8>(); 593 let b: (S<u64>, _, _) = Trait::<i64>::make::<u8>();
594} 594 }
595"#), 595 "#,
596 @r###" 596 expect![[r#"
597 106..210 '{ ...>(); }': () 597 106..210 '{ ...>(); }': ()
598 116..117 'a': (S<u64>, i64, u8) 598 116..117 'a': (S<u64>, i64, u8)
599 120..149 '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8) 599 120..149 '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8)
600 120..151 '<S as ...<u8>()': (S<u64>, i64, u8) 600 120..151 '<S as ...<u8>()': (S<u64>, i64, u8)
601 161..162 'b': (S<u64>, i64, u8) 601 161..162 'b': (S<u64>, i64, u8)
602 181..205 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8) 602 181..205 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8)
603 181..207 'Trait:...<u8>()': (S<u64>, i64, u8) 603 181..207 'Trait:...<u8>()': (S<u64>, i64, u8)
604 "### 604 "#]],
605 ); 605 );
606} 606}
607 607
608#[test] 608#[test]
609fn infer_call_trait_method_on_generic_param_1() { 609fn infer_call_trait_method_on_generic_param_1() {
610 assert_snapshot!( 610 check_infer(
611 infer(r#" 611 r#"
612trait Trait { 612 trait Trait {
613 fn method(&self) -> u32; 613 fn method(&self) -> u32;
614} 614 }
615fn test<T: Trait>(t: T) { 615 fn test<T: Trait>(t: T) {
616 t.method(); 616 t.method();
617} 617 }
618"#), 618 "#,
619 @r###" 619 expect![[r#"
620 29..33 'self': &Self 620 29..33 'self': &Self
621 63..64 't': T 621 63..64 't': T
622 69..88 '{ ...d(); }': () 622 69..88 '{ ...d(); }': ()
623 75..76 't': T 623 75..76 't': T
624 75..85 't.method()': u32 624 75..85 't.method()': u32
625 "### 625 "#]],
626 ); 626 );
627} 627}
628 628
629#[test] 629#[test]
630fn infer_call_trait_method_on_generic_param_2() { 630fn infer_call_trait_method_on_generic_param_2() {
631 assert_snapshot!( 631 check_infer(
632 infer(r#" 632 r#"
633trait Trait<T> { 633 trait Trait<T> {
634 fn method(&self) -> T; 634 fn method(&self) -> T;
635} 635 }
636fn test<U, T: Trait<U>>(t: T) { 636 fn test<U, T: Trait<U>>(t: T) {
637 t.method(); 637 t.method();
638} 638 }
639"#), 639 "#,
640 @r###" 640 expect![[r#"
641 32..36 'self': &Self 641 32..36 'self': &Self
642 70..71 't': T 642 70..71 't': T
643 76..95 '{ ...d(); }': () 643 76..95 '{ ...d(); }': ()
644 82..83 't': T 644 82..83 't': T
645 82..92 't.method()': U 645 82..92 't.method()': U
646 "### 646 "#]],
647 ); 647 );
648} 648}
649 649
650#[test] 650#[test]
651fn infer_with_multiple_trait_impls() { 651fn infer_with_multiple_trait_impls() {
652 assert_snapshot!( 652 check_infer(
653 infer(r#" 653 r#"
654trait Into<T> { 654 trait Into<T> {
655 fn into(self) -> T; 655 fn into(self) -> T;
656} 656 }
657struct S; 657 struct S;
658impl Into<u32> for S {} 658 impl Into<u32> for S {}
659impl Into<u64> for S {} 659 impl Into<u64> for S {}
660fn test() { 660 fn test() {
661 let x: u32 = S.into(); 661 let x: u32 = S.into();
662 let y: u64 = S.into(); 662 let y: u64 = S.into();
663 let z = Into::<u64>::into(S); 663 let z = Into::<u64>::into(S);
664} 664 }
665"#), 665 "#,
666 @r###" 666 expect![[r#"
667 28..32 'self': Self 667 28..32 'self': Self
668 110..201 '{ ...(S); }': () 668 110..201 '{ ...(S); }': ()
669 120..121 'x': u32 669 120..121 'x': u32
670 129..130 'S': S 670 129..130 'S': S
671 129..137 'S.into()': u32 671 129..137 'S.into()': u32
672 147..148 'y': u64 672 147..148 'y': u64
673 156..157 'S': S 673 156..157 'S': S
674 156..164 'S.into()': u64 674 156..164 'S.into()': u64
675 174..175 'z': u64 675 174..175 'z': u64
676 178..195 'Into::...::into': fn into<S, u64>(S) -> u64 676 178..195 'Into::...::into': fn into<S, u64>(S) -> u64
677 178..198 'Into::...nto(S)': u64 677 178..198 'Into::...nto(S)': u64
678 196..197 'S': S 678 196..197 'S': S
679 "### 679 "#]],
680 ); 680 );
681} 681}
682 682
@@ -1023,31 +1023,31 @@ fn test() { (S {}).method(); }
1023 1023
1024#[test] 1024#[test]
1025fn dyn_trait_super_trait_not_in_scope() { 1025fn dyn_trait_super_trait_not_in_scope() {
1026 assert_snapshot!( 1026 check_infer(
1027 infer(r#" 1027 r#"
1028mod m { 1028 mod m {
1029 pub trait SuperTrait { 1029 pub trait SuperTrait {
1030 fn foo(&self) -> u32 { 0 } 1030 fn foo(&self) -> u32 { 0 }
1031 } 1031 }
1032} 1032 }
1033trait Trait: m::SuperTrait {} 1033 trait Trait: m::SuperTrait {}
1034 1034
1035struct S; 1035 struct S;
1036impl m::SuperTrait for S {} 1036 impl m::SuperTrait for S {}
1037impl Trait for S {} 1037 impl Trait for S {}
1038 1038
1039fn test(d: &dyn Trait) { 1039 fn test(d: &dyn Trait) {
1040 d.foo(); 1040 d.foo();
1041} 1041 }
1042"#), 1042 "#,
1043 @r###" 1043 expect![[r#"
1044 51..55 'self': &Self 1044 51..55 'self': &Self
1045 64..69 '{ 0 }': u32 1045 64..69 '{ 0 }': u32
1046 66..67 '0': u32 1046 66..67 '0': u32
1047 176..177 'd': &dyn Trait 1047 176..177 'd': &dyn Trait
1048 191..207 '{ ...o(); }': () 1048 191..207 '{ ...o(); }': ()
1049 197..198 'd': &dyn Trait 1049 197..198 'd': &dyn Trait
1050 197..204 'd.foo()': u32 1050 197..204 'd.foo()': u32
1051 "### 1051 "#]],
1052 ); 1052 );
1053} 1053}
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs
index f937426bd..39fabf7eb 100644
--- a/crates/ra_hir_ty/src/tests/patterns.rs
+++ b/crates/ra_hir_ty/src/tests/patterns.rs
@@ -1,561 +1,561 @@
1use insta::assert_snapshot; 1use expect::expect;
2use test_utils::mark; 2use test_utils::mark;
3 3
4use super::{infer, infer_with_mismatches}; 4use super::{check_infer, check_infer_with_mismatches};
5 5
6#[test] 6#[test]
7fn infer_pattern() { 7fn infer_pattern() {
8 assert_snapshot!( 8 check_infer(
9 infer(r#" 9 r#"
10fn test(x: &i32) { 10 fn test(x: &i32) {
11 let y = x; 11 let y = x;
12 let &z = x; 12 let &z = x;
13 let a = z; 13 let a = z;
14 let (c, d) = (1, "hello"); 14 let (c, d) = (1, "hello");
15 15
16 for (e, f) in some_iter { 16 for (e, f) in some_iter {
17 let g = e; 17 let g = e;
18 } 18 }
19 19
20 if let [val] = opt { 20 if let [val] = opt {
21 let h = val; 21 let h = val;
22 } 22 }
23 23
24 let lambda = |a: u64, b, c: i32| { a + b; c }; 24 let lambda = |a: u64, b, c: i32| { a + b; c };
25 25
26 let ref ref_to_x = x; 26 let ref ref_to_x = x;
27 let mut mut_x = x; 27 let mut mut_x = x;
28 let ref mut mut_ref_to_x = x; 28 let ref mut mut_ref_to_x = x;
29 let k = mut_ref_to_x; 29 let k = mut_ref_to_x;
30} 30 }
31"#), 31 "#,
32 @r###" 32 expect![[r#"
33 8..9 'x': &i32 33 8..9 'x': &i32
34 17..368 '{ ...o_x; }': () 34 17..368 '{ ...o_x; }': ()
35 27..28 'y': &i32 35 27..28 'y': &i32
36 31..32 'x': &i32 36 31..32 'x': &i32
37 42..44 '&z': &i32 37 42..44 '&z': &i32
38 43..44 'z': i32 38 43..44 'z': i32
39 47..48 'x': &i32 39 47..48 'x': &i32
40 58..59 'a': i32 40 58..59 'a': i32
41 62..63 'z': i32 41 62..63 'z': i32
42 73..79 '(c, d)': (i32, &str) 42 73..79 '(c, d)': (i32, &str)
43 74..75 'c': i32 43 74..75 'c': i32
44 77..78 'd': &str 44 77..78 'd': &str
45 82..94 '(1, "hello")': (i32, &str) 45 82..94 '(1, "hello")': (i32, &str)
46 83..84 '1': i32 46 83..84 '1': i32
47 86..93 '"hello"': &str 47 86..93 '"hello"': &str
48 101..151 'for (e... }': () 48 101..151 'for (e... }': ()
49 105..111 '(e, f)': ({unknown}, {unknown}) 49 105..111 '(e, f)': ({unknown}, {unknown})
50 106..107 'e': {unknown} 50 106..107 'e': {unknown}
51 109..110 'f': {unknown} 51 109..110 'f': {unknown}
52 115..124 'some_iter': {unknown} 52 115..124 'some_iter': {unknown}
53 125..151 '{ ... }': () 53 125..151 '{ ... }': ()
54 139..140 'g': {unknown} 54 139..140 'g': {unknown}
55 143..144 'e': {unknown} 55 143..144 'e': {unknown}
56 157..204 'if let... }': () 56 157..204 'if let... }': ()
57 164..169 '[val]': [{unknown}] 57 164..169 '[val]': [{unknown}]
58 165..168 'val': {unknown} 58 165..168 'val': {unknown}
59 172..175 'opt': [{unknown}] 59 172..175 'opt': [{unknown}]
60 176..204 '{ ... }': () 60 176..204 '{ ... }': ()
61 190..191 'h': {unknown} 61 190..191 'h': {unknown}
62 194..197 'val': {unknown} 62 194..197 'val': {unknown}
63 214..220 'lambda': |u64, u64, i32| -> i32 63 214..220 'lambda': |u64, u64, i32| -> i32
64 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32 64 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32
65 224..225 'a': u64 65 224..225 'a': u64
66 232..233 'b': u64 66 232..233 'b': u64
67 235..236 'c': i32 67 235..236 'c': i32
68 243..255 '{ a + b; c }': i32 68 243..255 '{ a + b; c }': i32
69 245..246 'a': u64 69 245..246 'a': u64
70 245..250 'a + b': u64 70 245..250 'a + b': u64
71 249..250 'b': u64 71 249..250 'b': u64
72 252..253 'c': i32 72 252..253 'c': i32
73 266..278 'ref ref_to_x': &&i32 73 266..278 'ref ref_to_x': &&i32
74 281..282 'x': &i32 74 281..282 'x': &i32
75 292..301 'mut mut_x': &i32 75 292..301 'mut mut_x': &i32
76 304..305 'x': &i32 76 304..305 'x': &i32
77 315..335 'ref mu...f_to_x': &mut &i32 77 315..335 'ref mu...f_to_x': &mut &i32
78 338..339 'x': &i32 78 338..339 'x': &i32
79 349..350 'k': &mut &i32 79 349..350 'k': &mut &i32
80 353..365 'mut_ref_to_x': &mut &i32 80 353..365 'mut_ref_to_x': &mut &i32
81 "### 81 "#]],
82 ); 82 );
83} 83}
84 84
85#[test] 85#[test]
86fn infer_literal_pattern() { 86fn infer_literal_pattern() {
87 assert_snapshot!( 87 check_infer_with_mismatches(
88 infer_with_mismatches(r#" 88 r#"
89fn any<T>() -> T { loop {} } 89 fn any<T>() -> T { loop {} }
90fn test(x: &i32) { 90 fn test(x: &i32) {
91 if let "foo" = any() {} 91 if let "foo" = any() {}
92 if let 1 = any() {} 92 if let 1 = any() {}
93 if let 1u32 = any() {} 93 if let 1u32 = any() {}
94 if let 1f32 = any() {} 94 if let 1f32 = any() {}
95 if let 1.0 = any() {} 95 if let 1.0 = any() {}
96 if let true = any() {} 96 if let true = any() {}
97} 97 }
98"#, true), 98 "#,
99 @r###" 99 expect![[r#"
100 17..28 '{ loop {} }': T 100 17..28 '{ loop {} }': T
101 19..26 'loop {}': ! 101 19..26 'loop {}': !
102 24..26 '{}': () 102 24..26 '{}': ()
103 37..38 'x': &i32 103 37..38 'x': &i32
104 46..208 '{ ...) {} }': () 104 46..208 '{ ...) {} }': ()
105 52..75 'if let...y() {}': () 105 52..75 'if let...y() {}': ()
106 59..64 '"foo"': &str 106 59..64 '"foo"': &str
107 59..64 '"foo"': &str 107 59..64 '"foo"': &str
108 67..70 'any': fn any<&str>() -> &str 108 67..70 'any': fn any<&str>() -> &str
109 67..72 'any()': &str 109 67..72 'any()': &str
110 73..75 '{}': () 110 73..75 '{}': ()
111 80..99 'if let...y() {}': () 111 80..99 'if let...y() {}': ()
112 87..88 '1': i32 112 87..88 '1': i32
113 87..88 '1': i32 113 87..88 '1': i32
114 91..94 'any': fn any<i32>() -> i32 114 91..94 'any': fn any<i32>() -> i32
115 91..96 'any()': i32 115 91..96 'any()': i32
116 97..99 '{}': () 116 97..99 '{}': ()
117 104..126 'if let...y() {}': () 117 104..126 'if let...y() {}': ()
118 111..115 '1u32': u32 118 111..115 '1u32': u32
119 111..115 '1u32': u32 119 111..115 '1u32': u32
120 118..121 'any': fn any<u32>() -> u32 120 118..121 'any': fn any<u32>() -> u32
121 118..123 'any()': u32 121 118..123 'any()': u32
122 124..126 '{}': () 122 124..126 '{}': ()
123 131..153 'if let...y() {}': () 123 131..153 'if let...y() {}': ()
124 138..142 '1f32': f32 124 138..142 '1f32': f32
125 138..142 '1f32': f32 125 138..142 '1f32': f32
126 145..148 'any': fn any<f32>() -> f32 126 145..148 'any': fn any<f32>() -> f32
127 145..150 'any()': f32 127 145..150 'any()': f32
128 151..153 '{}': () 128 151..153 '{}': ()
129 158..179 'if let...y() {}': () 129 158..179 'if let...y() {}': ()
130 165..168 '1.0': f64 130 165..168 '1.0': f64
131 165..168 '1.0': f64 131 165..168 '1.0': f64
132 171..174 'any': fn any<f64>() -> f64 132 171..174 'any': fn any<f64>() -> f64
133 171..176 'any()': f64 133 171..176 'any()': f64
134 177..179 '{}': () 134 177..179 '{}': ()
135 184..206 'if let...y() {}': () 135 184..206 'if let...y() {}': ()
136 191..195 'true': bool 136 191..195 'true': bool
137 191..195 'true': bool 137 191..195 'true': bool
138 198..201 'any': fn any<bool>() -> bool 138 198..201 'any': fn any<bool>() -> bool
139 198..203 'any()': bool 139 198..203 'any()': bool
140 204..206 '{}': () 140 204..206 '{}': ()
141 "### 141 "#]],
142 ); 142 );
143} 143}
144 144
145#[test] 145#[test]
146fn infer_range_pattern() { 146fn infer_range_pattern() {
147 assert_snapshot!( 147 check_infer_with_mismatches(
148 infer_with_mismatches(r#" 148 r#"
149fn test(x: &i32) { 149 fn test(x: &i32) {
150 if let 1..76 = 2u32 {} 150 if let 1..76 = 2u32 {}
151 if let 1..=76 = 2u32 {} 151 if let 1..=76 = 2u32 {}
152} 152 }
153"#, true), 153 "#,
154 @r###" 154 expect![[r#"
155 8..9 'x': &i32 155 8..9 'x': &i32
156 17..75 '{ ...2 {} }': () 156 17..75 '{ ...2 {} }': ()
157 23..45 'if let...u32 {}': () 157 23..45 'if let...u32 {}': ()
158 30..35 '1..76': u32 158 30..35 '1..76': u32
159 38..42 '2u32': u32 159 38..42 '2u32': u32
160 43..45 '{}': () 160 43..45 '{}': ()
161 50..73 'if let...u32 {}': () 161 50..73 'if let...u32 {}': ()
162 57..63 '1..=76': u32 162 57..63 '1..=76': u32
163 66..70 '2u32': u32 163 66..70 '2u32': u32
164 71..73 '{}': () 164 71..73 '{}': ()
165 "### 165 "#]],
166 ); 166 );
167} 167}
168 168
169#[test] 169#[test]
170fn infer_pattern_match_ergonomics() { 170fn infer_pattern_match_ergonomics() {
171 assert_snapshot!( 171 check_infer(
172 infer(r#" 172 r#"
173struct A<T>(T); 173 struct A<T>(T);
174 174
175fn test() { 175 fn test() {
176 let A(n) = &A(1); 176 let A(n) = &A(1);
177 let A(n) = &mut A(1); 177 let A(n) = &mut A(1);
178} 178 }
179"#), 179 "#,
180 @r###" 180 expect![[r#"
181 27..78 '{ ...(1); }': () 181 27..78 '{ ...(1); }': ()
182 37..41 'A(n)': A<i32> 182 37..41 'A(n)': A<i32>
183 39..40 'n': &i32 183 39..40 'n': &i32
184 44..49 '&A(1)': &A<i32> 184 44..49 '&A(1)': &A<i32>
185 45..46 'A': A<i32>(i32) -> A<i32> 185 45..46 'A': A<i32>(i32) -> A<i32>
186 45..49 'A(1)': A<i32> 186 45..49 'A(1)': A<i32>
187 47..48 '1': i32 187 47..48 '1': i32
188 59..63 'A(n)': A<i32> 188 59..63 'A(n)': A<i32>
189 61..62 'n': &mut i32 189 61..62 'n': &mut i32
190 66..75 '&mut A(1)': &mut A<i32> 190 66..75 '&mut A(1)': &mut A<i32>
191 71..72 'A': A<i32>(i32) -> A<i32> 191 71..72 'A': A<i32>(i32) -> A<i32>
192 71..75 'A(1)': A<i32> 192 71..75 'A(1)': A<i32>
193 73..74 '1': i32 193 73..74 '1': i32
194 "### 194 "#]],
195 ); 195 );
196} 196}
197 197
198#[test] 198#[test]
199fn infer_pattern_match_ergonomics_ref() { 199fn infer_pattern_match_ergonomics_ref() {
200 mark::check!(match_ergonomics_ref); 200 mark::check!(match_ergonomics_ref);
201 assert_snapshot!( 201 check_infer(
202 infer(r#" 202 r#"
203fn test() { 203 fn test() {
204 let v = &(1, &2); 204 let v = &(1, &2);
205 let (_, &w) = v; 205 let (_, &w) = v;
206} 206 }
207"#), 207 "#,
208 @r###" 208 expect![[r#"
209 10..56 '{ ...= v; }': () 209 10..56 '{ ...= v; }': ()
210 20..21 'v': &(i32, &i32) 210 20..21 'v': &(i32, &i32)
211 24..32 '&(1, &2)': &(i32, &i32) 211 24..32 '&(1, &2)': &(i32, &i32)
212 25..32 '(1, &2)': (i32, &i32) 212 25..32 '(1, &2)': (i32, &i32)
213 26..27 '1': i32 213 26..27 '1': i32
214 29..31 '&2': &i32 214 29..31 '&2': &i32
215 30..31 '2': i32 215 30..31 '2': i32
216 42..49 '(_, &w)': (i32, &i32) 216 42..49 '(_, &w)': (i32, &i32)
217 43..44 '_': i32 217 43..44 '_': i32
218 46..48 '&w': &i32 218 46..48 '&w': &i32
219 47..48 'w': i32 219 47..48 'w': i32
220 52..53 'v': &(i32, &i32) 220 52..53 'v': &(i32, &i32)
221 "### 221 "#]],
222 ); 222 );
223} 223}
224 224
225#[test] 225#[test]
226fn infer_pattern_match_slice() { 226fn infer_pattern_match_slice() {
227 assert_snapshot!( 227 check_infer(
228 infer(r#" 228 r#"
229fn test() { 229 fn test() {
230 let slice: &[f64] = &[0.0]; 230 let slice: &[f64] = &[0.0];
231 match slice { 231 match slice {
232 &[] => {}, 232 &[] => {},
233 &[a] => { 233 &[a] => {
234 a; 234 a;
235 }, 235 },
236 &[b, c] => { 236 &[b, c] => {
237 b; 237 b;
238 c; 238 c;
239 }
240 _ => {}
241 }
239 } 242 }
240 _ => {} 243 "#,
241 } 244 expect![[r#"
242} 245 10..209 '{ ... } }': ()
243"#), 246 20..25 'slice': &[f64]
244 @r###" 247 36..42 '&[0.0]': &[f64; _]
245 10..209 '{ ... } }': () 248 37..42 '[0.0]': [f64; _]
246 20..25 'slice': &[f64] 249 38..41 '0.0': f64
247 36..42 '&[0.0]': &[f64; _] 250 48..207 'match ... }': ()
248 37..42 '[0.0]': [f64; _] 251 54..59 'slice': &[f64]
249 38..41 '0.0': f64 252 70..73 '&[]': &[f64]
250 48..207 'match ... }': () 253 71..73 '[]': [f64]
251 54..59 'slice': &[f64] 254 77..79 '{}': ()
252 70..73 '&[]': &[f64] 255 89..93 '&[a]': &[f64]
253 71..73 '[]': [f64] 256 90..93 '[a]': [f64]
254 77..79 '{}': () 257 91..92 'a': f64
255 89..93 '&[a]': &[f64] 258 97..123 '{ ... }': ()
256 90..93 '[a]': [f64] 259 111..112 'a': f64
257 91..92 'a': f64 260 133..140 '&[b, c]': &[f64]
258 97..123 '{ ... }': () 261 134..140 '[b, c]': [f64]
259 111..112 'a': f64 262 135..136 'b': f64
260 133..140 '&[b, c]': &[f64] 263 138..139 'c': f64
261 134..140 '[b, c]': [f64] 264 144..185 '{ ... }': ()
262 135..136 'b': f64 265 158..159 'b': f64
263 138..139 'c': f64 266 173..174 'c': f64
264 144..185 '{ ... }': () 267 194..195 '_': &[f64]
265 158..159 'b': f64 268 199..201 '{}': ()
266 173..174 'c': f64 269 "#]],
267 194..195 '_': &[f64]
268 199..201 '{}': ()
269 "###
270 ); 270 );
271} 271}
272 272
273#[test] 273#[test]
274fn infer_pattern_match_string_literal() { 274fn infer_pattern_match_string_literal() {
275 assert_snapshot!( 275 check_infer_with_mismatches(
276 infer_with_mismatches(r#" 276 r#"
277fn test() { 277 fn test() {
278 let s: &str = "hello"; 278 let s: &str = "hello";
279 match s { 279 match s {
280 "hello" => {} 280 "hello" => {}
281 _ => {} 281 _ => {}
282 } 282 }
283} 283 }
284"#, true), 284 "#,
285 @r###" 285 expect![[r#"
286 10..98 '{ ... } }': () 286 10..98 '{ ... } }': ()
287 20..21 's': &str 287 20..21 's': &str
288 30..37 '"hello"': &str 288 30..37 '"hello"': &str
289 43..96 'match ... }': () 289 43..96 'match ... }': ()
290 49..50 's': &str 290 49..50 's': &str
291 61..68 '"hello"': &str 291 61..68 '"hello"': &str
292 61..68 '"hello"': &str 292 61..68 '"hello"': &str
293 72..74 '{}': () 293 72..74 '{}': ()
294 83..84 '_': &str 294 83..84 '_': &str
295 88..90 '{}': () 295 88..90 '{}': ()
296 "### 296 "#]],
297 ); 297 );
298} 298}
299 299
300#[test] 300#[test]
301fn infer_pattern_match_or() { 301fn infer_pattern_match_or() {
302 assert_snapshot!( 302 check_infer_with_mismatches(
303 infer_with_mismatches(r#" 303 r#"
304fn test() { 304 fn test() {
305 let s: &str = "hello"; 305 let s: &str = "hello";
306 match s { 306 match s {
307 "hello" | "world" => {} 307 "hello" | "world" => {}
308 _ => {} 308 _ => {}
309 } 309 }
310} 310 }
311"#, true), 311 "#,
312 @r###" 312 expect![[r#"
313 10..108 '{ ... } }': () 313 10..108 '{ ... } }': ()
314 20..21 's': &str 314 20..21 's': &str
315 30..37 '"hello"': &str 315 30..37 '"hello"': &str
316 43..106 'match ... }': () 316 43..106 'match ... }': ()
317 49..50 's': &str 317 49..50 's': &str
318 61..68 '"hello"': &str 318 61..68 '"hello"': &str
319 61..68 '"hello"': &str 319 61..68 '"hello"': &str
320 61..78 '"hello...world"': &str 320 61..78 '"hello...world"': &str
321 71..78 '"world"': &str 321 71..78 '"world"': &str
322 71..78 '"world"': &str 322 71..78 '"world"': &str
323 82..84 '{}': () 323 82..84 '{}': ()
324 93..94 '_': &str 324 93..94 '_': &str
325 98..100 '{}': () 325 98..100 '{}': ()
326 "### 326 "#]],
327 ); 327 );
328} 328}
329 329
330#[test] 330#[test]
331fn infer_pattern_match_arr() { 331fn infer_pattern_match_arr() {
332 assert_snapshot!( 332 check_infer(
333 infer(r#" 333 r#"
334fn test() { 334 fn test() {
335 let arr: [f64; 2] = [0.0, 1.0]; 335 let arr: [f64; 2] = [0.0, 1.0];
336 match arr { 336 match arr {
337 [1.0, a] => { 337 [1.0, a] => {
338 a; 338 a;
339 }, 339 },
340 [b, c] => { 340 [b, c] => {
341 b; 341 b;
342 c; 342 c;
343 }
344 }
343 } 345 }
344 } 346 "#,
345} 347 expect![[r#"
346"#), 348 10..179 '{ ... } }': ()
347 @r###" 349 20..23 'arr': [f64; _]
348 10..179 '{ ... } }': () 350 36..46 '[0.0, 1.0]': [f64; _]
349 20..23 'arr': [f64; _] 351 37..40 '0.0': f64
350 36..46 '[0.0, 1.0]': [f64; _] 352 42..45 '1.0': f64
351 37..40 '0.0': f64 353 52..177 'match ... }': ()
352 42..45 '1.0': f64 354 58..61 'arr': [f64; _]
353 52..177 'match ... }': () 355 72..80 '[1.0, a]': [f64; _]
354 58..61 'arr': [f64; _] 356 73..76 '1.0': f64
355 72..80 '[1.0, a]': [f64; _] 357 73..76 '1.0': f64
356 73..76 '1.0': f64 358 78..79 'a': f64
357 73..76 '1.0': f64 359 84..110 '{ ... }': ()
358 78..79 'a': f64 360 98..99 'a': f64
359 84..110 '{ ... }': () 361 120..126 '[b, c]': [f64; _]
360 98..99 'a': f64 362 121..122 'b': f64
361 120..126 '[b, c]': [f64; _] 363 124..125 'c': f64
362 121..122 'b': f64 364 130..171 '{ ... }': ()
363 124..125 'c': f64 365 144..145 'b': f64
364 130..171 '{ ... }': () 366 159..160 'c': f64
365 144..145 'b': f64 367 "#]],
366 159..160 'c': f64
367 "###
368 ); 368 );
369} 369}
370 370
371#[test] 371#[test]
372fn infer_adt_pattern() { 372fn infer_adt_pattern() {
373 assert_snapshot!( 373 check_infer(
374 infer(r#" 374 r#"
375enum E { 375 enum E {
376 A { x: usize }, 376 A { x: usize },
377 B 377 B
378} 378 }
379 379
380struct S(u32, E); 380 struct S(u32, E);
381 381
382fn test() { 382 fn test() {
383 let e = E::A { x: 3 }; 383 let e = E::A { x: 3 };
384 384
385 let S(y, z) = foo; 385 let S(y, z) = foo;
386 let E::A { x: new_var } = e; 386 let E::A { x: new_var } = e;
387 387
388 match e { 388 match e {
389 E::A { x } => x, 389 E::A { x } => x,
390 E::B if foo => 1, 390 E::B if foo => 1,
391 E::B => 10, 391 E::B => 10,
392 }; 392 };
393 393
394 let ref d @ E::A { .. } = e; 394 let ref d @ E::A { .. } = e;
395 d; 395 d;
396} 396 }
397"#), 397 "#,
398 @r###" 398 expect![[r#"
399 67..288 '{ ... d; }': () 399 67..288 '{ ... d; }': ()
400 77..78 'e': E 400 77..78 'e': E
401 81..94 'E::A { x: 3 }': E 401 81..94 'E::A { x: 3 }': E
402 91..92 '3': usize 402 91..92 '3': usize
403 105..112 'S(y, z)': S 403 105..112 'S(y, z)': S
404 107..108 'y': u32 404 107..108 'y': u32
405 110..111 'z': E 405 110..111 'z': E
406 115..118 'foo': S 406 115..118 'foo': S
407 128..147 'E::A {..._var }': E 407 128..147 'E::A {..._var }': E
408 138..145 'new_var': usize 408 138..145 'new_var': usize
409 150..151 'e': E 409 150..151 'e': E
410 158..244 'match ... }': usize 410 158..244 'match ... }': usize
411 164..165 'e': E 411 164..165 'e': E
412 176..186 'E::A { x }': E 412 176..186 'E::A { x }': E
413 183..184 'x': usize 413 183..184 'x': usize
414 190..191 'x': usize 414 190..191 'x': usize
415 201..205 'E::B': E 415 201..205 'E::B': E
416 209..212 'foo': bool 416 209..212 'foo': bool
417 216..217 '1': usize 417 216..217 '1': usize
418 227..231 'E::B': E 418 227..231 'E::B': E
419 235..237 '10': usize 419 235..237 '10': usize
420 255..274 'ref d ...{ .. }': &E 420 255..274 'ref d ...{ .. }': &E
421 263..274 'E::A { .. }': E 421 263..274 'E::A { .. }': E
422 277..278 'e': E 422 277..278 'e': E
423 284..285 'd': &E 423 284..285 'd': &E
424 "### 424 "#]],
425 ); 425 );
426} 426}
427 427
428#[test] 428#[test]
429fn enum_variant_through_self_in_pattern() { 429fn enum_variant_through_self_in_pattern() {
430 assert_snapshot!( 430 check_infer(
431 infer(r#" 431 r#"
432enum E { 432 enum E {
433 A { x: usize }, 433 A { x: usize },
434 B(usize), 434 B(usize),
435 C 435 C
436} 436 }
437 437
438impl E { 438 impl E {
439 fn test() { 439 fn test() {
440 match (loop {}) { 440 match (loop {}) {
441 Self::A { x } => { x; }, 441 Self::A { x } => { x; },
442 Self::B(x) => { x; }, 442 Self::B(x) => { x; },
443 Self::C => {}, 443 Self::C => {},
444 }; 444 };
445 } 445 }
446} 446 }
447"#), 447 "#,
448 @r###" 448 expect![[r#"
449 75..217 '{ ... }': () 449 75..217 '{ ... }': ()
450 85..210 'match ... }': () 450 85..210 'match ... }': ()
451 92..99 'loop {}': ! 451 92..99 'loop {}': !
452 97..99 '{}': () 452 97..99 '{}': ()
453 115..128 'Self::A { x }': E 453 115..128 'Self::A { x }': E
454 125..126 'x': usize 454 125..126 'x': usize
455 132..138 '{ x; }': () 455 132..138 '{ x; }': ()
456 134..135 'x': usize 456 134..135 'x': usize
457 152..162 'Self::B(x)': E 457 152..162 'Self::B(x)': E
458 160..161 'x': usize 458 160..161 'x': usize
459 166..172 '{ x; }': () 459 166..172 '{ x; }': ()
460 168..169 'x': usize 460 168..169 'x': usize
461 186..193 'Self::C': E 461 186..193 'Self::C': E
462 197..199 '{}': () 462 197..199 '{}': ()
463 "### 463 "#]],
464 ); 464 );
465} 465}
466 466
467#[test] 467#[test]
468fn infer_generics_in_patterns() { 468fn infer_generics_in_patterns() {
469 assert_snapshot!( 469 check_infer(
470 infer(r#" 470 r#"
471struct A<T> { 471 struct A<T> {
472 x: T, 472 x: T,
473} 473 }
474 474
475enum Option<T> { 475 enum Option<T> {
476 Some(T), 476 Some(T),
477 None, 477 None,
478} 478 }
479 479
480fn test(a1: A<u32>, o: Option<u64>) { 480 fn test(a1: A<u32>, o: Option<u64>) {
481 let A { x: x2 } = a1; 481 let A { x: x2 } = a1;
482 let A::<i64> { x: x3 } = A { x: 1 }; 482 let A::<i64> { x: x3 } = A { x: 1 };
483 match o { 483 match o {
484 Option::Some(t) => t, 484 Option::Some(t) => t,
485 _ => 1, 485 _ => 1,
486 }; 486 };
487} 487 }
488"#), 488 "#,
489 @r###" 489 expect![[r#"
490 78..80 'a1': A<u32> 490 78..80 'a1': A<u32>
491 90..91 'o': Option<u64> 491 90..91 'o': Option<u64>
492 106..243 '{ ... }; }': () 492 106..243 '{ ... }; }': ()
493 116..127 'A { x: x2 }': A<u32> 493 116..127 'A { x: x2 }': A<u32>
494 123..125 'x2': u32 494 123..125 'x2': u32
495 130..132 'a1': A<u32> 495 130..132 'a1': A<u32>
496 142..160 'A::<i6...: x3 }': A<i64> 496 142..160 'A::<i6...: x3 }': A<i64>
497 156..158 'x3': i64 497 156..158 'x3': i64
498 163..173 'A { x: 1 }': A<i64> 498 163..173 'A { x: 1 }': A<i64>
499 170..171 '1': i64 499 170..171 '1': i64
500 179..240 'match ... }': u64 500 179..240 'match ... }': u64
501 185..186 'o': Option<u64> 501 185..186 'o': Option<u64>
502 197..212 'Option::Some(t)': Option<u64> 502 197..212 'Option::Some(t)': Option<u64>
503 210..211 't': u64 503 210..211 't': u64
504 216..217 't': u64 504 216..217 't': u64
505 227..228 '_': Option<u64> 505 227..228 '_': Option<u64>
506 232..233 '1': u64 506 232..233 '1': u64
507 "### 507 "#]],
508 ); 508 );
509} 509}
510 510
511#[test] 511#[test]
512fn infer_const_pattern() { 512fn infer_const_pattern() {
513 assert_snapshot!( 513 check_infer_with_mismatches(
514 infer_with_mismatches(r#" 514 r#"
515enum Option<T> { None } 515 enum Option<T> { None }
516use Option::None; 516 use Option::None;
517struct Foo; 517 struct Foo;
518const Bar: usize = 1; 518 const Bar: usize = 1;
519 519
520fn test() { 520 fn test() {
521 let a: Option<u32> = None; 521 let a: Option<u32> = None;
522 let b: Option<i64> = match a { 522 let b: Option<i64> = match a {
523 None => None, 523 None => None,
524 }; 524 };
525 let _: () = match () { Foo => Foo }; // Expected mismatch 525 let _: () = match () { Foo => Foo }; // Expected mismatch
526 let _: () = match () { Bar => Bar }; // Expected mismatch 526 let _: () = match () { Bar => Bar }; // Expected mismatch
527} 527 }
528"#, true), 528 "#,
529 @r###" 529 expect![[r#"
530 73..74 '1': usize 530 73..74 '1': usize
531 87..309 '{ ...atch }': () 531 87..309 '{ ...atch }': ()
532 97..98 'a': Option<u32> 532 97..98 'a': Option<u32>
533 114..118 'None': Option<u32> 533 114..118 'None': Option<u32>
534 128..129 'b': Option<i64> 534 128..129 'b': Option<i64>
535 145..182 'match ... }': Option<i64> 535 145..182 'match ... }': Option<i64>
536 151..152 'a': Option<u32> 536 151..152 'a': Option<u32>
537 163..167 'None': Option<u32> 537 163..167 'None': Option<u32>
538 171..175 'None': Option<i64> 538 171..175 'None': Option<i64>
539 192..193 '_': () 539 192..193 '_': ()
540 200..223 'match ... Foo }': Foo 540 200..223 'match ... Foo }': Foo
541 206..208 '()': () 541 206..208 '()': ()
542 211..214 'Foo': Foo 542 211..214 'Foo': Foo
543 218..221 'Foo': Foo 543 218..221 'Foo': Foo
544 254..255 '_': () 544 254..255 '_': ()
545 262..285 'match ... Bar }': usize 545 262..285 'match ... Bar }': usize
546 268..270 '()': () 546 268..270 '()': ()
547 273..276 'Bar': usize 547 273..276 'Bar': usize
548 280..283 'Bar': usize 548 280..283 'Bar': usize
549 200..223: expected (), got Foo 549 200..223: expected (), got Foo
550 262..285: expected (), got usize 550 262..285: expected (), got usize
551 "### 551 "#]],
552 ); 552 );
553} 553}
554 554
555#[test] 555#[test]
556fn infer_guard() { 556fn infer_guard() {
557 assert_snapshot!( 557 check_infer(
558 infer(r#" 558 r#"
559struct S; 559struct S;
560impl S { fn foo(&self) -> bool { false } } 560impl S { fn foo(&self) -> bool { false } }
561 561
@@ -564,91 +564,93 @@ fn main() {
564 s if s.foo() => (), 564 s if s.foo() => (),
565 } 565 }
566} 566}
567 "#), @r###" 567 "#,
568 27..31 'self': &S 568 expect![[r#"
569 41..50 '{ false }': bool 569 27..31 'self': &S
570 43..48 'false': bool 570 41..50 '{ false }': bool
571 64..115 '{ ... } }': () 571 43..48 'false': bool
572 70..113 'match ... }': () 572 64..115 '{ ... } }': ()
573 76..77 'S': S 573 70..113 'match ... }': ()
574 88..89 's': S 574 76..77 'S': S
575 93..94 's': S 575 88..89 's': S
576 93..100 's.foo()': bool 576 93..94 's': S
577 104..106 '()': () 577 93..100 's.foo()': bool
578 "###) 578 104..106 '()': ()
579 "#]],
580 )
579} 581}
580 582
581#[test] 583#[test]
582fn match_ergonomics_in_closure_params() { 584fn match_ergonomics_in_closure_params() {
583 assert_snapshot!( 585 check_infer(
584 infer(r#" 586 r#"
585#[lang = "fn_once"] 587 #[lang = "fn_once"]
586trait FnOnce<Args> { 588 trait FnOnce<Args> {
587 type Output; 589 type Output;
588} 590 }
589 591
590fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} } 592 fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
591 593
592fn test() { 594 fn test() {
593 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics 595 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
594 foo(&(1, "a"), |(x, y)| x); 596 foo(&(1, "a"), |(x, y)| x);
595} 597 }
596"#), 598 "#,
597 @r###" 599 expect![[r#"
598 93..94 't': T 600 93..94 't': T
599 99..100 'f': F 601 99..100 'f': F
600 110..121 '{ loop {} }': U 602 110..121 '{ loop {} }': U
601 112..119 'loop {}': ! 603 112..119 'loop {}': !
602 117..119 '{}': () 604 117..119 '{}': ()
603 133..232 '{ ... x); }': () 605 133..232 '{ ... x); }': ()
604 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 606 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
605 139..166 'foo(&(...y)| x)': i32 607 139..166 'foo(&(...y)| x)': i32
606 143..152 '&(1, "a")': &(i32, &str) 608 143..152 '&(1, "a")': &(i32, &str)
607 144..152 '(1, "a")': (i32, &str) 609 144..152 '(1, "a")': (i32, &str)
608 145..146 '1': i32 610 145..146 '1': i32
609 148..151 '"a"': &str 611 148..151 '"a"': &str
610 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 612 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32
611 155..162 '&(x, y)': &(i32, &str) 613 155..162 '&(x, y)': &(i32, &str)
612 156..162 '(x, y)': (i32, &str) 614 156..162 '(x, y)': (i32, &str)
613 157..158 'x': i32 615 157..158 'x': i32
614 160..161 'y': &str 616 160..161 'y': &str
615 164..165 'x': i32 617 164..165 'x': i32
616 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 618 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
617 203..229 'foo(&(...y)| x)': &i32 619 203..229 'foo(&(...y)| x)': &i32
618 207..216 '&(1, "a")': &(i32, &str) 620 207..216 '&(1, "a")': &(i32, &str)
619 208..216 '(1, "a")': (i32, &str) 621 208..216 '(1, "a")': (i32, &str)
620 209..210 '1': i32 622 209..210 '1': i32
621 212..215 '"a"': &str 623 212..215 '"a"': &str
622 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 624 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32
623 219..225 '(x, y)': (i32, &str) 625 219..225 '(x, y)': (i32, &str)
624 220..221 'x': &i32 626 220..221 'x': &i32
625 223..224 'y': &&str 627 223..224 'y': &&str
626 227..228 'x': &i32 628 227..228 'x': &i32
627 "### 629 "#]],
628 ); 630 );
629} 631}
630 632
631#[test] 633#[test]
632fn slice_tail_pattern() { 634fn slice_tail_pattern() {
633 assert_snapshot!( 635 check_infer(
634 infer(r#" 636 r#"
635fn foo(params: &[i32]) { 637 fn foo(params: &[i32]) {
636 match params { 638 match params {
637 [head, tail @ ..] => { 639 [head, tail @ ..] => {
640 }
641 }
638 } 642 }
639 } 643 "#,
640} 644 expect![[r#"
641"#), 645 7..13 'params': &[i32]
642 @r###" 646 23..92 '{ ... } }': ()
643 7..13 'params': &[i32] 647 29..90 'match ... }': ()
644 23..92 '{ ... } }': () 648 35..41 'params': &[i32]
645 29..90 'match ... }': () 649 52..69 '[head,... @ ..]': [i32]
646 35..41 'params': &[i32] 650 53..57 'head': &i32
647 52..69 '[head,... @ ..]': [i32] 651 59..68 'tail @ ..': &[i32]
648 53..57 'head': &i32 652 66..68 '..': [i32]
649 59..68 'tail @ ..': &[i32] 653 73..84 '{ }': ()
650 66..68 '..': [i32] 654 "#]],
651 73..84 '{ }': ()
652 "###
653 ); 655 );
654} 656}
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs
index 4367621fc..b9ab0f357 100644
--- a/crates/ra_hir_ty/src/tests/regression.rs
+++ b/crates/ra_hir_ty/src/tests/regression.rs
@@ -1,87 +1,87 @@
1use insta::assert_snapshot; 1use expect::expect;
2use test_utils::mark; 2use test_utils::mark;
3 3
4use super::{check_types, infer}; 4use super::{check_infer, check_types};
5 5
6#[test] 6#[test]
7fn bug_484() { 7fn bug_484() {
8 assert_snapshot!( 8 check_infer(
9 infer(r#" 9 r#"
10fn test() { 10 fn test() {
11 let x = if true {}; 11 let x = if true {};
12} 12 }
13"#), 13 "#,
14 @r###" 14 expect![[r#"
15 10..36 '{ l... {}; }': () 15 10..37 '{ ... {}; }': ()
16 19..20 'x': () 16 20..21 'x': ()
17 23..33 'if true {}': () 17 24..34 'if true {}': ()
18 26..30 'true': bool 18 27..31 'true': bool
19 31..33 '{}': () 19 32..34 '{}': ()
20 "### 20 "#]],
21 ); 21 );
22} 22}
23 23
24#[test] 24#[test]
25fn no_panic_on_field_of_enum() { 25fn no_panic_on_field_of_enum() {
26 assert_snapshot!( 26 check_infer(
27 infer(r#" 27 r#"
28enum X {} 28 enum X {}
29 29
30fn test(x: X) { 30 fn test(x: X) {
31 x.some_field; 31 x.some_field;
32} 32 }
33"#), 33 "#,
34 @r###" 34 expect![[r#"
35 19..20 'x': X 35 19..20 'x': X
36 25..46 '{ ...eld; }': () 36 25..46 '{ ...eld; }': ()
37 31..32 'x': X 37 31..32 'x': X
38 31..43 'x.some_field': {unknown} 38 31..43 'x.some_field': {unknown}
39 "### 39 "#]],
40 ); 40 );
41} 41}
42 42
43#[test] 43#[test]
44fn bug_585() { 44fn bug_585() {
45 assert_snapshot!( 45 check_infer(
46 infer(r#" 46 r#"
47fn test() { 47 fn test() {
48 X {}; 48 X {};
49 match x { 49 match x {
50 A::B {} => (), 50 A::B {} => (),
51 A::Y() => (), 51 A::Y() => (),
52 } 52 }
53} 53 }
54"#), 54 "#,
55 @r###" 55 expect![[r#"
56 10..88 '{ ... } }': () 56 10..88 '{ ... } }': ()
57 16..20 'X {}': {unknown} 57 16..20 'X {}': {unknown}
58 26..86 'match ... }': () 58 26..86 'match ... }': ()
59 32..33 'x': {unknown} 59 32..33 'x': {unknown}
60 44..51 'A::B {}': {unknown} 60 44..51 'A::B {}': {unknown}
61 55..57 '()': () 61 55..57 '()': ()
62 67..73 'A::Y()': {unknown} 62 67..73 'A::Y()': {unknown}
63 77..79 '()': () 63 77..79 '()': ()
64 "### 64 "#]],
65 ); 65 );
66} 66}
67 67
68#[test] 68#[test]
69fn bug_651() { 69fn bug_651() {
70 assert_snapshot!( 70 check_infer(
71 infer(r#" 71 r#"
72fn quux() { 72 fn quux() {
73 let y = 92; 73 let y = 92;
74 1 + y; 74 1 + y;
75} 75 }
76"#), 76 "#,
77 @r###" 77 expect![[r#"
78 10..40 '{ ...+ y; }': () 78 10..40 '{ ...+ y; }': ()
79 20..21 'y': i32 79 20..21 'y': i32
80 24..26 '92': i32 80 24..26 '92': i32
81 32..33 '1': i32 81 32..33 '1': i32
82 32..37 '1 + y': i32 82 32..37 '1 + y': i32
83 36..37 'y': i32 83 36..37 'y': i32
84 "### 84 "#]],
85 ); 85 );
86} 86}
87 87
@@ -89,78 +89,78 @@ fn quux() {
89fn recursive_vars() { 89fn recursive_vars() {
90 mark::check!(type_var_cycles_resolve_completely); 90 mark::check!(type_var_cycles_resolve_completely);
91 mark::check!(type_var_cycles_resolve_as_possible); 91 mark::check!(type_var_cycles_resolve_as_possible);
92 assert_snapshot!( 92 check_infer(
93 infer(r#" 93 r#"
94fn test() { 94 fn test() {
95 let y = unknown; 95 let y = unknown;
96 [y, &y]; 96 [y, &y];
97} 97 }
98"#), 98 "#,
99 @r###" 99 expect![[r#"
100 10..47 '{ ...&y]; }': () 100 10..47 '{ ...&y]; }': ()
101 20..21 'y': &{unknown} 101 20..21 'y': &{unknown}
102 24..31 'unknown': &{unknown} 102 24..31 'unknown': &{unknown}
103 37..44 '[y, &y]': [&&{unknown}; _] 103 37..44 '[y, &y]': [&&{unknown}; _]
104 38..39 'y': &{unknown} 104 38..39 'y': &{unknown}
105 41..43 '&y': &&{unknown} 105 41..43 '&y': &&{unknown}
106 42..43 'y': &{unknown} 106 42..43 'y': &{unknown}
107 "### 107 "#]],
108 ); 108 );
109} 109}
110 110
111#[test] 111#[test]
112fn recursive_vars_2() { 112fn recursive_vars_2() {
113 assert_snapshot!( 113 check_infer(
114 infer(r#" 114 r#"
115fn test() { 115 fn test() {
116 let x = unknown; 116 let x = unknown;
117 let y = unknown; 117 let y = unknown;
118 [(x, y), (&y, &x)]; 118 [(x, y), (&y, &x)];
119} 119 }
120"#), 120 "#,
121 @r###" 121 expect![[r#"
122 10..79 '{ ...x)]; }': () 122 10..79 '{ ...x)]; }': ()
123 20..21 'x': &&{unknown} 123 20..21 'x': &&{unknown}
124 24..31 'unknown': &&{unknown} 124 24..31 'unknown': &&{unknown}
125 41..42 'y': &&{unknown} 125 41..42 'y': &&{unknown}
126 45..52 'unknown': &&{unknown} 126 45..52 'unknown': &&{unknown}
127 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _] 127 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _]
128 59..65 '(x, y)': (&&&{unknown}, &&&{unknown}) 128 59..65 '(x, y)': (&&&{unknown}, &&&{unknown})
129 60..61 'x': &&{unknown} 129 60..61 'x': &&{unknown}
130 63..64 'y': &&{unknown} 130 63..64 'y': &&{unknown}
131 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown}) 131 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown})
132 68..70 '&y': &&&{unknown} 132 68..70 '&y': &&&{unknown}
133 69..70 'y': &&{unknown} 133 69..70 'y': &&{unknown}
134 72..74 '&x': &&&{unknown} 134 72..74 '&x': &&&{unknown}
135 73..74 'x': &&{unknown} 135 73..74 'x': &&{unknown}
136 "### 136 "#]],
137 ); 137 );
138} 138}
139 139
140#[test] 140#[test]
141fn infer_std_crash_1() { 141fn infer_std_crash_1() {
142 // caused stack overflow, taken from std 142 // caused stack overflow, taken from std
143 assert_snapshot!( 143 check_infer(
144 infer(r#" 144 r#"
145enum Maybe<T> { 145 enum Maybe<T> {
146 Real(T), 146 Real(T),
147 Fake, 147 Fake,
148} 148 }
149 149
150fn write() { 150 fn write() {
151 match something_unknown { 151 match something_unknown {
152 Maybe::Real(ref mut something) => (), 152 Maybe::Real(ref mut something) => (),
153 } 153 }
154} 154 }
155"#), 155 "#,
156 @r###" 156 expect![[r#"
157 53..138 '{ ... } }': () 157 53..138 '{ ... } }': ()
158 59..136 'match ... }': () 158 59..136 'match ... }': ()
159 65..82 'someth...nknown': Maybe<{unknown}> 159 65..82 'someth...nknown': Maybe<{unknown}>
160 93..123 'Maybe:...thing)': Maybe<{unknown}> 160 93..123 'Maybe:...thing)': Maybe<{unknown}>
161 105..122 'ref mu...ething': &mut {unknown} 161 105..122 'ref mu...ething': &mut {unknown}
162 127..129 '()': () 162 127..129 '()': ()
163 "### 163 "#]],
164 ); 164 );
165} 165}
166 166
@@ -168,234 +168,235 @@ fn write() {
168fn infer_std_crash_2() { 168fn infer_std_crash_2() {
169 mark::check!(type_var_resolves_to_int_var); 169 mark::check!(type_var_resolves_to_int_var);
170 // caused "equating two type variables, ...", taken from std 170 // caused "equating two type variables, ...", taken from std
171 assert_snapshot!( 171 check_infer(
172 infer(r#" 172 r#"
173fn test_line_buffer() { 173 fn test_line_buffer() {
174 &[0, b'\n', 1, b'\n']; 174 &[0, b'\n', 1, b'\n'];
175} 175 }
176"#), 176 "#,
177 @r###" 177 expect![[r#"
178 22..52 '{ ...n']; }': () 178 22..52 '{ ...n']; }': ()
179 28..49 '&[0, b...b'\n']': &[u8; _] 179 28..49 '&[0, b...b'\n']': &[u8; _]
180 29..49 '[0, b'...b'\n']': [u8; _] 180 29..49 '[0, b'...b'\n']': [u8; _]
181 30..31 '0': u8 181 30..31 '0': u8
182 33..38 'b'\n'': u8 182 33..38 'b'\n'': u8
183 40..41 '1': u8 183 40..41 '1': u8
184 43..48 'b'\n'': u8 184 43..48 'b'\n'': u8
185 "### 185 "#]],
186 ); 186 );
187} 187}
188 188
189#[test] 189#[test]
190fn infer_std_crash_3() { 190fn infer_std_crash_3() {
191 // taken from rustc 191 // taken from rustc
192 assert_snapshot!( 192 check_infer(
193 infer(r#" 193 r#"
194pub fn compute() { 194 pub fn compute() {
195 match nope!() { 195 match nope!() {
196 SizeSkeleton::Pointer { non_zero: true, tail } => {} 196 SizeSkeleton::Pointer { non_zero: true, tail } => {}
197 } 197 }
198} 198 }
199"#), 199 "#,
200 @r###" 200 expect![[r#"
201 17..107 '{ ... } }': () 201 17..107 '{ ... } }': ()
202 23..105 'match ... }': () 202 23..105 'match ... }': ()
203 29..36 'nope!()': {unknown} 203 29..36 'nope!()': {unknown}
204 47..93 'SizeSk...tail }': {unknown} 204 47..93 'SizeSk...tail }': {unknown}
205 81..85 'true': bool 205 81..85 'true': bool
206 81..85 'true': bool 206 81..85 'true': bool
207 87..91 'tail': {unknown} 207 87..91 'tail': {unknown}
208 97..99 '{}': () 208 97..99 '{}': ()
209 "### 209 "#]],
210 ); 210 );
211} 211}
212 212
213#[test] 213#[test]
214fn infer_std_crash_4() { 214fn infer_std_crash_4() {
215 // taken from rustc 215 // taken from rustc
216 assert_snapshot!( 216 check_infer(
217 infer(r#" 217 r#"
218pub fn primitive_type() { 218 pub fn primitive_type() {
219 match *self { 219 match *self {
220 BorrowedRef { type_: Primitive(p), ..} => {}, 220 BorrowedRef { type_: Primitive(p), ..} => {},
221 } 221 }
222} 222 }
223"#), 223 "#,
224 @r###" 224 expect![[r#"
225 24..105 '{ ... } }': () 225 24..105 '{ ... } }': ()
226 30..103 'match ... }': () 226 30..103 'match ... }': ()
227 36..41 '*self': {unknown} 227 36..41 '*self': {unknown}
228 37..41 'self': {unknown} 228 37..41 'self': {unknown}
229 52..90 'Borrow...), ..}': {unknown} 229 52..90 'Borrow...), ..}': {unknown}
230 73..85 'Primitive(p)': {unknown} 230 73..85 'Primitive(p)': {unknown}
231 83..84 'p': {unknown} 231 83..84 'p': {unknown}
232 94..96 '{}': () 232 94..96 '{}': ()
233 "### 233 "#]],
234 ); 234 );
235} 235}
236 236
237#[test] 237#[test]
238fn infer_std_crash_5() { 238fn infer_std_crash_5() {
239 // taken from rustc 239 // taken from rustc
240 assert_snapshot!( 240 check_infer(
241 infer(r#" 241 r#"
242fn extra_compiler_flags() { 242 fn extra_compiler_flags() {
243 for content in doesnt_matter { 243 for content in doesnt_matter {
244 let name = if doesnt_matter { 244 let name = if doesnt_matter {
245 first 245 first
246 } else { 246 } else {
247 &content 247 &content
248 }; 248 };
249 249
250 let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { 250 let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) {
251 name 251 name
252 } else { 252 } else {
253 content 253 content
254 }; 254 };
255 } 255 }
256} 256 }
257"#), 257 "#,
258 @r###" 258 expect![[r#"
259 26..322 '{ ... } }': () 259 26..322 '{ ... } }': ()
260 32..320 'for co... }': () 260 32..320 'for co... }': ()
261 36..43 'content': &{unknown} 261 36..43 'content': &{unknown}
262 47..60 'doesnt_matter': {unknown} 262 47..60 'doesnt_matter': {unknown}
263 61..320 '{ ... }': () 263 61..320 '{ ... }': ()
264 75..79 'name': &&{unknown} 264 75..79 'name': &&{unknown}
265 82..166 'if doe... }': &&{unknown} 265 82..166 'if doe... }': &&{unknown}
266 85..98 'doesnt_matter': bool 266 85..98 'doesnt_matter': bool
267 99..128 '{ ... }': &&{unknown} 267 99..128 '{ ... }': &&{unknown}
268 113..118 'first': &&{unknown} 268 113..118 'first': &&{unknown}
269 134..166 '{ ... }': &&{unknown} 269 134..166 '{ ... }': &&{unknown}
270 148..156 '&content': &&{unknown} 270 148..156 '&content': &&{unknown}
271 149..156 'content': &{unknown} 271 149..156 'content': &{unknown}
272 181..188 'content': &{unknown} 272 181..188 'content': &{unknown}
273 191..313 'if ICE... }': &{unknown} 273 191..313 'if ICE... }': &{unknown}
274 194..231 'ICE_RE..._VALUE': {unknown} 274 194..231 'ICE_RE..._VALUE': {unknown}
275 194..247 'ICE_RE...&name)': bool 275 194..247 'ICE_RE...&name)': bool
276 241..246 '&name': &&&{unknown} 276 241..246 '&name': &&&{unknown}
277 242..246 'name': &&{unknown} 277 242..246 'name': &&{unknown}
278 248..276 '{ ... }': &&{unknown} 278 248..276 '{ ... }': &&{unknown}
279 262..266 'name': &&{unknown} 279 262..266 'name': &&{unknown}
280 282..313 '{ ... }': &{unknown} 280 282..313 '{ ... }': &{unknown}
281 296..303 'content': &{unknown} 281 296..303 'content': &{unknown}
282 "### 282 "#]],
283 ); 283 );
284} 284}
285 285
286#[test] 286#[test]
287fn infer_nested_generics_crash() { 287fn infer_nested_generics_crash() {
288 // another crash found typechecking rustc 288 // another crash found typechecking rustc
289 assert_snapshot!( 289 check_infer(
290 infer(r#" 290 r#"
291struct Canonical<V> { 291 struct Canonical<V> {
292 value: V, 292 value: V,
293} 293 }
294struct QueryResponse<V> { 294 struct QueryResponse<V> {
295 value: V, 295 value: V,
296} 296 }
297fn test<R>(query_response: Canonical<QueryResponse<R>>) { 297 fn test<R>(query_response: Canonical<QueryResponse<R>>) {
298 &query_response.value; 298 &query_response.value;
299} 299 }
300"#), 300 "#,
301 @r###" 301 expect![[r#"
302 91..105 'query_response': Canonical<QueryResponse<R>> 302 91..105 'query_response': Canonical<QueryResponse<R>>
303 136..166 '{ ...lue; }': () 303 136..166 '{ ...lue; }': ()
304 142..163 '&query....value': &QueryResponse<R> 304 142..163 '&query....value': &QueryResponse<R>
305 143..157 'query_response': Canonical<QueryResponse<R>> 305 143..157 'query_response': Canonical<QueryResponse<R>>
306 143..163 'query_....value': QueryResponse<R> 306 143..163 'query_....value': QueryResponse<R>
307 "### 307 "#]],
308 ); 308 );
309} 309}
310 310
311#[test] 311#[test]
312fn infer_paren_macro_call() { 312fn infer_paren_macro_call() {
313 assert_snapshot!( 313 check_infer(
314 infer(r#" 314 r#"
315macro_rules! bar { () => {0u32} } 315 macro_rules! bar { () => {0u32} }
316fn test() { 316 fn test() {
317 let a = (bar!()); 317 let a = (bar!());
318} 318 }
319"#), 319 "#,
320 @r###" 320 expect![[r#"
321 !0..4 '0u32': u32 321 !0..4 '0u32': u32
322 44..69 '{ ...()); }': () 322 44..69 '{ ...()); }': ()
323 54..55 'a': u32 323 54..55 'a': u32
324 "### 324 "#]],
325 ); 325 );
326} 326}
327 327
328#[test] 328#[test]
329fn bug_1030() { 329fn bug_1030() {
330 assert_snapshot!(infer(r#" 330 check_infer(
331struct HashSet<T, H>; 331 r#"
332struct FxHasher; 332 struct HashSet<T, H>;
333type FxHashSet<T> = HashSet<T, FxHasher>; 333 struct FxHasher;
334 type FxHashSet<T> = HashSet<T, FxHasher>;
334 335
335impl<T, H> HashSet<T, H> { 336 impl<T, H> HashSet<T, H> {
336 fn default() -> HashSet<T, H> {} 337 fn default() -> HashSet<T, H> {}
337} 338 }
338 339
339pub fn main_loop() { 340 pub fn main_loop() {
340 FxHashSet::default(); 341 FxHashSet::default();
341} 342 }
342"#), 343 "#,
343 @r###" 344 expect![[r#"
344 143..145 '{}': () 345 143..145 '{}': ()
345 168..197 '{ ...t(); }': () 346 168..197 '{ ...t(); }': ()
346 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher> 347 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher>
347 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher> 348 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher>
348 "### 349 "#]],
349 ); 350 );
350} 351}
351 352
352#[test] 353#[test]
353fn issue_2669() { 354fn issue_2669() {
354 assert_snapshot!( 355 check_infer(
355 infer( 356 r#"
356 r#"trait A {} 357 trait A {}
357 trait Write {} 358 trait Write {}
358 struct Response<T> {} 359 struct Response<T> {}
359 360
360 trait D { 361 trait D {
361 fn foo(); 362 fn foo();
362 } 363 }
363 364
364 impl<T:A> D for Response<T> { 365 impl<T:A> D for Response<T> {
365 fn foo() { 366 fn foo() {
366 end(); 367 end();
367 fn end<W: Write>() { 368 fn end<W: Write>() {
368 let _x: T = loop {}; 369 let _x: T = loop {};
370 }
369 } 371 }
370 } 372 }
371 }"# 373 "#,
372 ), 374 expect![[r#"
373 @r###" 375 119..214 '{ ... }': ()
374 147..262 '{ ... }': () 376 129..132 'end': fn end<{unknown}>()
375 161..164 'end': fn end<{unknown}>() 377 129..134 'end()': ()
376 161..166 'end()': () 378 163..208 '{ ... }': ()
377 199..252 '{ ... }': () 379 181..183 '_x': !
378 221..223 '_x': ! 380 190..197 'loop {}': !
379 230..237 'loop {}': ! 381 195..197 '{}': ()
380 235..237 '{}': () 382 "#]],
381 "###
382 ) 383 )
383} 384}
384 385
385#[test] 386#[test]
386fn issue_2705() { 387fn issue_2705() {
387 assert_snapshot!( 388 check_infer(
388 infer(r#" 389 r#"
389trait Trait {} 390 trait Trait {}
390fn test() { 391 fn test() {
391 <Trait<u32>>::foo() 392 <Trait<u32>>::foo()
392} 393 }
393"#), 394 "#,
394 @r###" 395 expect![[r#"
395 25..52 '{ ...oo() }': () 396 25..52 '{ ...oo() }': ()
396 31..48 '<Trait...>::foo': {unknown} 397 31..48 '<Trait...>::foo': {unknown}
397 31..50 '<Trait...:foo()': () 398 31..50 '<Trait...:foo()': ()
398 "### 399 "#]],
399 ); 400 );
400} 401}
401 402
@@ -479,25 +480,25 @@ fn main() {
479 480
480#[test] 481#[test]
481fn issue_3999_slice() { 482fn issue_3999_slice() {
482 assert_snapshot!( 483 check_infer(
483 infer(r#" 484 r#"
484fn foo(params: &[usize]) { 485 fn foo(params: &[usize]) {
485 match params { 486 match params {
486 [ps @ .., _] => {} 487 [ps @ .., _] => {}
487 } 488 }
488} 489 }
489"#), 490 "#,
490 @r###" 491 expect![[r#"
491 7..13 'params': &[usize] 492 7..13 'params': &[usize]
492 25..80 '{ ... } }': () 493 25..80 '{ ... } }': ()
493 31..78 'match ... }': () 494 31..78 'match ... }': ()
494 37..43 'params': &[usize] 495 37..43 'params': &[usize]
495 54..66 '[ps @ .., _]': [usize] 496 54..66 '[ps @ .., _]': [usize]
496 55..62 'ps @ ..': &[usize] 497 55..62 'ps @ ..': &[usize]
497 60..62 '..': [usize] 498 60..62 '..': [usize]
498 64..65 '_': usize 499 64..65 '_': usize
499 70..72 '{}': () 500 70..72 '{}': ()
500 "### 501 "#]],
501 ); 502 );
502} 503}
503 504
@@ -505,334 +506,337 @@ fn foo(params: &[usize]) {
505fn issue_3999_struct() { 506fn issue_3999_struct() {
506 // rust-analyzer should not panic on seeing this malformed 507 // rust-analyzer should not panic on seeing this malformed
507 // record pattern. 508 // record pattern.
508 assert_snapshot!( 509 check_infer(
509 infer(r#" 510 r#"
510struct Bar { 511 struct Bar {
511 a: bool, 512 a: bool,
512} 513 }
513fn foo(b: Bar) { 514 fn foo(b: Bar) {
514 match b { 515 match b {
515 Bar { a: .. } => {}, 516 Bar { a: .. } => {},
516 } 517 }
517} 518 }
518"#), 519 "#,
519 @r###" 520 expect![[r#"
520 35..36 'b': Bar 521 35..36 'b': Bar
521 43..95 '{ ... } }': () 522 43..95 '{ ... } }': ()
522 49..93 'match ... }': () 523 49..93 'match ... }': ()
523 55..56 'b': Bar 524 55..56 'b': Bar
524 67..80 'Bar { a: .. }': Bar 525 67..80 'Bar { a: .. }': Bar
525 76..78 '..': bool 526 76..78 '..': bool
526 84..86 '{}': () 527 84..86 '{}': ()
527 "### 528 "#]],
528 ); 529 );
529} 530}
530 531
531#[test] 532#[test]
532fn issue_4235_name_conflicts() { 533fn issue_4235_name_conflicts() {
533 assert_snapshot!( 534 check_infer(
534 infer(r#" 535 r#"
535struct FOO {} 536 struct FOO {}
536static FOO:FOO = FOO {}; 537 static FOO:FOO = FOO {};
537 538
538impl FOO { 539 impl FOO {
539 fn foo(&self) {} 540 fn foo(&self) {}
540} 541 }
541 542
542fn main() { 543 fn main() {
543 let a = &FOO; 544 let a = &FOO;
544 a.foo(); 545 a.foo();
545} 546 }
546"#), @r###" 547 "#,
547 31..37 'FOO {}': FOO 548 expect![[r#"
548 63..67 'self': &FOO 549 31..37 'FOO {}': FOO
549 69..71 '{}': () 550 63..67 'self': &FOO
550 85..119 '{ ...o(); }': () 551 69..71 '{}': ()
551 95..96 'a': &FOO 552 85..119 '{ ...o(); }': ()
552 99..103 '&FOO': &FOO 553 95..96 'a': &FOO
553 100..103 'FOO': FOO 554 99..103 '&FOO': &FOO
554 109..110 'a': &FOO 555 100..103 'FOO': FOO
555 109..116 'a.foo()': () 556 109..110 'a': &FOO
556 "### 557 109..116 'a.foo()': ()
558 "#]],
557 ); 559 );
558} 560}
559 561
560#[test] 562#[test]
561fn issue_4465_dollar_crate_at_type() { 563fn issue_4465_dollar_crate_at_type() {
562 assert_snapshot!( 564 check_infer(
563 infer(r#" 565 r#"
564pub struct Foo {} 566 pub struct Foo {}
565pub fn anything<T>() -> T { 567 pub fn anything<T>() -> T {
566 loop {} 568 loop {}
567} 569 }
568macro_rules! foo { 570 macro_rules! foo {
569 () => {{ 571 () => {{
570 let r: $crate::Foo = anything(); 572 let r: $crate::Foo = anything();
571 r 573 r
572 }}; 574 }};
573} 575 }
574fn main() { 576 fn main() {
575 let _a = foo!(); 577 let _a = foo!();
576} 578 }
577"#), @r###" 579 "#,
578 44..59 '{ loop {} }': T 580 expect![[r#"
579 50..57 'loop {}': ! 581 44..59 '{ loop {} }': T
580 55..57 '{}': () 582 50..57 'loop {}': !
581 !0..31 '{letr:...g();r}': Foo 583 55..57 '{}': ()
582 !4..5 'r': Foo 584 !0..31 '{letr:...g();r}': Foo
583 !18..26 'anything': fn anything<Foo>() -> Foo 585 !4..5 'r': Foo
584 !18..28 'anything()': Foo 586 !18..26 'anything': fn anything<Foo>() -> Foo
585 !29..30 'r': Foo 587 !18..28 'anything()': Foo
586 163..187 '{ ...!(); }': () 588 !29..30 'r': Foo
587 173..175 '_a': Foo 589 163..187 '{ ...!(); }': ()
588 "###); 590 173..175 '_a': Foo
591 "#]],
592 );
589} 593}
590 594
591#[test] 595#[test]
592fn issue_4053_diesel_where_clauses() { 596fn issue_4053_diesel_where_clauses() {
593 assert_snapshot!( 597 check_infer(
594 infer(r#" 598 r#"
595trait BoxedDsl<DB> { 599 trait BoxedDsl<DB> {
596 type Output; 600 type Output;
597 fn internal_into_boxed(self) -> Self::Output; 601 fn internal_into_boxed(self) -> Self::Output;
598} 602 }
599 603
600struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> { 604 struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> {
601 order: Order, 605 order: Order,
602} 606 }
603 607
604trait QueryFragment<DB: Backend> {} 608 trait QueryFragment<DB: Backend> {}
605 609
606trait Into<T> { fn into(self) -> T; } 610 trait Into<T> { fn into(self) -> T; }
607 611
608impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB> 612 impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB>
609 for SelectStatement<F, S, D, W, O, LOf, G> 613 for SelectStatement<F, S, D, W, O, LOf, G>
610where 614 where
611 O: Into<dyn QueryFragment<DB>>, 615 O: Into<dyn QueryFragment<DB>>,
612{ 616 {
613 type Output = XXX; 617 type Output = XXX;
614 618
615 fn internal_into_boxed(self) -> Self::Output { 619 fn internal_into_boxed(self) -> Self::Output {
616 self.order.into(); 620 self.order.into();
617 } 621 }
618} 622 }
619"#), 623 "#,
620 @r###" 624 expect![[r#"
621 65..69 'self': Self 625 65..69 'self': Self
622 267..271 'self': Self 626 267..271 'self': Self
623 466..470 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> 627 466..470 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
624 488..522 '{ ... }': () 628 488..522 '{ ... }': ()
625 498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> 629 498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
626 498..508 'self.order': O 630 498..508 'self.order': O
627 498..515 'self.o...into()': dyn QueryFragment<DB> 631 498..515 'self.o...into()': dyn QueryFragment<DB>
628 "### 632 "#]],
629 ); 633 );
630} 634}
631 635
632#[test] 636#[test]
633fn issue_4953() { 637fn issue_4953() {
634 assert_snapshot!( 638 check_infer(
635 infer(r#" 639 r#"
636pub struct Foo(pub i64); 640 pub struct Foo(pub i64);
637impl Foo { 641 impl Foo {
638 fn test() -> Self { Self(0i64) } 642 fn test() -> Self { Self(0i64) }
639} 643 }
640"#), 644 "#,
641 @r###" 645 expect![[r#"
642 58..72 '{ Self(0i64) }': Foo 646 58..72 '{ Self(0i64) }': Foo
643 60..64 'Self': Foo(i64) -> Foo 647 60..64 'Self': Foo(i64) -> Foo
644 60..70 'Self(0i64)': Foo 648 60..70 'Self(0i64)': Foo
645 65..69 '0i64': i64 649 65..69 '0i64': i64
646 "### 650 "#]],
647 ); 651 );
648 assert_snapshot!( 652 check_infer(
649 infer(r#" 653 r#"
650pub struct Foo<T>(pub T); 654 pub struct Foo<T>(pub T);
651impl Foo<i64> { 655 impl Foo<i64> {
652 fn test() -> Self { Self(0i64) } 656 fn test() -> Self { Self(0i64) }
653} 657 }
654"#), 658 "#,
655 @r###" 659 expect![[r#"
656 64..78 '{ Self(0i64) }': Foo<i64> 660 64..78 '{ Self(0i64) }': Foo<i64>
657 66..70 'Self': Foo<i64>(i64) -> Foo<i64> 661 66..70 'Self': Foo<i64>(i64) -> Foo<i64>
658 66..76 'Self(0i64)': Foo<i64> 662 66..76 'Self(0i64)': Foo<i64>
659 71..75 '0i64': i64 663 71..75 '0i64': i64
660 "### 664 "#]],
661 ); 665 );
662} 666}
663 667
664#[test] 668#[test]
665fn issue_4931() { 669fn issue_4931() {
666 assert_snapshot!( 670 check_infer(
667 infer(r#" 671 r#"
668trait Div<T> { 672 trait Div<T> {
669 type Output; 673 type Output;
670} 674 }
671 675
672trait CheckedDiv: Div<()> {} 676 trait CheckedDiv: Div<()> {}
673 677
674trait PrimInt: CheckedDiv<Output = ()> { 678 trait PrimInt: CheckedDiv<Output = ()> {
675 fn pow(self); 679 fn pow(self);
676} 680 }
677 681
678fn check<T: PrimInt>(i: T) { 682 fn check<T: PrimInt>(i: T) {
679 i.pow(); 683 i.pow();
680} 684 }
681"#), 685 "#,
682 @r###" 686 expect![[r#"
683 117..121 'self': Self 687 117..121 'self': Self
684 148..149 'i': T 688 148..149 'i': T
685 154..170 '{ ...w(); }': () 689 154..170 '{ ...w(); }': ()
686 160..161 'i': T 690 160..161 'i': T
687 160..167 'i.pow()': () 691 160..167 'i.pow()': ()
688 "### 692 "#]],
689 ); 693 );
690} 694}
691 695
692#[test] 696#[test]
693fn issue_4885() { 697fn issue_4885() {
694 assert_snapshot!( 698 check_infer(
695 infer(r#" 699 r#"
696#[lang = "coerce_unsized"] 700 #[lang = "coerce_unsized"]
697pub trait CoerceUnsized<T> {} 701 pub trait CoerceUnsized<T> {}
698 702
699trait Future { 703 trait Future {
700 type Output; 704 type Output;
701} 705 }
702trait Foo<R> { 706 trait Foo<R> {
703 type Bar; 707 type Bar;
704} 708 }
705fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar> 709 fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar>
706where 710 where
707 K: Foo<R>, 711 K: Foo<R>,
708{ 712 {
709 bar(key) 713 bar(key)
710} 714 }
711fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar> 715 fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar>
712where 716 where
713 K: Foo<R>, 717 K: Foo<R>,
714{ 718 {
715} 719 }
716"#), 720 "#,
717 @r###" 721 expect![[r#"
718 136..139 'key': &K 722 136..139 'key': &K
719 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar> 723 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
720 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> 724 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
721 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> 725 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
722 208..211 'key': &K 726 208..211 'key': &K
723 228..231 'key': &K 727 228..231 'key': &K
724 290..293 '{ }': () 728 290..293 '{ }': ()
725 "### 729 "#]],
726 ); 730 );
727} 731}
728 732
729#[test] 733#[test]
730fn issue_4800() { 734fn issue_4800() {
731 assert_snapshot!( 735 check_infer(
732 infer(r#" 736 r#"
733trait Debug {} 737 trait Debug {}
734 738
735struct Foo<T>; 739 struct Foo<T>;
736 740
737type E1<T> = (T, T, T); 741 type E1<T> = (T, T, T);
738type E2<T> = E1<E1<E1<(T, T, T)>>>; 742 type E2<T> = E1<E1<E1<(T, T, T)>>>;
739 743
740impl Debug for Foo<E2<()>> {} 744 impl Debug for Foo<E2<()>> {}
741 745
742struct Request; 746 struct Request;
743 747
744pub trait Future { 748 pub trait Future {
745 type Output; 749 type Output;
746} 750 }
747 751
748pub struct PeerSet<D>; 752 pub struct PeerSet<D>;
749 753
750impl<D> Service<Request> for PeerSet<D> 754 impl<D> Service<Request> for PeerSet<D>
751where 755 where
752 D: Discover, 756 D: Discover,
753 D::Key: Debug, 757 D::Key: Debug,
754{ 758 {
755 type Error = (); 759 type Error = ();
756 type Future = dyn Future<Output = Self::Error>; 760 type Future = dyn Future<Output = Self::Error>;
757 761
758 fn call(&mut self) -> Self::Future { 762 fn call(&mut self) -> Self::Future {
759 loop {} 763 loop {}
760 } 764 }
761} 765 }
762 766
763pub trait Discover { 767 pub trait Discover {
764 type Key; 768 type Key;
765} 769 }
766 770
767pub trait Service<Request> { 771 pub trait Service<Request> {
768 type Error; 772 type Error;
769 type Future: Future<Output = Self::Error>; 773 type Future: Future<Output = Self::Error>;
770 fn call(&mut self) -> Self::Future; 774 fn call(&mut self) -> Self::Future;
771} 775 }
772"#), 776 "#,
773 @r###" 777 expect![[r#"
774 379..383 'self': &mut PeerSet<D> 778 379..383 'self': &mut PeerSet<D>
775 401..424 '{ ... }': dyn Future<Output = ()> 779 401..424 '{ ... }': dyn Future<Output = ()>
776 411..418 'loop {}': ! 780 411..418 'loop {}': !
777 416..418 '{}': () 781 416..418 '{}': ()
778 575..579 'self': &mut Self 782 575..579 'self': &mut Self
779 "### 783 "#]],
780 ); 784 );
781} 785}
782 786
783#[test] 787#[test]
784fn issue_4966() { 788fn issue_4966() {
785 assert_snapshot!( 789 check_infer(
786 infer(r#" 790 r#"
787pub trait IntoIterator { 791 pub trait IntoIterator {
788 type Item; 792 type Item;
789} 793 }
790 794
791struct Repeat<A> { element: A } 795 struct Repeat<A> { element: A }
792 796
793struct Map<F> { f: F } 797 struct Map<F> { f: F }
794 798
795struct Vec<T> {} 799 struct Vec<T> {}
796 800
797#[lang = "deref"] 801 #[lang = "deref"]
798pub trait Deref { 802 pub trait Deref {
799 type Target; 803 type Target;
800} 804 }
801 805
802impl<T> Deref for Vec<T> { 806 impl<T> Deref for Vec<T> {
803 type Target = [T]; 807 type Target = [T];
804} 808 }
805 809
806fn from_iter<A, T: IntoIterator<Item = A>>(iter: T) -> Vec<A> {} 810 fn from_iter<A, T: IntoIterator<Item = A>>(iter: T) -> Vec<A> {}
807 811
808fn main() { 812 fn main() {
809 let inner = Map { f: |_: &f64| 0.0 }; 813 let inner = Map { f: |_: &f64| 0.0 };
810 814
811 let repeat = Repeat { element: inner }; 815 let repeat = Repeat { element: inner };
812 816
813 let vec = from_iter(repeat); 817 let vec = from_iter(repeat);
814 818
815 vec.foo_bar(); 819 vec.foo_bar();
816} 820 }
817"#), 821 "#,
818 @r###" 822 expect![[r#"
819 270..274 'iter': T 823 270..274 'iter': T
820 289..291 '{}': () 824 289..291 '{}': ()
821 303..447 '{ ...r(); }': () 825 303..447 '{ ...r(); }': ()
822 313..318 'inner': Map<|&f64| -> f64> 826 313..318 'inner': Map<|&f64| -> f64>
823 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> 827 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64>
824 330..343 '|_: &f64| 0.0': |&f64| -> f64 828 330..343 '|_: &f64| 0.0': |&f64| -> f64
825 331..332 '_': &f64 829 331..332 '_': &f64
826 340..343 '0.0': f64 830 340..343 '0.0': f64
827 356..362 'repeat': Repeat<Map<|&f64| -> f64>> 831 356..362 'repeat': Repeat<Map<|&f64| -> f64>>
828 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> 832 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
829 383..388 'inner': Map<|&f64| -> f64> 833 383..388 'inner': Map<|&f64| -> f64>
830 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 834 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
831 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 835 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
832 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 836 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
833 417..423 'repeat': Repeat<Map<|&f64| -> f64>> 837 417..423 'repeat': Repeat<Map<|&f64| -> f64>>
834 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 838 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
835 431..444 'vec.foo_bar()': {unknown} 839 431..444 'vec.foo_bar()': {unknown}
836 "### 840 "#]],
837 ); 841 );
838} 842}
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index 6d3e264af..3fd7d5cd4 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -1,6 +1,6 @@
1use insta::assert_snapshot; 1use expect::expect;
2 2
3use super::{check_types, infer}; 3use super::{check_infer, check_types};
4 4
5#[test] 5#[test]
6fn infer_box() { 6fn infer_box() {
@@ -45,43 +45,44 @@ fn test() {
45 45
46#[test] 46#[test]
47fn self_in_struct_lit() { 47fn self_in_struct_lit() {
48 assert_snapshot!(infer( 48 check_infer(
49 r#"