authorbors <bors@rust-lang.org> 2025-10-14 17:45:05 UTC
committerbors <bors@rust-lang.org> 2025-10-14 17:45:05 UTC
log844264adda6f41ca6d0d61c4bcac0f263fc5072f
treeef873a1c2b817dab26151c4a355a6c7f71ec135c
parente100792918c8bd9e0cb830f96fc9b171e8892fa1
parent7d93599fb13060cd1a57d53133b5962106849a26

Auto merge of #147675 - lnicola:sync-from-ra, r=lnicola

`rust-analyzer` subtree update Subtree update of `rust-analyzer` to https://github.com/rust-lang/rust-analyzer/commit/6d4b23478d8e5114e68278c64d4691ee6cf615e4. Created using https://github.com/rust-lang/josh-sync. r? `@ghost`

219 files changed, 11101 insertions(+), 9715 deletions(-)

src/bootstrap/src/core/build_steps/tool.rs+1-1
......@@ -1021,7 +1021,7 @@ impl RustAnalyzer {
10211021}
10221022
10231023impl RustAnalyzer {
1024 pub const ALLOW_FEATURES: &'static str = "rustc_private,proc_macro_internals,proc_macro_diagnostic,proc_macro_span,proc_macro_span_shrink,proc_macro_def_site";
1024 pub const ALLOW_FEATURES: &'static str = "rustc_private,proc_macro_internals,proc_macro_diagnostic,proc_macro_span,proc_macro_span_shrink,proc_macro_def_site,new_zeroed_alloc";
10251025}
10261026
10271027impl Step for RustAnalyzer {
src/tools/rust-analyzer/.github/workflows/ci.yaml+1-1
......@@ -293,7 +293,7 @@ jobs:
293293 timeout-minutes: 10
294294 env:
295295 FORCE_COLOR: 1
296 TYPOS_VERSION: v1.28.3
296 TYPOS_VERSION: v1.38.1
297297 steps:
298298 - name: download typos
299299 run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin
src/tools/rust-analyzer/.github/workflows/release.yaml+2-2
......@@ -16,7 +16,7 @@ env:
1616 RUSTFLAGS: "-D warnings -W unreachable-pub"
1717 RUSTUP_MAX_RETRIES: 10
1818 FETCH_DEPTH: 0 # pull in the tags for the version string
19 MACOSX_DEPLOYMENT_TARGET: 13.0
19 MACOSX_DEPLOYMENT_TARGET: 14.0
2020 ZIG_VERSION: 0.13.0
2121 ZIGBUILD_VERSION: 0.19.8
2222
......@@ -52,7 +52,7 @@ jobs:
5252 target: arm-unknown-linux-gnueabihf
5353 zig_target: arm-unknown-linux-gnueabihf.2.28
5454 code-target: linux-armhf
55 - os: macos-13
55 - os: macos-14
5656 target: x86_64-apple-darwin
5757 code-target: darwin-x64
5858 pgo: clap-rs/clap@v4.5.36
src/tools/rust-analyzer/.typos.toml+1
......@@ -32,6 +32,7 @@ makro = "makro"
3232trivias = "trivias"
3333thir = "thir"
3434jod = "jod"
35tructure = "tructure"
3536
3637[default.extend-identifiers]
3738anc = "anc"
src/tools/rust-analyzer/Cargo.lock+251-274
......@@ -31,15 +31,15 @@ checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
3131
3232[[package]]
3333name = "anyhow"
34version = "1.0.98"
34version = "1.0.100"
3535source = "registry+https://github.com/rust-lang/crates.io-index"
36checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
36checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
3737
3838[[package]]
3939name = "arbitrary"
40version = "1.4.1"
40version = "1.4.2"
4141source = "registry+https://github.com/rust-lang/crates.io-index"
42checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
42checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
4343dependencies = [
4444 "derive_arbitrary",
4545]
......@@ -61,9 +61,9 @@ dependencies = [
6161
6262[[package]]
6363name = "autocfg"
64version = "1.4.0"
64version = "1.5.0"
6565source = "registry+https://github.com/rust-lang/crates.io-index"
66checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
66checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
6767
6868[[package]]
6969name = "backtrace"
......@@ -115,9 +115,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
115115
116116[[package]]
117117name = "bitflags"
118version = "2.9.1"
118version = "2.9.4"
119119source = "registry+https://github.com/rust-lang/crates.io-index"
120checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
120checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
121121
122122[[package]]
123123name = "borsh"
......@@ -130,9 +130,9 @@ dependencies = [
130130
131131[[package]]
132132name = "boxcar"
133version = "0.2.13"
133version = "0.2.14"
134134source = "registry+https://github.com/rust-lang/crates.io-index"
135checksum = "26c4925bc979b677330a8c7fe7a8c94af2dbb4a2d37b4a20a80d884400f46baa"
135checksum = "36f64beae40a84da1b4b26ff2761a5b895c12adc41dc25aaee1c4f2bbfe97a6e"
136136
137137[[package]]
138138name = "byteorder"
......@@ -142,11 +142,11 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
142142
143143[[package]]
144144name = "camino"
145version = "1.1.10"
145version = "1.2.0"
146146source = "registry+https://github.com/rust-lang/crates.io-index"
147checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab"
147checksum = "e1de8bc0aa9e9385ceb3bf0c152e3a9b9544f6c4a912c8ae504e80c1f0368603"
148148dependencies = [
149 "serde",
149 "serde_core",
150150]
151151
152152[[package]]
......@@ -184,7 +184,7 @@ dependencies = [
184184 "serde",
185185 "serde-untagged",
186186 "serde-value",
187 "thiserror 2.0.12",
187 "thiserror 2.0.16",
188188 "toml",
189189 "unicode-xid",
190190 "url",
......@@ -202,7 +202,7 @@ dependencies = [
202202 "semver",
203203 "serde",
204204 "serde_json",
205 "thiserror 2.0.12",
205 "thiserror 2.0.16",
206206]
207207
208208[[package]]
......@@ -217,15 +217,16 @@ dependencies = [
217217 "semver",
218218 "serde",
219219 "serde_json",
220 "thiserror 2.0.12",
220 "thiserror 2.0.16",
221221]
222222
223223[[package]]
224224name = "cc"
225version = "1.2.26"
225version = "1.2.38"
226226source = "registry+https://github.com/rust-lang/crates.io-index"
227checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac"
227checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9"
228228dependencies = [
229 "find-msvc-tools",
229230 "shlex",
230231]
231232
......@@ -234,7 +235,6 @@ name = "cfg"
234235version = "0.0.0"
235236dependencies = [
236237 "arbitrary",
237 "derive_arbitrary",
238238 "expect-test",
239239 "intern",
240240 "oorandom",
......@@ -247,9 +247,9 @@ dependencies = [
247247
248248[[package]]
249249name = "cfg-if"
250version = "1.0.1"
250version = "1.0.3"
251251source = "registry+https://github.com/rust-lang/crates.io-index"
252checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
252checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
253253
254254[[package]]
255255name = "cfg_aliases"
......@@ -275,24 +275,24 @@ version = "0.104.0"
275275source = "registry+https://github.com/rust-lang/crates.io-index"
276276checksum = "7047a516de16226cd17344d41a319d0ea1064bf9e60bd612ab341ab4a34bbfa8"
277277dependencies = [
278 "bitflags 2.9.1",
278 "bitflags 2.9.4",
279279 "chalk-derive",
280280]
281281
282282[[package]]
283283name = "clap"
284version = "4.5.42"
284version = "4.5.48"
285285source = "registry+https://github.com/rust-lang/crates.io-index"
286checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
286checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae"
287287dependencies = [
288288 "clap_builder",
289289]
290290
291291[[package]]
292292name = "clap_builder"
293version = "4.5.42"
293version = "4.5.48"
294294source = "registry+https://github.com/rust-lang/crates.io-index"
295checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
295checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9"
296296dependencies = [
297297 "anstyle",
298298 "clap_lex",
......@@ -310,7 +310,7 @@ version = "0.3.0"
310310source = "registry+https://github.com/rust-lang/crates.io-index"
311311checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
312312dependencies = [
313 "thiserror 2.0.12",
313 "thiserror 2.0.16",
314314]
315315
316316[[package]]
......@@ -321,15 +321,15 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
321321
322322[[package]]
323323name = "cov-mark"
324version = "2.0.0"
324version = "2.1.0"
325325source = "registry+https://github.com/rust-lang/crates.io-index"
326checksum = "0570650661aa447e7335f1d5e4f499d8e58796e617bedc9267d971e51c8b49d4"
326checksum = "3f1d92727879fb4f24cec33a35e3bff74035541326cbc12ad44ba8886d1927b0"
327327
328328[[package]]
329329name = "crc32fast"
330version = "1.4.2"
330version = "1.5.0"
331331source = "registry+https://github.com/rust-lang/crates.io-index"
332checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
332checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
333333dependencies = [
334334 "cfg-if",
335335]
......@@ -385,12 +385,13 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
385385
386386[[package]]
387387name = "ctrlc"
388version = "3.4.7"
388version = "3.5.0"
389389source = "registry+https://github.com/rust-lang/crates.io-index"
390checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73"
390checksum = "881c5d0a13b2f1498e2306e82cbada78390e152d4b1378fb28a84f4dcd0dc4f3"
391391dependencies = [
392 "dispatch",
392393 "nix",
393 "windows-sys 0.59.0",
394 "windows-sys 0.61.0",
394395]
395396
396397[[package]]
......@@ -409,18 +410,18 @@ dependencies = [
409410
410411[[package]]
411412name = "deranged"
412version = "0.4.0"
413version = "0.5.3"
413414source = "registry+https://github.com/rust-lang/crates.io-index"
414checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
415checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc"
415416dependencies = [
416417 "powerfmt",
417418]
418419
419420[[package]]
420421name = "derive-where"
421version = "1.5.0"
422version = "1.6.0"
422423source = "registry+https://github.com/rust-lang/crates.io-index"
423checksum = "510c292c8cf384b1a340b816a9a6cf2599eb8f566a44949024af88418000c50b"
424checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f"
424425dependencies = [
425426 "proc-macro2",
426427 "quote",
......@@ -429,9 +430,9 @@ dependencies = [
429430
430431[[package]]
431432name = "derive_arbitrary"
432version = "1.4.1"
433version = "1.4.2"
433434source = "registry+https://github.com/rust-lang/crates.io-index"
434checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800"
435checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
435436dependencies = [
436437 "proc-macro2",
437438 "quote",
......@@ -456,9 +457,15 @@ dependencies = [
456457 "libc",
457458 "option-ext",
458459 "redox_users",
459 "windows-sys 0.60.2",
460 "windows-sys 0.61.0",
460461]
461462
463[[package]]
464name = "dispatch"
465version = "0.2.0"
466source = "registry+https://github.com/rust-lang/crates.io-index"
467checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
468
462469[[package]]
463470name = "displaydoc"
464471version = "0.2.5"
......@@ -515,11 +522,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
515522
516523[[package]]
517524name = "erased-serde"
518version = "0.4.6"
525version = "0.4.8"
519526source = "registry+https://github.com/rust-lang/crates.io-index"
520checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
527checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b"
521528dependencies = [
522529 "serde",
530 "serde_core",
523531 "typeid",
524532]
525533
......@@ -534,16 +542,10 @@ dependencies = [
534542]
535543
536544[[package]]
537name = "filetime"
538version = "0.2.25"
545name = "find-msvc-tools"
546version = "0.1.2"
539547source = "registry+https://github.com/rust-lang/crates.io-index"
540checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
541dependencies = [
542 "cfg-if",
543 "libc",
544 "libredox",
545 "windows-sys 0.59.0",
546]
548checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959"
547549
548550[[package]]
549551name = "fixedbitset"
......@@ -569,9 +571,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
569571
570572[[package]]
571573name = "form_urlencoded"
572version = "1.2.1"
574version = "1.2.2"
573575source = "registry+https://github.com/rust-lang/crates.io-index"
574checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
576checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
575577dependencies = [
576578 "percent-encoding",
577579]
......@@ -625,22 +627,28 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
625627
626628[[package]]
627629name = "hashbrown"
628version = "0.15.4"
630version = "0.15.5"
629631source = "registry+https://github.com/rust-lang/crates.io-index"
630checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
632checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
631633dependencies = [
632634 "allocator-api2",
633635 "equivalent",
634636 "foldhash",
635637]
636638
639[[package]]
640name = "hashbrown"
641version = "0.16.0"
642source = "registry+https://github.com/rust-lang/crates.io-index"
643checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
644
637645[[package]]
638646name = "hashlink"
639647version = "0.10.0"
640648source = "registry+https://github.com/rust-lang/crates.io-index"
641649checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
642650dependencies = [
643 "hashbrown 0.15.4",
651 "hashbrown 0.15.5",
644652]
645653
646654[[package]]
......@@ -700,7 +708,7 @@ version = "0.0.0"
700708dependencies = [
701709 "arrayvec",
702710 "base-db",
703 "bitflags 2.9.1",
711 "bitflags 2.9.4",
704712 "cfg",
705713 "cov-mark",
706714 "drop_bomb",
......@@ -767,7 +775,7 @@ version = "0.0.0"
767775dependencies = [
768776 "arrayvec",
769777 "base-db",
770 "bitflags 2.9.1",
778 "bitflags 2.9.4",
771779 "chalk-derive",
772780 "chalk-ir",
773781 "cov-mark",
......@@ -780,6 +788,7 @@ dependencies = [
780788 "intern",
781789 "itertools",
782790 "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
791 "macros",
783792 "oorandom",
784793 "petgraph",
785794 "project-model",
......@@ -980,7 +989,7 @@ version = "0.0.0"
980989dependencies = [
981990 "arrayvec",
982991 "base-db",
983 "bitflags 2.9.1",
992 "bitflags 2.9.4",
984993 "cov-mark",
985994 "crossbeam-channel",
986995 "either",
......@@ -1047,9 +1056,9 @@ dependencies = [
10471056
10481057[[package]]
10491058name = "idna"
1050version = "1.0.3"
1059version = "1.1.0"
10511060source = "registry+https://github.com/rust-lang/crates.io-index"
1052checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
1061checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
10531062dependencies = [
10541063 "idna_adapter",
10551064 "smallvec",
......@@ -1068,13 +1077,14 @@ dependencies = [
10681077
10691078[[package]]
10701079name = "indexmap"
1071version = "2.9.0"
1080version = "2.11.4"
10721081source = "registry+https://github.com/rust-lang/crates.io-index"
1073checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
1082checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
10741083dependencies = [
10751084 "equivalent",
1076 "hashbrown 0.15.4",
1085 "hashbrown 0.16.0",
10771086 "serde",
1087 "serde_core",
10781088]
10791089
10801090[[package]]
......@@ -1083,7 +1093,7 @@ version = "0.11.0"
10831093source = "registry+https://github.com/rust-lang/crates.io-index"
10841094checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
10851095dependencies = [
1086 "bitflags 2.9.1",
1096 "bitflags 2.9.4",
10871097 "inotify-sys",
10881098 "libc",
10891099]
......@@ -1116,6 +1126,15 @@ dependencies = [
11161126 "memoffset",
11171127]
11181128
1129[[package]]
1130name = "inventory"
1131version = "0.3.21"
1132source = "registry+https://github.com/rust-lang/crates.io-index"
1133checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e"
1134dependencies = [
1135 "rustversion",
1136]
1137
11191138[[package]]
11201139name = "itertools"
11211140version = "0.14.0"
......@@ -1175,25 +1194,25 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
11751194
11761195[[package]]
11771196name = "libc"
1178version = "0.2.172"
1197version = "0.2.175"
11791198source = "registry+https://github.com/rust-lang/crates.io-index"
1180checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
1199checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
11811200
11821201[[package]]
11831202name = "libloading"
1184version = "0.8.8"
1203version = "0.8.9"
11851204source = "registry+https://github.com/rust-lang/crates.io-index"
1186checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
1205checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
11871206dependencies = [
11881207 "cfg-if",
1189 "windows-targets 0.53.2",
1208 "windows-link 0.2.0",
11901209]
11911210
11921211[[package]]
11931212name = "libmimalloc-sys"
1194version = "0.1.42"
1213version = "0.1.44"
11951214source = "registry+https://github.com/rust-lang/crates.io-index"
1196checksum = "ec9d6fac27761dabcd4ee73571cdb06b7022dc99089acbe5435691edffaac0f4"
1215checksum = "667f4fec20f29dfc6bc7357c582d91796c169ad7e2fce709468aefeb2c099870"
11971216dependencies = [
11981217 "cc",
11991218 "libc",
......@@ -1201,13 +1220,12 @@ dependencies = [
12011220
12021221[[package]]
12031222name = "libredox"
1204version = "0.1.3"
1223version = "0.1.10"
12051224source = "registry+https://github.com/rust-lang/crates.io-index"
1206checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
1225checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
12071226dependencies = [
1208 "bitflags 2.9.1",
1227 "bitflags 2.9.4",
12091228 "libc",
1210 "redox_syscall",
12111229]
12121230
12131231[[package]]
......@@ -1266,9 +1284,9 @@ dependencies = [
12661284
12671285[[package]]
12681286name = "log"
1269version = "0.4.27"
1287version = "0.4.28"
12701288source = "registry+https://github.com/rust-lang/crates.io-index"
1271checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
1289checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
12721290
12731291[[package]]
12741292name = "lsp-server"
......@@ -1312,6 +1330,16 @@ dependencies = [
13121330 "url",
13131331]
13141332
1333[[package]]
1334name = "macros"
1335version = "0.0.0"
1336dependencies = [
1337 "proc-macro2",
1338 "quote",
1339 "syn",
1340 "synstructure",
1341]
1342
13151343[[package]]
13161344name = "mbe"
13171345version = "0.0.0"
......@@ -1340,9 +1368,9 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
13401368
13411369[[package]]
13421370name = "memmap2"
1343version = "0.9.5"
1371version = "0.9.8"
13441372source = "registry+https://github.com/rust-lang/crates.io-index"
1345checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
1373checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7"
13461374dependencies = [
13471375 "libc",
13481376]
......@@ -1358,9 +1386,9 @@ dependencies = [
13581386
13591387[[package]]
13601388name = "mimalloc"
1361version = "0.1.46"
1389version = "0.1.48"
13621390source = "registry+https://github.com/rust-lang/crates.io-index"
1363checksum = "995942f432bbb4822a7e9c3faa87a695185b0d09273ba85f097b54f4e458f2af"
1391checksum = "e1ee66a4b64c74f4ef288bcbb9192ad9c3feaad75193129ac8509af543894fd8"
13641392dependencies = [
13651393 "libmimalloc-sys",
13661394]
......@@ -1388,11 +1416,11 @@ dependencies = [
13881416
13891417[[package]]
13901418name = "miow"
1391version = "0.6.0"
1419version = "0.6.1"
13921420source = "registry+https://github.com/rust-lang/crates.io-index"
1393checksum = "359f76430b20a79f9e20e115b3428614e654f04fab314482fc0fda0ebd3c6044"
1421checksum = "536bfad37a309d62069485248eeaba1e8d9853aaf951caaeaed0585a95346f08"
13941422dependencies = [
1395 "windows-sys 0.48.0",
1423 "windows-sys 0.61.0",
13961424]
13971425
13981426[[package]]
......@@ -1401,7 +1429,7 @@ version = "0.30.1"
14011429source = "registry+https://github.com/rust-lang/crates.io-index"
14021430checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
14031431dependencies = [
1404 "bitflags 2.9.1",
1432 "bitflags 2.9.4",
14051433 "cfg-if",
14061434 "cfg_aliases",
14071435 "libc",
......@@ -1415,12 +1443,11 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
14151443
14161444[[package]]
14171445name = "notify"
1418version = "8.0.0"
1446version = "8.2.0"
14191447source = "registry+https://github.com/rust-lang/crates.io-index"
1420checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
1448checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3"
14211449dependencies = [
1422 "bitflags 2.9.1",
1423 "filetime",
1450 "bitflags 2.9.4",
14241451 "fsevent-sys",
14251452 "inotify",
14261453 "kqueue",
......@@ -1429,7 +1456,7 @@ dependencies = [
14291456 "mio",
14301457 "notify-types",
14311458 "walkdir",
1432 "windows-sys 0.59.0",
1459 "windows-sys 0.60.2",
14331460]
14341461
14351462[[package]]
......@@ -1517,16 +1544,6 @@ dependencies = [
15171544 "num-traits",
15181545]
15191546
1520[[package]]
1521name = "papaya"
1522version = "0.2.3"
1523source = "registry+https://github.com/rust-lang/crates.io-index"
1524checksum = "f92dd0b07c53a0a0c764db2ace8c541dc47320dad97c2200c2a637ab9dd2328f"
1525dependencies = [
1526 "equivalent",
1527 "seize",
1528]
1529
15301547[[package]]
15311548name = "parking_lot"
15321549version = "0.12.4"
......@@ -1578,9 +1595,9 @@ dependencies = [
15781595
15791596[[package]]
15801597name = "percent-encoding"
1581version = "2.3.1"
1598version = "2.3.2"
15821599source = "registry+https://github.com/rust-lang/crates.io-index"
1583checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
1600checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
15841601
15851602[[package]]
15861603name = "perf-event"
......@@ -1608,7 +1625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
16081625checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca"
16091626dependencies = [
16101627 "fixedbitset",
1611 "hashbrown 0.15.4",
1628 "hashbrown 0.15.5",
16121629 "indexmap",
16131630]
16141631
......@@ -1637,9 +1654,9 @@ dependencies = [
16371654
16381655[[package]]
16391656name = "potential_utf"
1640version = "0.1.2"
1657version = "0.1.3"
16411658source = "registry+https://github.com/rust-lang/crates.io-index"
1642checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
1659checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a"
16431660dependencies = [
16441661 "zerovec",
16451662]
......@@ -1706,9 +1723,9 @@ dependencies = [
17061723
17071724[[package]]
17081725name = "proc-macro2"
1709version = "1.0.95"
1726version = "1.0.101"
17101727source = "registry+https://github.com/rust-lang/crates.io-index"
1711checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
1728checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
17121729dependencies = [
17131730 "unicode-ident",
17141731]
......@@ -1788,7 +1805,7 @@ version = "0.9.6"
17881805source = "registry+https://github.com/rust-lang/crates.io-index"
17891806checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
17901807dependencies = [
1791 "bitflags 2.9.1",
1808 "bitflags 2.9.4",
17921809 "memchr",
17931810 "unicase",
17941811]
......@@ -1825,11 +1842,11 @@ dependencies = [
18251842
18261843[[package]]
18271844name = "ra-ap-rustc_abi"
1828version = "0.132.0"
1845version = "0.133.0"
18291846source = "registry+https://github.com/rust-lang/crates.io-index"
1830checksum = "597bb303548ddcca3a2eb05af254508aaf39cf334d4350bb5da51de1eb728859"
1847checksum = "c063a7fef3c49d03837ee9a5d988aad83630c3460b03b32355c279d3fafa7d07"
18311848dependencies = [
1832 "bitflags 2.9.1",
1849 "bitflags 2.9.4",
18331850 "ra-ap-rustc_hashes",
18341851 "ra-ap-rustc_index",
18351852 "tracing",
......@@ -1837,24 +1854,24 @@ dependencies = [
18371854
18381855[[package]]
18391856name = "ra-ap-rustc_ast_ir"
1840version = "0.132.0"
1857version = "0.133.0"
18411858source = "registry+https://github.com/rust-lang/crates.io-index"
1842checksum = "78982b4e4432ee4b938e47bb5c8f1a5a5a88c27c782f193aefcc12a3250bd2e2"
1859checksum = "a210dbd77e794b33ff17d2d15750dee44eeabd1330685d69a6bad272d515892a"
18431860
18441861[[package]]
18451862name = "ra-ap-rustc_hashes"
1846version = "0.132.0"
1863version = "0.133.0"
18471864source = "registry+https://github.com/rust-lang/crates.io-index"
1848checksum = "2f7f33a422f724cc1ab43972cdd76a556b17fc256f301d23be620adfc8351df7"
1865checksum = "dea031ea45bb92cd346ed222b35c812e355f304183096ee91bb437b3813c6348"
18491866dependencies = [
18501867 "rustc-stable-hash",
18511868]
18521869
18531870[[package]]
18541871name = "ra-ap-rustc_index"
1855version = "0.132.0"
1872version = "0.133.0"
18561873source = "registry+https://github.com/rust-lang/crates.io-index"
1857checksum = "8a6006023c8be18c3ac225d69c1b42f55b3f597f3db03fb40764b4cf1454fd13"
1874checksum = "db0114f842b20cba9beb2d9002ca31ae706b47f28ba2d6a49cbf9fd65fa72b9d"
18581875dependencies = [
18591876 "ra-ap-rustc_index_macros",
18601877 "smallvec",
......@@ -1862,9 +1879,9 @@ dependencies = [
18621879
18631880[[package]]
18641881name = "ra-ap-rustc_index_macros"
1865version = "0.132.0"
1882version = "0.133.0"
18661883source = "registry+https://github.com/rust-lang/crates.io-index"
1867checksum = "9217c29f7fcc30d07ed13a62262144f665410ef1460202599ae924f9ae47ad78"
1884checksum = "bc738a5bb06fb3893725fbeb3640ff1822bb2aae3f416c4a49f0a706ba89d1cc"
18681885dependencies = [
18691886 "proc-macro2",
18701887 "quote",
......@@ -1873,9 +1890,9 @@ dependencies = [
18731890
18741891[[package]]
18751892name = "ra-ap-rustc_lexer"
1876version = "0.132.0"
1893version = "0.133.0"
18771894source = "registry+https://github.com/rust-lang/crates.io-index"
1878checksum = "573ad4f5da620e8ba1849d8862866abd7bc765c3d81cb2488c3ecbef33ce2c69"
1895checksum = "31c35b3d812cfc101d3f534640c13f24c0ec50ee2249685e4c20b2868609c9ee"
18791896dependencies = [
18801897 "memchr",
18811898 "unicode-properties",
......@@ -1884,9 +1901,9 @@ dependencies = [
18841901
18851902[[package]]
18861903name = "ra-ap-rustc_next_trait_solver"
1887version = "0.132.0"
1904version = "0.133.0"
18881905source = "registry+https://github.com/rust-lang/crates.io-index"
1889checksum = "0d42b095b99e988aeb94622ae62ebda4b7de55d7d98846eec352b8a5a2b8a858"
1906checksum = "e7b0fa6fb8e0717ebd0836f8de4a6efc954fca1a8652980fd2584dbe448c7d95"
18901907dependencies = [
18911908 "derive-where",
18921909 "ra-ap-rustc_index",
......@@ -1897,9 +1914,9 @@ dependencies = [
18971914
18981915[[package]]
18991916name = "ra-ap-rustc_parse_format"
1900version = "0.132.0"
1917version = "0.133.0"
19011918source = "registry+https://github.com/rust-lang/crates.io-index"
1902checksum = "a21b4e95cb45f840c172493c05f5b9471cf44adb2eccf95d76a0d76e88007870"
1919checksum = "33d01bad23470cc749ef607476890aabcc8993ca3ef87d4241d0f6a08c6f9402"
19031920dependencies = [
19041921 "ra-ap-rustc_lexer",
19051922 "rustc-literal-escaper 0.0.5",
......@@ -1907,9 +1924,9 @@ dependencies = [
19071924
19081925[[package]]
19091926name = "ra-ap-rustc_pattern_analysis"
1910version = "0.132.0"
1927version = "0.133.0"
19111928source = "registry+https://github.com/rust-lang/crates.io-index"
1912checksum = "b6aeacef1248066f7b67e7296ef135eeab6446d5d2a5c7f02b8d7b747b41e39b"
1929checksum = "8a181cf7943dc16e888046584d6172be95818811b25d695dbacbb4dd71973cc3"
19131930dependencies = [
19141931 "ra-ap-rustc_index",
19151932 "rustc-hash 2.1.1",
......@@ -1920,12 +1937,12 @@ dependencies = [
19201937
19211938[[package]]
19221939name = "ra-ap-rustc_type_ir"
1923version = "0.132.0"
1940version = "0.133.0"
19241941source = "registry+https://github.com/rust-lang/crates.io-index"
1925checksum = "52e35ee9e052406035016b8e6d54ca202bc39ccba1702780b33b2d5fb10d1da8"
1942checksum = "87c99f33be18d9e50cefef5442822da1f0b416e9a17a483879a9704e08a6a6e6"
19261943dependencies = [
19271944 "arrayvec",
1928 "bitflags 2.9.1",
1945 "bitflags 2.9.4",
19291946 "derive-where",
19301947 "ena",
19311948 "indexmap",
......@@ -1940,9 +1957,9 @@ dependencies = [
19401957
19411958[[package]]
19421959name = "ra-ap-rustc_type_ir_macros"
1943version = "0.132.0"
1960version = "0.133.0"
19441961source = "registry+https://github.com/rust-lang/crates.io-index"
1945checksum = "9b934c956b0c88df8176803416b69d85d2c392a69c8aa794a4c338f22c527d38"
1962checksum = "77b162d65e058abfc058e6b67ae68156cc282fbd78da148c1a7ec77b4230661e"
19461963dependencies = [
19471964 "proc-macro2",
19481965 "quote",
......@@ -1952,9 +1969,9 @@ dependencies = [
19521969
19531970[[package]]
19541971name = "rayon"
1955version = "1.10.0"
1972version = "1.11.0"
19561973source = "registry+https://github.com/rust-lang/crates.io-index"
1957checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
1974checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
19581975dependencies = [
19591976 "either",
19601977 "rayon-core",
......@@ -1962,9 +1979,9 @@ dependencies = [
19621979
19631980[[package]]
19641981name = "rayon-core"
1965version = "1.12.1"
1982version = "1.13.0"
19661983source = "registry+https://github.com/rust-lang/crates.io-index"
1967checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
1984checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
19681985dependencies = [
19691986 "crossbeam-deque",
19701987 "crossbeam-utils",
......@@ -1972,22 +1989,22 @@ dependencies = [
19721989
19731990[[package]]
19741991name = "redox_syscall"
1975version = "0.5.13"
1992version = "0.5.17"
19761993source = "registry+https://github.com/rust-lang/crates.io-index"
1977checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
1994checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
19781995dependencies = [
1979 "bitflags 2.9.1",
1996 "bitflags 2.9.4",
19801997]
19811998
19821999[[package]]
19832000name = "redox_users"
1984version = "0.5.0"
2001version = "0.5.2"
19852002source = "registry+https://github.com/rust-lang/crates.io-index"
1986checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
2003checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
19872004dependencies = [
19882005 "getrandom",
19892006 "libredox",
1990 "thiserror 2.0.12",
2007 "thiserror 2.0.16",
19912008]
19922009
19932010[[package]]
......@@ -2040,6 +2057,7 @@ dependencies = [
20402057 "process-wrap",
20412058 "profile",
20422059 "project-model",
2060 "ra-ap-rustc_type_ir",
20432061 "rayon",
20442062 "rustc-hash 2.1.1",
20452063 "scip",
......@@ -2070,9 +2088,9 @@ dependencies = [
20702088
20712089[[package]]
20722090name = "rustc-demangle"
2073version = "0.1.25"
2091version = "0.1.26"
20742092source = "registry+https://github.com/rust-lang/crates.io-index"
2075checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
2093checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
20762094
20772095[[package]]
20782096name = "rustc-hash"
......@@ -2110,7 +2128,7 @@ version = "0.2.3+llvm-462a31f5a5ab"
21102128source = "registry+https://github.com/rust-lang/crates.io-index"
21112129checksum = "486c2179b4796f65bfe2ee33679acf0927ac83ecf583ad6c91c3b4570911b9ad"
21122130dependencies = [
2113 "bitflags 2.9.1",
2131 "bitflags 2.9.4",
21142132 "smallvec",
21152133]
21162134
......@@ -2123,6 +2141,12 @@ dependencies = [
21232141 "semver",
21242142]
21252143
2144[[package]]
2145name = "rustversion"
2146version = "1.0.22"
2147source = "registry+https://github.com/rust-lang/crates.io-index"
2148checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
2149
21262150[[package]]
21272151name = "ryu"
21282152version = "1.0.20"
......@@ -2131,18 +2155,18 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
21312155
21322156[[package]]
21332157name = "salsa"
2134version = "0.23.0"
2158version = "0.24.0"
21352159source = "registry+https://github.com/rust-lang/crates.io-index"
2136checksum = "2e235afdb8e510f38a07138fbe5a0b64691894358a9c0cbd813b1aade110efc9"
2160checksum = "27956164373aeec733ac24ff1736de8541234e3a8e7e6f916b28175b5752af3b"
21372161dependencies = [
21382162 "boxcar",
21392163 "crossbeam-queue",
21402164 "crossbeam-utils",
2141 "hashbrown 0.15.4",
2165 "hashbrown 0.15.5",
21422166 "hashlink",
21432167 "indexmap",
21442168 "intrusive-collections",
2145 "papaya",
2169 "inventory",
21462170 "parking_lot",
21472171 "portable-atomic",
21482172 "rayon",
......@@ -2156,15 +2180,15 @@ dependencies = [
21562180
21572181[[package]]
21582182name = "salsa-macro-rules"
2159version = "0.23.0"
2183version = "0.24.0"
21602184source = "registry+https://github.com/rust-lang/crates.io-index"
2161checksum = "2edb86a7e9c91f6d30c9ce054312721dbe773a162db27bbfae834d16177b30ce"
2185checksum = "6ca3b9d6e47c08b5de4b218e0c5f7ec910b51bce6314e651c8e7b9d154d174da"
21622186
21632187[[package]]
21642188name = "salsa-macros"
2165version = "0.23.0"
2189version = "0.24.0"
21662190source = "registry+https://github.com/rust-lang/crates.io-index"
2167checksum = "d0778d6e209051bc4e75acfe83bcd7848601ec3dbe9c3dbb982829020e9128af"
2191checksum = "6337b62f2968be6b8afa30017d7564ecbde6832ada47ed2261fb14d0fd402ff4"
21682192dependencies = [
21692193 "proc-macro2",
21702194 "quote",
......@@ -2202,42 +2226,35 @@ version = "1.2.0"
22022226source = "registry+https://github.com/rust-lang/crates.io-index"
22032227checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
22042228
2205[[package]]
2206name = "seize"
2207version = "0.5.0"
2208source = "registry+https://github.com/rust-lang/crates.io-index"
2209checksum = "e4b8d813387d566f627f3ea1b914c068aac94c40ae27ec43f5f33bde65abefe7"
2210dependencies = [
2211 "libc",
2212 "windows-sys 0.52.0",
2213]
2214
22152229[[package]]
22162230name = "semver"
2217version = "1.0.26"
2231version = "1.0.27"
22182232source = "registry+https://github.com/rust-lang/crates.io-index"
2219checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
2233checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
22202234dependencies = [
22212235 "serde",
2236 "serde_core",
22222237]
22232238
22242239[[package]]
22252240name = "serde"
2226version = "1.0.219"
2241version = "1.0.226"
22272242source = "registry+https://github.com/rust-lang/crates.io-index"
2228checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
2243checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd"
22292244dependencies = [
2245 "serde_core",
22302246 "serde_derive",
22312247]
22322248
22332249[[package]]
22342250name = "serde-untagged"
2235version = "0.1.7"
2251version = "0.1.9"
22362252source = "registry+https://github.com/rust-lang/crates.io-index"
2237checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e"
2253checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058"
22382254dependencies = [
22392255 "erased-serde",
22402256 "serde",
2257 "serde_core",
22412258 "typeid",
22422259]
22432260
......@@ -2251,11 +2268,20 @@ dependencies = [
22512268 "serde",
22522269]
22532270
2271[[package]]
2272name = "serde_core"
2273version = "1.0.226"
2274source = "registry+https://github.com/rust-lang/crates.io-index"
2275checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4"
2276dependencies = [
2277 "serde_derive",
2278]
2279
22542280[[package]]
22552281name = "serde_derive"
2256version = "1.0.219"
2282version = "1.0.226"
22572283source = "registry+https://github.com/rust-lang/crates.io-index"
2258checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
2284checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33"
22592285dependencies = [
22602286 "proc-macro2",
22612287 "quote",
......@@ -2264,15 +2290,16 @@ dependencies = [
22642290
22652291[[package]]
22662292name = "serde_json"
2267version = "1.0.140"
2293version = "1.0.145"
22682294source = "registry+https://github.com/rust-lang/crates.io-index"
2269checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
2295checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
22702296dependencies = [
22712297 "indexmap",
22722298 "itoa",
22732299 "memchr",
22742300 "ryu",
22752301 "serde",
2302 "serde_core",
22762303]
22772304
22782305[[package]]
......@@ -2372,9 +2399,9 @@ dependencies = [
23722399
23732400[[package]]
23742401name = "syn"
2375version = "2.0.103"
2402version = "2.0.106"
23762403source = "registry+https://github.com/rust-lang/crates.io-index"
2377checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
2404checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
23782405dependencies = [
23792406 "proc-macro2",
23802407 "quote",
......@@ -2490,11 +2517,11 @@ dependencies = [
24902517
24912518[[package]]
24922519name = "thiserror"
2493version = "2.0.12"
2520version = "2.0.16"
24942521source = "registry+https://github.com/rust-lang/crates.io-index"
2495checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
2522checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
24962523dependencies = [
2497 "thiserror-impl 2.0.12",
2524 "thiserror-impl 2.0.16",
24982525]
24992526
25002527[[package]]
......@@ -2510,9 +2537,9 @@ dependencies = [
25102537
25112538[[package]]
25122539name = "thiserror-impl"
2513version = "2.0.12"
2540version = "2.0.16"
25142541source = "registry+https://github.com/rust-lang/crates.io-index"
2515checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
2542checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
25162543dependencies = [
25172544 "proc-macro2",
25182545 "quote",
......@@ -2561,9 +2588,9 @@ dependencies = [
25612588
25622589[[package]]
25632590name = "time"
2564version = "0.3.41"
2591version = "0.3.44"
25652592source = "registry+https://github.com/rust-lang/crates.io-index"
2566checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
2593checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
25672594dependencies = [
25682595 "deranged",
25692596 "itoa",
......@@ -2578,15 +2605,15 @@ dependencies = [
25782605
25792606[[package]]
25802607name = "time-core"
2581version = "0.1.4"
2608version = "0.1.6"
25822609source = "registry+https://github.com/rust-lang/crates.io-index"
2583checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
2610checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
25842611
25852612[[package]]
25862613name = "time-macros"
2587version = "0.2.22"
2614version = "0.2.24"
25882615source = "registry+https://github.com/rust-lang/crates.io-index"
2589checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
2616checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
25902617dependencies = [
25912618 "num-conv",
25922619 "time-core",
......@@ -2664,9 +2691,9 @@ dependencies = [
26642691
26652692[[package]]
26662693name = "tracing-attributes"
2667version = "0.1.29"
2694version = "0.1.30"
26682695source = "registry+https://github.com/rust-lang/crates.io-index"
2669checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662"
2696checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
26702697dependencies = [
26712698 "proc-macro2",
26722699 "quote",
......@@ -2762,9 +2789,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
27622789
27632790[[package]]
27642791name = "unicode-ident"
2765version = "1.0.18"
2792version = "1.0.19"
27662793source = "registry+https://github.com/rust-lang/crates.io-index"
2767checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
2794checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
27682795
27692796[[package]]
27702797name = "unicode-properties"
......@@ -2780,9 +2807,9 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
27802807
27812808[[package]]
27822809name = "url"
2783version = "2.5.4"
2810version = "2.5.7"
27842811source = "registry+https://github.com/rust-lang/crates.io-index"
2785checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
2812checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
27862813dependencies = [
27872814 "form_urlencoded",
27882815 "idna",
......@@ -2849,11 +2876,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
28492876
28502877[[package]]
28512878name = "winapi-util"
2852version = "0.1.9"
2879version = "0.1.11"
28532880source = "registry+https://github.com/rust-lang/crates.io-index"
2854checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
2881checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
28552882dependencies = [
2856 "windows-sys 0.59.0",
2883 "windows-sys 0.61.0",
28572884]
28582885
28592886[[package]]
......@@ -2865,7 +2892,7 @@ dependencies = [
28652892 "windows-collections",
28662893 "windows-core",
28672894 "windows-future",
2868 "windows-link",
2895 "windows-link 0.1.3",
28692896 "windows-numerics",
28702897]
28712898
......@@ -2886,7 +2913,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
28862913dependencies = [
28872914 "windows-implement",
28882915 "windows-interface",
2889 "windows-link",
2916 "windows-link 0.1.3",
28902917 "windows-result",
28912918 "windows-strings",
28922919]
......@@ -2898,7 +2925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
28982925checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
28992926dependencies = [
29002927 "windows-core",
2901 "windows-link",
2928 "windows-link 0.1.3",
29022929 "windows-threading",
29032930]
29042931
......@@ -2930,6 +2957,12 @@ version = "0.1.3"
29302957source = "registry+https://github.com/rust-lang/crates.io-index"
29312958checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
29322959
2960[[package]]
2961name = "windows-link"
2962version = "0.2.0"
2963source = "registry+https://github.com/rust-lang/crates.io-index"
2964checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
2965
29332966[[package]]
29342967name = "windows-numerics"
29352968version = "0.2.0"
......@@ -2937,7 +2970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
29372970checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
29382971dependencies = [
29392972 "windows-core",
2940 "windows-link",
2973 "windows-link 0.1.3",
29412974]
29422975
29432976[[package]]
......@@ -2946,7 +2979,7 @@ version = "0.3.4"
29462979source = "registry+https://github.com/rust-lang/crates.io-index"
29472980checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
29482981dependencies = [
2949 "windows-link",
2982 "windows-link 0.1.3",
29502983]
29512984
29522985[[package]]
......@@ -2955,16 +2988,7 @@ version = "0.4.2"
29552988source = "registry+https://github.com/rust-lang/crates.io-index"
29562989checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
29572990dependencies = [
2958 "windows-link",
2959]
2960
2961[[package]]
2962name = "windows-sys"
2963version = "0.48.0"
2964source = "registry+https://github.com/rust-lang/crates.io-index"
2965checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
2966dependencies = [
2967 "windows-targets 0.48.5",
2991 "windows-link 0.1.3",
29682992]
29692993
29702994[[package]]
......@@ -2991,22 +3015,16 @@ version = "0.60.2"
29913015source = "registry+https://github.com/rust-lang/crates.io-index"
29923016checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
29933017dependencies = [
2994 "windows-targets 0.53.2",
3018 "windows-targets 0.53.3",
29953019]
29963020
29973021[[package]]
2998name = "windows-targets"
2999version = "0.48.5"
3022name = "windows-sys"
3023version = "0.61.0"
30003024source = "registry+https://github.com/rust-lang/crates.io-index"
3001checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
3025checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
30023026dependencies = [
3003 "windows_aarch64_gnullvm 0.48.5",
3004 "windows_aarch64_msvc 0.48.5",
3005 "windows_i686_gnu 0.48.5",
3006 "windows_i686_msvc 0.48.5",
3007 "windows_x86_64_gnu 0.48.5",
3008 "windows_x86_64_gnullvm 0.48.5",
3009 "windows_x86_64_msvc 0.48.5",
3027 "windows-link 0.2.0",
30103028]
30113029
30123030[[package]]
......@@ -3027,10 +3045,11 @@ dependencies = [
30273045
30283046[[package]]
30293047name = "windows-targets"
3030version = "0.53.2"
3048version = "0.53.3"
30313049source = "registry+https://github.com/rust-lang/crates.io-index"
3032checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
3050checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
30333051dependencies = [
3052 "windows-link 0.1.3",
30343053 "windows_aarch64_gnullvm 0.53.0",
30353054 "windows_aarch64_msvc 0.53.0",
30363055 "windows_i686_gnu 0.53.0",
......@@ -3047,15 +3066,9 @@ version = "0.1.0"
30473066source = "registry+https://github.com/rust-lang/crates.io-index"
30483067checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
30493068dependencies = [
3050 "windows-link",
3069 "windows-link 0.1.3",
30513070]
30523071
3053[[package]]
3054name = "windows_aarch64_gnullvm"
3055version = "0.48.5"
3056source = "registry+https://github.com/rust-lang/crates.io-index"
3057checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
3058
30593072[[package]]
30603073name = "windows_aarch64_gnullvm"
30613074version = "0.52.6"
......@@ -3068,12 +3081,6 @@ version = "0.53.0"
30683081source = "registry+https://github.com/rust-lang/crates.io-index"
30693082checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
30703083
3071[[package]]
3072name = "windows_aarch64_msvc"
3073version = "0.48.5"
3074source = "registry+https://github.com/rust-lang/crates.io-index"
3075checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
3076
30773084[[package]]
30783085name = "windows_aarch64_msvc"
30793086version = "0.52.6"
......@@ -3086,12 +3093,6 @@ version = "0.53.0"
30863093source = "registry+https://github.com/rust-lang/crates.io-index"
30873094checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
30883095
3089[[package]]
3090name = "windows_i686_gnu"
3091version = "0.48.5"
3092source = "registry+https://github.com/rust-lang/crates.io-index"
3093checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
3094
30953096[[package]]
30963097name = "windows_i686_gnu"
30973098version = "0.52.6"
......@@ -3116,12 +3117,6 @@ version = "0.53.0"
31163117source = "registry+https://github.com/rust-lang/crates.io-index"
31173118checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
31183119
3119[[package]]
3120name = "windows_i686_msvc"
3121version = "0.48.5"
3122source = "registry+https://github.com/rust-lang/crates.io-index"
3123checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
3124
31253120[[package]]
31263121name = "windows_i686_msvc"
31273122version = "0.52.6"
......@@ -3134,12 +3129,6 @@ version = "0.53.0"
31343129source = "registry+https://github.com/rust-lang/crates.io-index"
31353130checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
31363131
3137[[package]]
3138name = "windows_x86_64_gnu"
3139version = "0.48.5"
3140source = "registry+https://github.com/rust-lang/crates.io-index"
3141checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
3142
31433132[[package]]
31443133name = "windows_x86_64_gnu"
31453134version = "0.52.6"
......@@ -3152,12 +3141,6 @@ version = "0.53.0"
31523141source = "registry+https://github.com/rust-lang/crates.io-index"
31533142checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
31543143
3155[[package]]
3156name = "windows_x86_64_gnullvm"
3157version = "0.48.5"
3158source = "registry+https://github.com/rust-lang/crates.io-index"
3159checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
3160
31613144[[package]]
31623145name = "windows_x86_64_gnullvm"
31633146version = "0.52.6"
......@@ -3170,12 +3153,6 @@ version = "0.53.0"
31703153source = "registry+https://github.com/rust-lang/crates.io-index"
31713154checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
31723155
3173[[package]]
3174name = "windows_x86_64_msvc"
3175version = "0.48.5"
3176source = "registry+https://github.com/rust-lang/crates.io-index"
3177checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
3178
31793156[[package]]
31803157name = "windows_x86_64_msvc"
31813158version = "0.52.6"
......@@ -3190,9 +3167,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
31903167
31913168[[package]]
31923169name = "winnow"
3193version = "0.7.11"
3170version = "0.7.13"
31943171source = "registry+https://github.com/rust-lang/crates.io-index"
3195checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
3172checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
31963173dependencies = [
31973174 "memchr",
31983175]
......@@ -3317,9 +3294,9 @@ dependencies = [
33173294
33183295[[package]]
33193296name = "zerovec"
3320version = "0.11.2"
3297version = "0.11.4"
33213298source = "registry+https://github.com/rust-lang/crates.io-index"
3322checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
3299checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b"
33233300dependencies = [
33243301 "yoke",
33253302 "zerofrom",
......@@ -3339,9 +3316,9 @@ dependencies = [
33393316
33403317[[package]]
33413318name = "zip"
3342version = "4.0.0"
3319version = "4.6.1"
33433320source = "registry+https://github.com/rust-lang/crates.io-index"
3344checksum = "153a6fff49d264c4babdcfa6b4d534747f520e56e8f0f384f3b808c4b64cc1fd"
3321checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1"
33453322dependencies = [
33463323 "arbitrary",
33473324 "crc32fast",
src/tools/rust-analyzer/Cargo.toml+11-10
......@@ -52,6 +52,7 @@ debug = 2
5252
5353[workspace.dependencies]
5454# local crates
55macros = { path = "./crates/macros", version = "0.0.0" }
5556base-db = { path = "./crates/base-db", version = "0.0.0" }
5657cfg = { path = "./crates/cfg", version = "0.0.0", features = ["tt"] }
5758hir = { path = "./crates/hir", version = "0.0.0" }
......@@ -87,14 +88,14 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
8788vfs = { path = "./crates/vfs", version = "0.0.0" }
8889edition = { path = "./crates/edition", version = "0.0.0" }
8990
90ra-ap-rustc_lexer = { version = "0.132", default-features = false }
91ra-ap-rustc_parse_format = { version = "0.132", default-features = false }
92ra-ap-rustc_index = { version = "0.132", default-features = false }
93ra-ap-rustc_abi = { version = "0.132", default-features = false }
94ra-ap-rustc_pattern_analysis = { version = "0.132", default-features = false }
95ra-ap-rustc_ast_ir = { version = "0.132", default-features = false }
96ra-ap-rustc_type_ir = { version = "0.132", default-features = false }
97ra-ap-rustc_next_trait_solver = { version = "0.132", default-features = false }
91ra-ap-rustc_lexer = { version = "0.133", default-features = false }
92ra-ap-rustc_parse_format = { version = "0.133", default-features = false }
93ra-ap-rustc_index = { version = "0.133", default-features = false }
94ra-ap-rustc_abi = { version = "0.133", default-features = false }
95ra-ap-rustc_pattern_analysis = { version = "0.133", default-features = false }
96ra-ap-rustc_ast_ir = { version = "0.133", default-features = false }
97ra-ap-rustc_type_ir = { version = "0.133", default-features = false }
98ra-ap-rustc_next_trait_solver = { version = "0.133", default-features = false }
9899
99100# local crates that aren't published to crates.io. These should not have versions.
100101
......@@ -137,12 +138,12 @@ rayon = "1.10.0"
137138rowan = "=0.15.15"
138139# Ideally we'd not enable the macros feature but unfortunately the `tracked` attribute does not work
139140# on impls without it
140salsa = { version = "0.23.0", default-features = true, features = [
141salsa = { version = "0.24.0", default-features = true, features = [
141142 "rayon",
142143 "salsa_unstable",
143144 "macros",
144145] }
145salsa-macros = "0.23.0"
146salsa-macros = "0.24.0"
146147semver = "1.0.26"
147148serde = { version = "1.0.219" }
148149serde_derive = { version = "1.0.219" }
src/tools/rust-analyzer/README.md+1-1
......@@ -61,4 +61,4 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer
6161rust-analyzer is primarily distributed under the terms of both the MIT
6262license and the Apache License (Version 2.0).
6363
64See LICENSE-APACHE and LICENSE-MIT for details.
64See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.
src/tools/rust-analyzer/crates/cfg/Cargo.toml+1-5
......@@ -23,11 +23,7 @@ intern.workspace = true
2323[dev-dependencies]
2424expect-test = "1.5.1"
2525oorandom = "11.1.5"
26# We depend on both individually instead of using `features = ["derive"]` to microoptimize the
27# build graph: if the feature was enabled, syn would be built early on in the graph if `smolstr`
28# supports `arbitrary`. This way, we avoid feature unification.
29arbitrary = "1.4.1"
30derive_arbitrary = "1.4.1"
26arbitrary = { version = "1.4.1", features = ["derive"] }
3127
3228# local deps
3329syntax-bridge.workspace = true
src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs+1-1
......@@ -47,7 +47,7 @@ impl fmt::Display for CfgAtom {
4747}
4848
4949#[derive(Debug, Clone, PartialEq, Eq, Hash)]
50#[cfg_attr(test, derive(derive_arbitrary::Arbitrary))]
50#[cfg_attr(test, derive(arbitrary::Arbitrary))]
5151pub enum CfgExpr {
5252 Invalid,
5353 Atom(CfgAtom),
src/tools/rust-analyzer/crates/hir-def/src/expr_store/path.rs+1-1
......@@ -88,7 +88,7 @@ pub struct AssociatedTypeBinding {
8888}
8989
9090/// A single generic argument.
91#[derive(Debug, Clone, PartialEq, Eq, Hash)]
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9292pub enum GenericArg {
9393 Type(TypeRefId),
9494 Lifetime(LifetimeRefId),
src/tools/rust-analyzer/crates/hir-def/src/signatures.rs+14
......@@ -349,6 +349,7 @@ bitflags::bitflags! {
349349 #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
350350 pub struct ImplFlags: u8 {
351351 const NEGATIVE = 1 << 1;
352 const DEFAULT = 1 << 2;
352353 const UNSAFE = 1 << 3;
353354 }
354355}
......@@ -374,6 +375,9 @@ impl ImplSignature {
374375 if src.value.excl_token().is_some() {
375376 flags.insert(ImplFlags::NEGATIVE);
376377 }
378 if src.value.default_token().is_some() {
379 flags.insert(ImplFlags::DEFAULT);
380 }
377381
378382 let (store, source_map, self_ty, target_trait, generic_params) =
379383 crate::expr_store::lower::lower_impl(db, loc.container, src, id);
......@@ -389,6 +393,16 @@ impl ImplSignature {
389393 Arc::new(source_map),
390394 )
391395 }
396
397 #[inline]
398 pub fn is_negative(&self) -> bool {
399 self.flags.contains(ImplFlags::NEGATIVE)
400 }
401
402 #[inline]
403 pub fn is_default(&self) -> bool {
404 self.flags.contains(ImplFlags::DEFAULT)
405 }
392406}
393407
394408bitflags::bitflags! {
src/tools/rust-analyzer/crates/hir-def/src/test_db.rs+2-3
......@@ -7,7 +7,7 @@ use base_db::{
77 SourceDatabase, SourceRoot, SourceRootId, SourceRootInput,
88};
99use hir_expand::{InFile, files::FilePosition};
10use salsa::{AsDynDatabase, Durability};
10use salsa::Durability;
1111use span::FileId;
1212use syntax::{AstNode, algo, ast};
1313use triomphe::Arc;
......@@ -303,8 +303,7 @@ impl TestDB {
303303 // This is pretty horrible, but `Debug` is the only way to inspect
304304 // QueryDescriptor at the moment.
305305 salsa::EventKind::WillExecute { database_key } => {
306 let ingredient = self
307 .as_dyn_database()
306 let ingredient = (self as &dyn salsa::Database)
308307 .ingredient_debug_name(database_key.ingredient_index());
309308 Some(ingredient.to_string())
310309 }
src/tools/rust-analyzer/crates/hir-ty/Cargo.toml+1
......@@ -50,6 +50,7 @@ tracing-tree.workspace = true
5050
5151# local deps
5252stdx.workspace = true
53macros.workspace = true
5354intern.workspace = true
5455hir-def.workspace = true
5556hir-expand.workspace = true
src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs+44-21
......@@ -5,20 +5,21 @@
55
66use std::fmt;
77
8use hir_def::{TypeAliasId, lang_item::LangItem};
8use hir_def::{TraitId, TypeAliasId, lang_item::LangItem};
99use rustc_type_ir::inherent::{IntoKind, Ty as _};
1010use tracing::debug;
1111use triomphe::Arc;
1212
13use crate::next_solver::infer::InferOk;
1413use crate::{
1514 TraitEnvironment,
1615 db::HirDatabase,
1716 infer::unify::InferenceTable,
1817 next_solver::{
19 Ty, TyKind,
20 infer::traits::{ObligationCause, PredicateObligations},
21 mapping::{ChalkToNextSolver, NextSolverToChalk},
18 Canonical, TraitRef, Ty, TyKind,
19 infer::{
20 InferOk,
21 traits::{Obligation, ObligationCause, PredicateObligations},
22 },
2223 obligation_ctxt::ObligationCtxt,
2324 },
2425};
......@@ -35,17 +36,16 @@ const AUTODEREF_RECURSION_LIMIT: usize = 20;
3536pub fn autoderef<'db>(
3637 db: &'db dyn HirDatabase,
3738 env: Arc<TraitEnvironment<'db>>,
38 ty: crate::Canonical<crate::Ty>,
39) -> impl Iterator<Item = crate::Ty> + use<> {
39 ty: Canonical<'db, Ty<'db>>,
40) -> impl Iterator<Item = Ty<'db>> + use<'db> {
4041 let mut table = InferenceTable::new(db, env);
41 let interner = table.interner;
4242 let ty = table.instantiate_canonical(ty);
43 let mut autoderef = Autoderef::new_no_tracking(&mut table, ty.to_nextsolver(interner));
43 let mut autoderef = Autoderef::new_no_tracking(&mut table, ty);
4444 let mut v = Vec::new();
4545 while let Some((ty, _steps)) = autoderef.next() {
4646 // `ty` may contain unresolved inference variables. Since there's no chance they would be
4747 // resolved, just replace with fallback type.
48 let resolved = autoderef.table.resolve_completely(ty.to_chalk(interner));
48 let resolved = autoderef.table.resolve_completely(ty);
4949
5050 // If the deref chain contains a cycle (e.g. `A` derefs to `B` and `B` derefs to `A`), we
5151 // would revisit some already visited types. Stop here to avoid duplication.
......@@ -101,6 +101,7 @@ struct AutoderefSnapshot<'db, Steps> {
101101
102102#[derive(Clone, Copy)]
103103struct AutoderefTraits {
104 trait_: TraitId,
104105 trait_target: TypeAliasId,
105106}
106107
......@@ -215,16 +216,26 @@ impl<'a, 'db, Steps: TrackAutoderefSteps<'db>> Autoderef<'a, 'db, Steps> {
215216 Some(it) => Some(*it),
216217 None => {
217218 let traits = if self.use_receiver_trait {
218 AutoderefTraits {
219 trait_target: LangItem::ReceiverTarget
220 .resolve_type_alias(self.table.db, self.table.trait_env.krate)
221 .or_else(|| {
222 LangItem::DerefTarget
223 .resolve_type_alias(self.table.db, self.table.trait_env.krate)
224 })?,
225 }
219 (|| {
220 Some(AutoderefTraits {
221 trait_: LangItem::Receiver
222 .resolve_trait(self.table.db, self.table.trait_env.krate)?,
223 trait_target: LangItem::ReceiverTarget
224 .resolve_type_alias(self.table.db, self.table.trait_env.krate)?,
225 })
226 })()
227 .or_else(|| {
228 Some(AutoderefTraits {
229 trait_: LangItem::Deref
230 .resolve_trait(self.table.db, self.table.trait_env.krate)?,
231 trait_target: LangItem::DerefTarget
232 .resolve_type_alias(self.table.db, self.table.trait_env.krate)?,
233 })
234 })?
226235 } else {
227236 AutoderefTraits {
237 trait_: LangItem::Deref
238 .resolve_trait(self.table.db, self.table.trait_env.krate)?,
228239 trait_target: LangItem::DerefTarget
229240 .resolve_type_alias(self.table.db, self.table.trait_env.krate)?,
230241 }
......@@ -236,10 +247,22 @@ impl<'a, 'db, Steps: TrackAutoderefSteps<'db>> Autoderef<'a, 'db, Steps> {
236247
237248 fn overloaded_deref_ty(&mut self, ty: Ty<'db>) -> Option<Ty<'db>> {
238249 debug!("overloaded_deref_ty({:?})", ty);
239 let interner = self.table.interner;
250 let interner = self.table.interner();
240251
241252 // <ty as Deref>, or whatever the equivalent trait is that we've been asked to walk.
242 let AutoderefTraits { trait_target } = self.autoderef_traits()?;
253 let AutoderefTraits { trait_, trait_target } = self.autoderef_traits()?;
254
255 let trait_ref = TraitRef::new(interner, trait_.into(), [ty]);
256 let obligation =
257 Obligation::new(interner, ObligationCause::new(), self.table.trait_env.env, trait_ref);
258 // We detect whether the self type implements `Deref` before trying to
259 // structurally normalize. We use `predicate_may_hold_opaque_types_jank`
260 // to support not-yet-defined opaque types. It will succeed for `impl Deref`
261 // but fail for `impl OtherTrait`.
262 if !self.table.infer_ctxt.predicate_may_hold_opaque_types_jank(&obligation) {
263 debug!("overloaded_deref_ty: cannot match obligation");
264 return None;
265 }
243266
244267 let (normalized_ty, obligations) = structurally_normalize_ty(
245268 self.table,
......@@ -316,7 +339,7 @@ pub(crate) fn overloaded_deref_ty<'db>(
316339 table: &InferenceTable<'db>,
317340 ty: Ty<'db>,
318341) -> Option<InferOk<'db, Ty<'db>>> {
319 let interner = table.interner;
342 let interner = table.interner();
320343
321344 let trait_target = LangItem::DerefTarget.resolve_type_alias(table.db, table.trait_env.krate)?;
322345
src/tools/rust-analyzer/crates/hir-ty/src/builder.rs+23-8
......@@ -15,7 +15,10 @@ use crate::{
1515 error_lifetime,
1616 generics::generics,
1717 infer::unify::InferenceTable,
18 next_solver::{DbInterner, EarlyBinder, mapping::ChalkToNextSolver},
18 next_solver::{
19 DbInterner, EarlyBinder,
20 mapping::{ChalkToNextSolver, NextSolverToChalk},
21 },
1922 primitive, to_assoc_type_id, to_chalk_trait_id,
2023};
2124
......@@ -127,11 +130,14 @@ impl<D> TyBuilder<D> {
127130 }
128131
129132 pub fn fill_with_unknown(self) -> Self {
133 let interner = DbInterner::conjure();
130134 // self.fill is inlined to make borrow checker happy
131135 let mut this = self;
132136 let filler = this.param_kinds[this.vec.len()..].iter().map(|x| match x {
133137 ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
134 ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
138 ParamKind::Const(ty) => {
139 unknown_const_as_generic(ty.to_nextsolver(interner)).to_chalk(interner)
140 }
135141 ParamKind::Lifetime => error_lifetime().cast(Interner),
136142 });
137143 this.vec.extend(filler.casted(Interner));
......@@ -141,10 +147,13 @@ impl<D> TyBuilder<D> {
141147
142148 #[tracing::instrument(skip_all)]
143149 pub(crate) fn fill_with_inference_vars(self, table: &mut InferenceTable<'_>) -> Self {
144 self.fill(|x| match x {
145 ParamKind::Type => table.new_type_var().cast(Interner),
146 ParamKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
147 ParamKind::Lifetime => table.new_lifetime_var().cast(Interner),
150 self.fill(|x| {
151 match x {
152 ParamKind::Type => crate::next_solver::GenericArg::Ty(table.next_ty_var()),
153 ParamKind::Const(_) => table.next_const_var().into(),
154 ParamKind::Lifetime => table.next_region_var().into(),
155 }
156 .to_chalk(table.interner())
148157 })
149158 }
150159
......@@ -213,13 +222,16 @@ impl TyBuilder<()> {
213222 }
214223
215224 pub fn unknown_subst(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
225 let interner = DbInterner::conjure();
216226 let params = generics(db, def.into());
217227 Substitution::from_iter(
218228 Interner,
219229 params.iter_id().map(|id| match id {
220230 GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
221231 GenericParamId::ConstParamId(id) => {
222 unknown_const_as_generic(db.const_param_ty(id)).cast(Interner)
232 unknown_const_as_generic(db.const_param_ty_ns(id))
233 .to_chalk(interner)
234 .cast(Interner)
223235 }
224236 GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
225237 }),
......@@ -261,6 +273,7 @@ impl TyBuilder<hir_def::AdtId> {
261273 db: &dyn HirDatabase,
262274 mut fallback: impl FnMut() -> Ty,
263275 ) -> Self {
276 let interner = DbInterner::conjure();
264277 // Note that we're building ADT, so we never have parent generic parameters.
265278 let defaults = db.generic_defaults(self.data.into());
266279
......@@ -281,7 +294,9 @@ impl TyBuilder<hir_def::AdtId> {
281294 // The defaults may be missing if no param has default, so fill that.
282295 let filler = self.param_kinds[self.vec.len()..].iter().map(|x| match x {
283296 ParamKind::Type => fallback().cast(Interner),
284 ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
297 ParamKind::Const(ty) => {
298 unknown_const_as_generic(ty.to_nextsolver(interner)).to_chalk(interner)
299 }
285300 ParamKind::Lifetime => error_lifetime().cast(Interner),
286301 });
287302 self.vec.extend(filler.casted(Interner));
src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs+1-14
......@@ -2,7 +2,7 @@
22//! about the code that Chalk needs.
33use hir_def::{CallableDefId, GenericDefId};
44
5use crate::{Interner, Substitution, db::HirDatabase, mapping::from_chalk};
5use crate::{Interner, db::HirDatabase, mapping::from_chalk};
66
77pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
88pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
......@@ -53,16 +53,3 @@ pub(crate) fn adt_variance_query(db: &dyn HirDatabase, adt_id: hir_def::AdtId) -
5353 }),
5454 )
5555}
56
57/// Returns instantiated predicates.
58pub(super) fn convert_where_clauses(
59 db: &dyn HirDatabase,
60 def: GenericDefId,
61 substs: &Substitution,
62) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
63 db.generic_predicates(def)
64 .iter()
65 .cloned()
66 .map(|pred| pred.substitute(Interner, substs))
67 .collect()
68}
src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs+7-320
......@@ -1,66 +1,32 @@
11//! Various extensions traits for Chalk types.
22
3use chalk_ir::{
4 FloatTy, IntTy, Mutability, Scalar, TyVariableKind, TypeOutlives, UintTy, cast::Cast,
5};
6use hir_def::{
7 DefWithBodyId, FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId,
8 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
9 hir::generics::{TypeOrConstParamData, TypeParamProvenance},
10 lang_item::LangItem,
11 type_ref::Rawness,
12};
3use chalk_ir::Mutability;
4use hir_def::{FunctionId, ItemContainerId, Lookup, TraitId};
135
146use crate::{
15 AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Canonical, CanonicalVarKinds,
16 ClosureId, DynTy, FnPointer, ImplTraitId, InEnvironment, Interner, Lifetime, ProjectionTy,
17 QuantifiedWhereClause, Substitution, ToChalk, TraitRef, Ty, TyBuilder, TyKind, TypeFlags,
18 WhereClause,
19 db::HirDatabase,
20 from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
21 generics::generics,
22 next_solver::{DbInterner, mapping::NextSolverToChalk},
23 to_chalk_trait_id,
7 AdtId, Binders, CallableDefId, CallableSig, DynTy, Interner, Lifetime, ProjectionTy,
8 Substitution, ToChalk, TraitRef, Ty, TyKind, TypeFlags, WhereClause, db::HirDatabase,
9 from_assoc_type_id, from_chalk_trait_id, generics::generics, to_chalk_trait_id,
2410 utils::ClosureSubst,
2511};
2612
27pub trait TyExt {
13pub(crate) trait TyExt {
2814 fn is_unit(&self) -> bool;
29 fn is_integral(&self) -> bool;
30 fn is_scalar(&self) -> bool;
31 fn is_floating_point(&self) -> bool;
32 fn is_never(&self) -> bool;
33 fn is_str(&self) -> bool;
3415 fn is_unknown(&self) -> bool;
3516 fn contains_unknown(&self) -> bool;
36 fn is_ty_var(&self) -> bool;
37 fn is_union(&self) -> bool;
3817
3918 fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
40 fn as_builtin(&self) -> Option<BuiltinType>;
4119 fn as_tuple(&self) -> Option<&Substitution>;
42 fn as_closure(&self) -> Option<ClosureId>;
4320 fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId>;
4421 fn as_reference(&self) -> Option<(&Ty, Lifetime, Mutability)>;
45 fn as_raw_ptr(&self) -> Option<(&Ty, Mutability)>;
46 fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)>;
47 fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId>;
4822
4923 fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId>;
5024 fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig>;
5125
5226 fn strip_references(&self) -> &Ty;
53 fn strip_reference(&self) -> &Ty;
5427
5528 /// If this is a `dyn Trait`, returns that trait.
5629 fn dyn_trait(&self) -> Option<TraitId>;
57
58 fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>>;
59 fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId>;
60 fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool;
61
62 /// FIXME: Get rid of this, it's not a good abstraction
63 fn equals_ctor(&self, other: &Ty) -> bool;
6430}
6531
6632impl TyExt for Ty {
......@@ -68,33 +34,6 @@ impl TyExt for Ty {
6834 matches!(self.kind(Interner), TyKind::Tuple(0, _))
6935 }
7036
71 fn is_integral(&self) -> bool {
72 matches!(
73 self.kind(Interner),
74 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))
75 | TyKind::InferenceVar(_, TyVariableKind::Integer)
76 )
77 }
78
79 fn is_scalar(&self) -> bool {
80 matches!(self.kind(Interner), TyKind::Scalar(_))
81 }
82
83 fn is_floating_point(&self) -> bool {
84 matches!(
85 self.kind(Interner),
86 TyKind::Scalar(Scalar::Float(_)) | TyKind::InferenceVar(_, TyVariableKind::Float)
87 )
88 }
89
90 fn is_never(&self) -> bool {
91 matches!(self.kind(Interner), TyKind::Never)
92 }
93
94 fn is_str(&self) -> bool {
95 matches!(self.kind(Interner), TyKind::Str)
96 }
97
9837 fn is_unknown(&self) -> bool {
9938 matches!(self.kind(Interner), TyKind::Error)
10039 }
......@@ -103,14 +42,6 @@ impl TyExt for Ty {
10342 self.data(Interner).flags.contains(TypeFlags::HAS_ERROR)
10443 }
10544
106 fn is_ty_var(&self) -> bool {
107 matches!(self.kind(Interner), TyKind::InferenceVar(_, _))
108 }
109
110 fn is_union(&self) -> bool {
111 matches!(self.adt_id(Interner), Some(AdtId(hir_def::AdtId::UnionId(_))))
112 }
113
11445 fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
11546 match self.kind(Interner) {
11647 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
......@@ -118,37 +49,6 @@ impl TyExt for Ty {
11849 }
11950 }
12051
121 fn as_builtin(&self) -> Option<BuiltinType> {
122 match self.kind(Interner) {
123 TyKind::Str => Some(BuiltinType::Str),
124 TyKind::Scalar(Scalar::Bool) => Some(BuiltinType::Bool),
125 TyKind::Scalar(Scalar::Char) => Some(BuiltinType::Char),
126 TyKind::Scalar(Scalar::Float(fty)) => Some(BuiltinType::Float(match fty {
127 FloatTy::F128 => BuiltinFloat::F128,
128 FloatTy::F64 => BuiltinFloat::F64,
129 FloatTy::F32 => BuiltinFloat::F32,
130 FloatTy::F16 => BuiltinFloat::F16,
131 })),
132 TyKind::Scalar(Scalar::Int(ity)) => Some(BuiltinType::Int(match ity {
133 IntTy::Isize => BuiltinInt::Isize,
134 IntTy::I8 => BuiltinInt::I8,
135 IntTy::I16 => BuiltinInt::I16,
136 IntTy::I32 => BuiltinInt::I32,
137 IntTy::I64 => BuiltinInt::I64,
138 IntTy::I128 => BuiltinInt::I128,
139 })),
140 TyKind::Scalar(Scalar::Uint(ity)) => Some(BuiltinType::Uint(match ity {
141 UintTy::Usize => BuiltinUint::Usize,
142 UintTy::U8 => BuiltinUint::U8,
143 UintTy::U16 => BuiltinUint::U16,
144 UintTy::U32 => BuiltinUint::U32,
145 UintTy::U64 => BuiltinUint::U64,
146 UintTy::U128 => BuiltinUint::U128,
147 })),
148 _ => None,
149 }
150 }
151
15252 fn as_tuple(&self) -> Option<&Substitution> {
15353 match self.kind(Interner) {
15454 TyKind::Tuple(_, substs) => Some(substs),
......@@ -156,13 +56,6 @@ impl TyExt for Ty {
15656 }
15757 }
15858
159 fn as_closure(&self) -> Option<ClosureId> {
160 match self.kind(Interner) {
161 TyKind::Closure(id, _) => Some(*id),
162 _ => None,
163 }
164 }
165
16659 fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> {
16760 match self.callable_def(db) {
16861 Some(CallableDefId::FunctionId(func)) => Some(func),
......@@ -177,33 +70,6 @@ impl TyExt for Ty {
17770 }
17871 }
17972
180 fn as_raw_ptr(&self) -> Option<(&Ty, Mutability)> {
181 match self.kind(Interner) {
182 TyKind::Raw(mutability, ty) => Some((ty, *mutability)),
183 _ => None,
184 }
185 }
186
187 fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
188 match self.kind(Interner) {
189 TyKind::Ref(mutability, _, ty) => Some((ty, Rawness::Ref, *mutability)),
190 TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)),
191 _ => None,
192 }
193 }
194
195 fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
196 match *self.kind(Interner) {
197 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
198 TyKind::FnDef(callable, ..) => {
199 Some(GenericDefId::from_callable(db, ToChalk::from_chalk(db, callable)))
200 }
201 TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()),
202 TyKind::Foreign(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
203 _ => None,
204 }
205 }
206
20773 fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> {
20874 match self.kind(Interner) {
20975 &TyKind::FnDef(def, ..) => Some(ToChalk::from_chalk(db, def)),
......@@ -244,177 +110,6 @@ impl TyExt for Ty {
244110 }
245111 t
246112 }
247
248 fn strip_reference(&self) -> &Ty {
249 self.as_reference().map_or(self, |(ty, _, _)| ty)
250 }
251
252 fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
253 let handle_async_block_type_impl_trait = |def: DefWithBodyId| {
254 let krate = def.module(db).krate();
255 if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
256 // This is only used by type walking.
257 // Parameters will be walked outside, and projection predicate is not used.
258 // So just provide the Future trait.
259 let impl_bound = Binders::empty(
260 Interner,
261 WhereClause::Implemented(TraitRef {
262 trait_id: to_chalk_trait_id(future_trait),
263 substitution: Substitution::empty(Interner),
264 }),
265 );
266 Some(vec![impl_bound])
267 } else {
268 None
269 }
270 };
271
272 match self.kind(Interner) {
273 TyKind::OpaqueType(opaque_ty_id, subst) => {
274 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
275 ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
276 handle_async_block_type_impl_trait(def)
277 }
278 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
279 db.return_type_impl_traits(func).map(|it| {
280 let data =
281 (*it).as_ref().map(|rpit| rpit.impl_traits[idx].bounds.clone());
282 data.substitute(Interner, &subst).into_value_and_skipped_binders().0
283 })
284 }
285 ImplTraitId::TypeAliasImplTrait(alias, idx) => {
286 db.type_alias_impl_traits(alias).map(|it| {
287 let data =
288 (*it).as_ref().map(|rpit| rpit.impl_traits[idx].bounds.clone());
289 data.substitute(Interner, &subst).into_value_and_skipped_binders().0
290 })
291 }
292 }
293 }
294 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
295 let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into())
296 {
297 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
298 db.return_type_impl_traits(func).map(|it| {
299 let data =
300 (*it).as_ref().map(|rpit| rpit.impl_traits[idx].bounds.clone());
301 data.substitute(Interner, &opaque_ty.substitution)
302 })
303 }
304 ImplTraitId::TypeAliasImplTrait(alias, idx) => {
305 db.type_alias_impl_traits(alias).map(|it| {
306 let data =
307 (*it).as_ref().map(|rpit| rpit.impl_traits[idx].bounds.clone());
308 data.substitute(Interner, &opaque_ty.substitution)
309 })
310 }
311 ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
312 return handle_async_block_type_impl_trait(def);
313 }
314 };
315
316 predicates.map(|it| it.into_value_and_skipped_binders().0)
317 }
318 TyKind::Placeholder(idx) => {
319 let id = from_placeholder_idx(db, *idx).0;
320 let generic_params = db.generic_params(id.parent);
321 let param_data = &generic_params[id.local_id];
322 match param_data {
323 TypeOrConstParamData::TypeParamData(p) => match p.provenance {
324 TypeParamProvenance::ArgumentImplTrait => {
325 let substs = TyBuilder::placeholder_subst(db, id.parent);
326 let predicates = db
327 .generic_predicates(id.parent)
328 .iter()
329 .map(|pred| pred.clone().substitute(Interner, &substs))
330 .filter(|wc| match wc.skip_binders() {
331 WhereClause::Implemented(tr) => {
332 &tr.self_type_parameter(Interner) == self
333 }
334 WhereClause::AliasEq(AliasEq {
335 alias: AliasTy::Projection(proj),
336 ty: _,
337 }) => &proj.self_type_parameter(db) == self,
338 WhereClause::TypeOutlives(TypeOutlives { ty, lifetime: _ }) => {
339 ty == self
340 }
341 _ => false,
342 })
343 .collect::<Vec<_>>();
344
345 Some(predicates)
346 }
347 _ => None,
348 },
349 _ => None,
350 }
351 }
352 _ => None,
353 }
354 }
355
356 fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
357 match self.kind(Interner) {
358 TyKind::AssociatedType(id, ..) => match from_assoc_type_id(*id).lookup(db).container {
359 ItemContainerId::TraitId(trait_id) => Some(trait_id),
360 _ => None,
361 },
362 TyKind::Alias(AliasTy::Projection(projection_ty)) => {
363 match from_assoc_type_id(projection_ty.associated_ty_id).lookup(db).container {
364 ItemContainerId::TraitId(trait_id) => Some(trait_id),
365 _ => None,
366 }
367 }
368 _ => None,
369 }
370 }
371
372 fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool {
373 let crate_id = owner.module(db).krate();
374 let Some(copy_trait) = LangItem::Copy.resolve_trait(db, crate_id) else {
375 return false;
376 };
377 let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build();
378 let env = db.trait_environment_for_body(owner);
379 let goal = Canonical {
380 value: InEnvironment::new(
381 &env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)),
382 trait_ref.cast(Interner),
383 ),
384 binders: CanonicalVarKinds::empty(Interner),
385 };
386 !db.trait_solve(crate_id, None, goal).no_solution()
387 }
388
389 fn equals_ctor(&self, other: &Ty) -> bool {
390 match (self.kind(Interner), other.kind(Interner)) {
391 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
392 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_, _), TyKind::Array(_, _)) => {
393 true
394 }
395 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
396 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
397 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => {
398 ty_id == ty_id2
399 }
400 (TyKind::Foreign(ty_id, ..), TyKind::Foreign(ty_id2, ..)) => ty_id == ty_id2,
401 (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
402 (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..))
403 | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => {
404 mutability == mutability2
405 }
406 (
407 TyKind::Function(FnPointer { num_binders, sig, .. }),
408 TyKind::Function(FnPointer { num_binders: num_binders2, sig: sig2, .. }),
409 ) => num_binders == num_binders2 && sig == sig2,
410 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
411 cardinality == cardinality2
412 }
413 (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true,
414 (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2,
415 _ => false,
416 }
417 }
418113}
419114
420115pub trait ProjectionTyExt {
......@@ -445,9 +140,8 @@ impl ProjectionTyExt for ProjectionTy {
445140 }
446141}
447142
448pub trait DynTyExt {
143pub(crate) trait DynTyExt {
449144 fn principal(&self) -> Option<Binders<Binders<&TraitRef>>>;
450 fn principal_id(&self) -> Option<chalk_ir::TraitId<Interner>>;
451145}
452146
453147impl DynTyExt for DynTy {
......@@ -461,13 +155,6 @@ impl DynTyExt for DynTy {
461155 })
462156 })
463157 }
464
465 fn principal_id(&self) -> Option<chalk_ir::TraitId<Interner>> {
466 self.bounds.skip_binders().interned().first().and_then(|b| match b.skip_binders() {
467 crate::WhereClause::Implemented(trait_ref) => Some(trait_ref.trait_id),
468 _ => None,
469 })
470 }
471158}
472159
473160pub trait TraitRefExt {
src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs+208-218
......@@ -1,67 +1,95 @@
11//! Constant evaluation details
22
3#[cfg(test)]
4mod tests;
5
36use base_db::Crate;
4use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast};
57use hir_def::{
6 EnumVariantId, GeneralConstId, HasModule as _, StaticId,
8 EnumVariantId, GeneralConstId,
79 expr_store::{Body, HygieneId, path::Path},
810 hir::{Expr, ExprId},
911 resolver::{Resolver, ValueNs},
1012 type_ref::LiteralConstRef,
1113};
14use hir_def::{HasModule, StaticId};
1215use hir_expand::Lookup;
16use rustc_type_ir::{UnevaluatedConst, inherent::IntoKind};
1317use stdx::never;
1418use triomphe::Arc;
1519
1620use crate::{
17 Const, ConstData, ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution,
18 TraitEnvironment, Ty, TyBuilder,
21 MemoryMap, TraitEnvironment,
1922 db::HirDatabase,
2023 display::DisplayTarget,
2124 generics::Generics,
2225 infer::InferenceContext,
23 lower::ParamLoweringMode,
24 next_solver::{DbInterner, mapping::ChalkToNextSolver},
25 to_placeholder_idx,
26 mir::{MirEvalError, MirLowerError},
27 next_solver::{
28 Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs,
29 ParamConst, SolverDefId, Ty, ValueConst,
30 },
2631};
2732
28use super::mir::{MirEvalError, MirLowerError, interpret_mir, lower_to_mir, pad16};
29
30/// Extension trait for [`Const`]
31pub trait ConstExt {
32 /// Is a [`Const`] unknown?
33 fn is_unknown(&self) -> bool;
34}
35
36impl ConstExt for Const {
37 fn is_unknown(&self) -> bool {
38 match self.data(Interner).value {
39 // interned Unknown
40 chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst {
41 interned: ConstScalar::Unknown,
42 }) => true,
33use super::mir::{interpret_mir, lower_to_mir, pad16};
4334
44 // interned concrete anything else
45 chalk_ir::ConstValue::Concrete(..) => false,
46
47 _ => {
48 tracing::error!(
49 "is_unknown was called on a non-concrete constant value! {:?}",
50 self
51 );
52 true
35pub(crate) fn path_to_const<'a, 'g>(
36 db: &'a dyn HirDatabase,
37 resolver: &Resolver<'a>,
38 path: &Path,
39 args: impl FnOnce() -> &'g Generics,
40 _expected_ty: Ty<'a>,
41) -> Option<Const<'a>> {
42 let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
43 match resolver.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT) {
44 Some(ValueNs::GenericParam(p)) => {
45 let args = args();
46 match args
47 .type_or_const_param(p.into())
48 .and_then(|(idx, p)| p.const_param().map(|p| (idx, p.clone())))
49 {
50 Some((idx, _param)) => {
51 Some(Const::new_param(interner, ParamConst { index: idx as u32, id: p }))
52 }
53 None => {
54 never!(
55 "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
56 args,
57 path,
58 p
59 );
60 None
61 }
5362 }
5463 }
64 Some(ValueNs::ConstId(c)) => {
65 let args = GenericArgs::new_from_iter(interner, []);
66 Some(Const::new(
67 interner,
68 rustc_type_ir::ConstKind::Unevaluated(UnevaluatedConst::new(
69 SolverDefId::ConstId(c),
70 args,
71 )),
72 ))
73 }
74 _ => None,
5575 }
5676}
5777
78pub fn unknown_const<'db>(_ty: Ty<'db>) -> Const<'db> {
79 Const::new(DbInterner::conjure(), rustc_type_ir::ConstKind::Error(ErrorGuaranteed))
80}
81
82pub fn unknown_const_as_generic<'db>(ty: Ty<'db>) -> GenericArg<'db> {
83 unknown_const(ty).into()
84}
85
5886#[derive(Debug, Clone, PartialEq, Eq)]
59pub enum ConstEvalError {
60 MirLowerError(MirLowerError),
61 MirEvalError(MirEvalError),
87pub enum ConstEvalError<'db> {
88 MirLowerError(MirLowerError<'db>),
89 MirEvalError(MirEvalError<'db>),
6290}
6391
64impl ConstEvalError {
92impl ConstEvalError<'_> {
6593 pub fn pretty_print(
6694 &self,
6795 f: &mut String,
......@@ -80,8 +108,8 @@ impl ConstEvalError {
80108 }
81109}
82110
83impl From<MirLowerError> for ConstEvalError {
84 fn from(value: MirLowerError) -> Self {
111impl<'db> From<MirLowerError<'db>> for ConstEvalError<'db> {
112 fn from(value: MirLowerError<'db>) -> Self {
85113 match value {
86114 MirLowerError::ConstEvalError(_, e) => *e,
87115 _ => ConstEvalError::MirLowerError(value),
......@@ -89,201 +117,118 @@ impl From<MirLowerError> for ConstEvalError {
89117 }
90118}
91119
92impl From<MirEvalError> for ConstEvalError {
93 fn from(value: MirEvalError) -> Self {
120impl<'db> From<MirEvalError<'db>> for ConstEvalError<'db> {
121 fn from(value: MirEvalError<'db>) -> Self {
94122 ConstEvalError::MirEvalError(value)
95123 }
96124}
97125
98pub(crate) fn path_to_const<'g>(
99 db: &dyn HirDatabase,
100 resolver: &Resolver<'_>,
101 path: &Path,
102 mode: ParamLoweringMode,
103 args: impl FnOnce() -> &'g Generics,
104 debruijn: DebruijnIndex,
105 expected_ty: Ty,
106) -> Option<Const> {
107 match resolver.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT) {
108 Some(ValueNs::GenericParam(p)) => {
109 let ty = db.const_param_ty(p);
110 let args = args();
111 let value = match mode {
112 ParamLoweringMode::Placeholder => {
113 let idx = args.type_or_const_param_idx(p.into()).unwrap();
114 ConstValue::Placeholder(to_placeholder_idx(db, p.into(), idx as u32))
115 }
116 ParamLoweringMode::Variable => match args.type_or_const_param_idx(p.into()) {
117 Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
118 None => {
119 never!(
120 "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
121 args,
122 path,
123 p
124 );
125 return None;
126 }
127 },
128 };
129 Some(ConstData { ty, value }.intern(Interner))
130 }
131 Some(ValueNs::ConstId(c)) => Some(intern_const_scalar(
132 ConstScalar::UnevaluatedConst(c.into(), Substitution::empty(Interner)),
133 expected_ty,
134 )),
135 // FIXME: With feature(adt_const_params), we also need to consider other things here, e.g. struct constructors.
136 _ => None,
137 }
138}
139
140pub fn unknown_const(ty: Ty) -> Const {
141 ConstData {
142 ty,
143 value: ConstValue::Concrete(chalk_ir::ConcreteConst { interned: ConstScalar::Unknown }),
144 }
145 .intern(Interner)
146}
147
148pub fn unknown_const_as_generic(ty: Ty) -> GenericArg {
149 unknown_const(ty).cast(Interner)
150}
151
152126/// Interns a constant scalar with the given type
153pub fn intern_const_scalar(value: ConstScalar, ty: Ty) -> Const {
154 ConstData { ty, value: ConstValue::Concrete(chalk_ir::ConcreteConst { interned: value }) }
155 .intern(Interner)
156}
157
158/// Interns a constant scalar with the given type
159pub fn intern_const_ref(
160 db: &dyn HirDatabase,
127pub fn intern_const_ref<'a>(
128 db: &'a dyn HirDatabase,
161129 value: &LiteralConstRef,
162 ty: Ty,
130 ty: Ty<'a>,
163131 krate: Crate,
164) -> Const {
132) -> Const<'a> {
165133 let interner = DbInterner::new_with(db, Some(krate), None);
166 let layout = || db.layout_of_ty(ty.to_nextsolver(interner), TraitEnvironment::empty(krate));
167 let bytes = match value {
134 let layout = db.layout_of_ty(ty, TraitEnvironment::empty(krate));
135 let kind = match value {
168136 LiteralConstRef::Int(i) => {
169137 // FIXME: We should handle failure of layout better.
170 let size = layout().map(|it| it.size.bytes_usize()).unwrap_or(16);
171 ConstScalar::Bytes(i.to_le_bytes()[0..size].into(), MemoryMap::default())
138 let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16);
139 rustc_type_ir::ConstKind::Value(ValueConst::new(
140 ty,
141 ConstBytes {
142 memory: i.to_le_bytes()[0..size].into(),
143 memory_map: MemoryMap::default(),
144 },
145 ))
172146 }
173147 LiteralConstRef::UInt(i) => {
174 let size = layout().map(|it| it.size.bytes_usize()).unwrap_or(16);
175 ConstScalar::Bytes(i.to_le_bytes()[0..size].into(), MemoryMap::default())
176 }
177 LiteralConstRef::Bool(b) => ConstScalar::Bytes(Box::new([*b as u8]), MemoryMap::default()),
178 LiteralConstRef::Char(c) => {
179 ConstScalar::Bytes((*c as u32).to_le_bytes().into(), MemoryMap::default())
148 let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16);
149 rustc_type_ir::ConstKind::Value(ValueConst::new(
150 ty,
151 ConstBytes {
152 memory: i.to_le_bytes()[0..size].into(),
153 memory_map: MemoryMap::default(),
154 },
155 ))
180156 }
181 LiteralConstRef::Unknown => ConstScalar::Unknown,
157 LiteralConstRef::Bool(b) => rustc_type_ir::ConstKind::Value(ValueConst::new(
158 ty,
159 ConstBytes { memory: Box::new([*b as u8]), memory_map: MemoryMap::default() },
160 )),
161 LiteralConstRef::Char(c) => rustc_type_ir::ConstKind::Value(ValueConst::new(
162 ty,
163 ConstBytes {
164 memory: (*c as u32).to_le_bytes().into(),
165 memory_map: MemoryMap::default(),
166 },
167 )),
168 LiteralConstRef::Unknown => rustc_type_ir::ConstKind::Error(ErrorGuaranteed),
182169 };
183 intern_const_scalar(bytes, ty)
170 Const::new(interner, kind)
184171}
185172
186173/// Interns a possibly-unknown target usize
187pub fn usize_const(db: &dyn HirDatabase, value: Option<u128>, krate: Crate) -> Const {
174pub fn usize_const<'db>(db: &'db dyn HirDatabase, value: Option<u128>, krate: Crate) -> Const<'db> {
188175 intern_const_ref(
189176 db,
190177 &value.map_or(LiteralConstRef::Unknown, LiteralConstRef::UInt),
191 TyBuilder::usize(),
178 Ty::new_uint(DbInterner::new_with(db, Some(krate), None), rustc_type_ir::UintTy::Usize),
192179 krate,
193180 )
194181}
195182
196pub fn try_const_usize(db: &dyn HirDatabase, c: &Const) -> Option<u128> {
197 match &c.data(Interner).value {
198 chalk_ir::ConstValue::BoundVar(_) => None,
199 chalk_ir::ConstValue::InferenceVar(_) => None,
200 chalk_ir::ConstValue::Placeholder(_) => None,
201 chalk_ir::ConstValue::Concrete(c) => match &c.interned {
202 ConstScalar::Bytes(it, _) => Some(u128::from_le_bytes(pad16(it, false))),
203 ConstScalar::UnevaluatedConst(c, subst) => {
204 let ec = db.const_eval(*c, subst.clone(), None).ok()?;
205 try_const_usize(db, &ec)
206 }
207 _ => None,
208 },
209 }
210}
211
212pub fn try_const_isize(db: &dyn HirDatabase, c: &Const) -> Option<i128> {
213 match &c.data(Interner).value {
214 chalk_ir::ConstValue::BoundVar(_) => None,
215 chalk_ir::ConstValue::InferenceVar(_) => None,
216 chalk_ir::ConstValue::Placeholder(_) => None,
217 chalk_ir::ConstValue::Concrete(c) => match &c.interned {
218 ConstScalar::Bytes(it, _) => Some(i128::from_le_bytes(pad16(it, true))),
219 ConstScalar::UnevaluatedConst(c, subst) => {
220 let ec = db.const_eval(*c, subst.clone(), None).ok()?;
221 try_const_isize(db, &ec)
222 }
223 _ => None,
224 },
183pub fn try_const_usize<'db>(db: &'db dyn HirDatabase, c: Const<'db>) -> Option<u128> {
184 match c.kind() {
185 ConstKind::Param(_) => None,
186 ConstKind::Infer(_) => None,
187 ConstKind::Bound(_, _) => None,
188 ConstKind::Placeholder(_) => None,
189 ConstKind::Unevaluated(unevaluated_const) => {
190 let c = match unevaluated_const.def {
191 SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
192 SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
193 _ => unreachable!(),
194 };
195 let subst = unevaluated_const.args;
196 let ec = db.const_eval(c, subst, None).ok()?;
197 try_const_usize(db, ec)
198 }
199 ConstKind::Value(val) => Some(u128::from_le_bytes(pad16(&val.value.inner().memory, false))),
200 ConstKind::Error(_) => None,
201 ConstKind::Expr(_) => None,
225202 }
226203}
227204
228pub(crate) fn const_eval_cycle_result(
229 _: &dyn HirDatabase,
230 _: GeneralConstId,
231 _: Substitution,
232 _: Option<Arc<TraitEnvironment<'_>>>,
233) -> Result<Const, ConstEvalError> {
234 Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
235}
236
237pub(crate) fn const_eval_static_cycle_result(
238 _: &dyn HirDatabase,
239 _: StaticId,
240) -> Result<Const, ConstEvalError> {
241 Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
242}
243
244pub(crate) fn const_eval_discriminant_cycle_result(
245 _: &dyn HirDatabase,
246 _: EnumVariantId,
247) -> Result<i128, ConstEvalError> {
248 Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
249}
250
251pub(crate) fn const_eval_query(
252 db: &dyn HirDatabase,
253 def: GeneralConstId,
254 subst: Substitution,
255 trait_env: Option<Arc<TraitEnvironment<'_>>>,
256) -> Result<Const, ConstEvalError> {
257 let body = match def {
258 GeneralConstId::ConstId(c) => {
259 db.monomorphized_mir_body(c.into(), subst, db.trait_environment(c.into()))?
260 }
261 GeneralConstId::StaticId(s) => {
262 let krate = s.module(db).krate();
263 db.monomorphized_mir_body(s.into(), subst, TraitEnvironment::empty(krate))?
205pub fn try_const_isize<'db>(db: &'db dyn HirDatabase, c: &Const<'db>) -> Option<i128> {
206 match (*c).kind() {
207 ConstKind::Param(_) => None,
208 ConstKind::Infer(_) => None,
209 ConstKind::Bound(_, _) => None,
210 ConstKind::Placeholder(_) => None,
211 ConstKind::Unevaluated(unevaluated_const) => {
212 let c = match unevaluated_const.def {
213 SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
214 SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
215 _ => unreachable!(),
216 };
217 let subst = unevaluated_const.args;
218 let ec = db.const_eval(c, subst, None).ok()?;
219 try_const_isize(db, &ec)
264220 }
265 };
266 let c = interpret_mir(db, body, false, trait_env)?.0?;
267 Ok(c)
268}
269
270pub(crate) fn const_eval_static_query(
271 db: &dyn HirDatabase,
272 def: StaticId,
273) -> Result<Const, ConstEvalError> {
274 let body = db.monomorphized_mir_body(
275 def.into(),
276 Substitution::empty(Interner),
277 db.trait_environment_for_body(def.into()),
278 )?;
279 let c = interpret_mir(db, body, false, None)?.0?;
280 Ok(c)
221 ConstKind::Value(val) => Some(i128::from_le_bytes(pad16(&val.value.inner().memory, true))),
222 ConstKind::Error(_) => None,
223 ConstKind::Expr(_) => None,
224 }
281225}
282226
283pub(crate) fn const_eval_discriminant_variant(
284 db: &dyn HirDatabase,
227pub(crate) fn const_eval_discriminant_variant<'db>(
228 db: &'db dyn HirDatabase,
285229 variant_id: EnumVariantId,
286) -> Result<i128, ConstEvalError> {
230) -> Result<i128, ConstEvalError<'db>> {
231 let interner = DbInterner::new_with(db, None, None);
287232 let def = variant_id.into();
288233 let body = db.body(def);
289234 let loc = variant_id.lookup(db);
......@@ -305,14 +250,14 @@ pub(crate) fn const_eval_discriminant_variant(
305250
306251 let mir_body = db.monomorphized_mir_body(
307252 def,
308 Substitution::empty(Interner),
253 GenericArgs::new_from_iter(interner, []),
309254 db.trait_environment_for_body(def),
310255 )?;
311256 let c = interpret_mir(db, mir_body, false, None)?.0?;
312257 let c = if is_signed {
313258 try_const_isize(db, &c).unwrap()
314259 } else {
315 try_const_usize(db, &c).unwrap() as i128
260 try_const_usize(db, c).unwrap() as i128
316261 };
317262 Ok(c)
318263}
......@@ -320,13 +265,7 @@ pub(crate) fn const_eval_discriminant_variant(
320265// FIXME: Ideally constants in const eval should have separate body (issue #7434), and this function should
321266// get an `InferenceResult` instead of an `InferenceContext`. And we should remove `ctx.clone().resolve_all()` here
322267// and make this function private. See the fixme comment on `InferenceContext::resolve_all`.
323pub(crate) fn eval_to_const(
324 expr: ExprId,
325 mode: ParamLoweringMode,
326 ctx: &mut InferenceContext<'_>,
327 debruijn: DebruijnIndex,
328) -> Const {
329 let db = ctx.db;
268pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'db>) -> Const<'db> {
330269 let infer = ctx.fixme_resolve_all_clone();
331270 fn has_closure(body: &Body, expr: ExprId) -> bool {
332271 if matches!(body[expr], Expr::Closure { .. }) {
......@@ -338,23 +277,74 @@ pub(crate) fn eval_to_const(
338277 }
339278 if has_closure(ctx.body, expr) {
340279 // Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic.
341 return unknown_const(infer[expr].clone());
280 return unknown_const(infer[expr]);
342281 }
343282 if let Expr::Path(p) = &ctx.body[expr] {
344283 let resolver = &ctx.resolver;
345 if let Some(c) =
346 path_to_const(db, resolver, p, mode, || ctx.generics(), debruijn, infer[expr].clone())
347 {
284 if let Some(c) = path_to_const(ctx.db, resolver, p, || ctx.generics(), infer[expr]) {
348285 return c;
349286 }
350287 }
351288 if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr)
352 && let Ok((Ok(result), _)) = interpret_mir(db, Arc::new(mir_body), true, None)
289 && let Ok((Ok(result), _)) = interpret_mir(ctx.db, Arc::new(mir_body), true, None)
353290 {
354291 return result;
355292 }
356 unknown_const(infer[expr].clone())
293 unknown_const(infer[expr])
357294}
358295
359#[cfg(test)]
360mod tests;
296pub(crate) fn const_eval_cycle_result<'db>(
297 _: &'db dyn HirDatabase,
298 _: GeneralConstId,
299 _: GenericArgs<'db>,
300 _: Option<Arc<TraitEnvironment<'db>>>,
301) -> Result<Const<'db>, ConstEvalError<'db>> {
302 Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
303}
304
305pub(crate) fn const_eval_static_cycle_result<'db>(
306 _: &'db dyn HirDatabase,
307 _: StaticId,
308) -> Result<Const<'db>, ConstEvalError<'db>> {
309 Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
310}
311
312pub(crate) fn const_eval_discriminant_cycle_result<'db>(
313 _: &'db dyn HirDatabase,
314 _: EnumVariantId,
315) -> Result<i128, ConstEvalError<'db>> {
316 Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
317}
318
319pub(crate) fn const_eval_query<'db>(
320 db: &'db dyn HirDatabase,
321 def: GeneralConstId,
322 subst: GenericArgs<'db>,
323 trait_env: Option<Arc<TraitEnvironment<'db>>>,
324) -> Result<Const<'db>, ConstEvalError<'db>> {
325 let body = match def {
326 GeneralConstId::ConstId(c) => {
327 db.monomorphized_mir_body(c.into(), subst, db.trait_environment(c.into()))?
328 }
329 GeneralConstId::StaticId(s) => {
330 let krate = s.module(db).krate();
331 db.monomorphized_mir_body(s.into(), subst, TraitEnvironment::empty(krate))?
332 }
333 };
334 let c = interpret_mir(db, body, false, trait_env)?.0?;
335 Ok(c)
336}
337
338pub(crate) fn const_eval_static_query<'db>(
339 db: &'db dyn HirDatabase,
340 def: StaticId,
341) -> Result<Const<'db>, ConstEvalError<'db>> {
342 let interner = DbInterner::new_with(db, None, None);
343 let body = db.monomorphized_mir_body(
344 def.into(),
345 GenericArgs::new_from_iter(interner, []),
346 db.trait_environment_for_body(def.into()),
347 )?;
348 let c = interpret_mir(db, body, false, None)?.0?;
349 Ok(c)
350}
src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs+27-20
......@@ -1,17 +1,23 @@
11use base_db::RootQueryDb;
2use chalk_ir::Substitution;
32use hir_def::db::DefDatabase;
43use hir_expand::EditionedFileId;
54use rustc_apfloat::{
65 Float,
76 ieee::{Half as f16, Quad as f128},
87};
8use rustc_type_ir::inherent::IntoKind;
99use test_fixture::WithFixture;
1010use test_utils::skip_slow_tests;
1111
1212use crate::{
13 Const, ConstScalar, Interner, MemoryMap, consteval::try_const_usize, db::HirDatabase,
14 display::DisplayTarget, mir::pad16, setup_tracing, test_db::TestDB,
13 MemoryMap,
14 consteval::try_const_usize,
15 db::HirDatabase,
16 display::DisplayTarget,
17 mir::pad16,
18 next_solver::{Const, ConstBytes, ConstKind, DbInterner, GenericArgs},
19 setup_tracing,
20 test_db::TestDB,
1521};
1622
1723use super::{
......@@ -21,7 +27,7 @@ use super::{
2127
2228mod intrinsics;
2329
24fn simplify(e: ConstEvalError) -> ConstEvalError {
30fn simplify(e: ConstEvalError<'_>) -> ConstEvalError<'_> {
2531 match e {
2632 ConstEvalError::MirEvalError(MirEvalError::InFunction(e, _)) => {
2733 simplify(ConstEvalError::MirEvalError(*e))
......@@ -33,10 +39,10 @@ fn simplify(e: ConstEvalError) -> ConstEvalError {
3339#[track_caller]
3440fn check_fail(
3541 #[rust_analyzer::rust_fixture] ra_fixture: &str,
36 error: impl FnOnce(ConstEvalError) -> bool,
42 error: impl FnOnce(ConstEvalError<'_>) -> bool,
3743) {
3844 let (db, file_id) = TestDB::with_single_file(ra_fixture);
39 salsa::attach(&db, || match eval_goal(&db, file_id) {
45 crate::attach_db(&db, || match eval_goal(&db, file_id) {
4046 Ok(_) => panic!("Expected fail, but it succeeded"),
4147 Err(e) => {
4248 assert!(error(simplify(e.clone())), "Actual error was: {}", pretty_print_err(e, &db))
......@@ -79,7 +85,7 @@ fn check_answer(
7985 check: impl FnOnce(&[u8], &MemoryMap<'_>),
8086) {
8187 let (db, file_ids) = TestDB::with_many_files(ra_fixture);
82 salsa::attach(&db, || {
88 crate::attach_db(&db, || {
8389 let file_id = *file_ids.last().unwrap();
8490 let r = match eval_goal(&db, file_id) {
8591 Ok(t) => t,
......@@ -88,19 +94,17 @@ fn check_answer(
8894 panic!("Error in evaluating goal: {err}");
8995 }
9096 };
91 match &r.data(Interner).value {
92 chalk_ir::ConstValue::Concrete(c) => match &c.interned {
93 ConstScalar::Bytes(b, mm) => {
94 check(b, mm);
95 }
96 x => panic!("Expected number but found {x:?}"),
97 },
98 _ => panic!("result of const eval wasn't a concrete const"),
97 match r.kind() {
98 ConstKind::Value(value) => {
99 let ConstBytes { memory, memory_map } = value.value.inner();
100 check(memory, memory_map);
101 }
102 _ => panic!("Expected number but found {r:?}"),
99103 }
100104 });
101105}
102106
103fn pretty_print_err(e: ConstEvalError, db: &TestDB) -> String {
107fn pretty_print_err(e: ConstEvalError<'_>, db: &TestDB) -> String {
104108 let mut err = String::new();
105109 let span_formatter = |file, range| format!("{file:?} {range:?}");
106110 let display_target =
......@@ -117,8 +121,9 @@ fn pretty_print_err(e: ConstEvalError, db: &TestDB) -> String {
117121 err
118122}
119123
120fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const, ConstEvalError> {
124fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEvalError<'_>> {
121125 let _tracing = setup_tracing();
126 let interner = DbInterner::new_with(db, None, None);
122127 let module_id = db.module_for_file(file_id.file_id(db));
123128 let def_map = module_id.def_map(db);
124129 let scope = &def_map[module_id.local_id].scope;
......@@ -137,7 +142,7 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const, ConstEvalEr
137142 _ => None,
138143 })
139144 .expect("No const named GOAL found in the test");
140 db.const_eval(const_id.into(), Substitution::empty(Interner), None)
145 db.const_eval(const_id.into(), GenericArgs::new_from_iter(interner, []), None)
141146}
142147
143148#[test]
......@@ -2506,8 +2511,10 @@ fn enums() {
25062511 const GOAL: E = E::A;
25072512 "#,
25082513 );
2509 let r = eval_goal(&db, file_id).unwrap();
2510 assert_eq!(try_const_usize(&db, &r), Some(1));
2514 crate::attach_db(&db, || {
2515 let r = eval_goal(&db, file_id).unwrap();
2516 assert_eq!(try_const_usize(&db, r), Some(1));
2517 })
25112518}
25122519
25132520#[test]
src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs+6-3
......@@ -354,8 +354,9 @@ fn overflowing_add() {
354354fn needs_drop() {
355355 check_number(
356356 r#"
357 //- minicore: drop, manually_drop, copy, sized
357 //- minicore: drop, manually_drop, copy, sized, phantom_data
358358 use core::mem::ManuallyDrop;
359 use core::marker::PhantomData;
359360 extern "rust-intrinsic" {
360361 pub fn needs_drop<T: ?Sized>() -> bool;
361362 }
......@@ -380,17 +381,19 @@ fn needs_drop() {
380381 const fn opaque_copy() -> impl Sized + Copy {
381382 || {}
382383 }
384 struct RecursiveType(RecursiveType);
383385 trait Everything {}
384386 impl<T> Everything for T {}
385387 const GOAL: bool = !needs_drop::<i32>() && !needs_drop::<X>()
386388 && needs_drop::<NeedsDrop>() && !needs_drop::<ManuallyDrop<NeedsDrop>>()
387389 && needs_drop::<[NeedsDrop; 1]>() && !needs_drop::<[NeedsDrop; 0]>()
388 && needs_drop::<(X, NeedsDrop)>()
390 && needs_drop::<(X, NeedsDrop)>() && !needs_drop::<PhantomData<NeedsDrop>>()
389391 && needs_drop::<Enum<NeedsDrop>>() && !needs_drop::<Enum<X>>()
390392 && closure_needs_drop()
391393 && !val_needs_drop(opaque()) && !val_needs_drop(opaque_copy())
392394 && needs_drop::<[NeedsDrop]>() && needs_drop::<dyn Everything>()
393 && !needs_drop::<&dyn Everything>() && !needs_drop::<str>();
395 && !needs_drop::<&dyn Everything>() && !needs_drop::<str>()
396 && !needs_drop::<RecursiveType>();
394397 "#,
395398 1,
396399 );
src/tools/rust-analyzer/crates/hir-ty/src/consteval_chalk.rs created+108
......@@ -0,0 +1,108 @@
1//! Constant evaluation details
2
3use base_db::Crate;
4use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast};
5use hir_def::{
6 expr_store::{HygieneId, path::Path},
7 resolver::{Resolver, ValueNs},
8 type_ref::LiteralConstRef,
9};
10use stdx::never;
11
12use crate::{
13 Const, ConstData, ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution,
14 TraitEnvironment, Ty,
15 db::HirDatabase,
16 generics::Generics,
17 lower::ParamLoweringMode,
18 next_solver::{DbInterner, mapping::ChalkToNextSolver},
19 to_placeholder_idx,
20};
21
22pub(crate) fn path_to_const<'g>(
23 db: &dyn HirDatabase,
24 resolver: &Resolver<'_>,
25 path: &Path,
26 mode: ParamLoweringMode,
27 args: impl FnOnce() -> &'g Generics,
28 debruijn: DebruijnIndex,
29 expected_ty: Ty,
30) -> Option<Const> {
31 match resolver.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT) {
32 Some(ValueNs::GenericParam(p)) => {
33 let ty = db.const_param_ty(p);
34 let args = args();
35 let value = match mode {
36 ParamLoweringMode::Placeholder => {
37 let idx = args.type_or_const_param_idx(p.into()).unwrap();
38 ConstValue::Placeholder(to_placeholder_idx(db, p.into(), idx as u32))
39 }
40 ParamLoweringMode::Variable => match args.type_or_const_param_idx(p.into()) {
41 Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
42 None => {
43 never!(
44 "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
45 args,
46 path,
47 p
48 );
49 return None;
50 }
51 },
52 };
53 Some(ConstData { ty, value }.intern(Interner))
54 }
55 Some(ValueNs::ConstId(c)) => Some(intern_const_scalar(
56 ConstScalar::UnevaluatedConst(c.into(), Substitution::empty(Interner)),
57 expected_ty,
58 )),
59 // FIXME: With feature(adt_const_params), we also need to consider other things here, e.g. struct constructors.
60 _ => None,
61 }
62}
63
64pub(crate) fn unknown_const(ty: Ty) -> Const {
65 ConstData {
66 ty,
67 value: ConstValue::Concrete(chalk_ir::ConcreteConst { interned: ConstScalar::Unknown }),
68 }
69 .intern(Interner)
70}
71
72pub(crate) fn unknown_const_as_generic(ty: Ty) -> GenericArg {
73 unknown_const(ty).cast(Interner)
74}
75
76/// Interns a constant scalar with the given type
77pub(crate) fn intern_const_scalar(value: ConstScalar, ty: Ty) -> Const {
78 ConstData { ty, value: ConstValue::Concrete(chalk_ir::ConcreteConst { interned: value }) }
79 .intern(Interner)
80}
81
82/// Interns a constant scalar with the given type
83pub(crate) fn intern_const_ref(
84 db: &dyn HirDatabase,
85 value: &LiteralConstRef,
86 ty: Ty,
87 krate: Crate,
88) -> Const {
89 let interner = DbInterner::new_with(db, Some(krate), None);
90 let layout = || db.layout_of_ty(ty.to_nextsolver(interner), TraitEnvironment::empty(krate));
91 let bytes = match value {
92 LiteralConstRef::Int(i) => {
93 // FIXME: We should handle failure of layout better.
94 let size = layout().map(|it| it.size.bytes_usize()).unwrap_or(16);
95 ConstScalar::Bytes(i.to_le_bytes()[0..size].into(), MemoryMap::default())
96 }
97 LiteralConstRef::UInt(i) => {
98 let size = layout().map(|it| it.size.bytes_usize()).unwrap_or(16);
99 ConstScalar::Bytes(i.to_le_bytes()[0..size].into(), MemoryMap::default())
100 }
101 LiteralConstRef::Bool(b) => ConstScalar::Bytes(Box::new([*b as u8]), MemoryMap::default()),
102 LiteralConstRef::Char(c) => {
103 ConstScalar::Bytes((*c as u32).to_le_bytes().into(), MemoryMap::default())
104 }
105 LiteralConstRef::Unknown => ConstScalar::Unknown,
106 };
107 intern_const_scalar(bytes, ty)
108}
src/tools/rust-analyzer/crates/hir-ty/src/consteval_nextsolver.rs deleted-256
......@@ -1,256 +0,0 @@
1//! Constant evaluation details
2// FIXME(next-solver): this should get removed as things get moved to rustc_type_ir from chalk_ir
3#![allow(unused)]
4
5use base_db::Crate;
6use hir_def::{
7 EnumVariantId, GeneralConstId,
8 expr_store::{Body, HygieneId, path::Path},
9 hir::{Expr, ExprId},
10 resolver::{Resolver, ValueNs},
11 type_ref::LiteralConstRef,
12};
13use hir_expand::Lookup;
14use rustc_type_ir::{
15 UnevaluatedConst,
16 inherent::{IntoKind, SliceLike},
17};
18use stdx::never;
19use triomphe::Arc;
20
21use crate::{
22 ConstScalar, Interner, MemoryMap, Substitution, TraitEnvironment,
23 consteval::ConstEvalError,
24 db::HirDatabase,
25 generics::Generics,
26 infer::InferenceContext,
27 next_solver::{
28 Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs,
29 ParamConst, SolverDefId, Ty, ValueConst,
30 mapping::{ChalkToNextSolver, NextSolverToChalk, convert_binder_to_early_binder},
31 },
32};
33
34use super::mir::{interpret_mir, lower_to_mir, pad16};
35
36pub(crate) fn path_to_const<'a, 'g>(
37 db: &'a dyn HirDatabase,
38 resolver: &Resolver<'a>,
39 path: &Path,
40 args: impl FnOnce() -> &'g Generics,
41 expected_ty: Ty<'a>,
42) -> Option<Const<'a>> {
43 let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
44 match resolver.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT) {
45 Some(ValueNs::GenericParam(p)) => {
46 let args = args();
47 match args
48 .type_or_const_param(p.into())
49 .and_then(|(idx, p)| p.const_param().map(|p| (idx, p.clone())))
50 {
51 Some((idx, _param)) => {
52 Some(Const::new_param(interner, ParamConst { index: idx as u32, id: p }))
53 }
54 None => {
55 never!(
56 "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
57 args,
58 path,
59 p
60 );
61 None
62 }
63 }
64 }
65 Some(ValueNs::ConstId(c)) => {
66 let args = GenericArgs::new_from_iter(interner, []);
67 Some(Const::new(
68 interner,
69 rustc_type_ir::ConstKind::Unevaluated(UnevaluatedConst::new(
70 SolverDefId::ConstId(c),
71 args,
72 )),
73 ))
74 }
75 _ => None,
76 }
77}
78
79pub fn unknown_const<'db>(ty: Ty<'db>) -> Const<'db> {
80 Const::new(DbInterner::conjure(), rustc_type_ir::ConstKind::Error(ErrorGuaranteed))
81}
82
83pub fn unknown_const_as_generic<'db>(ty: Ty<'db>) -> GenericArg<'db> {
84 unknown_const(ty).into()
85}
86
87/// Interns a constant scalar with the given type
88pub fn intern_const_ref<'a>(
89 db: &'a dyn HirDatabase,
90 value: &LiteralConstRef,
91 ty: Ty<'a>,
92 krate: Crate,
93) -> Const<'a> {
94 let interner = DbInterner::new_with(db, Some(krate), None);
95 let layout = db.layout_of_ty(ty, TraitEnvironment::empty(krate));
96 let kind = match value {
97 LiteralConstRef::Int(i) => {
98 // FIXME: We should handle failure of layout better.
99 let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16);
100 rustc_type_ir::ConstKind::Value(ValueConst::new(
101 ty,
102 ConstBytes(i.to_le_bytes()[0..size].into(), MemoryMap::default()),
103 ))
104 }
105 LiteralConstRef::UInt(i) => {
106 let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16);
107 rustc_type_ir::ConstKind::Value(ValueConst::new(
108 ty,
109 ConstBytes(i.to_le_bytes()[0..size].into(), MemoryMap::default()),
110 ))
111 }
112 LiteralConstRef::Bool(b) => rustc_type_ir::ConstKind::Value(ValueConst::new(
113 ty,
114 ConstBytes(Box::new([*b as u8]), MemoryMap::default()),
115 )),
116 LiteralConstRef::Char(c) => rustc_type_ir::ConstKind::Value(ValueConst::new(
117 ty,
118 ConstBytes((*c as u32).to_le_bytes().into(), MemoryMap::default()),
119 )),
120 LiteralConstRef::Unknown => rustc_type_ir::ConstKind::Error(ErrorGuaranteed),
121 };
122 Const::new(interner, kind)
123}
124
125/// Interns a possibly-unknown target usize
126pub fn usize_const<'db>(db: &'db dyn HirDatabase, value: Option<u128>, krate: Crate) -> Const<'db> {
127 intern_const_ref(
128 db,
129 &value.map_or(LiteralConstRef::Unknown, LiteralConstRef::UInt),
130 Ty::new_uint(DbInterner::new_with(db, Some(krate), None), rustc_type_ir::UintTy::Usize),
131 krate,
132 )
133}
134
135pub fn try_const_usize<'db>(db: &'db dyn HirDatabase, c: Const<'db>) -> Option<u128> {
136 let interner = DbInterner::new_with(db, None, None);
137 match c.kind() {
138 ConstKind::Param(_) => None,
139 ConstKind::Infer(_) => None,
140 ConstKind::Bound(_, _) => None,
141 ConstKind::Placeholder(_) => None,
142 ConstKind::Unevaluated(unevaluated_const) => {
143 let c = match unevaluated_const.def {
144 SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
145 SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
146 _ => unreachable!(),
147 };
148 let subst = unevaluated_const.args.to_chalk(interner);
149 let ec = db.const_eval(c, subst, None).ok()?.to_nextsolver(interner);
150 try_const_usize(db, ec)
151 }
152 ConstKind::Value(val) => Some(u128::from_le_bytes(pad16(&val.value.inner().0, false))),
153 ConstKind::Error(_) => None,
154 ConstKind::Expr(_) => None,
155 }
156}
157
158pub fn try_const_isize<'db>(db: &'db dyn HirDatabase, c: &Const<'db>) -> Option<i128> {
159 let interner = DbInterner::new_with(db, None, None);
160 match (*c).kind() {
161 ConstKind::Param(_) => None,
162 ConstKind::Infer(_) => None,
163 ConstKind::Bound(_, _) => None,
164 ConstKind::Placeholder(_) => None,
165 ConstKind::Unevaluated(unevaluated_const) => {
166 let c = match unevaluated_const.def {
167 SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
168 SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
169 _ => unreachable!(),
170 };
171 let subst = unevaluated_const.args.to_chalk(interner);
172 let ec = db.const_eval(c, subst, None).ok()?.to_nextsolver(interner);
173 try_const_isize(db, &ec)
174 }
175 ConstKind::Value(val) => Some(i128::from_le_bytes(pad16(&val.value.inner().0, true))),
176 ConstKind::Error(_) => None,
177 ConstKind::Expr(_) => None,
178 }
179}
180
181pub(crate) fn const_eval_discriminant_variant(
182 db: &dyn HirDatabase,
183 variant_id: EnumVariantId,
184) -> Result<i128, ConstEvalError> {
185 let interner = DbInterner::new_with(db, None, None);
186 let def = variant_id.into();
187 let body = db.body(def);
188 let loc = variant_id.lookup(db);
189 if matches!(body[body.body_expr], Expr::Missing) {
190 let prev_idx = loc.index.checked_sub(1);
191 let value = match prev_idx {
192 Some(prev_idx) => {
193 1 + db.const_eval_discriminant(
194 loc.parent.enum_variants(db).variants[prev_idx as usize].0,
195 )?
196 }
197 _ => 0,
198 };
199 return Ok(value);
200 }
201
202 let repr = db.enum_signature(loc.parent).repr;
203 let is_signed = repr.and_then(|repr| repr.int).is_none_or(|int| int.is_signed());
204
205 let mir_body = db.monomorphized_mir_body(
206 def,
207 Substitution::empty(Interner),
208 db.trait_environment_for_body(def),
209 )?;
210 let c = interpret_mir(db, mir_body, false, None)?.0?;
211 let c = c.to_nextsolver(interner);
212 let c = if is_signed {
213 try_const_isize(db, &c).unwrap()
214 } else {
215 try_const_usize(db, c).unwrap() as i128
216 };
217 Ok(c)
218}
219
220// FIXME: Ideally constants in const eval should have separate body (issue #7434), and this function should
221// get an `InferenceResult` instead of an `InferenceContext`. And we should remove `ctx.clone().resolve_all()` here
222// and make this function private. See the fixme comment on `InferenceContext::resolve_all`.
223pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'db>) -> Const<'db> {
224 let interner = DbInterner::new_with(ctx.db, None, None);
225 let infer = ctx.fixme_resolve_all_clone();
226 fn has_closure(body: &Body, expr: ExprId) -> bool {
227 if matches!(body[expr], Expr::Closure { .. }) {
228 return true;
229 }
230 let mut r = false;
231 body.walk_child_exprs(expr, |idx| r |= has_closure(body, idx));
232 r
233 }
234 if has_closure(ctx.body, expr) {
235 // Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic.
236 return unknown_const(infer[expr].clone().to_nextsolver(interner));
237 }
238 if let Expr::Path(p) = &ctx.body[expr] {
239 let resolver = &ctx.resolver;
240 if let Some(c) = path_to_const(
241 ctx.db,
242 resolver,
243 p,
244 || ctx.generics(),
245 infer[expr].to_nextsolver(interner),
246 ) {
247 return c;
248 }
249 }
250 if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr)
251 && let Ok((Ok(result), _)) = interpret_mir(ctx.db, Arc::new(mir_body), true, None)
252 {
253 return result.to_nextsolver(interner);
254 }
255 unknown_const(infer[expr].to_nextsolver(interner))
256}
src/tools/rust-analyzer/crates/hir-ty/src/db.rs+60-33
......@@ -16,10 +16,9 @@ use smallvec::SmallVec;
1616use triomphe::Arc;
1717
1818use crate::{
19 Binders, Const, ImplTraitId, ImplTraits, InferenceResult, Substitution, TraitEnvironment, Ty,
20 TyDefId, ValueTyDefId, chalk_db,
19 Binders, ImplTraitId, ImplTraits, InferenceResult, TraitEnvironment, Ty, TyDefId, ValueTyDefId,
20 chalk_db,
2121 consteval::ConstEvalError,
22 drop::DropGlue,
2322 dyn_compatibility::DynCompatibilityViolation,
2423 layout::{Layout, LayoutError},
2524 lower::{Diagnostics, GenericDefaults, GenericPredicates},
......@@ -32,62 +31,77 @@ use crate::{
3231pub trait HirDatabase: DefDatabase + std::fmt::Debug {
3332 #[salsa::invoke(crate::infer::infer_query)]
3433 #[salsa::cycle(cycle_result = crate::infer::infer_cycle_result)]
35 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
34 fn infer<'db>(&'db self, def: DefWithBodyId) -> Arc<InferenceResult<'db>>;
3635
3736 // region:mir
3837
3938 #[salsa::invoke(crate::mir::mir_body_query)]
4039 #[salsa::cycle(cycle_result = crate::mir::mir_body_cycle_result)]
41 fn mir_body(&self, def: DefWithBodyId) -> Result<Arc<MirBody>, MirLowerError>;
40 fn mir_body<'db>(
41 &'db self,
42 def: DefWithBodyId,
43 ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
4244
4345 #[salsa::invoke(crate::mir::mir_body_for_closure_query)]
44 fn mir_body_for_closure(&self, def: InternedClosureId) -> Result<Arc<MirBody>, MirLowerError>;
46 fn mir_body_for_closure<'db>(
47 &'db self,
48 def: InternedClosureId,
49 ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
4550
4651 #[salsa::invoke(crate::mir::monomorphized_mir_body_query)]
4752 #[salsa::cycle(cycle_result = crate::mir::monomorphized_mir_body_cycle_result)]
48 fn monomorphized_mir_body(
49 &self,
53 fn monomorphized_mir_body<'db>(
54 &'db self,
5055 def: DefWithBodyId,
51 subst: Substitution,
52 env: Arc<TraitEnvironment<'_>>,
53 ) -> Result<Arc<MirBody>, MirLowerError>;
56 subst: crate::next_solver::GenericArgs<'db>,
57 env: Arc<TraitEnvironment<'db>>,
58 ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
5459
5560 #[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)]
56 fn monomorphized_mir_body_for_closure(
57 &self,
61 fn monomorphized_mir_body_for_closure<'db>(
62 &'db self,
5863 def: InternedClosureId,
59 subst: Substitution,
60 env: Arc<TraitEnvironment<'_>>,
61 ) -> Result<Arc<MirBody>, MirLowerError>;
64 subst: crate::next_solver::GenericArgs<'db>,
65 env: Arc<TraitEnvironment<'db>>,
66 ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
6267
6368 #[salsa::invoke(crate::mir::borrowck_query)]
6469 #[salsa::lru(2024)]
65 fn borrowck(&self, def: DefWithBodyId) -> Result<Arc<[BorrowckResult]>, MirLowerError>;
70 fn borrowck<'db>(
71 &'db self,
72 def: DefWithBodyId,
73 ) -> Result<Arc<[BorrowckResult<'db>]>, MirLowerError<'db>>;
6674
6775 #[salsa::invoke(crate::consteval::const_eval_query)]
6876 #[salsa::cycle(cycle_result = crate::consteval::const_eval_cycle_result)]
69 fn const_eval(
70 &self,
77 fn const_eval<'db>(
78 &'db self,
7179 def: GeneralConstId,
72 subst: Substitution,
73 trait_env: Option<Arc<TraitEnvironment<'_>>>,
74 ) -> Result<Const, ConstEvalError>;
80 subst: crate::next_solver::GenericArgs<'db>,
81 trait_env: Option<Arc<TraitEnvironment<'db>>>,
82 ) -> Result<crate::next_solver::Const<'db>, ConstEvalError<'db>>;
7583
7684 #[salsa::invoke(crate::consteval::const_eval_static_query)]
7785 #[salsa::cycle(cycle_result = crate::consteval::const_eval_static_cycle_result)]
78 fn const_eval_static(&self, def: StaticId) -> Result<Const, ConstEvalError>;
86 fn const_eval_static<'db>(
87 &'db self,
88 def: StaticId,
89 ) -> Result<crate::next_solver::Const<'db>, ConstEvalError<'db>>;
7990
8091 #[salsa::invoke(crate::consteval::const_eval_discriminant_variant)]
8192 #[salsa::cycle(cycle_result = crate::consteval::const_eval_discriminant_cycle_result)]
82 fn const_eval_discriminant(&self, def: EnumVariantId) -> Result<i128, ConstEvalError>;
93 fn const_eval_discriminant<'db>(
94 &'db self,
95 def: EnumVariantId,
96 ) -> Result<i128, ConstEvalError<'db>>;
8397
8498 #[salsa::invoke(crate::method_resolution::lookup_impl_method_query)]
85 fn lookup_impl_method(
86 &self,
87 env: Arc<TraitEnvironment<'_>>,
99 fn lookup_impl_method<'db>(
100 &'db self,
101 env: Arc<TraitEnvironment<'db>>,
88102 func: FunctionId,
89 fn_subst: Substitution,
90 ) -> (FunctionId, Substitution);
103 fn_subst: crate::next_solver::GenericArgs<'db>,
104 ) -> (FunctionId, crate::next_solver::GenericArgs<'db>);
91105
92106 // endregion:mir
93107
......@@ -325,10 +339,6 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
325339 goal: crate::Canonical<crate::InEnvironment<crate::Goal>>,
326340 ) -> NextTraitSolveResult;
327341
328 #[salsa::invoke(crate::drop::has_drop_glue)]
329 #[salsa::cycle(cycle_result = crate::drop::has_drop_glue_cycle_result)]
330 fn has_drop_glue(&self, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> DropGlue;
331
332342 // next trait solver
333343
334344 #[salsa::invoke(crate::lower_nextsolver::const_param_ty_query)]
......@@ -370,6 +380,23 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
370380 &'db self,
371381 def: GenericDefId,
372382 ) -> crate::lower_nextsolver::GenericPredicates<'db>;
383
384 #[salsa::invoke(crate::lower_nextsolver::generic_defaults_with_diagnostics_query)]
385 #[salsa::cycle(cycle_result = crate::lower_nextsolver::generic_defaults_with_diagnostics_cycle_result)]
386 fn generic_defaults_ns_with_diagnostics<'db>(
387 &'db self,
388 def: GenericDefId,
389 ) -> (crate::lower_nextsolver::GenericDefaults<'db>, Diagnostics);
390
391 /// This returns an empty list if no parameter has default.
392 ///
393 /// The binders of the returned defaults are only up to (not including) this parameter.
394 #[salsa::invoke(crate::lower_nextsolver::generic_defaults_query)]
395 #[salsa::transparent]
396 fn generic_defaults_ns<'db>(
397 &'db self,
398 def: GenericDefId,
399 ) -> crate::lower_nextsolver::GenericDefaults<'db>;
373400}
374401
375402#[test]
src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs+31-15
......@@ -23,6 +23,8 @@ use tracing::debug;
2323use triomphe::Arc;
2424use typed_arena::Arena;
2525
26use crate::next_solver::DbInterner;
27use crate::next_solver::mapping::NextSolverToChalk;
2628use crate::{
2729 Adjust, InferenceResult, Interner, TraitEnvironment, Ty, TyExt, TyKind,
2830 db::HirDatabase,
......@@ -74,8 +76,16 @@ impl BodyValidationDiagnostic {
7476 let infer = db.infer(owner);
7577 let body = db.body(owner);
7678 let env = db.trait_environment_for_body(owner);
77 let mut validator =
78 ExprValidator { owner, body, infer, diagnostics: Vec::new(), validate_lints, env };
79 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
80 let mut validator = ExprValidator {
81 owner,
82 body,
83 infer,
84 diagnostics: Vec::new(),
85 validate_lints,
86 env,
87 interner,
88 };
7989 validator.validate_body(db);
8090 validator.diagnostics
8191 }
......@@ -84,10 +94,11 @@ impl BodyValidationDiagnostic {
8494struct ExprValidator<'db> {
8595 owner: DefWithBodyId,
8696 body: Arc<Body>,
87 infer: Arc<InferenceResult>,
97 infer: Arc<InferenceResult<'db>>,
8898 env: Arc<TraitEnvironment<'db>>,
8999 diagnostics: Vec<BodyValidationDiagnostic>,
90100 validate_lints: bool,
101 interner: DbInterner<'db>,
91102}
92103
93104impl<'db> ExprValidator<'db> {
......@@ -175,7 +186,7 @@ impl<'db> ExprValidator<'db> {
175186 }
176187
177188 if let Some(receiver_ty) = self.infer.type_of_expr_with_adjust(*receiver) {
178 checker.prev_receiver_ty = Some(receiver_ty.clone());
189 checker.prev_receiver_ty = Some(receiver_ty.to_chalk(self.interner));
179190 }
180191 }
181192 }
......@@ -190,6 +201,7 @@ impl<'db> ExprValidator<'db> {
190201 let Some(scrut_ty) = self.infer.type_of_expr_with_adjust(scrutinee_expr) else {
191202 return;
192203 };
204 let scrut_ty = scrut_ty.to_chalk(self.interner);
193205 if scrut_ty.contains_unknown() {
194206 return;
195207 }
......@@ -205,6 +217,7 @@ impl<'db> ExprValidator<'db> {
205217 let Some(pat_ty) = self.infer.type_of_pat_with_adjust(arm.pat) else {
206218 return;
207219 };
220 let pat_ty = pat_ty.to_chalk(self.interner);
208221 if pat_ty.contains_unknown() {
209222 return;
210223 }
......@@ -222,7 +235,7 @@ impl<'db> ExprValidator<'db> {
222235 if (pat_ty == scrut_ty
223236 || scrut_ty
224237 .as_reference()
225 .map(|(match_expr_ty, ..)| match_expr_ty == pat_ty)
238 .map(|(match_expr_ty, ..)| *match_expr_ty == pat_ty)
226239 .unwrap_or(false))
227240 && types_of_subpatterns_do_match(arm.pat, &self.body, &self.infer)
228241 {
......@@ -264,7 +277,7 @@ impl<'db> ExprValidator<'db> {
264277 match_expr,
265278 uncovered_patterns: missing_match_arms(
266279 &cx,
267 scrut_ty,
280 &scrut_ty,
268281 witnesses,
269282 m_arms.is_empty(),
270283 self.owner.krate(db),
......@@ -298,10 +311,12 @@ impl<'db> ExprValidator<'db> {
298311 );
299312 value_or_partial.is_none_or(|v| !matches!(v, ValueNs::StaticId(_)))
300313 }
301 Expr::Field { expr, .. } => match self.infer.type_of_expr[*expr].kind(Interner) {
302 TyKind::Adt(adt, ..) if matches!(adt.0, AdtId::UnionId(_)) => false,
303 _ => self.is_known_valid_scrutinee(*expr, db),
304 },
314 Expr::Field { expr, .. } => {
315 match self.infer.type_of_expr[*expr].to_chalk(self.interner).kind(Interner) {
316 TyKind::Adt(adt, ..) if matches!(adt.0, AdtId::UnionId(_)) => false,
317 _ => self.is_known_valid_scrutinee(*expr, db),
318 }
319 }
305320 Expr::Index { base, .. } => self.is_known_valid_scrutinee(*base, db),
306321 Expr::Cast { expr, .. } => self.is_known_valid_scrutinee(*expr, db),
307322 Expr::Missing => false,
......@@ -327,6 +342,7 @@ impl<'db> ExprValidator<'db> {
327342 }
328343 let Some(initializer) = initializer else { continue };
329344 let Some(ty) = self.infer.type_of_expr_with_adjust(initializer) else { continue };
345 let ty = ty.to_chalk(self.interner);
330346 if ty.contains_unknown() {
331347 continue;
332348 }
......@@ -357,7 +373,7 @@ impl<'db> ExprValidator<'db> {
357373 pat,
358374 uncovered_patterns: missing_match_arms(
359375 &cx,
360 ty,
376 &ty,
361377 witnesses,
362378 false,
363379 self.owner.krate(db),
......@@ -542,7 +558,7 @@ impl FilterMapNextChecker {
542558
543559pub fn record_literal_missing_fields(
544560 db: &dyn HirDatabase,
545 infer: &InferenceResult,
561 infer: &InferenceResult<'_>,
546562 id: ExprId,
547563 expr: &Expr,
548564) -> Option<(VariantId, Vec<LocalFieldId>, /*exhaustive*/ bool)> {
......@@ -572,7 +588,7 @@ pub fn record_literal_missing_fields(
572588
573589pub fn record_pattern_missing_fields(
574590 db: &dyn HirDatabase,
575 infer: &InferenceResult,
591 infer: &InferenceResult<'_>,
576592 id: PatId,
577593 pat: &Pat,
578594) -> Option<(VariantId, Vec<LocalFieldId>, /*exhaustive*/ bool)> {
......@@ -600,8 +616,8 @@ pub fn record_pattern_missing_fields(
600616 Some((variant_def, missed_fields, exhaustive))
601617}
602618
603fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResult) -> bool {
604 fn walk(pat: PatId, body: &Body, infer: &InferenceResult, has_type_mismatches: &mut bool) {
619fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResult<'_>) -> bool {
620 fn walk(pat: PatId, body: &Body, infer: &InferenceResult<'_>, has_type_mismatches: &mut bool) {
605621 match infer.type_mismatch_for_pat(pat) {
606622 Some(_) => *has_type_mismatches = true,
607623 None if *has_type_mismatches => (),
src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs+22-15
......@@ -20,6 +20,8 @@ use hir_expand::name::Name;
2020use span::Edition;
2121use stdx::{always, never};
2222
23use crate::next_solver::DbInterner;
24use crate::next_solver::mapping::NextSolverToChalk;
2325use crate::{
2426 InferenceResult, Interner, Substitution, Ty, TyExt, TyKind,
2527 db::HirDatabase,
......@@ -93,16 +95,21 @@ pub(crate) enum PatKind {
9395 },
9496}
9597
96pub(crate) struct PatCtxt<'a> {
97 db: &'a dyn HirDatabase,
98 infer: &'a InferenceResult,
99 body: &'a Body,
98pub(crate) struct PatCtxt<'db> {
99 db: &'db dyn HirDatabase,
100 infer: &'db InferenceResult<'db>,
101 body: &'db Body,
100102 pub(crate) errors: Vec<PatternError>,
103 interner: DbInterner<'db>,
101104}
102105
103106impl<'a> PatCtxt<'a> {
104 pub(crate) fn new(db: &'a dyn HirDatabase, infer: &'a InferenceResult, body: &'a Body) -> Self {
105 Self { db, infer, body, errors: Vec::new() }
107 pub(crate) fn new(
108 db: &'a dyn HirDatabase,
109 infer: &'a InferenceResult<'a>,
110 body: &'a Body,
111 ) -> Self {
112 Self { db, infer, body, errors: Vec::new(), interner: DbInterner::new_with(db, None, None) }
106113 }
107114
108115 pub(crate) fn lower_pattern(&mut self, pat: PatId) -> Pat {
......@@ -115,14 +122,14 @@ impl<'a> PatCtxt<'a> {
115122 self.infer.pat_adjustments.get(&pat).map(|it| &**it).unwrap_or_default().iter().rev().fold(
116123 unadjusted_pat,
117124 |subpattern, ref_ty| Pat {
118 ty: ref_ty.clone(),
125 ty: ref_ty.to_chalk(self.interner).clone(),
119126 kind: Box::new(PatKind::Deref { subpattern }),
120127 },
121128 )
122129 }
123130
124131 fn lower_pattern_unadjusted(&mut self, pat: PatId) -> Pat {
125 let mut ty = &self.infer[pat];
132 let mut ty = self.infer[pat].to_chalk(self.interner);
126133 let variant = self.infer.variant_resolution_for_pat(pat);
127134
128135 let kind = match self.body[pat] {
......@@ -140,7 +147,7 @@ impl<'a> PatCtxt<'a> {
140147 _ => {
141148 never!("unexpected type for tuple pattern: {:?}", ty);
142149 self.errors.push(PatternError::UnexpectedType);
143 return Pat { ty: ty.clone(), kind: PatKind::Wild.into() };
150 return Pat { ty, kind: PatKind::Wild.into() };
144151 }
145152 };
146153 let subpatterns = self.lower_tuple_subpats(args, arity, ellipsis);
......@@ -149,10 +156,10 @@ impl<'a> PatCtxt<'a> {
149156
150157 hir_def::hir::Pat::Bind { id, subpat, .. } => {
151158 let bm = self.infer.binding_modes[pat];
152 ty = &self.infer[id];
159 ty = self.infer[id].to_chalk(self.interner);
153160 let name = &self.body[id].name;
154161 match (bm, ty.kind(Interner)) {
155 (BindingMode::Ref(_), TyKind::Ref(.., rty)) => ty = rty,
162 (BindingMode::Ref(_), TyKind::Ref(.., rty)) => ty = rty.clone(),
156163 (BindingMode::Ref(_), _) => {
157164 never!(
158165 "`ref {}` has wrong type {:?}",
......@@ -170,7 +177,7 @@ impl<'a> PatCtxt<'a> {
170177 hir_def::hir::Pat::TupleStruct { ref args, ellipsis, .. } if variant.is_some() => {
171178 let expected_len = variant.unwrap().fields(self.db).fields().len();
172179 let subpatterns = self.lower_tuple_subpats(args, expected_len, ellipsis);
173 self.lower_variant_or_leaf(pat, ty, subpatterns)
180 self.lower_variant_or_leaf(pat, &ty, subpatterns)
174181 }
175182
176183 hir_def::hir::Pat::Record { ref args, .. } if variant.is_some() => {
......@@ -186,7 +193,7 @@ impl<'a> PatCtxt<'a> {
186193 })
187194 .collect();
188195 match subpatterns {
189 Some(subpatterns) => self.lower_variant_or_leaf(pat, ty, subpatterns),
196 Some(subpatterns) => self.lower_variant_or_leaf(pat, &ty, subpatterns),
190197 None => {
191198 self.errors.push(PatternError::MissingField);
192199 PatKind::Wild
......@@ -271,12 +278,12 @@ impl<'a> PatCtxt<'a> {
271278 }
272279
273280 fn lower_path(&mut self, pat: PatId, _path: &Path) -> Pat {
274 let ty = &self.infer[pat];
281 let ty = self.infer[pat].to_chalk(self.interner);
275282
276283 let pat_from_kind = |kind| Pat { ty: ty.clone(), kind: Box::new(kind) };
277284
278285 match self.infer.variant_resolution_for_pat(pat) {
279 Some(_) => pat_from_kind(self.lower_variant_or_leaf(pat, ty, Vec::new())),
286 Some(_) => pat_from_kind(self.lower_variant_or_leaf(pat, &ty, Vec::new())),
280287 None => {
281288 self.errors.push(PatternError::UnresolvedVariant);
282289 pat_from_kind(PatKind::Wild)
src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs+14-10
......@@ -14,6 +14,8 @@ use hir_def::{
1414};
1515use span::Edition;
1616
17use crate::next_solver::DbInterner;
18use crate::next_solver::mapping::NextSolverToChalk;
1719use crate::utils::TargetFeatureIsSafeInTarget;
1820use crate::{
1921 InferenceResult, Interner, TargetFeatures, TyExt, TyKind,
......@@ -96,9 +98,9 @@ enum UnsafeDiagnostic {
9698 DeprecatedSafe2024 { node: ExprId, inside_unsafe_block: InsideUnsafeBlock },
9799}
98100
99pub fn unsafe_operations_for_body(
100 db: &dyn HirDatabase,
101 infer: &InferenceResult,
101pub fn unsafe_operations_for_body<'db>(
102 db: &'db dyn HirDatabase,
103 infer: &InferenceResult<'db>,
102104 def: DefWithBodyId,
103105 body: &Body,
104106 callback: &mut dyn FnMut(ExprOrPatId),
......@@ -115,9 +117,9 @@ pub fn unsafe_operations_for_body(
115117 }
116118}
117119
118pub fn unsafe_operations(
119 db: &dyn HirDatabase,
120 infer: &InferenceResult,
120pub fn unsafe_operations<'db>(
121 db: &'db dyn HirDatabase,
122 infer: &InferenceResult<'db>,
121123 def: DefWithBodyId,
122124 body: &Body,
123125 current: ExprId,
......@@ -135,7 +137,7 @@ pub fn unsafe_operations(
135137
136138struct UnsafeVisitor<'db> {
137139 db: &'db dyn HirDatabase,
138 infer: &'db InferenceResult,
140 infer: &'db InferenceResult<'db>,
139141 body: &'db Body,
140142 resolver: Resolver<'db>,
141143 def: DefWithBodyId,
......@@ -149,12 +151,13 @@ struct UnsafeVisitor<'db> {
149151 /// On some targets (WASM), calling safe functions with `#[target_feature]` is always safe, even when
150152 /// the target feature is not enabled. This flag encodes that.
151153 target_feature_is_safe: TargetFeatureIsSafeInTarget,
154 interner: DbInterner<'db>,
152155}
153156
154157impl<'db> UnsafeVisitor<'db> {
155158 fn new(
156159 db: &'db dyn HirDatabase,
157 infer: &'db InferenceResult,
160 infer: &'db InferenceResult<'db>,
158161 body: &'db Body,
159162 def: DefWithBodyId,
160163 unsafe_expr_cb: &'db mut dyn FnMut(UnsafeDiagnostic),
......@@ -183,6 +186,7 @@ impl<'db> UnsafeVisitor<'db> {
183186 def_target_features,
184187 edition,
185188 target_feature_is_safe,
189 interner: DbInterner::new_with(db, None, None),
186190 }
187191 }
188192
......@@ -285,7 +289,7 @@ impl<'db> UnsafeVisitor<'db> {
285289 let inside_assignment = mem::replace(&mut self.inside_assignment, false);
286290 match expr {
287291 &Expr::Call { callee, .. } => {
288 let callee = &self.infer[callee];
292 let callee = self.infer[callee].to_chalk(self.interner);
289293 if let Some(func) = callee.as_fn_def(self.db) {
290294 self.check_call(current, func);
291295 }
......@@ -338,7 +342,7 @@ impl<'db> UnsafeVisitor<'db> {
338342 }
339343 }
340344 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
341 if let TyKind::Raw(..) = &self.infer[*expr].kind(Interner) {
345 if let TyKind::Raw(..) = &self.infer[*expr].to_chalk(self.interner).kind(Interner) {
342346 self.on_unsafe_op(current.into(), UnsafetyReason::RawPtrDeref);
343347 }
344348 }
src/tools/rust-analyzer/crates/hir-ty/src/display.rs+11-8
......@@ -52,7 +52,7 @@ use crate::{
5252 AliasEq, AliasTy, Binders, CallableDefId, CallableSig, ConcreteConst, Const, ConstScalar,
5353 ConstValue, DomainGoal, FnAbi, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData,
5454 LifetimeOutlives, MemoryMap, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause,
55 TraitEnvironment, TraitRef, TraitRefExt, Ty, TyExt, WhereClause, consteval_nextsolver,
55 TraitEnvironment, TraitRef, TraitRefExt, Ty, TyExt, WhereClause, consteval,
5656 db::{HirDatabase, InternedClosure},
5757 from_assoc_type_id, from_placeholder_idx,
5858 generics::generics,
......@@ -750,8 +750,8 @@ impl<'db> HirDisplay for crate::next_solver::Const<'db> {
750750 }
751751 rustc_type_ir::ConstKind::Value(const_bytes) => render_const_scalar_ns(
752752 f,
753 &const_bytes.value.inner().0,
754 &const_bytes.value.inner().1,
753 &const_bytes.value.inner().memory,
754 &const_bytes.value.inner().memory_map,
755755 const_bytes.ty,
756756 ),
757757 rustc_type_ir::ConstKind::Unevaluated(unev) => {
......@@ -1025,7 +1025,7 @@ fn render_const_scalar_inner<'db>(
10251025 ty.hir_fmt(f)
10261026 }
10271027 TyKind::Array(ty, len) => {
1028 let Some(len) = consteval_nextsolver::try_const_usize(f.db, len) else {
1028 let Some(len) = consteval::try_const_usize(f.db, len) else {
10291029 return f.write_str("<unknown-array-len>");
10301030 };
10311031 let Ok(layout) = f.db.layout_of_ty(ty, trait_env) else {
......@@ -1545,14 +1545,17 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
15451545 never!("Only `impl Fn` is valid for displaying closures in source code");
15461546 }
15471547 }
1548 let chalk_id: chalk_ir::ClosureId<_> = id.into();
15491548 match f.closure_style {
15501549 ClosureStyle::Hide => return write!(f, "{TYPE_HINT_TRUNCATION}"),
15511550 ClosureStyle::ClosureWithId => {
1552 return write!(f, "{{closure#{:?}}}", chalk_id.0.index());
1551 return write!(
1552 f,
1553 "{{closure#{:?}}}",
1554 salsa::plumbing::AsId::as_id(&id).index()
1555 );
15531556 }
15541557 ClosureStyle::ClosureWithSubst => {
1555 write!(f, "{{closure#{:?}}}", chalk_id.0.index())?;
1558 write!(f, "{{closure#{:?}}}", salsa::plumbing::AsId::as_id(&id).index())?;
15561559 return hir_fmt_generics(f, substs.as_slice(Interner), None, None);
15571560 }
15581561 _ => (),
......@@ -1561,7 +1564,7 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
15611564 if let Some(sig) = sig {
15621565 let InternedClosure(def, _) = db.lookup_intern_closure(id);
15631566 let infer = db.infer(def);
1564 let (_, kind) = infer.closure_info(&chalk_id);
1567 let (_, kind) = infer.closure_info(id);
15651568 match f.closure_style {
15661569 ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
15671570 ClosureStyle::RANotation => write!(f, "|")?,
src/tools/rust-analyzer/crates/hir-ty/src/drop.rs+87-104
......@@ -1,18 +1,20 @@
11//! Utilities for computing drop info about types.
22
3use chalk_ir::cast::Cast;
4use hir_def::AdtId;
5use hir_def::lang_item::LangItem;
6use hir_def::signatures::StructFlags;
3use hir_def::{AdtId, lang_item::LangItem, signatures::StructFlags};
4use rustc_hash::FxHashSet;
5use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike};
76use stdx::never;
87use triomphe::Arc;
98
10use crate::next_solver::DbInterner;
11use crate::next_solver::mapping::NextSolverToChalk;
129use crate::{
13 AliasTy, Canonical, CanonicalVarKinds, ConcreteConst, ConstScalar, ConstValue, InEnvironment,
14 Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind, db::HirDatabase,
10 TraitEnvironment, consteval,
11 db::HirDatabase,
1512 method_resolution::TyFingerprint,
13 next_solver::{
14 Ty, TyKind,
15 infer::{InferCtxt, traits::ObligationCause},
16 obligation_ctxt::ObligationCtxt,
17 },
1618};
1719
1820fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
......@@ -45,27 +47,52 @@ pub enum DropGlue {
4547 HasDropGlue,
4648}
4749
48pub(crate) fn has_drop_glue(
49 db: &dyn HirDatabase,
50 ty: Ty,
51 env: Arc<TraitEnvironment<'_>>,
50pub fn has_drop_glue<'db>(
51 infcx: &InferCtxt<'db>,
52 ty: Ty<'db>,
53 env: Arc<TraitEnvironment<'db>>,
5254) -> DropGlue {
53 match ty.kind(Interner) {
54 TyKind::Adt(adt, subst) => {
55 if has_destructor(db, adt.0) {
55 has_drop_glue_impl(infcx, ty, env, &mut FxHashSet::default())
56}
57
58fn has_drop_glue_impl<'db>(
59 infcx: &InferCtxt<'db>,
60 ty: Ty<'db>,
61 env: Arc<TraitEnvironment<'db>>,
62 visited: &mut FxHashSet<Ty<'db>>,
63) -> DropGlue {
64 let mut ocx = ObligationCtxt::new(infcx);
65 let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env.env, ty).unwrap_or(ty);
66
67 if !visited.insert(ty) {
68 // Recursive type.
69 return DropGlue::None;
70 }
71
72 let db = infcx.interner.db;
73 match ty.kind() {
74 TyKind::Adt(adt_def, subst) => {
75 let adt_id = adt_def.def_id().0;
76 if has_destructor(db, adt_id) {
5677 return DropGlue::HasDropGlue;
5778 }
58 match adt.0 {
79 match adt_id {
5980 AdtId::StructId(id) => {
60 if db.struct_signature(id).flags.contains(StructFlags::IS_MANUALLY_DROP) {
81 if db
82 .struct_signature(id)
83 .flags
84 .intersects(StructFlags::IS_MANUALLY_DROP | StructFlags::IS_PHANTOM_DATA)
85 {
6186 return DropGlue::None;
6287 }
63 db.field_types(id.into())
88 db.field_types_ns(id.into())
6489 .iter()
6590 .map(|(_, field_ty)| {
66 db.has_drop_glue(
67 field_ty.clone().substitute(Interner, subst),
91 has_drop_glue_impl(
92 infcx,
93 field_ty.instantiate(infcx.interner, subst),
6894 env.clone(),
95 visited,
6996 )
7097 })
7198 .max()
......@@ -78,12 +105,14 @@ pub(crate) fn has_drop_glue(
78105 .variants
79106 .iter()
80107 .map(|&(variant, _, _)| {
81 db.field_types(variant.into())
108 db.field_types_ns(variant.into())
82109 .iter()
83110 .map(|(_, field_ty)| {
84 db.has_drop_glue(
85 field_ty.clone().substitute(Interner, subst),
111 has_drop_glue_impl(
112 infcx,
113 field_ty.instantiate(infcx.interner, subst),
86114 env.clone(),
115 visited,
87116 )
88117 })
89118 .max()
......@@ -93,116 +122,70 @@ pub(crate) fn has_drop_glue(
93122 .unwrap_or(DropGlue::None),
94123 }
95124 }
96 TyKind::Tuple(_, subst) => subst
97 .iter(Interner)
98 .map(|ty| ty.assert_ty_ref(Interner))
99 .map(|ty| db.has_drop_glue(ty.clone(), env.clone()))
125 TyKind::Tuple(tys) => tys
126 .iter()
127 .map(|ty| has_drop_glue_impl(infcx, ty, env.clone(), visited))
100128 .max()
101129 .unwrap_or(DropGlue::None),
102130 TyKind::Array(ty, len) => {
103 if let ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Bytes(len, _) }) =
104 &len.data(Interner).value
105 {
106 match (&**len).try_into() {
107 Ok(len) => {
108 let len = usize::from_le_bytes(len);
109 if len == 0 {
110 // Arrays of size 0 don't have drop glue.
111 return DropGlue::None;
112 }
113 }
114 Err(_) => {
115 never!("const array size with non-usize len");
116 }
117 }
131 if consteval::try_const_usize(db, len) == Some(0) {
132 // Arrays of size 0 don't have drop glue.
133 return DropGlue::None;
118134 }
119 db.has_drop_glue(ty.clone(), env)
135 has_drop_glue_impl(infcx, ty, env, visited)
120136 }
121 TyKind::Slice(ty) => db.has_drop_glue(ty.clone(), env),
137 TyKind::Slice(ty) => has_drop_glue_impl(infcx, ty, env, visited),
122138 TyKind::Closure(closure_id, subst) => {
123 let owner = db.lookup_intern_closure((*closure_id).into()).0;
139 let owner = db.lookup_intern_closure(closure_id.0).0;
124140 let infer = db.infer(owner);
125 let (captures, _) = infer.closure_info(closure_id);
141 let (captures, _) = infer.closure_info(closure_id.0);
126142 let env = db.trait_environment_for_body(owner);
127143 captures
128144 .iter()
129 .map(|capture| db.has_drop_glue(capture.ty(db, subst), env.clone()))
145 .map(|capture| {
146 has_drop_glue_impl(infcx, capture.ty(db, subst), env.clone(), visited)
147 })
130148 .max()
131149 .unwrap_or(DropGlue::None)
132150 }
133151 // FIXME: Handle coroutines.
134 TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) => DropGlue::None,
152 TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) | TyKind::CoroutineClosure(..) => {
153 DropGlue::None
154 }
135155 TyKind::Ref(..)
136 | TyKind::Raw(..)
156 | TyKind::RawPtr(..)
137157 | TyKind::FnDef(..)
138158 | TyKind::Str
139159 | TyKind::Never
140 | TyKind::Scalar(_)
141 | TyKind::Function(_)
160 | TyKind::Bool
161 | TyKind::Char
162 | TyKind::Int(_)
163 | TyKind::Uint(_)
164 | TyKind::Float(_)
165 | TyKind::FnPtr(..)
142166 | TyKind::Foreign(_)
143 | TyKind::Error => DropGlue::None,
144 TyKind::Dyn(_) => DropGlue::HasDropGlue,
145 TyKind::AssociatedType(assoc_type_id, subst) => projection_has_drop_glue(
146 db,
147 env,
148 ProjectionTy { associated_ty_id: *assoc_type_id, substitution: subst.clone() },
149 ty,
150 ),
151 TyKind::Alias(AliasTy::Projection(projection)) => {
152 projection_has_drop_glue(db, env, projection.clone(), ty)
153 }
154 TyKind::OpaqueType(..) | TyKind::Alias(AliasTy::Opaque(_)) => {
155 if is_copy(db, ty, env) {
167 | TyKind::Error(_)
168 | TyKind::Bound(..)
169 | TyKind::Placeholder(..) => DropGlue::None,
170 TyKind::Dynamic(..) => DropGlue::HasDropGlue,
171 TyKind::Alias(..) => {
172 if infcx.type_is_copy_modulo_regions(env.env, ty) {
156173 DropGlue::None
157174 } else {
158175 DropGlue::HasDropGlue
159176 }
160177 }
161 TyKind::Placeholder(_) | TyKind::BoundVar(_) => {
162 if is_copy(db, ty, env) {
178 TyKind::Param(_) => {
179 if infcx.type_is_copy_modulo_regions(env.env, ty) {
163180 DropGlue::None
164181 } else {
165182 DropGlue::DependOnParams
166183 }
167184 }
168 TyKind::InferenceVar(..) => unreachable!("inference vars shouldn't exist out of inference"),
169 }
170}
171
172fn projection_has_drop_glue(
173 db: &dyn HirDatabase,
174 env: Arc<TraitEnvironment<'_>>,
175 projection: ProjectionTy,
176 ty: Ty,
177) -> DropGlue {
178 let normalized = db.normalize_projection(projection, env.clone());
179 match normalized.kind(Interner) {
180 TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(..) => {
181 if is_copy(db, ty, env) { DropGlue::None } else { DropGlue::DependOnParams }
185 TyKind::Infer(..) => unreachable!("inference vars shouldn't exist out of inference"),
186 TyKind::Pat(..) | TyKind::UnsafeBinder(..) => {
187 never!("we do not handle pattern and unsafe binder types");
188 DropGlue::None
182189 }
183 _ => db.has_drop_glue(normalized, env),
184190 }
185191}
186
187fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> bool {
188 let Some(copy_trait) = LangItem::Copy.resolve_trait(db, env.krate) else {
189 return false;
190 };
191 let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build();
192 let goal = Canonical {
193 value: InEnvironment::new(
194 &env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)),
195 trait_ref.cast(Interner),
196 ),
197 binders: CanonicalVarKinds::empty(Interner),
198 };
199 db.trait_solve(env.krate, env.block, goal).certain()
200}
201
202pub(crate) fn has_drop_glue_cycle_result(
203 _db: &dyn HirDatabase,
204 _ty: Ty,
205 _env: Arc<TraitEnvironment<'_>>,
206) -> DropGlue {
207 DropGlue::None
208}
src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs+1-1
......@@ -57,7 +57,7 @@ fn check_dyn_compatibility<'a>(
5757 };
5858 let mut osvs = FxHashSet::default();
5959 let db = &db;
60 salsa::attach(db, || {
60 crate::attach_db(db, || {
6161 _ = dyn_compatibility_with_callback(db, trait_id, &mut |osv| {
6262 osvs.insert(match osv {
6363 DynCompatibilityViolation::SizedSelf => SizedSelf,
src/tools/rust-analyzer/crates/hir-ty/src/infer.rs+536-710
......@@ -28,19 +28,11 @@ pub(crate) mod unify;
2828use std::{cell::OnceCell, convert::identity, iter, ops::Index};
2929
3030use base_db::Crate;
31use chalk_ir::{
32 DebruijnIndex, Mutability, Safety, Scalar, TyKind, TypeFlags, Variance,
33 cast::Cast,
34 fold::TypeFoldable,
35 interner::HasInterner,
36 visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
37};
3831use either::Either;
3932use hir_def::{
4033 AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId,
4134 ImplId, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId,
4235 VariantId,
43 builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
4436 expr_store::{Body, ExpressionStore, HygieneId, path::Path},
4537 hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
4638 lang_item::{LangItem, LangItemTarget, lang_item},
......@@ -53,18 +45,19 @@ use hir_expand::{mod_path::ModPath, name::Name};
5345use indexmap::IndexSet;
5446use intern::sym;
5547use la_arena::{ArenaMap, Entry};
48use rustc_ast_ir::Mutability;
5649use rustc_hash::{FxHashMap, FxHashSet};
57use rustc_type_ir::inherent::Ty as _;
58use stdx::{always, never};
50use rustc_type_ir::{
51 AliasTyKind, Flags, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
52 inherent::{AdtDef, IntoKind, Region as _, SliceLike, Ty as _},
53};
54use stdx::never;
5955use triomphe::Arc;
6056
6157use crate::{
62 AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, ImplTraitId, ImplTraitIdx,
63 IncorrectGenericsLenKind, Interner, Lifetime, OpaqueTyId, ParamLoweringMode,
64 PathLoweringDiagnostic, ProjectionTy, Substitution, TargetFeatures, TraitEnvironment, Ty,
65 TyBuilder, TyExt,
66 db::{HirDatabase, InternedClosureId},
67 fold_tys,
58 ImplTraitId, IncorrectGenericsLenKind, Interner, PathLoweringDiagnostic, TargetFeatures,
59 TraitEnvironment,
60 db::{HirDatabase, InternedClosureId, InternedOpaqueTyId},
6861 generics::Generics,
6962 infer::{
7063 coerce::{CoerceMany, DynamicCoerceMany},
......@@ -72,16 +65,22 @@ use crate::{
7265 expr::ExprIsRead,
7366 unify::InferenceTable,
7467 },
75 lower::{ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic},
68 lower::diagnostics::TyLoweringDiagnostic,
69 lower_nextsolver::{ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind},
7670 mir::MirSpan,
7771 next_solver::{
78 self, DbInterner,
79 infer::{DefineOpaqueTypes, traits::ObligationCause},
72 AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Region, Ty, TyKind,
73 Tys,
74 abi::Safety,
75 fold::fold_tys,
76 infer::{
77 DefineOpaqueTypes,
78 traits::{Obligation, ObligationCause},
79 },
8080 mapping::{ChalkToNextSolver, NextSolverToChalk},
8181 },
82 static_lifetime, to_assoc_type_id,
8382 traits::FnTrait,
84 utils::{TargetFeatureIsSafeInTarget, UnevaluatedConstEvaluatorFolder},
83 utils::TargetFeatureIsSafeInTarget,
8584};
8685
8786// This lint has a false positive here. See the link below for details.
......@@ -96,7 +95,7 @@ use cast::{CastCheck, CastError};
9695pub(crate) use closure::analysis::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
9796
9897/// The entry point of type inference.
99pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
98pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult<'_>> {
10099 let _p = tracing::info_span!("infer_query").entered();
101100 let resolver = def.resolver(db);
102101 let body = db.body(def);
......@@ -109,30 +108,28 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
109108 DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)),
110109 DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)),
111110 DefWithBodyId::VariantId(v) => {
112 ctx.return_ty = TyBuilder::builtin(
113 match db.enum_signature(v.lookup(db).parent).variant_body_type() {
114 hir_def::layout::IntegerType::Pointer(signed) => match signed {
115 true => BuiltinType::Int(BuiltinInt::Isize),
116 false => BuiltinType::Uint(BuiltinUint::Usize),
111 ctx.return_ty = match db.enum_signature(v.lookup(db).parent).variant_body_type() {
112 hir_def::layout::IntegerType::Pointer(signed) => match signed {
113 true => ctx.types.isize,
114 false => ctx.types.usize,
115 },
116 hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
117 true => match size {
118 Integer::I8 => ctx.types.i8,
119 Integer::I16 => ctx.types.i16,
120 Integer::I32 => ctx.types.i32,
121 Integer::I64 => ctx.types.i64,
122 Integer::I128 => ctx.types.i128,
117123 },
118 hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
119 true => BuiltinType::Int(match size {
120 Integer::I8 => BuiltinInt::I8,
121 Integer::I16 => BuiltinInt::I16,
122 Integer::I32 => BuiltinInt::I32,
123 Integer::I64 => BuiltinInt::I64,
124 Integer::I128 => BuiltinInt::I128,
125 }),
126 false => BuiltinType::Uint(match size {
127 Integer::I8 => BuiltinUint::U8,
128 Integer::I16 => BuiltinUint::U16,
129 Integer::I32 => BuiltinUint::U32,
130 Integer::I64 => BuiltinUint::U64,
131 Integer::I128 => BuiltinUint::U128,
132 }),
124 false => match size {
125 Integer::I8 => ctx.types.u8,
126 Integer::I16 => ctx.types.u16,
127 Integer::I32 => ctx.types.u32,
128 Integer::I64 => ctx.types.u64,
129 Integer::I128 => ctx.types.u128,
133130 },
134131 },
135 );
132 };
136133 }
137134 }
138135
......@@ -159,8 +156,14 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
159156 Arc::new(ctx.resolve_all())
160157}
161158
162pub(crate) fn infer_cycle_result(_: &dyn HirDatabase, _: DefWithBodyId) -> Arc<InferenceResult> {
163 Arc::new(InferenceResult { has_errors: true, ..Default::default() })
159pub(crate) fn infer_cycle_result(
160 db: &dyn HirDatabase,
161 _: DefWithBodyId,
162) -> Arc<InferenceResult<'_>> {
163 Arc::new(InferenceResult {
164 has_errors: true,
165 ..InferenceResult::new(Ty::new_error(DbInterner::new_with(db, None, None), ErrorGuaranteed))
166 })
164167}
165168
166169/// Fully normalize all the types found within `ty` in context of `owner` body definition.
......@@ -168,20 +171,24 @@ pub(crate) fn infer_cycle_result(_: &dyn HirDatabase, _: DefWithBodyId) -> Arc<I
168171/// This is appropriate to use only after type-check: it assumes
169172/// that normalization will succeed, for example.
170173#[tracing::instrument(level = "debug", skip(db))]
171pub(crate) fn normalize(db: &dyn HirDatabase, trait_env: Arc<TraitEnvironment<'_>>, ty: Ty) -> Ty {
174pub(crate) fn normalize(
175 db: &dyn HirDatabase,
176 trait_env: Arc<TraitEnvironment<'_>>,
177 ty: crate::Ty,
178) -> crate::Ty {
172179 // FIXME: TypeFlags::HAS_CT_PROJECTION is not implemented in chalk, so TypeFlags::HAS_PROJECTION only
173180 // works for the type case, so we check array unconditionally. Remove the array part
174181 // when the bug in chalk becomes fixed.
175 if !ty.data(Interner).flags.intersects(TypeFlags::HAS_PROJECTION)
176 && !matches!(ty.kind(Interner), TyKind::Array(..))
182 if !ty.data(Interner).flags.intersects(crate::TypeFlags::HAS_PROJECTION)
183 && !matches!(ty.kind(Interner), crate::TyKind::Array(..))
177184 {
178185 return ty;
179186 }
180187 let mut table = unify::InferenceTable::new(db, trait_env);
181188
182 let ty_with_vars = table.normalize_associated_types_in(ty);
189 let ty_with_vars = table.normalize_associated_types_in(ty.to_nextsolver(table.interner()));
183190 table.select_obligations_where_possible();
184 table.resolve_completely(ty_with_vars)
191 table.resolve_completely(ty_with_vars).to_chalk(table.interner())
185192}
186193
187194/// Binding modes inferred for patterns.
......@@ -203,14 +210,6 @@ impl BindingMode {
203210 }
204211}
205212
206// FIXME: Remove this `InferOk`, switch all code to the second one, that uses `Obligation` instead of `Goal`.
207#[derive(Debug)]
208pub(crate) struct InferOk<'db, T> {
209 #[allow(dead_code)]
210 value: T,
211 goals: Vec<next_solver::Goal<'db, next_solver::Predicate<'db>>>,
212}
213
214213#[derive(Debug, PartialEq, Eq, Clone, Copy)]
215214pub enum InferenceTyDiagnosticSource {
216215 /// Diagnostics that come from types in the body.
......@@ -219,12 +218,8 @@ pub enum InferenceTyDiagnosticSource {
219218 Signature,
220219}
221220
222#[derive(Debug)]
223pub(crate) struct TypeError;
224pub(crate) type InferResult<'db, T> = Result<InferOk<'db, T>, TypeError>;
225
226221#[derive(Debug, PartialEq, Eq, Clone)]
227pub enum InferenceDiagnostic {
222pub enum InferenceDiagnostic<'db> {
228223 NoSuchField {
229224 field: ExprOrPatId,
230225 private: Option<LocalFieldId>,
......@@ -240,16 +235,16 @@ pub enum InferenceDiagnostic {
240235 },
241236 UnresolvedField {
242237 expr: ExprId,
243 receiver: Ty,
238 receiver: Ty<'db>,
244239 name: Name,
245240 method_with_same_name_exists: bool,
246241 },
247242 UnresolvedMethodCall {
248243 expr: ExprId,
249 receiver: Ty,
244 receiver: Ty<'db>,
250245 name: Name,
251246 /// Contains the type the field resolves to
252 field_with_same_name: Option<Ty>,
247 field_with_same_name: Option<Ty<'db>>,
253248 assoc_func_with_same_name: Option<FunctionId>,
254249 },
255250 UnresolvedAssocItem {
......@@ -276,21 +271,21 @@ pub enum InferenceDiagnostic {
276271 },
277272 ExpectedFunction {
278273 call_expr: ExprId,
279 found: Ty,
274 found: Ty<'db>,
280275 },
281276 TypedHole {
282277 expr: ExprId,
283 expected: Ty,
278 expected: Ty<'db>,
284279 },
285280 CastToUnsized {
286281 expr: ExprId,
287 cast_ty: Ty,
282 cast_ty: Ty<'db>,
288283 },
289284 InvalidCast {
290285 expr: ExprId,
291286 error: CastError,
292 expr_ty: Ty,
293 cast_ty: Ty,
287 expr_ty: Ty<'db>,
288 cast_ty: Ty<'db>,
294289 },
295290 TyDiagnostic {
296291 source: InferenceTyDiagnosticSource,
......@@ -318,29 +313,11 @@ pub enum InferenceDiagnostic {
318313
319314/// A mismatch between an expected and an inferred type.
320315#[derive(Clone, PartialEq, Eq, Debug, Hash)]
321pub struct TypeMismatch {
322 pub expected: Ty,
323 pub actual: Ty,
316pub struct TypeMismatch<'db> {
317 pub expected: Ty<'db>,
318 pub actual: Ty<'db>,
324319}
325320
326#[derive(Clone, PartialEq, Eq, Debug)]
327struct InternedStandardTypes {
328 unknown: Ty,
329 bool_: Ty,
330 unit: Ty,
331 never: Ty,
332}
333
334impl Default for InternedStandardTypes {
335 fn default() -> Self {
336 InternedStandardTypes {
337 unknown: TyKind::Error.intern(Interner),
338 bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
339 unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
340 never: TyKind::Never.intern(Interner),
341 }
342 }
343}
344321/// Represents coercing a value to a different type of value.
345322///
346323/// We transform values by following a number of `Adjust` steps in order.
......@@ -382,14 +359,14 @@ impl Default for InternedStandardTypes {
382359/// case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
383360/// Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
384361#[derive(Clone, Debug, PartialEq, Eq, Hash)]
385pub struct Adjustment {
386 pub kind: Adjust,
387 pub target: Ty,
362pub struct Adjustment<'db> {
363 pub kind: Adjust<'db>,
364 pub target: Ty<'db>,
388365}
389366
390impl Adjustment {
391 pub fn borrow(m: Mutability, ty: Ty, lt: Lifetime) -> Self {
392 let ty = TyKind::Ref(m, lt.clone(), ty).intern(Interner);
367impl<'db> Adjustment<'db> {
368 pub fn borrow(interner: DbInterner<'db>, m: Mutability, ty: Ty<'db>, lt: Region<'db>) -> Self {
369 let ty = Ty::new_ref(interner, lt, ty, m);
393370 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(lt, m)), target: ty }
394371 }
395372}
......@@ -415,13 +392,13 @@ pub(crate) enum AllowTwoPhase {
415392}
416393
417394#[derive(Clone, Debug, PartialEq, Eq, Hash)]
418pub enum Adjust {
395pub enum Adjust<'db> {
419396 /// Go from ! to any type.
420397 NeverToAny,
421398 /// Dereference once, producing a place.
422399 Deref(Option<OverloadedDeref>),
423400 /// Take the address and produce either a `&` or `*` pointer.
424 Borrow(AutoBorrow),
401 Borrow(AutoBorrow<'db>),
425402 Pointer(PointerCast),
426403}
427404
......@@ -433,14 +410,14 @@ pub enum Adjust {
433410pub struct OverloadedDeref(pub Option<Mutability>);
434411
435412#[derive(Clone, Debug, PartialEq, Eq, Hash)]
436pub enum AutoBorrow {
413pub enum AutoBorrow<'db> {
437414 /// Converts from T to &T.
438 Ref(Lifetime, Mutability),
415 Ref(Region<'db>, Mutability),
439416 /// Converts from T to *T.
440417 RawPtr(Mutability),
441418}
442419
443impl AutoBorrow {
420impl<'db> AutoBorrow<'db> {
444421 fn mutability(&self) -> Mutability {
445422 let (AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) = self;
446423 *m
......@@ -484,41 +461,41 @@ pub enum PointerCast {
484461/// When you add a field that stores types (including `Substitution` and the like), don't forget
485462/// `resolve_completely()`'ing them in `InferenceContext::resolve_all()`. Inference variables must
486463/// not appear in the final inference result.
487#[derive(Clone, PartialEq, Eq, Debug, Default)]
488pub struct InferenceResult {
464#[derive(Clone, PartialEq, Eq, Debug)]
465pub struct InferenceResult<'db> {
489466 /// For each method call expr, records the function it resolves to.
490 method_resolutions: FxHashMap<ExprId, (FunctionId, Substitution)>,
467 method_resolutions: FxHashMap<ExprId, (FunctionId, GenericArgs<'db>)>,
491468 /// For each field access expr, records the field it resolves to.
492469 field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,
493470 /// For each struct literal or pattern, records the variant it resolves to.
494471 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
495472 /// For each associated item record what it resolves to
496 assoc_resolutions: FxHashMap<ExprOrPatId, (AssocItemId, Substitution)>,
473 assoc_resolutions: FxHashMap<ExprOrPatId, (AssocItemId, GenericArgs<'db>)>,
497474 /// Whenever a tuple field expression access a tuple field, we allocate a tuple id in
498475 /// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of
499476 /// that which allows us to resolve a [`TupleFieldId`]s type.
500 tuple_field_access_types: FxHashMap<TupleId, Substitution>,
477 tuple_field_access_types: FxHashMap<TupleId, Tys<'db>>,
501478 /// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead.
502 diagnostics: Vec<InferenceDiagnostic>,
503 pub(crate) type_of_expr: ArenaMap<ExprId, Ty>,
479 diagnostics: Vec<InferenceDiagnostic<'db>>,
480 pub(crate) type_of_expr: ArenaMap<ExprId, Ty<'db>>,
504481 /// For each pattern record the type it resolves to.
505482 ///
506483 /// **Note**: When a pattern type is resolved it may still contain
507484 /// unresolved or missing subpatterns or subpatterns of mismatched types.
508 pub(crate) type_of_pat: ArenaMap<PatId, Ty>,
509 pub(crate) type_of_binding: ArenaMap<BindingId, Ty>,
510 pub(crate) type_of_rpit: ArenaMap<ImplTraitIdx, Ty>,
511 type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
485 pub(crate) type_of_pat: ArenaMap<PatId, Ty<'db>>,
486 pub(crate) type_of_binding: ArenaMap<BindingId, Ty<'db>>,
487 pub(crate) type_of_rpit: ArenaMap<ImplTraitIdx<'db>, Ty<'db>>,
488 type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch<'db>>,
512489 /// Whether there are any type-mismatching errors in the result.
513490 // FIXME: This isn't as useful as initially thought due to us falling back placeholders to
514491 // `TyKind::Error`.
515492 // Which will then mark this field.
516493 pub(crate) has_errors: bool,
517 /// Interned common types to return references to.
518 // FIXME: Move this into `InferenceContext`
519 standard_types: InternedStandardTypes,
494 /// Interned `Error` type to return references to.
495 // FIXME: Remove this.
496 error_ty: Ty<'db>,
520497 /// Stores the types which were implicitly dereferenced in pattern binding modes.
521 pub(crate) pat_adjustments: FxHashMap<PatId, Vec<Ty>>,
498 pub(crate) pat_adjustments: FxHashMap<PatId, Vec<Ty<'db>>>,
522499 /// Stores the binding mode (`ref` in `let ref x = 2`) of bindings.
523500 ///
524501 /// This one is tied to the `PatId` instead of `BindingId`, because in some rare cases, a binding in an
......@@ -533,16 +510,40 @@ pub struct InferenceResult {
533510 /// ```
534511 /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.
535512 pub(crate) binding_modes: ArenaMap<PatId, BindingMode>,
536 pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,
537 pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>,
513 pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment<'db>]>>,
514 pub(crate) closure_info: FxHashMap<InternedClosureId, (Vec<CapturedItem<'db>>, FnTrait)>,
538515 // FIXME: remove this field
539516 pub mutated_bindings_in_closure: FxHashSet<BindingId>,
540517 pub(crate) coercion_casts: FxHashSet<ExprId>,
541518}
542519
543impl InferenceResult {
544 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, Substitution)> {
545 self.method_resolutions.get(&expr).cloned()
520impl<'db> InferenceResult<'db> {
521 fn new(error_ty: Ty<'db>) -> Self {
522 Self {
523 method_resolutions: Default::default(),
524 field_resolutions: Default::default(),
525 variant_resolutions: Default::default(),
526 assoc_resolutions: Default::default(),
527 tuple_field_access_types: Default::default(),
528 diagnostics: Default::default(),
529 type_of_expr: Default::default(),
530 type_of_pat: Default::default(),
531 type_of_binding: Default::default(),
532 type_of_rpit: Default::default(),
533 type_mismatches: Default::default(),
534 has_errors: Default::default(),
535 error_ty,
536 pat_adjustments: Default::default(),
537 binding_modes: Default::default(),
538 expr_adjustments: Default::default(),
539 closure_info: Default::default(),
540 mutated_bindings_in_closure: Default::default(),
541 coercion_casts: Default::default(),
542 }
543 }
544
545 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> {
546 self.method_resolutions.get(&expr).copied()
546547 }
547548 pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {
548549 self.field_resolutions.get(&expr).copied()
......@@ -559,46 +560,49 @@ impl InferenceResult {
559560 ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),
560561 }
561562 }
562 pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<(AssocItemId, Substitution)> {
563 self.assoc_resolutions.get(&id.into()).cloned()
563 pub fn assoc_resolutions_for_expr(
564 &self,
565 id: ExprId,
566 ) -> Option<(AssocItemId, GenericArgs<'db>)> {
567 self.assoc_resolutions.get(&id.into()).copied()
564568 }
565 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(AssocItemId, Substitution)> {
566 self.assoc_resolutions.get(&id.into()).cloned()
569 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(AssocItemId, GenericArgs<'db>)> {
570 self.assoc_resolutions.get(&id.into()).copied()
567571 }
568572 pub fn assoc_resolutions_for_expr_or_pat(
569573 &self,
570574 id: ExprOrPatId,
571 ) -> Option<(AssocItemId, Substitution)> {
575 ) -> Option<(AssocItemId, GenericArgs<'db>)> {
572576 match id {
573577 ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),
574578 ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),
575579 }
576580 }
577 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
581 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch<'db>> {
578582 self.type_mismatches.get(&expr.into())
579583 }
580 pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch> {
584 pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch<'db>> {
581585 self.type_mismatches.get(&pat.into())
582586 }
583 pub fn type_mismatches(&self) -> impl Iterator<Item = (ExprOrPatId, &TypeMismatch)> {
587 pub fn type_mismatches(&self) -> impl Iterator<Item = (ExprOrPatId, &TypeMismatch<'db>)> {
584588 self.type_mismatches.iter().map(|(expr_or_pat, mismatch)| (*expr_or_pat, mismatch))
585589 }
586 pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch)> {
590 pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch<'db>)> {
587591 self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
588592 ExprOrPatId::ExprId(expr) => Some((expr, mismatch)),
589593 _ => None,
590594 })
591595 }
592 pub fn closure_info(&self, closure: &ClosureId) -> &(Vec<CapturedItem>, FnTrait) {
593 self.closure_info.get(closure).unwrap()
596 pub fn closure_info(&self, closure: InternedClosureId) -> &(Vec<CapturedItem<'db>>, FnTrait) {
597 self.closure_info.get(&closure).unwrap()
594598 }
595 pub fn type_of_expr_or_pat(&self, id: ExprOrPatId) -> Option<&Ty> {
599 pub fn type_of_expr_or_pat(&self, id: ExprOrPatId) -> Option<Ty<'db>> {
596600 match id {
597 ExprOrPatId::ExprId(id) => self.type_of_expr.get(id),
598 ExprOrPatId::PatId(id) => self.type_of_pat.get(id),
601 ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).copied(),
602 ExprOrPatId::PatId(id) => self.type_of_pat.get(id).copied(),
599603 }
600604 }
601 pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option<&Ty> {
605 pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option<Ty<'db>> {
602606 match self.expr_adjustments.get(&id).and_then(|adjustments| {
603607 adjustments
604608 .iter()
......@@ -614,33 +618,33 @@ impl InferenceResult {
614618 })
615619 .next_back()
616620 }) {
617 Some(adjustment) => Some(&adjustment.target),
618 None => self.type_of_expr.get(id),
621 Some(adjustment) => Some(adjustment.target),
622 None => self.type_of_expr.get(id).copied(),
619623 }
620624 }
621 pub fn type_of_pat_with_adjust(&self, id: PatId) -> Option<&Ty> {
625 pub fn type_of_pat_with_adjust(&self, id: PatId) -> Option<Ty<'db>> {
622626 match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {
623 adjusted @ Some(_) => adjusted,
624 None => self.type_of_pat.get(id),
627 Some(adjusted) => Some(*adjusted),
628 None => self.type_of_pat.get(id).copied(),
625629 }
626630 }
627631 pub fn is_erroneous(&self) -> bool {
628632 self.has_errors && self.type_of_expr.iter().count() == 0
629633 }
630634
631 pub fn diagnostics(&self) -> &[InferenceDiagnostic] {
635 pub fn diagnostics(&self) -> &[InferenceDiagnostic<'db>] {
632636 &self.diagnostics
633637 }
634638
635 pub fn tuple_field_access_type(&self, id: TupleId) -> &Substitution {
636 &self.tuple_field_access_types[&id]
639 pub fn tuple_field_access_type(&self, id: TupleId) -> Tys<'db> {
640 self.tuple_field_access_types[&id]
637641 }
638642
639 pub fn pat_adjustment(&self, id: PatId) -> Option<&[Ty]> {
643 pub fn pat_adjustment(&self, id: PatId) -> Option<&[Ty<'db>]> {
640644 self.pat_adjustments.get(&id).map(|it| &**it)
641645 }
642646
643 pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> {
647 pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment<'db>]> {
644648 self.expr_adjustments.get(&id).map(|it| &**it)
645649 }
646650
......@@ -649,83 +653,138 @@ impl InferenceResult {
649653 }
650654
651655 // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.
652 pub fn expression_types(&self) -> impl Iterator<Item = (ExprId, &Ty)> {
653 self.type_of_expr.iter()
656 pub fn expression_types(&self) -> impl Iterator<Item = (ExprId, Ty<'db>)> {
657 self.type_of_expr.iter().map(|(k, v)| (k, *v))
654658 }
655659
656660 // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.
657 pub fn pattern_types(&self) -> impl Iterator<Item = (PatId, &Ty)> {
658 self.type_of_pat.iter()
661 pub fn pattern_types(&self) -> impl Iterator<Item = (PatId, Ty<'db>)> {
662 self.type_of_pat.iter().map(|(k, v)| (k, *v))
659663 }
660664
661665 // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.
662 pub fn binding_types(&self) -> impl Iterator<Item = (BindingId, &Ty)> {
663 self.type_of_binding.iter()
666 pub fn binding_types(&self) -> impl Iterator<Item = (BindingId, Ty<'db>)> {
667 self.type_of_binding.iter().map(|(k, v)| (k, *v))
664668 }
665669
666670 // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.
667 pub fn return_position_impl_trait_types(&self) -> impl Iterator<Item = (ImplTraitIdx, &Ty)> {
668 self.type_of_rpit.iter()
671 pub fn return_position_impl_trait_types(
672 &self,
673 ) -> impl Iterator<Item = (ImplTraitIdx<'db>, Ty<'db>)> {
674 self.type_of_rpit.iter().map(|(k, v)| (k, *v))
669675 }
670676}
671677
672impl Index<ExprId> for InferenceResult {
673 type Output = Ty;
678impl<'db> Index<ExprId> for InferenceResult<'db> {
679 type Output = Ty<'db>;
674680
675 fn index(&self, expr: ExprId) -> &Ty {
676 self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown)
681 fn index(&self, expr: ExprId) -> &Ty<'db> {
682 self.type_of_expr.get(expr).unwrap_or(&self.error_ty)
677683 }
678684}
679685
680impl Index<PatId> for InferenceResult {
681 type Output = Ty;
686impl<'db> Index<PatId> for InferenceResult<'db> {
687 type Output = Ty<'db>;
682688
683 fn index(&self, pat: PatId) -> &Ty {
684 self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown)
689 fn index(&self, pat: PatId) -> &Ty<'db> {
690 self.type_of_pat.get(pat).unwrap_or(&self.error_ty)
685691 }
686692}
687693
688impl Index<ExprOrPatId> for InferenceResult {
689 type Output = Ty;
694impl<'db> Index<ExprOrPatId> for InferenceResult<'db> {
695 type Output = Ty<'db>;
690696
691 fn index(&self, id: ExprOrPatId) -> &Ty {
692 self.type_of_expr_or_pat(id).unwrap_or(&self.standard_types.unknown)
697 fn index(&self, id: ExprOrPatId) -> &Ty<'db> {
698 match id {
699 ExprOrPatId::ExprId(id) => &self[id],
700 ExprOrPatId::PatId(id) => &self[id],
701 }
693702 }
694703}
695704
696impl Index<BindingId> for InferenceResult {
697 type Output = Ty;
705impl<'db> Index<BindingId> for InferenceResult<'db> {
706 type Output = Ty<'db>;
698707
699 fn index(&self, b: BindingId) -> &Ty {
700 self.type_of_binding.get(b).unwrap_or(&self.standard_types.unknown)
708 fn index(&self, b: BindingId) -> &Ty<'db> {
709 self.type_of_binding.get(b).unwrap_or(&self.error_ty)
701710 }
702711}
703712
704713#[derive(Debug, Clone)]
705struct InternedStandardTypesNextSolver<'db> {
706 unit: crate::next_solver::Ty<'db>,
707 never: crate::next_solver::Ty<'db>,
708 i32: crate::next_solver::Ty<'db>,
709 f64: crate::next_solver::Ty<'db>,
714struct InternedStandardTypes<'db> {
715 unit: Ty<'db>,
716 never: Ty<'db>,
717 char: Ty<'db>,
718 bool: Ty<'db>,
719 i8: Ty<'db>,
720 i16: Ty<'db>,
721 i32: Ty<'db>,
722 i64: Ty<'db>,
723 i128: Ty<'db>,
724 isize: Ty<'db>,
725 u8: Ty<'db>,
726 u16: Ty<'db>,
727 u32: Ty<'db>,
728 u64: Ty<'db>,
729 u128: Ty<'db>,
730 usize: Ty<'db>,
731 f16: Ty<'db>,
732 f32: Ty<'db>,
733 f64: Ty<'db>,
734 f128: Ty<'db>,
735 static_str_ref: Ty<'db>,
736 error: Ty<'db>,
737
738 re_static: Region<'db>,
739 re_error: Region<'db>,
740
741 empty_args: GenericArgs<'db>,
742 empty_tys: Tys<'db>,
710743}
711744
712impl<'db> InternedStandardTypesNextSolver<'db> {
745impl<'db> InternedStandardTypes<'db> {
713746 fn new(interner: DbInterner<'db>) -> Self {
747 let str = Ty::new(interner, rustc_type_ir::TyKind::Str);
748 let re_static = Region::new_static(interner);
714749 Self {
715 unit: crate::next_solver::Ty::new_unit(interner),
716 never: crate::next_solver::Ty::new(interner, crate::next_solver::TyKind::Never),
717 i32: crate::next_solver::Ty::new_int(interner, rustc_type_ir::IntTy::I32),
718 f64: crate::next_solver::Ty::new_float(interner, rustc_type_ir::FloatTy::F64),
750 unit: Ty::new_unit(interner),
751 never: Ty::new(interner, TyKind::Never),
752 char: Ty::new(interner, TyKind::Char),
753 bool: Ty::new(interner, TyKind::Bool),
754 i8: Ty::new_int(interner, rustc_type_ir::IntTy::I8),
755 i16: Ty::new_int(interner, rustc_type_ir::IntTy::I16),
756 i32: Ty::new_int(interner, rustc_type_ir::IntTy::I32),
757 i64: Ty::new_int(interner, rustc_type_ir::IntTy::I64),
758 i128: Ty::new_int(interner, rustc_type_ir::IntTy::I128),
759 isize: Ty::new_int(interner, rustc_type_ir::IntTy::Isize),
760 u8: Ty::new_uint(interner, rustc_type_ir::UintTy::U8),
761 u16: Ty::new_uint(interner, rustc_type_ir::UintTy::U16),
762 u32: Ty::new_uint(interner, rustc_type_ir::UintTy::U32),
763 u64: Ty::new_uint(interner, rustc_type_ir::UintTy::U64),
764 u128: Ty::new_uint(interner, rustc_type_ir::UintTy::U128),
765 usize: Ty::new_uint(interner, rustc_type_ir::UintTy::Usize),
766 f16: Ty::new_float(interner, rustc_type_ir::FloatTy::F16),
767 f32: Ty::new_float(interner, rustc_type_ir::FloatTy::F32),
768 f64: Ty::new_float(interner, rustc_type_ir::FloatTy::F64),
769 f128: Ty::new_float(interner, rustc_type_ir::FloatTy::F128),
770 static_str_ref: Ty::new_ref(interner, re_static, str, Mutability::Not),
771 error: Ty::new_error(interner, ErrorGuaranteed),
772
773 re_static,
774 re_error: Region::error(interner),
775
776 empty_args: GenericArgs::new_from_iter(interner, []),
777 empty_tys: Tys::new_from_iter(interner, []),
719778 }
720779 }
721780}
722781
723782/// The inference context contains all information needed during type inference.
724783#[derive(Clone, Debug)]
725pub(crate) struct InferenceContext<'db> {
784pub(crate) struct InferenceContext<'body, 'db> {
726785 pub(crate) db: &'db dyn HirDatabase,
727786 pub(crate) owner: DefWithBodyId,
728 pub(crate) body: &'db Body,
787 pub(crate) body: &'body Body,
729788 /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext
730789 /// and resolve the path via its methods. This will ensure proper error reporting.
731790 pub(crate) resolver: Resolver<'db>,
......@@ -735,32 +794,32 @@ pub(crate) struct InferenceContext<'db> {
735794 table: unify::InferenceTable<'db>,
736795 /// The traits in scope, disregarding block modules. This is used for caching purposes.
737796 traits_in_scope: FxHashSet<TraitId>,
738 pub(crate) result: InferenceResult,
797 pub(crate) result: InferenceResult<'db>,
739798 tuple_field_accesses_rev:
740 IndexSet<Substitution, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,
799 IndexSet<Tys<'db>, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,
741800 /// The return type of the function being inferred, the closure or async block if we're
742801 /// currently within one.
743802 ///
744803 /// We might consider using a nested inference context for checking
745804 /// closures so we can swap all shared things out at once.
746 return_ty: Ty,
805 return_ty: Ty<'db>,
747806 /// If `Some`, this stores coercion information for returned
748807 /// expressions. If `None`, this is in a context where return is
749808 /// inappropriate, such as a const expression.
750809 return_coercion: Option<DynamicCoerceMany<'db>>,
751810 /// The resume type and the yield type, respectively, of the coroutine being inferred.
752 resume_yield_tys: Option<(Ty, Ty)>,
811 resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>,
753812 diverges: Diverges,
754813 breakables: Vec<BreakableContext<'db>>,
755 types: InternedStandardTypesNextSolver<'db>,
814 types: InternedStandardTypes<'db>,
756815
757816 /// Whether we are inside the pattern of a destructuring assignment.
758817 inside_assignment: bool,
759818
760 deferred_cast_checks: Vec<CastCheck>,
819 deferred_cast_checks: Vec<CastCheck<'db>>,
761820
762821 // fields related to closure capture
763 current_captures: Vec<CapturedItemWithoutTy>,
822 current_captures: Vec<CapturedItemWithoutTy<'db>>,
764823 /// A stack that has an entry for each projection in the current capture.
765824 ///
766825 /// For example, in `a.b.c`, we capture the spans of `a`, `a.b`, and `a.b.c`.
......@@ -771,9 +830,9 @@ pub(crate) struct InferenceContext<'db> {
771830 /// Stores the list of closure ids that need to be analyzed before this closure. See the
772831 /// comment on `InferenceContext::sort_closures`
773832 closure_dependencies: FxHashMap<InternedClosureId, Vec<InternedClosureId>>,
774 deferred_closures: FxHashMap<InternedClosureId, Vec<(Ty, Ty, Vec<Ty>, ExprId)>>,
833 deferred_closures: FxHashMap<InternedClosureId, Vec<(Ty<'db>, Ty<'db>, Vec<Ty<'db>>, ExprId)>>,
775834
776 diagnostics: Diagnostics,
835 diagnostics: Diagnostics<'db>,
777836}
778837
779838#[derive(Clone, Debug)]
......@@ -820,28 +879,29 @@ fn find_continuable<'a, 'db>(
820879 }
821880}
822881
823enum ImplTraitReplacingMode {
824 ReturnPosition(FxHashSet<Ty>),
882enum ImplTraitReplacingMode<'db> {
883 ReturnPosition(FxHashSet<Ty<'db>>),
825884 TypeAlias,
826885}
827886
828impl<'db> InferenceContext<'db> {
887impl<'body, 'db> InferenceContext<'body, 'db> {
829888 fn new(
830889 db: &'db dyn HirDatabase,
831890 owner: DefWithBodyId,
832 body: &'db Body,
891 body: &'body Body,
833892 resolver: Resolver<'db>,
834893 ) -> Self {
835894 let trait_env = db.trait_environment_for_body(owner);
836895 let table = unify::InferenceTable::new(db, trait_env);
896 let types = InternedStandardTypes::new(table.interner());
837897 InferenceContext {
838 types: InternedStandardTypesNextSolver::new(table.interner),
898 result: InferenceResult::new(types.error),
899 return_ty: types.error, // set in collect_* calls
900 types,
839901 target_features: OnceCell::new(),
840902 generics: OnceCell::new(),
841 result: InferenceResult::default(),
842903 table,
843904 tuple_field_accesses_rev: Default::default(),
844 return_ty: TyKind::Error.intern(Interner), // set in collect_* calls
845905 resume_yield_tys: None,
846906 return_coercion: None,
847907 db,
......@@ -904,7 +964,7 @@ impl<'db> InferenceContext<'db> {
904964
905965 /// Clones `self` and calls `resolve_all()` on it.
906966 // FIXME: Remove this.
907 pub(crate) fn fixme_resolve_all_clone(&self) -> InferenceResult {
967 pub(crate) fn fixme_resolve_all_clone(&self) -> InferenceResult<'db> {
908968 let mut ctx = self.clone();
909969
910970 ctx.type_inference_fallback();
......@@ -928,7 +988,7 @@ impl<'db> InferenceContext<'db> {
928988 // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you
929989 // used this function for another workaround, mention it here. If you really need this function and believe that
930990 // there is no problem in it being `pub(crate)`, remove this comment.
931 pub(crate) fn resolve_all(self) -> InferenceResult {
991 pub(crate) fn resolve_all(self) -> InferenceResult<'db> {
932992 let InferenceContext {
933993 mut table, mut result, tuple_field_accesses_rev, diagnostics, ..
934994 } = self;
......@@ -946,7 +1006,7 @@ impl<'db> InferenceContext<'db> {
9461006 type_of_rpit,
9471007 type_mismatches,
9481008 has_errors,
949 standard_types: _,
1009 error_ty: _,
9501010 pat_adjustments,
9511011 binding_modes: _,
9521012 expr_adjustments,
......@@ -961,39 +1021,32 @@ impl<'db> InferenceContext<'db> {
9611021 } = &mut result;
9621022
9631023 for ty in type_of_expr.values_mut() {
964 *ty = table.resolve_completely(ty.clone());
965 *has_errors = *has_errors || ty.contains_unknown();
1024 *ty = table.resolve_completely(*ty);
1025 *has_errors = *has_errors || ty.references_non_lt_error();
9661026 }
9671027 type_of_expr.shrink_to_fit();
9681028 for ty in type_of_pat.values_mut() {
969 *ty = table.resolve_completely(ty.clone());
970 *has_errors = *has_errors || ty.contains_unknown();
1029 *ty = table.resolve_completely(*ty);
1030 *has_errors = *has_errors || ty.references_non_lt_error();
9711031 }
9721032 type_of_pat.shrink_to_fit();
9731033 for ty in type_of_binding.values_mut() {
974 *ty = table.resolve_completely(ty.clone());
975 *has_errors = *has_errors || ty.contains_unknown();
1034 *ty = table.resolve_completely(*ty);
1035 *has_errors = *has_errors || ty.references_non_lt_error();
9761036 }
9771037 type_of_binding.shrink_to_fit();
9781038 for ty in type_of_rpit.values_mut() {
979 *ty = table.resolve_completely(ty.clone());
980 *has_errors = *has_errors || ty.contains_unknown();
1039 *ty = table.resolve_completely(*ty);
1040 *has_errors = *has_errors || ty.references_non_lt_error();
9811041 }
9821042 type_of_rpit.shrink_to_fit();
9831043
9841044 *has_errors |= !type_mismatches.is_empty();
9851045
986 type_mismatches.retain(|_, mismatch| {
987 mismatch.expected = table.resolve_completely(mismatch.expected.clone());
988 mismatch.actual = table.resolve_completely(mismatch.actual.clone());
989 chalk_ir::zip::Zip::zip_with(
990 &mut UnknownMismatch(self.db),
991 Variance::Invariant,
992 &mismatch.expected,
993 &mismatch.actual,
994 )
995 .is_ok()
996 });
1046 for mismatch in (*type_mismatches).values_mut() {
1047 mismatch.expected = table.resolve_completely(mismatch.expected);
1048 mismatch.actual = table.resolve_completely(mismatch.actual);
1049 }
9971050 type_mismatches.shrink_to_fit();
9981051 diagnostics.retain_mut(|diagnostic| {
9991052 use InferenceDiagnostic::*;
......@@ -1001,23 +1054,23 @@ impl<'db> InferenceContext<'db> {
10011054 ExpectedFunction { found: ty, .. }
10021055 | UnresolvedField { receiver: ty, .. }
10031056 | UnresolvedMethodCall { receiver: ty, .. } => {
1004 *ty = table.resolve_completely(ty.clone());
1057 *ty = table.resolve_completely(*ty);
10051058 // FIXME: Remove this when we are on par with rustc in terms of inference
1006 if ty.contains_unknown() {
1059 if ty.references_non_lt_error() {
10071060 return false;
10081061 }
10091062
10101063 if let UnresolvedMethodCall { field_with_same_name, .. } = diagnostic
10111064 && let Some(ty) = field_with_same_name
10121065 {
1013 *ty = table.resolve_completely(ty.clone());
1014 if ty.contains_unknown() {
1066 *ty = table.resolve_completely(*ty);
1067 if ty.references_non_lt_error() {
10151068 *field_with_same_name = None;
10161069 }
10171070 }
10181071 }
10191072 TypedHole { expected: ty, .. } => {
1020 *ty = table.resolve_completely(ty.clone());
1073 *ty = table.resolve_completely(*ty);
10211074 }
10221075 _ => (),
10231076 }
......@@ -1025,41 +1078,31 @@ impl<'db> InferenceContext<'db> {
10251078 });
10261079 diagnostics.shrink_to_fit();
10271080 for (_, subst) in method_resolutions.values_mut() {
1028 *subst =
1029 table.resolve_completely::<_, crate::next_solver::GenericArgs<'db>>(subst.clone());
1030 *has_errors =
1031 *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
1081 *subst = table.resolve_completely(*subst);
1082 *has_errors = *has_errors || subst.types().any(|ty| ty.references_non_lt_error());
10321083 }
10331084 method_resolutions.shrink_to_fit();
10341085 for (_, subst) in assoc_resolutions.values_mut() {
1035 *subst =
1036 table.resolve_completely::<_, crate::next_solver::GenericArgs<'db>>(subst.clone());
1037 *has_errors =
1038 *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
1086 *subst = table.resolve_completely(*subst);
1087 *has_errors = *has_errors || subst.types().any(|ty| ty.references_non_lt_error());
10391088 }
10401089 assoc_resolutions.shrink_to_fit();
10411090 for adjustment in expr_adjustments.values_mut().flatten() {
1042 adjustment.target = table.resolve_completely(adjustment.target.clone());
1043 *has_errors = *has_errors || adjustment.target.contains_unknown();
1091 adjustment.target = table.resolve_completely(adjustment.target);
1092 *has_errors = *has_errors || adjustment.target.references_non_lt_error();
10441093 }
10451094 expr_adjustments.shrink_to_fit();
10461095 for adjustment in pat_adjustments.values_mut().flatten() {
1047 *adjustment = table.resolve_completely(adjustment.clone());
1048 *has_errors = *has_errors || adjustment.contains_unknown();
1096 *adjustment = table.resolve_completely(*adjustment);
1097 *has_errors = *has_errors || adjustment.references_non_lt_error();
10491098 }
10501099 pat_adjustments.shrink_to_fit();
10511100 result.tuple_field_access_types = tuple_field_accesses_rev
10521101 .into_iter()
10531102 .enumerate()
1054 .map(|(idx, subst)| {
1055 (
1056 TupleId(idx as u32),
1057 table.resolve_completely::<_, crate::next_solver::GenericArgs<'db>>(subst),
1058 )
1059 })
1103 .map(|(idx, subst)| (TupleId(idx as u32), table.resolve_completely(subst)))
10601104 .inspect(|(_, subst)| {
1061 *has_errors =
1062 *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
1105 *has_errors = *has_errors || subst.iter().any(|ty| ty.references_non_lt_error());
10631106 })
10641107 .collect();
10651108 result.tuple_field_access_types.shrink_to_fit();
......@@ -1074,11 +1117,11 @@ impl<'db> InferenceContext<'db> {
10741117 data.type_ref,
10751118 &data.store,
10761119 InferenceTyDiagnosticSource::Signature,
1077 LifetimeElisionKind::for_const(id.loc(self.db).container),
1120 LifetimeElisionKind::for_const(self.interner(), id.loc(self.db).container),
10781121 );
10791122
10801123 // Constants might be defining usage sites of TAITs.
1081 self.make_tait_coercion_table(iter::once(&return_ty));
1124 self.make_tait_coercion_table(iter::once(return_ty));
10821125
10831126 self.return_ty = return_ty;
10841127 }
......@@ -1088,11 +1131,11 @@ impl<'db> InferenceContext<'db> {
10881131 data.type_ref,
10891132 &data.store,
10901133 InferenceTyDiagnosticSource::Signature,
1091 LifetimeElisionKind::Elided(static_lifetime()),
1134 LifetimeElisionKind::Elided(self.types.re_static),
10921135 );
10931136
10941137 // Statics might be defining usage sites of TAITs.
1095 self.make_tait_coercion_table(iter::once(&return_ty));
1138 self.make_tait_coercion_table(iter::once(return_ty));
10961139
10971140 self.return_ty = return_ty;
10981141 }
......@@ -1103,25 +1146,28 @@ impl<'db> InferenceContext<'db> {
11031146 &data.store,
11041147 InferenceTyDiagnosticSource::Signature,
11051148 LifetimeElisionKind::for_fn_params(&data),
1106 |ctx| {
1107 ctx.type_param_mode(ParamLoweringMode::Placeholder);
1108 data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>()
1109 },
1149 |ctx| data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(),
11101150 );
11111151
11121152 // Check if function contains a va_list, if it does then we append it to the parameter types
11131153 // that are collected from the function data
11141154 if data.is_varargs() {
11151155 let va_list_ty = match self.resolve_va_list() {
1116 Some(va_list) => TyBuilder::adt(self.db, va_list)
1117 .fill_with_defaults(self.db, || self.table.new_type_var())
1118 .build(),
1156 Some(va_list) => Ty::new_adt(
1157 self.interner(),
1158 va_list,
1159 GenericArgs::for_item_with_defaults(
1160 self.interner(),
1161 va_list.into(),
1162 |_, _, id, _| self.table.next_var_for_param(id),
1163 ),
1164 ),
11191165 None => self.err_ty(),
11201166 };
11211167
11221168 param_tys.push(va_list_ty);
11231169 }
1124 let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
1170 let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.next_ty_var()));
11251171 if let Some(self_param) = self.body.self_param
11261172 && let Some(ty) = param_tys.next()
11271173 {
......@@ -1132,12 +1178,8 @@ impl<'db> InferenceContext<'db> {
11321178 for (ty, pat) in param_tys.zip(&*self.body.params) {
11331179 let ty = self.process_user_written_ty(ty);
11341180
1135 self.infer_top_pat(*pat, &ty, None);
1136 if ty
1137 .data(Interner)
1138 .flags
1139 .intersects(TypeFlags::HAS_TY_OPAQUE.union(TypeFlags::HAS_TY_INFER))
1140 {
1181 self.infer_top_pat(*pat, ty, None);
1182 if ty.flags().intersects(TypeFlags::HAS_TY_OPAQUE.union(TypeFlags::HAS_TY_INFER)) {
11411183 tait_candidates.insert(ty);
11421184 }
11431185 }
......@@ -1146,31 +1188,24 @@ impl<'db> InferenceContext<'db> {
11461188 let return_ty = self.with_ty_lowering(
11471189 &data.store,
11481190 InferenceTyDiagnosticSource::Signature,
1149 LifetimeElisionKind::for_fn_ret(),
1191 LifetimeElisionKind::for_fn_ret(self.interner()),
11501192 |ctx| {
1151 ctx.type_param_mode(ParamLoweringMode::Placeholder)
1152 .impl_trait_mode(ImplTraitLoweringMode::Opaque);
1193 ctx.impl_trait_mode(ImplTraitLoweringMode::Opaque);
11531194 ctx.lower_ty(return_ty)
11541195 },
11551196 );
11561197 let return_ty = self.insert_type_vars(return_ty);
1157 if let Some(rpits) = self.db.return_type_impl_traits(func) {
1158 // RPIT opaque types use substitution of their parent function.
1159 let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
1198 if let Some(rpits) = self.db.return_type_impl_traits_ns(func) {
11601199 let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default());
1161 let result = self.insert_inference_vars_for_impl_trait(
1162 return_ty,
1163 fn_placeholders,
1164 &mut mode,
1165 );
1200 let result = self.insert_inference_vars_for_impl_trait(return_ty, &mut mode);
11661201 if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
11671202 tait_candidates.extend(taits);
11681203 }
1169 let rpits = rpits.skip_binders();
1204 let rpits = (*rpits).as_ref().skip_binder();
11701205 for (id, _) in rpits.impl_traits.iter() {
11711206 if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) {
11721207 never!("Missed RPIT in `insert_inference_vars_for_rpit`");
1173 e.insert(TyKind::Error.intern(Interner));
1208 e.insert(self.types.error);
11741209 }
11751210 }
11761211 result
......@@ -1178,111 +1213,97 @@ impl<'db> InferenceContext<'db> {
11781213 return_ty
11791214 }
11801215 }
1181 None => self.result.standard_types.unit.clone(),
1216 None => self.types.unit,
11821217 };
11831218
11841219 self.return_ty = self.process_user_written_ty(return_ty);
1185 self.return_coercion =
1186 Some(CoerceMany::new(self.return_ty.to_nextsolver(self.table.interner)));
1220 self.return_coercion = Some(CoerceMany::new(self.return_ty));
11871221
11881222 // Functions might be defining usage sites of TAITs.
11891223 // To define an TAITs, that TAIT must appear in the function's signatures.
11901224 // So, it suffices to check for params and return types.
1191 fold_tys(
1192 self.return_ty.clone(),
1193 |ty, _| {
1194 match ty.kind(Interner) {
1195 TyKind::OpaqueType(..)
1196 | TyKind::Alias(AliasTy::Opaque(..))
1197 | TyKind::InferenceVar(..) => {
1198 tait_candidates.insert(self.return_ty.clone());
1199 }
1200 _ => {}
1225 fold_tys(self.interner(), self.return_ty, |ty| {
1226 match ty.kind() {
1227 TyKind::Alias(AliasTyKind::Opaque, _) | TyKind::Infer(..) => {
1228 tait_candidates.insert(self.return_ty);
12011229 }
1202 ty
1203 },
1204 DebruijnIndex::INNERMOST,
1205 );
1230 _ => {}
1231 }
1232 ty
1233 });
1234
1235 self.make_tait_coercion_table(tait_candidates.iter().copied());
1236 }
12061237
1207 self.make_tait_coercion_table(tait_candidates.iter());
1238 #[inline]
1239 pub(crate) fn interner(&self) -> DbInterner<'db> {
1240 self.table.interner()
12081241 }
12091242
12101243 fn insert_inference_vars_for_impl_trait<T>(
12111244 &mut self,
12121245 t: T,
1213 placeholders: Substitution,
1214 mode: &mut ImplTraitReplacingMode,
1246 mode: &mut ImplTraitReplacingMode<'db>,
12151247 ) -> T
12161248 where
1217 T: crate::HasInterner<Interner = Interner> + crate::TypeFoldable<Interner>,
1249 T: TypeFoldable<DbInterner<'db>>,
12181250 {
1219 fold_tys(
1220 t,
1221 |ty, _| {
1222 let ty = self.table.structurally_resolve_type(&ty);
1223 let opaque_ty_id = match ty.kind(Interner) {
1224 TyKind::OpaqueType(opaque_ty_id, _)
1225 | TyKind::Alias(AliasTy::Opaque(crate::OpaqueTy { opaque_ty_id, .. })) => {
1226 *opaque_ty_id
1227 }
1228 _ => return ty,
1229 };
1230 let (impl_traits, idx) =
1231 match self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) {
1232 // We don't replace opaque types from other kind with inference vars
1233 // because `insert_inference_vars_for_impl_traits` for each kinds
1234 // and unreplaced opaque types of other kind are resolved while
1235 // inferencing because of `tait_coercion_table`.
1236 // Moreover, calling `insert_inference_vars_for_impl_traits` with same
1237 // `placeholders` for other kind may cause trouble because
1238 // the substs for the bounds of each impl traits do not match
1239 ImplTraitId::ReturnTypeImplTrait(def, idx) => {
1240 if matches!(mode, ImplTraitReplacingMode::TypeAlias) {
1241 // RPITs don't have `tait_coercion_table`, so use inserted inference
1242 // vars for them.
1243 if let Some(ty) = self.result.type_of_rpit.get(idx) {
1244 return ty.clone();
1245 }
1246 return ty;
1247 }
1248 (self.db.return_type_impl_traits(def), idx)
1249 }
1250 ImplTraitId::TypeAliasImplTrait(def, idx) => {
1251 if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
1252 // Gather TAITs while replacing RPITs because TAITs inside RPITs
1253 // may not visited while replacing TAITs
1254 taits.insert(ty.clone());
1255 return ty;
1256 }
1257 (self.db.type_alias_impl_traits(def), idx)
1251 fold_tys(self.interner(), t, |ty| {
1252 let ty = self.table.try_structurally_resolve_type(ty);
1253 let opaque_ty_id = match ty.kind() {
1254 TyKind::Alias(AliasTyKind::Opaque, alias_ty) => alias_ty.def_id.expect_opaque_ty(),
1255 _ => return ty,
1256 };
1257 let (impl_traits, idx) = match self.db.lookup_intern_impl_trait_id(opaque_ty_id) {
1258 // We don't replace opaque types from other kind with inference vars
1259 // because `insert_inference_vars_for_impl_traits` for each kinds
1260 // and unreplaced opaque types of other kind are resolved while
1261 // inferencing because of `tait_coercion_table`.
1262 ImplTraitId::ReturnTypeImplTrait(def, idx) => {
1263 if matches!(mode, ImplTraitReplacingMode::TypeAlias) {
1264 // RPITs don't have `tait_coercion_table`, so use inserted inference
1265 // vars for them.
1266 if let Some(ty) =
1267 self.result.type_of_rpit.get(idx.to_nextsolver(self.interner()))
1268 {
1269 return *ty;
12581270 }
1259 _ => unreachable!(),
1260 };
1261 let Some(impl_traits) = impl_traits else {
1262 return ty;
1263 };
1264 let bounds = (*impl_traits)
1265 .map_ref(|its| its.impl_traits[idx].bounds.map_ref(|it| it.iter()));
1266 let var = self.table.new_type_var();
1267 let var_subst = Substitution::from1(Interner, var.clone());
1268 for bound in bounds {
1269 let predicate = bound.map(|it| it.cloned());
1270 let predicate = predicate.substitute(Interner, &placeholders);
1271 let (var_predicate, binders) =
1272 predicate.substitute(Interner, &var_subst).into_value_and_skipped_binders();
1273 always!(binders.is_empty(Interner)); // quantified where clauses not yet handled
1274 let var_predicate = self.insert_inference_vars_for_impl_trait(
1275 var_predicate,
1276 placeholders.clone(),
1277 mode,
1278 );
1279 self.push_obligation(var_predicate.cast(Interner));
1271 return ty;
1272 }
1273 (self.db.return_type_impl_traits_ns(def), idx)
12801274 }
1281 self.result.type_of_rpit.insert(idx, var.clone());
1282 var
1283 },
1284 DebruijnIndex::INNERMOST,
1285 )
1275 ImplTraitId::TypeAliasImplTrait(def, idx) => {
1276 if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
1277 // Gather TAITs while replacing RPITs because TAITs inside RPITs
1278 // may not visited while replacing TAITs
1279 taits.insert(ty);
1280 return ty;
1281 }
1282 (self.db.type_alias_impl_traits_ns(def), idx)
1283 }
1284 _ => unreachable!(),
1285 };
1286 let Some(impl_traits) = impl_traits else {
1287 return ty;
1288 };
1289 let bounds = (*impl_traits).as_ref().map_bound(|its| {
1290 its.impl_traits[idx.to_nextsolver(self.interner())].predicates.as_slice()
1291 });
1292 let var = match self.result.type_of_rpit.entry(idx.to_nextsolver(self.interner())) {
1293 Entry::Occupied(entry) => return *entry.get(),
1294 Entry::Vacant(entry) => *entry.insert(self.table.next_ty_var()),
1295 };
1296 for clause in bounds.iter_identity_copied() {
1297 let clause = self.insert_inference_vars_for_impl_trait(clause, mode);
1298 self.table.register_predicate(Obligation::new(
1299 self.interner(),
1300 ObligationCause::new(),
1301 self.table.trait_env.env,
1302 clause,
1303 ));
1304 }
1305 var
1306 })
12861307 }
12871308
12881309 /// The coercion of a non-inference var into an opaque type should fail,
......@@ -1296,51 +1317,38 @@ impl<'db> InferenceContext<'db> {
12961317 /// - We are pushing `impl Trait` bounds into it
12971318 ///
12981319 /// This function inserts a map that maps the opaque type to that proxy inference var.
1299 fn make_tait_coercion_table<'b>(&mut self, tait_candidates: impl Iterator<Item = &'b Ty>) {
1300 struct TypeAliasImplTraitCollector<'a, 'b> {
1301 db: &'b dyn HirDatabase,
1302 table: &'b mut InferenceTable<'a>,
1303 assocs: FxHashMap<OpaqueTyId, (ImplId, Ty)>,
1304 non_assocs: FxHashMap<OpaqueTyId, Ty>,
1320 fn make_tait_coercion_table(&mut self, tait_candidates: impl Iterator<Item = Ty<'db>>) {
1321 struct TypeAliasImplTraitCollector<'a, 'db> {
1322 db: &'a dyn HirDatabase,
1323 table: &'a mut InferenceTable<'db>,
1324 assocs: FxHashMap<InternedOpaqueTyId, (ImplId, Ty<'db>)>,
1325 non_assocs: FxHashMap<InternedOpaqueTyId, Ty<'db>>,
13051326 }
13061327
1307 impl TypeVisitor<Interner> for TypeAliasImplTraitCollector<'_, '_> {
1308 type BreakTy = ();
1309
1310 fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
1311 self
1312 }
1313
1314 fn interner(&self) -> Interner {
1315 Interner
1316 }
1328 impl<'db> TypeVisitor<DbInterner<'db>> for TypeAliasImplTraitCollector<'_, 'db> {
1329 type Result = ();
13171330
1318 fn visit_ty(
1319 &mut self,
1320 ty: &chalk_ir::Ty<Interner>,
1321 outer_binder: DebruijnIndex,
1322 ) -> std::ops::ControlFlow<Self::BreakTy> {
1323 let ty = self.table.structurally_resolve_type(ty);
1331 fn visit_ty(&mut self, ty: Ty<'db>) {
1332 let ty = self.table.try_structurally_resolve_type(ty);
13241333
1325 if let TyKind::OpaqueType(id, _)
1326 | TyKind::Alias(AliasTy::Opaque(crate::OpaqueTy { opaque_ty_id: id, .. })) =
1327 ty.kind(Interner)
1334 if let TyKind::Alias(AliasTyKind::Opaque, alias_ty) = ty.kind()
1335 && let id = alias_ty.def_id.expect_opaque_ty()
13281336 && let ImplTraitId::TypeAliasImplTrait(alias_id, _) =
1329 self.db.lookup_intern_impl_trait_id((*id).into())
1337 self.db.lookup_intern_impl_trait_id(id)
13301338 {
13311339 let loc = self.db.lookup_intern_type_alias(alias_id);
13321340 match loc.container {
13331341 ItemContainerId::ImplId(impl_id) => {
1334 self.assocs.insert(*id, (impl_id, ty.clone()));
1342 self.assocs.insert(id, (impl_id, ty));
13351343 }
13361344 ItemContainerId::ModuleId(..) | ItemContainerId::ExternBlockId(..) => {
1337 self.non_assocs.insert(*id, ty.clone());
1345 self.non_assocs.insert(id, ty);
13381346 }
13391347 _ => {}
13401348 }
13411349 }
13421350
1343 ty.super_visit_with(self, outer_binder)
1351 ty.super_visit_with(self)
13441352 }
13451353 }
13461354
......@@ -1351,7 +1359,7 @@ impl<'db> InferenceContext<'db> {
13511359 non_assocs: FxHashMap::default(),
13521360 };
13531361 for ty in tait_candidates {
1354 _ = ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST);
1362 ty.visit_with(&mut collector);
13551363 }
13561364
13571365 // Non-assoc TAITs can be define-used everywhere as long as they are
......@@ -1405,13 +1413,10 @@ impl<'db> InferenceContext<'db> {
14051413 let tait_coercion_table: FxHashMap<_, _> = taits
14061414 .into_iter()
14071415 .filter_map(|(id, ty)| {
1408 if let ImplTraitId::TypeAliasImplTrait(alias_id, _) =
1409 self.db.lookup_intern_impl_trait_id(id.into())
1416 if let ImplTraitId::TypeAliasImplTrait(..) = self.db.lookup_intern_impl_trait_id(id)
14101417 {
1411 let subst = TyBuilder::placeholder_subst(self.db, alias_id);
14121418 let ty = self.insert_inference_vars_for_impl_trait(
14131419 ty,
1414 subst,
14151420 &mut ImplTraitReplacingMode::TypeAlias,
14161421 );
14171422 Some((id, ty))
......@@ -1432,18 +1437,18 @@ impl<'db> InferenceContext<'db> {
14321437 None => {
14331438 _ = self.infer_expr_coerce(
14341439 self.body.body_expr,
1435 &Expectation::has_type(self.return_ty.clone()),
1440 &Expectation::has_type(self.return_ty),
14361441 ExprIsRead::Yes,
14371442 )
14381443 }
14391444 }
14401445 }
14411446
1442 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
1447 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) {
14431448 self.result.type_of_expr.insert(expr, ty);
14441449 }
14451450
1446 fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {
1451 fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment<'db>]>) {
14471452 if adjustments.is_empty() {
14481453 return;
14491454 }
......@@ -1456,7 +1461,7 @@ impl<'db> InferenceContext<'db> {
14561461 ) => {
14571462 // NeverToAny coercion can target any type, so instead of adding a new
14581463 // adjustment on top we can change the target.
1459 *target = new_target.clone();
1464 *target = *new_target;
14601465 }
14611466 _ => {
14621467 *entry.get_mut() = adjustments;
......@@ -1469,14 +1474,14 @@ impl<'db> InferenceContext<'db> {
14691474 }
14701475 }
14711476
1472 fn write_pat_adj(&mut self, pat: PatId, adjustments: Box<[Ty]>) {
1477 fn write_pat_adj(&mut self, pat: PatId, adjustments: Box<[Ty<'db>]>) {
14731478 if adjustments.is_empty() {
14741479 return;
14751480 }
14761481 self.result.pat_adjustments.entry(pat).or_default().extend(adjustments);
14771482 }
14781483
1479 fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: Substitution) {
1484 fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: GenericArgs<'db>) {
14801485 self.result.method_resolutions.insert(expr, (func, subst));
14811486 }
14821487
......@@ -1484,19 +1489,24 @@ impl<'db> InferenceContext<'db> {
14841489 self.result.variant_resolutions.insert(id, variant);
14851490 }
14861491
1487 fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId, subs: Substitution) {
1492 fn write_assoc_resolution(
1493 &mut self,
1494 id: ExprOrPatId,
1495 item: AssocItemId,
1496 subs: GenericArgs<'db>,
1497 ) {
14881498 self.result.assoc_resolutions.insert(id, (item, subs));
14891499 }
14901500
1491 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
1501 fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) {
14921502 self.result.type_of_pat.insert(pat, ty);
14931503 }
14941504
1495 fn write_binding_ty(&mut self, id: BindingId, ty: Ty) {
1505 fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) {
14961506 self.result.type_of_binding.insert(id, ty);
14971507 }
14981508
1499 fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {
1509 fn push_diagnostic(&self, diagnostic: InferenceDiagnostic<'db>) {
15001510 self.diagnostics.push(diagnostic);
15011511 }
15021512
......@@ -1504,8 +1514,8 @@ impl<'db> InferenceContext<'db> {
15041514 &mut self,
15051515 store: &ExpressionStore,
15061516 types_source: InferenceTyDiagnosticSource,
1507 lifetime_elision: LifetimeElisionKind,
1508 f: impl FnOnce(&mut TyLoweringContext<'_>) -> R,
1517 lifetime_elision: LifetimeElisionKind<'db>,
1518 f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,
15091519 ) -> R {
15101520 let mut ctx = TyLoweringContext::new(
15111521 self.db,
......@@ -1519,7 +1529,10 @@ impl<'db> InferenceContext<'db> {
15191529 f(&mut ctx)
15201530 }
15211531
1522 fn with_body_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'_>) -> R) -> R {
1532 fn with_body_ty_lowering<R>(
1533 &mut self,
1534 f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,
1535 ) -> R {
15231536 self.with_ty_lowering(
15241537 self.body,
15251538 InferenceTyDiagnosticSource::Body,
......@@ -1533,14 +1546,14 @@ impl<'db> InferenceContext<'db> {
15331546 type_ref: TypeRefId,
15341547 store: &ExpressionStore,
15351548 type_source: InferenceTyDiagnosticSource,
1536 lifetime_elision: LifetimeElisionKind,
1537 ) -> Ty {
1549 lifetime_elision: LifetimeElisionKind<'db>,
1550 ) -> Ty<'db> {
15381551 let ty = self
15391552 .with_ty_lowering(store, type_source, lifetime_elision, |ctx| ctx.lower_ty(type_ref));
15401553 self.process_user_written_ty(ty)
15411554 }
15421555
1543 fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty {
1556 fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
15441557 self.make_ty(
15451558 type_ref,
15461559 self.body,
......@@ -1549,37 +1562,31 @@ impl<'db> InferenceContext<'db> {
15491562 )
15501563 }
15511564
1552 fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty) -> Const {
1565 fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty<'db>) -> Const<'db> {
15531566 let const_ = self.with_ty_lowering(
15541567 self.body,
15551568 InferenceTyDiagnosticSource::Body,
15561569 LifetimeElisionKind::Infer,
1557 |ctx| {
1558 ctx.type_param_mode = ParamLoweringMode::Placeholder;
1559 ctx.lower_const(&const_ref, ty)
1560 },
1570 |ctx| ctx.lower_const(const_ref, ty),
15611571 );
15621572 self.insert_type_vars(const_)
15631573 }
15641574
1565 fn make_path_as_body_const(&mut self, path: &Path, ty: Ty) -> Const {
1575 fn make_path_as_body_const(&mut self, path: &Path, ty: Ty<'db>) -> Const<'db> {
15661576 let const_ = self.with_ty_lowering(
15671577 self.body,
15681578 InferenceTyDiagnosticSource::Body,
15691579 LifetimeElisionKind::Infer,
1570 |ctx| {
1571 ctx.type_param_mode = ParamLoweringMode::Placeholder;
1572 ctx.lower_path_as_const(path, ty)
1573 },
1580 |ctx| ctx.lower_path_as_const(path, ty),
15741581 );
15751582 self.insert_type_vars(const_)
15761583 }
15771584
1578 fn err_ty(&self) -> Ty {
1579 self.result.standard_types.unknown.clone()
1585 fn err_ty(&self) -> Ty<'db> {
1586 self.types.error
15801587 }
15811588
1582 fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Lifetime {
1589 fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Region<'db> {
15831590 let lt = self.with_ty_lowering(
15841591 self.body,
15851592 InferenceTyDiagnosticSource::Body,
......@@ -1590,44 +1597,25 @@ impl<'db> InferenceContext<'db> {
15901597 }
15911598
15921599 /// Replaces `Ty::Error` by a new type var, so we can maybe still infer it.
1593 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
1600 fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {
15941601 self.table.insert_type_vars_shallow(ty)
15951602 }
15961603
15971604 fn insert_type_vars<T>(&mut self, ty: T) -> T
15981605 where
1599 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
1606 T: TypeFoldable<DbInterner<'db>>,
16001607 {
16011608 self.table.insert_type_vars(ty)
16021609 }
16031610
1604 fn push_obligation(&mut self, o: DomainGoal) {
1605 let goal: crate::Goal = o.cast(Interner);
1606 self.table.register_obligation(goal.to_nextsolver(self.table.interner));
1607 }
1608
1609 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
1610 let ty1 = ty1
1611 .clone()
1612 .try_fold_with(
1613 &mut UnevaluatedConstEvaluatorFolder { db: self.db },
1614 DebruijnIndex::INNERMOST,
1615 )
1616 .unwrap();
1617 let ty2 = ty2
1618 .clone()
1619 .try_fold_with(
1620 &mut UnevaluatedConstEvaluatorFolder { db: self.db },
1621 DebruijnIndex::INNERMOST,
1622 )
1623 .unwrap();
1624 self.table.unify(&ty1, &ty2)
1611 fn unify(&mut self, ty1: Ty<'db>, ty2: Ty<'db>) -> bool {
1612 self.table.unify(ty1, ty2)
16251613 }
16261614
16271615 /// Attempts to returns the deeply last field of nested structures, but
16281616 /// does not apply any normalization in its search. Returns the same type
16291617 /// if input `ty` is not a structure at all.
1630 fn struct_tail_without_normalization(&mut self, ty: Ty) -> Ty {
1618 fn struct_tail_without_normalization(&mut self, ty: Ty<'db>) -> Ty<'db> {
16311619 self.struct_tail_with_normalize(ty, identity)
16321620 }
16331621
......@@ -1640,37 +1628,34 @@ impl<'db> InferenceContext<'db> {
16401628 /// function to indicate no normalization should take place.
16411629 fn struct_tail_with_normalize(
16421630 &mut self,
1643 mut ty: Ty,
1644 mut normalize: impl FnMut(Ty) -> Ty,
1645 ) -> Ty {
1631 mut ty: Ty<'db>,
1632 mut normalize: impl FnMut(Ty<'db>) -> Ty<'db>,
1633 ) -> Ty<'db> {
16461634 // FIXME: fetch the limit properly
16471635 let recursion_limit = 10;
16481636 for iteration in 0.. {
16491637 if iteration > recursion_limit {
16501638 return self.err_ty();
16511639 }
1652 match ty.kind(Interner) {
1653 TyKind::Adt(chalk_ir::AdtId(hir_def::AdtId::StructId(struct_id)), substs) => {
1654 match self.db.field_types((*struct_id).into()).values().next_back().cloned() {
1655 Some(field) => {
1656 ty = field.substitute(Interner, substs);
1640 match ty.kind() {
1641 TyKind::Adt(adt_def, substs) => match adt_def.def_id().0 {
1642 AdtId::StructId(struct_id) => {
1643 match self.db.field_types_ns(struct_id.into()).values().next_back().copied()
1644 {
1645 Some(field) => {
1646 ty = field.instantiate(self.interner(), substs);
1647 }
1648 None => break,
16571649 }
1658 None => break,
1659 }
1660 }
1661 TyKind::Adt(..) => break,
1662 TyKind::Tuple(_, substs) => {
1663 match substs
1664 .as_slice(Interner)
1665 .split_last()
1666 .and_then(|(last_ty, _)| last_ty.ty(Interner))
1667 {
1668 Some(last_ty) => ty = last_ty.clone(),
1669 None => break,
16701650 }
1671 }
1651 _ => break,
1652 },
1653 TyKind::Tuple(substs) => match substs.as_slice().split_last() {
1654 Some((last_ty, _)) => ty = *last_ty,
1655 None => break,
1656 },
16721657 TyKind::Alias(..) => {
1673 let normalized = normalize(ty.clone());
1658 let normalized = normalize(ty);
16741659 if ty == normalized {
16751660 return ty;
16761661 } else {
......@@ -1684,41 +1669,35 @@ impl<'db> InferenceContext<'db> {
16841669 }
16851670
16861671 /// Whenever you lower a user-written type, you should call this.
1687 fn process_user_written_ty<T, U>(&mut self, ty: T) -> T
1672 fn process_user_written_ty<T>(&mut self, ty: T) -> T
16881673 where
1689 T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + ChalkToNextSolver<'db, U>,
1690 U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
1674 T: TypeFoldable<DbInterner<'db>>,
16911675 {
16921676 self.table.process_user_written_ty(ty)
16931677 }
16941678
16951679 /// The difference of this method from `process_user_written_ty()` is that this method doesn't register a well-formed obligation,
16961680 /// while `process_user_written_ty()` should (but doesn't currently).
1697 fn process_remote_user_written_ty<T, U>(&mut self, ty: T) -> T
1681 fn process_remote_user_written_ty<T>(&mut self, ty: T) -> T
16981682 where
1699 T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + ChalkToNextSolver<'db, U>,
1700 U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
1683 T: TypeFoldable<DbInterner<'db>>,
17011684 {
17021685 self.table.process_remote_user_written_ty(ty)
17031686 }
17041687
1705 fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
1706 self.table.resolve_ty_shallow(ty)
1707 }
1708
1709 fn shallow_resolve(&self, ty: crate::next_solver::Ty<'db>) -> crate::next_solver::Ty<'db> {
1688 fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {
17101689 self.table.shallow_resolve(ty)
17111690 }
17121691
1713 fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
1692 fn resolve_associated_type(
1693 &mut self,
1694 inner_ty: Ty<'db>,
1695 assoc_ty: Option<TypeAliasId>,
1696 ) -> Ty<'db> {
17141697 self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[])
17151698 }
17161699
1717 fn demand_eqtype(
1718 &mut self,
1719 expected: crate::next_solver::Ty<'db>,
1720 actual: crate::next_solver::Ty<'db>,
1721 ) {
1700 fn demand_eqtype(&mut self, expected: Ty<'db>, actual: Ty<'db>) {
17221701 let result = self
17231702 .table
17241703 .infer_ctxt
......@@ -1732,34 +1711,24 @@ impl<'db> InferenceContext<'db> {
17321711
17331712 fn resolve_associated_type_with_params(
17341713 &mut self,
1735 inner_ty: Ty,
1714 inner_ty: Ty<'db>,
17361715 assoc_ty: Option<TypeAliasId>,
17371716 // FIXME(GATs): these are args for the trait ref, args for assoc type itself should be
17381717 // handled when we support them.
1739 params: &[GenericArg],
1740 ) -> Ty {
1718 params: &[GenericArg<'db>],
1719 ) -> Ty<'db> {
17411720 match assoc_ty {
17421721 Some(res_assoc_ty) => {
1743 let trait_ = match res_assoc_ty.lookup(self.db).container {
1744 hir_def::ItemContainerId::TraitId(trait_) => trait_,
1745 _ => panic!("resolve_associated_type called with non-associated type"),
1746 };
1747 let ty = self.table.new_type_var();
1748 let mut param_iter = params.iter().cloned();
1749 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
1750 .push(inner_ty)
1751 .fill(|_| param_iter.next().unwrap())
1752 .build();
1753 let alias_eq = AliasEq {
1754 alias: AliasTy::Projection(ProjectionTy {
1755 associated_ty_id: to_assoc_type_id(res_assoc_ty),
1756 substitution: trait_ref.substitution.clone(),
1757 }),
1758 ty: ty.clone(),
1759 };
1760 self.push_obligation(trait_ref.cast(Interner));
1761 self.push_obligation(alias_eq.cast(Interner));
1762 ty
1722 let alias = Ty::new_alias(
1723 self.interner(),
1724 AliasTyKind::Projection,
1725 AliasTy::new(
1726 self.interner(),
1727 res_assoc_ty.into(),
1728 iter::once(inner_ty.into()).chain(params.iter().copied()),
1729 ),
1730 );
1731 self.table.try_structurally_resolve_type(alias)
17631732 }
17641733 None => self.err_ty(),
17651734 }
......@@ -1770,7 +1739,7 @@ impl<'db> InferenceContext<'db> {
17701739 node: ExprOrPatId,
17711740 path: Option<&Path>,
17721741 value_ns: bool,
1773 ) -> (Ty, Option<VariantId>) {
1742 ) -> (Ty<'db>, Option<VariantId>) {
17741743 let path = match path {
17751744 Some(path) => path,
17761745 None => return (self.err_ty(), None),
......@@ -1793,28 +1762,19 @@ impl<'db> InferenceContext<'db> {
17931762 match res {
17941763 ResolveValueResult::ValueNs(value, _) => match value {
17951764 ValueNs::EnumVariantId(var) => {
1796 let substs = path_ctx.substs_from_path(var.into(), true, false);
1765 let args = path_ctx.substs_from_path(var.into(), true, false);
17971766 drop(ctx);
1798 let args: crate::next_solver::GenericArgs<'_> =
1799 substs.to_nextsolver(interner);
18001767 let ty = self
18011768 .db
18021769 .ty(var.lookup(self.db).parent.into())
1803 .instantiate(interner, args)
1804 .to_chalk(interner);
1770 .instantiate(interner, args);
18051771 let ty = self.insert_type_vars(ty);
18061772 return (ty, Some(var.into()));
18071773 }
18081774 ValueNs::StructId(strukt) => {
1809 let substs = path_ctx.substs_from_path(strukt.into(), true, false);
1775 let args = path_ctx.substs_from_path(strukt.into(), true, false);
18101776 drop(ctx);
1811 let args: crate::next_solver::GenericArgs<'_> =
1812 substs.to_nextsolver(interner);
1813 let ty = self
1814 .db
1815 .ty(strukt.into())
1816 .instantiate(interner, args)
1817 .to_chalk(interner);
1777 let ty = self.db.ty(strukt.into()).instantiate(interner, args);
18181778 let ty = self.insert_type_vars(ty);
18191779 return (ty, Some(strukt.into()));
18201780 }
......@@ -1834,39 +1794,28 @@ impl<'db> InferenceContext<'db> {
18341794 };
18351795 return match resolution {
18361796 TypeNs::AdtId(AdtId::StructId(strukt)) => {
1837 let substs = path_ctx.substs_from_path(strukt.into(), true, false);
1797 let args = path_ctx.substs_from_path(strukt.into(), true, false);
18381798 drop(ctx);
1839 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
1840 let ty = self.db.ty(strukt.into()).instantiate(interner, args).to_chalk(interner);
1799 let ty = self.db.ty(strukt.into()).instantiate(interner, args);
18411800 let ty = self.insert_type_vars(ty);
1842 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
1801 forbid_unresolved_segments(self, (ty, Some(strukt.into())), unresolved)
18431802 }
18441803 TypeNs::AdtId(AdtId::UnionId(u)) => {
1845 let substs = path_ctx.substs_from_path(u.into(), true, false);
1804 let args = path_ctx.substs_from_path(u.into(), true, false);
18461805 drop(ctx);
1847 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
1848 let ty = self.db.ty(u.into()).instantiate(interner, args).to_chalk(interner);
1806 let ty = self.db.ty(u.into()).instantiate(interner, args);
18491807 let ty = self.insert_type_vars(ty);
1850 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
1808 forbid_unresolved_segments(self, (ty, Some(u.into())), unresolved)
18511809 }
18521810 TypeNs::EnumVariantId(var) => {
1853 let substs = path_ctx.substs_from_path(var.into(), true, false);
1811 let args = path_ctx.substs_from_path(var.into(), true, false);
18541812 drop(ctx);
1855 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
1856 let ty = self
1857 .db
1858 .ty(var.lookup(self.db).parent.into())
1859 .instantiate(interner, args)
1860 .to_chalk(interner);
1813 let ty = self.db.ty(var.lookup(self.db).parent.into()).instantiate(interner, args);
18611814 let ty = self.insert_type_vars(ty);
1862 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
1815 forbid_unresolved_segments(self, (ty, Some(var.into())), unresolved)
18631816 }
18641817 TypeNs::SelfType(impl_id) => {
1865 let generics = crate::generics::generics(self.db, impl_id.into());
1866 let substs = generics.placeholder_subst(self.db);
1867 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
1868 let mut ty =
1869 self.db.impl_self_ty(impl_id).instantiate(interner, args).to_chalk(interner);
1818 let mut ty = self.db.impl_self_ty(impl_id).instantiate_identity();
18701819
18711820 let Some(remaining_idx) = unresolved else {
18721821 drop(ctx);
......@@ -1889,7 +1838,9 @@ impl<'db> InferenceContext<'db> {
18891838 while let Some(current_segment) = remaining_segments.first() {
18901839 // If we can resolve to an enum variant, it takes priority over associated type
18911840 // of the same name.
1892 if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
1841 if let TyKind::Adt(adt_def, _) = ty.kind()
1842 && let AdtId::EnumId(id) = adt_def.def_id().0
1843 {
18931844 let enum_data = id.enum_variants(self.db);
18941845 if let Some(variant) = enum_data.variant(current_segment.name) {
18951846 return if remaining_segments.len() == 1 {
......@@ -1917,8 +1868,8 @@ impl<'db> InferenceContext<'db> {
19171868
19181869 ty = self.table.insert_type_vars(ty);
19191870 ty = self.table.normalize_associated_types_in(ty);
1920 ty = self.table.structurally_resolve_type(&ty);
1921 if ty.is_unknown() {
1871 ty = self.table.structurally_resolve_type(ty);
1872 if ty.is_ty_error() {
19221873 return (self.err_ty(), None);
19231874 }
19241875
......@@ -1941,11 +1892,10 @@ impl<'db> InferenceContext<'db> {
19411892 never!("resolver should always resolve lang item paths");
19421893 return (self.err_ty(), None);
19431894 };
1944 let substs = path_ctx.substs_from_path_segment(it.into(), true, None, false);
1895 let args = path_ctx.substs_from_path_segment(it.into(), true, None, false);
19451896 drop(ctx);
19461897 let interner = DbInterner::conjure();
1947 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
1948 let ty = self.db.ty(it.into()).instantiate(interner, args).to_chalk(interner);
1898 let ty = self.db.ty(it.into()).instantiate(interner, args);
19491899 let ty = self.insert_type_vars(ty);
19501900
19511901 self.resolve_variant_on_alias(ty, unresolved, mod_path)
......@@ -1967,33 +1917,28 @@ impl<'db> InferenceContext<'db> {
19671917 }
19681918 };
19691919
1970 fn forbid_unresolved_segments(
1971 result: (Ty, Option<VariantId>),
1920 fn forbid_unresolved_segments<'db>(
1921 ctx: &InferenceContext<'_, 'db>,
1922 result: (Ty<'db>, Option<VariantId>),
19721923 unresolved: Option<usize>,
1973 ) -> (Ty, Option<VariantId>) {
1924 ) -> (Ty<'db>, Option<VariantId>) {
19741925 if unresolved.is_none() {
19751926 result
19761927 } else {
19771928 // FIXME diagnostic
1978 (TyKind::Error.intern(Interner), None)
1929 (ctx.types.error, None)
19791930 }
19801931 }
19811932 }
19821933
19831934 fn resolve_variant_on_alias(
19841935 &mut self,
1985 ty: Ty,
1936 ty: Ty<'db>,
19861937 unresolved: Option<usize>,
19871938 path: &ModPath,
1988 ) -> (Ty, Option<VariantId>) {
1939 ) -> (Ty<'db>, Option<VariantId>) {
19891940 let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
1990 let ty = match ty.kind(Interner) {
1991 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
1992 let ty = self.table.normalize_projection_ty(proj_ty.clone());
1993 self.table.structurally_resolve_type(&ty)
1994 }
1995 _ => ty,
1996 };
1941 let ty = self.table.try_structurally_resolve_type(ty);
19971942 match remaining {
19981943 None => {
19991944 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
......@@ -2115,19 +2060,18 @@ impl<'db> InferenceContext<'db> {
21152060/// When inferring an expression, we propagate downward whatever type hint we
21162061/// are able in the form of an `Expectation`.
21172062#[derive(Clone, PartialEq, Eq, Debug)]
2118pub(crate) enum Expectation {
2063pub(crate) enum Expectation<'db> {
21192064 None,
2120 HasType(Ty),
2121 #[allow(dead_code)]
2122 Castable(Ty),
2123 RValueLikeUnsized(Ty),
2065 HasType(Ty<'db>),
2066 Castable(Ty<'db>),
2067 RValueLikeUnsized(Ty<'db>),
21242068}
21252069
2126impl Expectation {
2070impl<'db> Expectation<'db> {
21272071 /// The expectation that the type of the expression needs to equal the given
21282072 /// type.
2129 fn has_type(ty: Ty) -> Self {
2130 if ty.is_unknown() {
2073 fn has_type(ty: Ty<'db>) -> Self {
2074 if ty.is_ty_error() {
21312075 // FIXME: get rid of this?
21322076 Expectation::None
21332077 } else {
......@@ -2155,9 +2099,11 @@ impl Expectation {
21552099 /// which still is useful, because it informs integer literals and the like.
21562100 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
21572101 /// for examples of where this comes up,.
2158 fn rvalue_hint(ctx: &mut InferenceContext<'_>, ty: Ty) -> Self {
2159 match ctx.struct_tail_without_normalization(ty.clone()).kind(Interner) {
2160 TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
2102 fn rvalue_hint(ctx: &mut InferenceContext<'_, 'db>, ty: Ty<'db>) -> Self {
2103 match ctx.struct_tail_without_normalization(ty).kind() {
2104 TyKind::Slice(_) | TyKind::Str | TyKind::Dynamic(..) => {
2105 Expectation::RValueLikeUnsized(ty)
2106 }
21612107 _ => Expectation::has_type(ty),
21622108 }
21632109 }
......@@ -2167,18 +2113,18 @@ impl Expectation {
21672113 Expectation::None
21682114 }
21692115
2170 fn resolve(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
2116 fn resolve(&self, table: &mut unify::InferenceTable<'db>) -> Expectation<'db> {
21712117 match self {
21722118 Expectation::None => Expectation::None,
2173 Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
2174 Expectation::Castable(t) => Expectation::Castable(table.resolve_ty_shallow(t)),
2119 Expectation::HasType(t) => Expectation::HasType(table.shallow_resolve(*t)),
2120 Expectation::Castable(t) => Expectation::Castable(table.shallow_resolve(*t)),
21752121 Expectation::RValueLikeUnsized(t) => {
2176 Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
2122 Expectation::RValueLikeUnsized(table.shallow_resolve(*t))
21772123 }
21782124 }
21792125 }
21802126
2181 fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
2127 fn to_option(&self, table: &mut unify::InferenceTable<'db>) -> Option<Ty<'db>> {
21822128 match self.resolve(table) {
21832129 Expectation::None => None,
21842130 Expectation::HasType(t)
......@@ -2187,17 +2133,17 @@ impl Expectation {
21872133 }
21882134 }
21892135
2190 fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
2136 fn only_has_type(&self, table: &mut unify::InferenceTable<'db>) -> Option<Ty<'db>> {
21912137 match self {
2192 Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
2138 Expectation::HasType(t) => Some(table.shallow_resolve(*t)),
21932139 Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
21942140 None
21952141 }
21962142 }
21972143 }
21982144
2199 fn coercion_target_type(&self, table: &mut unify::InferenceTable<'_>) -> Ty {
2200 self.only_has_type(table).unwrap_or_else(|| table.new_type_var())
2145 fn coercion_target_type(&self, table: &mut unify::InferenceTable<'db>) -> Ty<'db> {
2146 self.only_has_type(table).unwrap_or_else(|| table.next_ty_var())
22012147 }
22022148
22032149 /// Comment copied from rustc:
......@@ -2217,13 +2163,13 @@ impl Expectation {
22172163 /// an expected type. Otherwise, we might write parts of the type
22182164 /// when checking the 'then' block which are incompatible with the
22192165 /// 'else' branch.
2220 fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
2221 match self {
2166 fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'db>) -> Expectation<'db> {
2167 match *self {
22222168 Expectation::HasType(ety) => {
22232169 let ety = table.structurally_resolve_type(ety);
22242170 if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) }
22252171 }
2226 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()),
2172 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety),
22272173 _ => Expectation::None,
22282174 }
22292175 }
......@@ -2266,123 +2212,3 @@ impl std::ops::BitOrAssign for Diverges {
22662212 *self = *self | other;
22672213 }
22682214}
2269
2270/// A zipper that checks for unequal occurrences of `{unknown}` and unresolved projections
2271/// in the two types. Used to filter out mismatch diagnostics that only differ in
2272/// `{unknown}` and unresolved projections. These mismatches are usually not helpful.
2273/// As the cause is usually an underlying name resolution problem
2274struct UnknownMismatch<'db>(&'db dyn HirDatabase);
2275impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
2276 fn zip_tys(&mut self, variance: Variance, a: &Ty, b: &Ty) -> chalk_ir::Fallible<()> {
2277 let zip_substs = |this: &mut Self,
2278 variances,
2279 sub_a: &Substitution,
2280 sub_b: &Substitution| {
2281 this.zip_substs(variance, variances, sub_a.as_slice(Interner), sub_b.as_slice(Interner))
2282 };
2283 match (a.kind(Interner), b.kind(Interner)) {
2284 (TyKind::Adt(id_a, sub_a), TyKind::Adt(id_b, sub_b)) if id_a == id_b => zip_substs(
2285 self,
2286 Some(self.unification_database().adt_variance(*id_a)),
2287 sub_a,
2288 sub_b,
2289 )?,
2290 (
2291 TyKind::AssociatedType(assoc_ty_a, sub_a),
2292 TyKind::AssociatedType(assoc_ty_b, sub_b),
2293 ) if assoc_ty_a == assoc_ty_b => zip_substs(self, None, sub_a, sub_b)?,
2294 (TyKind::Tuple(arity_a, sub_a), TyKind::Tuple(arity_b, sub_b))
2295 if arity_a == arity_b =>
2296 {
2297 zip_substs(self, None, sub_a, sub_b)?
2298 }
2299 (TyKind::OpaqueType(opaque_ty_a, sub_a), TyKind::OpaqueType(opaque_ty_b, sub_b))
2300 if opaque_ty_a == opaque_ty_b =>
2301 {
2302 zip_substs(self, None, sub_a, sub_b)?
2303 }
2304 (TyKind::Slice(ty_a), TyKind::Slice(ty_b)) => self.zip_tys(variance, ty_a, ty_b)?,
2305 (TyKind::FnDef(fn_def_a, sub_a), TyKind::FnDef(fn_def_b, sub_b))
2306 if fn_def_a == fn_def_b =>
2307 {
2308 zip_substs(
2309 self,
2310 Some(self.unification_database().fn_def_variance(*fn_def_a)),
2311 sub_a,
2312 sub_b,
2313 )?
2314 }
2315 (TyKind::Ref(mutability_a, _, ty_a), TyKind::Ref(mutability_b, _, ty_b))
2316 if mutability_a == mutability_b =>
2317 {
2318 self.zip_tys(variance, ty_a, ty_b)?
2319 }
2320 (TyKind::Raw(mutability_a, ty_a), TyKind::Raw(mutability_b, ty_b))
2321 if mutability_a == mutability_b =>
2322 {
2323 self.zip_tys(variance, ty_a, ty_b)?
2324 }
2325 (TyKind::Array(ty_a, const_a), TyKind::Array(ty_b, const_b)) if const_a == const_b => {
2326 self.zip_tys(variance, ty_a, ty_b)?
2327 }
2328 (TyKind::Closure(id_a, sub_a), TyKind::Closure(id_b, sub_b)) if id_a == id_b => {
2329 zip_substs(self, None, sub_a, sub_b)?
2330 }
2331 (TyKind::Coroutine(coroutine_a, sub_a), TyKind::Coroutine(coroutine_b, sub_b))
2332 if coroutine_a == coroutine_b =>
2333 {
2334 zip_substs(self, None, sub_a, sub_b)?
2335 }
2336 (
2337 TyKind::CoroutineWitness(coroutine_a, sub_a),
2338 TyKind::CoroutineWitness(coroutine_b, sub_b),
2339 ) if coroutine_a == coroutine_b => zip_substs(self, None, sub_a, sub_b)?,
2340 (TyKind::Function(fn_ptr_a), TyKind::Function(fn_ptr_b))
2341 if fn_ptr_a.sig == fn_ptr_b.sig && fn_ptr_a.num_binders == fn_ptr_b.num_binders =>
2342 {
2343 zip_substs(self, None, &fn_ptr_a.substitution.0, &fn_ptr_b.substitution.0)?
2344 }
2345 (TyKind::Error, TyKind::Error) => (),
2346 (TyKind::Error, _)
2347 | (_, TyKind::Error)
2348 | (TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _), _)
2349 | (_, TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)) => {
2350 return Err(chalk_ir::NoSolution);
2351 }
2352 _ => (),
2353 }
2354
2355 Ok(())
2356 }
2357
2358 fn zip_lifetimes(&mut self, _: Variance, _: &Lifetime, _: &Lifetime) -> chalk_ir::Fallible<()> {
2359 Ok(())
2360 }
2361
2362 fn zip_consts(&mut self, _: Variance, _: &Const, _: &Const) -> chalk_ir::Fallible<()> {
2363 Ok(())
2364 }
2365
2366 fn zip_binders<T>(
2367 &mut self,
2368 variance: Variance,
2369 a: &Binders<T>,
2370 b: &Binders<T>,
2371 ) -> chalk_ir::Fallible<()>
2372 where
2373 T: Clone
2374 + HasInterner<Interner = Interner>
2375 + chalk_ir::zip::Zip<Interner>
2376 + TypeFoldable<Interner>,
2377 {
2378 chalk_ir::zip::Zip::zip_with(self, variance, a.skip_binders(), b.skip_binders())
2379 }
2380
2381 fn interner(&self) -> Interner {
2382 Interner
2383 }
2384
2385 fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase<Interner> {
2386 &self.0
2387 }
2388}
src/tools/rust-analyzer/crates/hir-ty/src/infer/autoderef.rs+6-8
......@@ -2,6 +2,8 @@
22
33use std::iter;
44
5use rustc_ast_ir::Mutability;
6
57use crate::{
68 Adjust, Adjustment, OverloadedDeref,
79 autoderef::{Autoderef, AutoderefKind},
......@@ -9,7 +11,6 @@ use crate::{
911 next_solver::{
1012 Ty,
1113 infer::{InferOk, traits::PredicateObligations},
12 mapping::NextSolverToChalk,
1314 },
1415};
1516
......@@ -21,12 +22,12 @@ impl<'db> InferenceTable<'db> {
2122
2223impl<'db> Autoderef<'_, 'db> {
2324 /// Returns the adjustment steps.
24 pub(crate) fn adjust_steps(mut self) -> Vec<Adjustment> {
25 pub(crate) fn adjust_steps(mut self) -> Vec<Adjustment<'db>> {
2526 let infer_ok = self.adjust_steps_as_infer_ok();
2627 self.table.register_infer_ok(infer_ok)
2728 }
2829
29 pub(crate) fn adjust_steps_as_infer_ok(&mut self) -> InferOk<'db, Vec<Adjustment>> {
30 pub(crate) fn adjust_steps_as_infer_ok(&mut self) -> InferOk<'db, Vec<Adjustment<'db>>> {
3031 let steps = self.steps();
3132 if steps.is_empty() {
3233 return InferOk { obligations: PredicateObligations::new(), value: vec![] };
......@@ -37,16 +38,13 @@ impl<'db> Autoderef<'_, 'db> {
3738 .iter()
3839 .map(|&(_source, kind)| {
3940 if let AutoderefKind::Overloaded = kind {
40 Some(OverloadedDeref(Some(chalk_ir::Mutability::Not)))
41 Some(OverloadedDeref(Some(Mutability::Not)))
4142 } else {
4243 None
4344 }
4445 })
4546 .zip(targets)
46 .map(|(autoderef, target)| Adjustment {
47 kind: Adjust::Deref(autoderef),
48 target: target.to_chalk(self.table.interner),
49 })
47 .map(|(autoderef, target)| Adjustment { kind: Adjust::Deref(autoderef), target })
5048 .collect();
5149
5250 InferOk { obligations: self.take_obligations(), value: steps }
src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs+169-178
......@@ -1,17 +1,18 @@
11//! Type cast logic. Basically coercion + additional casts.
22
3use chalk_ir::{Mutability, Scalar, TyVariableKind, UintTy};
43use hir_def::{AdtId, hir::ExprId, signatures::TraitFlags};
4use rustc_ast_ir::Mutability;
5use rustc_type_ir::{
6 Flags, InferTy, TypeFlags, UintTy,
7 inherent::{AdtDef, BoundExistentialPredicates as _, IntoKind, SliceLike, Ty as _},
8};
59use stdx::never;
610
7use crate::infer::coerce::CoerceNever;
811use crate::{
9 Binders, DynTy, InferenceDiagnostic, Interner, PlaceholderIndex, QuantifiedWhereClauses, Ty,
10 TyExt, TyKind, TypeFlags, WhereClause,
12 InferenceDiagnostic,
1113 db::HirDatabase,
12 from_chalk_trait_id,
13 infer::{AllowTwoPhase, InferenceContext},
14 next_solver::mapping::ChalkToNextSolver,
14 infer::{AllowTwoPhase, InferenceContext, coerce::CoerceNever},
15 next_solver::{BoundExistentialPredicates, DbInterner, ParamTy, Ty, TyKind},
1516};
1617
1718#[derive(Debug)]
......@@ -25,24 +26,24 @@ pub(crate) enum Int {
2526}
2627
2728#[derive(Debug)]
28pub(crate) enum CastTy {
29pub(crate) enum CastTy<'db> {
2930 Int(Int),
3031 Float,
3132 FnPtr,
32 Ptr(Ty, Mutability),
33 Ptr(Ty<'db>, Mutability),
3334 // `DynStar` is Not supported yet in r-a
3435}
3536
36impl CastTy {
37 pub(crate) fn from_ty(db: &dyn HirDatabase, t: &Ty) -> Option<Self> {
38 match t.kind(Interner) {
39 TyKind::Scalar(Scalar::Bool) => Some(Self::Int(Int::Bool)),
40 TyKind::Scalar(Scalar::Char) => Some(Self::Int(Int::Char)),
41 TyKind::Scalar(Scalar::Int(_)) => Some(Self::Int(Int::I)),
42 TyKind::Scalar(Scalar::Uint(it)) => Some(Self::Int(Int::U(*it))),
43 TyKind::InferenceVar(_, TyVariableKind::Integer) => Some(Self::Int(Int::InferenceVar)),
44 TyKind::InferenceVar(_, TyVariableKind::Float) => Some(Self::Float),
45 TyKind::Scalar(Scalar::Float(_)) => Some(Self::Float),
37impl<'db> CastTy<'db> {
38 pub(crate) fn from_ty(db: &dyn HirDatabase, t: Ty<'db>) -> Option<Self> {
39 match t.kind() {
40 TyKind::Bool => Some(Self::Int(Int::Bool)),
41 TyKind::Char => Some(Self::Int(Int::Char)),
42 TyKind::Int(_) => Some(Self::Int(Int::I)),
43 TyKind::Uint(it) => Some(Self::Int(Int::U(it))),
44 TyKind::Infer(InferTy::IntVar(_)) => Some(Self::Int(Int::InferenceVar)),
45 TyKind::Infer(InferTy::FloatVar(_)) => Some(Self::Float),
46 TyKind::Float(_) => Some(Self::Float),
4647 TyKind::Adt(..) => {
4748 let (AdtId::EnumId(id), _) = t.as_adt()? else {
4849 return None;
......@@ -50,8 +51,8 @@ impl CastTy {
5051 let enum_data = id.enum_variants(db);
5152 if enum_data.is_payload_free(db) { Some(Self::Int(Int::CEnum)) } else { None }
5253 }
53 TyKind::Raw(m, ty) => Some(Self::Ptr(ty.clone(), *m)),
54 TyKind::Function(_) => Some(Self::FnPtr),
54 TyKind::RawPtr(ty, m) => Some(Self::Ptr(ty, m)),
55 TyKind::FnPtr(..) => Some(Self::FnPtr),
5556 _ => None,
5657 }
5758 }
......@@ -77,37 +78,47 @@ pub enum CastError {
7778}
7879
7980impl CastError {
80 fn into_diagnostic(self, expr: ExprId, expr_ty: Ty, cast_ty: Ty) -> InferenceDiagnostic {
81 fn into_diagnostic<'db>(
82 self,
83 expr: ExprId,
84 expr_ty: Ty<'db>,
85 cast_ty: Ty<'db>,
86 ) -> InferenceDiagnostic<'db> {
8187 InferenceDiagnostic::InvalidCast { expr, error: self, expr_ty, cast_ty }
8288 }
8389}
8490
8591#[derive(Clone, Debug)]
86pub(super) struct CastCheck {
92pub(super) struct CastCheck<'db> {
8793 expr: ExprId,
8894 source_expr: ExprId,
89 expr_ty: Ty,
90 cast_ty: Ty,
95 expr_ty: Ty<'db>,
96 cast_ty: Ty<'db>,
9197}
9298
93impl CastCheck {
94 pub(super) fn new(expr: ExprId, source_expr: ExprId, expr_ty: Ty, cast_ty: Ty) -> Self {
99impl<'db> CastCheck<'db> {
100 pub(super) fn new(
101 expr: ExprId,
102 source_expr: ExprId,
103 expr_ty: Ty<'db>,
104 cast_ty: Ty<'db>,
105 ) -> Self {
95106 Self { expr, source_expr, expr_ty, cast_ty }
96107 }
97108
98109 pub(super) fn check(
99110 &mut self,
100 ctx: &mut InferenceContext<'_>,
101 ) -> Result<(), InferenceDiagnostic> {
102 self.expr_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.expr_ty.clone());
103 self.cast_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.cast_ty.clone());
111 ctx: &mut InferenceContext<'_, 'db>,
112 ) -> Result<(), InferenceDiagnostic<'db>> {
113 self.expr_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.expr_ty);
114 self.cast_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.cast_ty);
104115
105116 // This should always come first so that we apply the coercion, which impacts infer vars.
106117 if ctx
107118 .coerce(
108119 self.source_expr.into(),
109 self.expr_ty.to_nextsolver(ctx.table.interner),
110 self.cast_ty.to_nextsolver(ctx.table.interner),
120 self.expr_ty,
121 self.cast_ty,
111122 AllowTwoPhase::No,
112123 CoerceNever::Yes,
113124 )
......@@ -117,83 +128,82 @@ impl CastCheck {
117128 return Ok(());
118129 }
119130
120 if self.expr_ty.contains_unknown() || self.cast_ty.contains_unknown() {
131 if self.expr_ty.references_non_lt_error() || self.cast_ty.references_non_lt_error() {
121132 return Ok(());
122133 }
123134
124 if !self.cast_ty.data(Interner).flags.contains(TypeFlags::HAS_TY_INFER)
125 && !ctx.table.is_sized(&self.cast_ty)
135 if !self.cast_ty.flags().contains(TypeFlags::HAS_TY_INFER)
136 && !ctx.table.is_sized(self.cast_ty)
126137 {
127138 return Err(InferenceDiagnostic::CastToUnsized {
128139 expr: self.expr,
129 cast_ty: self.cast_ty.clone(),
140 cast_ty: self.cast_ty,
130141 });
131142 }
132143
133144 // Chalk doesn't support trait upcasting and fails to solve some obvious goals
134145 // when the trait environment contains some recursive traits (See issue #18047)
135146 // We skip cast checks for such cases for now, until the next-gen solver.
136 if contains_dyn_trait(&self.cast_ty) {
147 if contains_dyn_trait(self.cast_ty) {
137148 return Ok(());
138149 }
139150
140 self.do_check(ctx)
141 .map_err(|e| e.into_diagnostic(self.expr, self.expr_ty.clone(), self.cast_ty.clone()))
151 self.do_check(ctx).map_err(|e| e.into_diagnostic(self.expr, self.expr_ty, self.cast_ty))
142152 }
143153
144 fn do_check(&self, ctx: &mut InferenceContext<'_>) -> Result<(), CastError> {
145 let (t_from, t_cast) = match (
146 CastTy::from_ty(ctx.db, &self.expr_ty),
147 CastTy::from_ty(ctx.db, &self.cast_ty),
148 ) {
149 (Some(t_from), Some(t_cast)) => (t_from, t_cast),
150 (None, Some(t_cast)) => match self.expr_ty.kind(Interner) {
151 TyKind::FnDef(..) => {
152 let sig = self.expr_ty.callable_sig(ctx.db).expect("FnDef had no sig");
153 let sig = ctx.table.eagerly_normalize_and_resolve_shallow_in(sig);
154 let fn_ptr = TyKind::Function(sig.to_fn_ptr()).intern(Interner);
155 if ctx
156 .coerce(
157 self.source_expr.into(),
158 self.expr_ty.to_nextsolver(ctx.table.interner),
159 fn_ptr.to_nextsolver(ctx.table.interner),
160 AllowTwoPhase::No,
161 CoerceNever::Yes,
162 )
163 .is_ok()
164 {
165 } else {
166 return Err(CastError::IllegalCast);
167 }
154 fn do_check(&self, ctx: &mut InferenceContext<'_, 'db>) -> Result<(), CastError> {
155 let (t_from, t_cast) =
156 match (CastTy::from_ty(ctx.db, self.expr_ty), CastTy::from_ty(ctx.db, self.cast_ty)) {
157 (Some(t_from), Some(t_cast)) => (t_from, t_cast),
158 (None, Some(t_cast)) => match self.expr_ty.kind() {
159 TyKind::FnDef(..) => {
160 let sig =
161 self.expr_ty.callable_sig(ctx.interner()).expect("FnDef had no sig");
162 let sig = ctx.table.eagerly_normalize_and_resolve_shallow_in(sig);
163 let fn_ptr = Ty::new_fn_ptr(ctx.interner(), sig);
164 if ctx
165 .coerce(
166 self.source_expr.into(),
167 self.expr_ty,
168 fn_ptr,
169 AllowTwoPhase::No,
170 CoerceNever::Yes,
171 )
172 .is_ok()
173 {
174 } else {
175 return Err(CastError::IllegalCast);
176 }
168177
169 (CastTy::FnPtr, t_cast)
170 }
171 TyKind::Ref(mutbl, _, inner_ty) => {
172 return match t_cast {
173 CastTy::Int(_) | CastTy::Float => match inner_ty.kind(Interner) {
174 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_))
175 | TyKind::InferenceVar(
176 _,
177 TyVariableKind::Integer | TyVariableKind::Float,
178 ) => Err(CastError::NeedDeref),
179
180 _ => Err(CastError::NeedViaPtr),
181 },
182 // array-ptr-cast
183 CastTy::Ptr(t, m) => {
184 let t = ctx.table.eagerly_normalize_and_resolve_shallow_in(t);
185 if !ctx.table.is_sized(&t) {
186 return Err(CastError::IllegalCast);
178 (CastTy::FnPtr, t_cast)
179 }
180 TyKind::Ref(_, inner_ty, mutbl) => {
181 return match t_cast {
182 CastTy::Int(_) | CastTy::Float => match inner_ty.kind() {
183 TyKind::Int(_)
184 | TyKind::Uint(_)
185 | TyKind::Float(_)
186 | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_)) => {
187 Err(CastError::NeedDeref)
188 }
189
190 _ => Err(CastError::NeedViaPtr),
191 },
192 // array-ptr-cast
193 CastTy::Ptr(t, m) => {
194 let t = ctx.table.eagerly_normalize_and_resolve_shallow_in(t);
195 if !ctx.table.is_sized(t) {
196 return Err(CastError::IllegalCast);
197 }
198 self.check_ref_cast(ctx, inner_ty, mutbl, t, m)
187199 }
188 self.check_ref_cast(ctx, inner_ty, *mutbl, &t, m)
189 }
190 _ => Err(CastError::NonScalar),
191 };
192 }
200 _ => Err(CastError::NonScalar),
201 };
202 }
203 _ => return Err(CastError::NonScalar),
204 },
193205 _ => return Err(CastError::NonScalar),
194 },
195 _ => return Err(CastError::NonScalar),
196 };
206 };
197207
198208 // rustc checks whether the `expr_ty` is foreign adt with `non_exhaustive` sym
199209
......@@ -207,10 +217,10 @@ impl CastCheck {
207217 }
208218 (CastTy::Int(Int::Bool | Int::CEnum | Int::Char) | CastTy::Float, CastTy::Ptr(..))
209219 | (CastTy::Ptr(..) | CastTy::FnPtr, CastTy::Float) => Err(CastError::IllegalCast),
210 (CastTy::Ptr(src, _), CastTy::Ptr(dst, _)) => self.check_ptr_ptr_cast(ctx, &src, &dst),
211 (CastTy::Ptr(src, _), CastTy::Int(_)) => self.check_ptr_addr_cast(ctx, &src),
212 (CastTy::Int(_), CastTy::Ptr(dst, _)) => self.check_addr_ptr_cast(ctx, &dst),
213 (CastTy::FnPtr, CastTy::Ptr(dst, _)) => self.check_fptr_ptr_cast(ctx, &dst),
220 (CastTy::Ptr(src, _), CastTy::Ptr(dst, _)) => self.check_ptr_ptr_cast(ctx, src, dst),
221 (CastTy::Ptr(src, _), CastTy::Int(_)) => self.check_ptr_addr_cast(ctx, src),
222 (CastTy::Int(_), CastTy::Ptr(dst, _)) => self.check_addr_ptr_cast(ctx, dst),
223 (CastTy::FnPtr, CastTy::Ptr(dst, _)) => self.check_fptr_ptr_cast(ctx, dst),
214224 (CastTy::Int(Int::CEnum), CastTy::Int(_)) => Ok(()),
215225 (CastTy::Int(Int::Char | Int::Bool), CastTy::Int(_)) => Ok(()),
216226 (CastTy::Int(_) | CastTy::Float, CastTy::Int(_) | CastTy::Float) => Ok(()),
......@@ -220,23 +230,23 @@ impl CastCheck {
220230
221231 fn check_ref_cast(
222232 &self,
223 ctx: &mut InferenceContext<'_>,
224 t_expr: &Ty,
233 ctx: &mut InferenceContext<'_, 'db>,
234 t_expr: Ty<'db>,
225235 m_expr: Mutability,
226 t_cast: &Ty,
236 t_cast: Ty<'db>,
227237 m_cast: Mutability,
228238 ) -> Result<(), CastError> {
229239 // Mutability order is opposite to rustc. `Mut < Not`
230240 if m_expr <= m_cast
231 && let TyKind::Array(ety, _) = t_expr.kind(Interner)
241 && let TyKind::Array(ety, _) = t_expr.kind()
232242 {
233243 // Coerce to a raw pointer so that we generate RawPtr in MIR.
234 let array_ptr_type = TyKind::Raw(m_expr, t_expr.clone()).intern(Interner);
244 let array_ptr_type = Ty::new_ptr(ctx.interner(), t_expr, m_expr);
235245 if ctx
236246 .coerce(
237247 self.source_expr.into(),
238 self.expr_ty.to_nextsolver(ctx.table.interner),
239 array_ptr_type.to_nextsolver(ctx.table.interner),
248 self.expr_ty,
249 array_ptr_type,
240250 AllowTwoPhase::No,
241251 CoerceNever::Yes,
242252 )
......@@ -253,13 +263,7 @@ impl CastCheck {
253263 // This is a less strict condition than rustc's `demand_eqtype`,
254264 // but false negative is better than false positive
255265 if ctx
256 .coerce(
257 self.source_expr.into(),
258 ety.to_nextsolver(ctx.table.interner),
259 t_cast.to_nextsolver(ctx.table.interner),
260 AllowTwoPhase::No,
261 CoerceNever::Yes,
262 )
266 .coerce(self.source_expr.into(), ety, t_cast, AllowTwoPhase::No, CoerceNever::Yes)
263267 .is_ok()
264268 {
265269 return Ok(());
......@@ -271,9 +275,9 @@ impl CastCheck {
271275
272276 fn check_ptr_ptr_cast(
273277 &self,
274 ctx: &mut InferenceContext<'_>,
275 src: &Ty,
276 dst: &Ty,
278 ctx: &mut InferenceContext<'_, 'db>,
279 src: Ty<'db>,
280 dst: Ty<'db>,
277281 ) -> Result<(), CastError> {
278282 let src_kind = pointer_kind(src, ctx).map_err(|_| CastError::Unknown)?;
279283 let dst_kind = pointer_kind(dst, ctx).map_err(|_| CastError::Unknown)?;
......@@ -286,24 +290,13 @@ impl CastCheck {
286290 (_, Some(PointerKind::Thin)) => Ok(()),
287291 (Some(PointerKind::Thin), _) => Err(CastError::SizedUnsizedCast),
288292 (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => {
289 let principal = |tty: &Binders<QuantifiedWhereClauses>| {
290 tty.skip_binders().as_slice(Interner).first().and_then(|pred| {
291 if let WhereClause::Implemented(tr) = pred.skip_binders() {
292 Some(tr.trait_id)
293 } else {
294 None
295 }
296 })
297 };
298 match (principal(&src_tty), principal(&dst_tty)) {
293 match (src_tty.principal_def_id(), dst_tty.principal_def_id()) {
299294 (Some(src_principal), Some(dst_principal)) => {
300295 if src_principal == dst_principal {
301296 return Ok(());
302297 }
303 let src_principal =
304 ctx.db.trait_signature(from_chalk_trait_id(src_principal));
305 let dst_principal =
306 ctx.db.trait_signature(from_chalk_trait_id(dst_principal));
298 let src_principal = ctx.db.trait_signature(src_principal.0);
299 let dst_principal = ctx.db.trait_signature(dst_principal.0);
307300 if src_principal.flags.contains(TraitFlags::AUTO)
308301 && dst_principal.flags.contains(TraitFlags::AUTO)
309302 {
......@@ -322,8 +315,8 @@ impl CastCheck {
322315
323316 fn check_ptr_addr_cast(
324317 &self,
325 ctx: &mut InferenceContext<'_>,
326 expr_ty: &Ty,
318 ctx: &mut InferenceContext<'_, 'db>,
319 expr_ty: Ty<'db>,
327320 ) -> Result<(), CastError> {
328321 match pointer_kind(expr_ty, ctx).map_err(|_| CastError::Unknown)? {
329322 // None => Err(CastError::UnknownExprPtrKind),
......@@ -336,8 +329,8 @@ impl CastCheck {
336329
337330 fn check_addr_ptr_cast(
338331 &self,
339 ctx: &mut InferenceContext<'_>,
340 cast_ty: &Ty,
332 ctx: &mut InferenceContext<'_, 'db>,
333 cast_ty: Ty<'db>,
341334 ) -> Result<(), CastError> {
342335 match pointer_kind(cast_ty, ctx).map_err(|_| CastError::Unknown)? {
343336 // None => Err(CastError::UnknownCastPtrKind),
......@@ -352,8 +345,8 @@ impl CastCheck {
352345
353346 fn check_fptr_ptr_cast(
354347 &self,
355 ctx: &mut InferenceContext<'_>,
356 cast_ty: &Ty,
348 ctx: &mut InferenceContext<'_, 'db>,
349 cast_ty: Ty<'db>,
357350 ) -> Result<(), CastError> {
358351 match pointer_kind(cast_ty, ctx).map_err(|_| CastError::Unknown)? {
359352 // None => Err(CastError::UnknownCastPtrKind),
......@@ -366,30 +359,34 @@ impl CastCheck {
366359}
367360
368361#[derive(Debug, PartialEq, Eq)]
369enum PointerKind {
362enum PointerKind<'db> {
370363 // thin pointer
371364 Thin,
372365 // trait object
373 VTable(Binders<QuantifiedWhereClauses>),
366 VTable(BoundExistentialPredicates<'db>),
374367 // slice
375368 Length,
376369 OfAlias,
377 OfParam(PlaceholderIndex),
370 OfParam(ParamTy),
378371 Error,
379372}
380373
381fn pointer_kind(ty: &Ty, ctx: &mut InferenceContext<'_>) -> Result<Option<PointerKind>, ()> {
382 let ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(ty.clone());
374fn pointer_kind<'db>(
375 ty: Ty<'db>,
376 ctx: &mut InferenceContext<'_, 'db>,
377) -> Result<Option<PointerKind<'db>>, ()> {
378 let ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(ty);
383379
384 if ctx.table.is_sized(&ty) {
380 if ctx.table.is_sized(ty) {
385381 return Ok(Some(PointerKind::Thin));
386382 }
387383
388 match ty.kind(Interner) {
384 match ty.kind() {
389385 TyKind::Slice(_) | TyKind::Str => Ok(Some(PointerKind::Length)),
390 TyKind::Dyn(DynTy { bounds, .. }) => Ok(Some(PointerKind::VTable(bounds.clone()))),
391 TyKind::Adt(chalk_ir::AdtId(id), subst) => {
392 let AdtId::StructId(id) = *id else {
386 TyKind::Dynamic(bounds, _) => Ok(Some(PointerKind::VTable(bounds))),
387 TyKind::Adt(adt_def, subst) => {
388 let id = adt_def.def_id().0;
389 let AdtId::StructId(id) = id else {
393390 never!("`{:?}` should be sized but is not?", ty);
394391 return Err(());
395392 };
......@@ -397,69 +394,63 @@ fn pointer_kind(ty: &Ty, ctx: &mut InferenceContext<'_>) -> Result<Option<Pointe
397394 let struct_data = id.fields(ctx.db);
398395 if let Some((last_field, _)) = struct_data.fields().iter().last() {
399396 let last_field_ty =
400 ctx.db.field_types(id.into())[last_field].clone().substitute(Interner, subst);
401 pointer_kind(&last_field_ty, ctx)
397 ctx.db.field_types_ns(id.into())[last_field].instantiate(ctx.interner(), subst);
398 pointer_kind(last_field_ty, ctx)
402399 } else {
403400 Ok(Some(PointerKind::Thin))
404401 }
405402 }
406 TyKind::Tuple(_, subst) => {
407 match subst.iter(Interner).last().and_then(|arg| arg.ty(Interner)) {
408 None => Ok(Some(PointerKind::Thin)),
409 Some(ty) => pointer_kind(ty, ctx),
410 }
411 }
403 TyKind::Tuple(subst) => match subst.iter().next_back() {
404 None => Ok(Some(PointerKind::Thin)),
405 Some(ty) => pointer_kind(ty, ctx),
406 },
412407 TyKind::Foreign(_) => Ok(Some(PointerKind::Thin)),
413 TyKind::Alias(_) | TyKind::AssociatedType(..) | TyKind::OpaqueType(..) => {
414 Ok(Some(PointerKind::OfAlias))
415 }
416 TyKind::Error => Ok(Some(PointerKind::Error)),
417 TyKind::Placeholder(idx) => Ok(Some(PointerKind::OfParam(*idx))),
418 TyKind::BoundVar(_) | TyKind::InferenceVar(..) => Ok(None),
419 TyKind::Scalar(_)
408 TyKind::Alias(..) => Ok(Some(PointerKind::OfAlias)),
409 TyKind::Error(_) => Ok(Some(PointerKind::Error)),
410 TyKind::Param(idx) => Ok(Some(PointerKind::OfParam(idx))),
411 TyKind::Bound(..) | TyKind::Placeholder(..) | TyKind::Infer(..) => Ok(None),
412 TyKind::Int(_)
413 | TyKind::Uint(_)
414 | TyKind::Float(_)
415 | TyKind::Bool
416 | TyKind::Char
420417 | TyKind::Array(..)
421418 | TyKind::CoroutineWitness(..)
422 | TyKind::Raw(..)
419 | TyKind::RawPtr(..)
423420 | TyKind::Ref(..)
424421 | TyKind::FnDef(..)
425 | TyKind::Function(_)
422 | TyKind::FnPtr(..)
426423 | TyKind::Closure(..)
427424 | TyKind::Coroutine(..)
425 | TyKind::CoroutineClosure(..)
428426 | TyKind::Never => {
429427 never!("`{:?}` should be sized but is not?", ty);
430428 Err(())
431429 }
430 TyKind::UnsafeBinder(..) | TyKind::Pat(..) => {
431 never!("we don't produce these types: {ty:?}");
432 Err(())
433 }
432434 }
433435}
434436
435fn contains_dyn_trait(ty: &Ty) -> bool {
437fn contains_dyn_trait<'db>(ty: Ty<'db>) -> bool {
436438 use std::ops::ControlFlow;
437439
438 use chalk_ir::{
439 DebruijnIndex,
440 visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
441 };
440 use rustc_type_ir::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
442441
443442 struct DynTraitVisitor;
444443
445 impl TypeVisitor<Interner> for DynTraitVisitor {
446 type BreakTy = ();
447
448 fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
449 self
450 }
451
452 fn interner(&self) -> Interner {
453 Interner
454 }
444 impl<'db> TypeVisitor<DbInterner<'db>> for DynTraitVisitor {
445 type Result = ControlFlow<()>;
455446
456 fn visit_ty(&mut self, ty: &Ty, outer_binder: DebruijnIndex) -> ControlFlow<Self::BreakTy> {
457 match ty.kind(Interner) {
458 TyKind::Dyn(_) => ControlFlow::Break(()),
459 _ => ty.super_visit_with(self.as_dyn(), outer_binder),
447 fn visit_ty(&mut self, ty: Ty<'db>) -> ControlFlow<()> {
448 match ty.kind() {
449 TyKind::Dynamic(..) => ControlFlow::Break(()),
450 _ => ty.super_visit_with(self),
460451 }
461452 }
462453 }
463454
464 ty.visit_with(DynTraitVisitor.as_dyn(), DebruijnIndex::INNERMOST).is_break()
455 ty.visit_with(&mut DynTraitVisitor).is_break()
465456}
src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs+33-45
......@@ -2,8 +2,7 @@
22
33pub(crate) mod analysis;
44
5use std::ops::ControlFlow;
6use std::{iter, mem};
5use std::{iter, mem, ops::ControlFlow};
76
87use hir_def::{
98 TraitId,
......@@ -18,7 +17,6 @@ use rustc_type_ir::{
1817};
1918use tracing::debug;
2019
21use crate::traits::FnTrait;
2220use crate::{
2321 FnAbi,
2422 db::{InternedClosure, InternedCoroutine},
......@@ -31,25 +29,25 @@ use crate::{
3129 BoundRegionConversionTime, DefineOpaqueTypes, InferOk, InferResult,
3230 traits::{ObligationCause, PredicateObligations},
3331 },
34 mapping::{ChalkToNextSolver, NextSolverToChalk},
3532 util::explicit_item_bounds,
3633 },
34 traits::FnTrait,
3735};
3836
3937use super::{Expectation, InferenceContext};
4038
4139#[derive(Debug)]
42struct ClosureSignatures<'tcx> {
40struct ClosureSignatures<'db> {
4341 /// The signature users of the closure see.
44 bound_sig: PolyFnSig<'tcx>,
42 bound_sig: PolyFnSig<'db>,
4543 /// The signature within the function body.
4644 /// This mostly differs in the sense that lifetimes are now early bound and any
4745 /// opaque types from the signature expectation are overridden in case there are
4846 /// explicit hidden types written by the user in the closure signature.
49 liberated_sig: FnSig<'tcx>,
47 liberated_sig: FnSig<'db>,
5048}
5149
52impl<'db> InferenceContext<'db> {
50impl<'db> InferenceContext<'_, 'db> {
5351 pub(super) fn infer_closure(
5452 &mut self,
5553 body: ExprId,
......@@ -58,15 +56,13 @@ impl<'db> InferenceContext<'db> {
5856 arg_types: &[Option<TypeRefId>],
5957 closure_kind: ClosureKind,
6058 tgt_expr: ExprId,
61 expected: &Expectation,
62 ) -> crate::Ty {
59 expected: &Expectation<'db>,
60 ) -> Ty<'db> {
6361 assert_eq!(args.len(), arg_types.len());
6462
65 let interner = self.table.interner;
63 let interner = self.interner();
6664 let (expected_sig, expected_kind) = match expected.to_option(&mut self.table) {
67 Some(expected_ty) => {
68 self.deduce_closure_signature(expected_ty.to_nextsolver(interner), closure_kind)
69 }
65 Some(expected_ty) => self.deduce_closure_signature(expected_ty, closure_kind),
7066 None => (None, None),
7167 };
7268
......@@ -79,10 +75,7 @@ impl<'db> InferenceContext<'db> {
7975 let (id, ty, resume_yield_tys) = match closure_kind {
8076 ClosureKind::Coroutine(_) => {
8177 let yield_ty = self.table.next_ty_var();
82 let resume_ty = liberated_sig
83 .inputs()
84 .get(0)
85 .unwrap_or(self.result.standard_types.unit.to_nextsolver(interner));
78 let resume_ty = liberated_sig.inputs().get(0).unwrap_or(self.types.unit);
8679
8780 // FIXME: Infer the upvars later.
8881 let parts = CoroutineArgsParts {
......@@ -102,11 +95,7 @@ impl<'db> InferenceContext<'db> {
10295 CoroutineArgs::new(interner, parts).args,
10396 );
10497
105 (
106 None,
107 coroutine_ty,
108 Some((resume_ty.to_chalk(interner), yield_ty.to_chalk(interner))),
109 )
98 (None, coroutine_ty, Some((resume_ty, yield_ty)))
11099 }
111100 // FIXME(next-solver): `ClosureKind::Async` should really be a separate arm that creates a `CoroutineClosure`.
112101 // But for now we treat it as a closure.
......@@ -115,7 +104,7 @@ impl<'db> InferenceContext<'db> {
115104 match expected_kind {
116105 Some(kind) => {
117106 self.result.closure_info.insert(
118 closure_id.into(),
107 closure_id,
119108 (
120109 Vec::new(),
121110 match kind {
......@@ -151,13 +140,13 @@ impl<'db> InferenceContext<'db> {
151140
152141 // Now go through the argument patterns
153142 for (arg_pat, arg_ty) in args.iter().zip(bound_sig.skip_binder().inputs()) {
154 self.infer_top_pat(*arg_pat, &arg_ty.to_chalk(interner), None);
143 self.infer_top_pat(*arg_pat, arg_ty, None);
155144 }
156145
157146 // FIXME: lift these out into a struct
158147 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
159148 let prev_closure = mem::replace(&mut self.current_closure, id);
160 let prev_ret_ty = mem::replace(&mut self.return_ty, body_ret_ty.to_chalk(interner));
149 let prev_ret_ty = mem::replace(&mut self.return_ty, body_ret_ty);
161150 let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(body_ret_ty));
162151 let prev_resume_yield_tys = mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
163152
......@@ -171,7 +160,7 @@ impl<'db> InferenceContext<'db> {
171160 self.current_closure = prev_closure;
172161 self.resume_yield_tys = prev_resume_yield_tys;
173162
174 ty.to_chalk(interner)
163 ty
175164 }
176165
177166 fn fn_trait_kind_from_def_id(&self, trait_id: TraitId) -> Option<rustc_type_ir::ClosureKind> {
......@@ -209,14 +198,13 @@ impl<'db> InferenceContext<'db> {
209198 .deduce_closure_signature_from_predicates(
210199 expected_ty,
211200 closure_kind,
212 explicit_item_bounds(self.table.interner, def_id)
213 .iter_instantiated(self.table.interner, args)
201 explicit_item_bounds(self.interner(), def_id)
202 .iter_instantiated(self.interner(), args)
214203 .map(|clause| clause.as_predicate()),
215204 ),
216205 TyKind::Dynamic(object_type, ..) => {
217206 let sig = object_type.projection_bounds().into_iter().find_map(|pb| {
218 let pb =
219 pb.with_self_ty(self.table.interner, Ty::new_unit(self.table.interner));
207 let pb = pb.with_self_ty(self.interner(), Ty::new_unit(self.interner()));
220208 self.deduce_sig_from_projection(closure_kind, pb)
221209 });
222210 let kind = object_type
......@@ -226,7 +214,7 @@ impl<'db> InferenceContext<'db> {
226214 }
227215 TyKind::Infer(rustc_type_ir::TyVar(vid)) => self
228216 .deduce_closure_signature_from_predicates(
229 Ty::new_var(self.table.interner, self.table.infer_ctxt.root_var(vid)),
217 Ty::new_var(self.interner(), self.table.infer_ctxt.root_var(vid)),
230218 closure_kind,
231219 self.table.obligations_for_self_ty(vid).into_iter().map(|obl| obl.predicate),
232220 ),
......@@ -251,7 +239,7 @@ impl<'db> InferenceContext<'db> {
251239 let mut expected_kind = None;
252240
253241 for pred in rustc_type_ir::elaborate::elaborate(
254 self.table.interner,
242 self.interner(),
255243 // Reverse the obligations here, since `elaborate_*` uses a stack,
256244 // and we want to keep inference generally in the same order of
257245 // the registered obligations.
......@@ -313,7 +301,7 @@ impl<'db> InferenceContext<'db> {
313301 // even though the normalized form may not name `expected_ty`. However, this matches the existing
314302 // behaviour of the old solver and would be technically a breaking change to fix.
315303 let generalized_fnptr_sig = self.table.next_ty_var();
316 let inferred_fnptr_sig = Ty::new_fn_ptr(self.table.interner, inferred_sig);
304 let inferred_fnptr_sig = Ty::new_fn_ptr(self.interner(), inferred_sig);
317305 // FIXME: Report diagnostics.
318306 _ = self
319307 .table
......@@ -326,7 +314,7 @@ impl<'db> InferenceContext<'db> {
326314 self.table.infer_ctxt.resolve_vars_if_possible(generalized_fnptr_sig);
327315
328316 if resolved_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
329 expected_sig = Some(resolved_sig.fn_sig(self.table.interner));
317 expected_sig = Some(resolved_sig.fn_sig(self.interner()));
330318 }
331319 } else if inferred_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
332320 expected_sig = inferred_sig;
......@@ -339,7 +327,7 @@ impl<'db> InferenceContext<'db> {
339327 // many viable options, so pick the most restrictive.
340328 let trait_def_id = match bound_predicate.skip_binder() {
341329 PredicateKind::Clause(ClauseKind::Projection(data)) => {
342 Some(data.projection_term.trait_def_id(self.table.interner).0)
330 Some(data.projection_term.trait_def_id(self.interner()).0)
343331 }
344332 PredicateKind::Clause(ClauseKind::Trait(data)) => Some(data.def_id().0),
345333 _ => None,
......@@ -427,7 +415,7 @@ impl<'db> InferenceContext<'db> {
427415 let ret_param_ty = projection.skip_binder().term.expect_type();
428416 debug!(?ret_param_ty);
429417
430 let sig = projection.rebind(self.table.interner.mk_fn_sig(
418 let sig = projection.rebind(self.interner().mk_fn_sig(
431419 input_tys,
432420 ret_param_ty,
433421 false,
......@@ -515,7 +503,7 @@ impl<'db> InferenceContext<'db> {
515503 // that does not misuse a `FnSig` type, but that can be done separately.
516504 let return_ty = return_ty.unwrap_or_else(|| self.table.next_ty_var());
517505
518 let sig = projection.rebind(self.table.interner.mk_fn_sig(
506 let sig = projection.rebind(self.interner().mk_fn_sig(
519507 input_tys,
520508 return_ty,
521509 false,
......@@ -619,7 +607,7 @@ impl<'db> InferenceContext<'db> {
619607 // in this binder we are creating.
620608 assert!(!expected_sig.skip_binder().has_vars_bound_above(rustc_type_ir::INNERMOST));
621609 let bound_sig = expected_sig.map_bound(|sig| {
622 self.table.interner.mk_fn_sig(
610 self.interner().mk_fn_sig(
623611 sig.inputs(),
624612 sig.output(),
625613 sig.c_variadic,
......@@ -631,7 +619,7 @@ impl<'db> InferenceContext<'db> {
631619 // `deduce_expectations_from_expected_type` introduces
632620 // late-bound lifetimes defined elsewhere, which we now
633621 // anonymize away, so as not to confuse the user.
634 let bound_sig = self.table.interner.anonymize_bound_vars(bound_sig);
622 let bound_sig = self.interner().anonymize_bound_vars(bound_sig);
635623
636624 let closure_sigs = self.closure_sigs(bound_sig);
637625
......@@ -723,7 +711,7 @@ impl<'db> InferenceContext<'db> {
723711 .into_iter()
724712 .map(|ty| table.infer_ctxt.resolve_vars_if_possible(ty));
725713
726 expected_sigs.liberated_sig = table.interner.mk_fn_sig(
714 expected_sigs.liberated_sig = table.interner().mk_fn_sig(
727715 inputs,
728716 supplied_output_ty,
729717 expected_sigs.liberated_sig.c_variadic,
......@@ -744,12 +732,12 @@ impl<'db> InferenceContext<'db> {
744732 decl_inputs: &[Option<TypeRefId>],
745733 decl_output: Option<TypeRefId>,
746734 ) -> PolyFnSig<'db> {
747 let interner = self.table.interner;
735 let interner = self.interner();
748736
749737 let supplied_return = match decl_output {
750738 Some(output) => {
751739 let output = self.make_body_ty(output);
752 self.process_user_written_ty(output).to_nextsolver(interner)
740 self.process_user_written_ty(output)
753741 }
754742 None => self.table.next_ty_var(),
755743 };
......@@ -757,7 +745,7 @@ impl<'db> InferenceContext<'db> {
757745 let supplied_arguments = decl_inputs.iter().map(|&input| match input {
758746 Some(input) => {
759747 let input = self.make_body_ty(input);
760 self.process_user_written_ty(input).to_nextsolver(interner)
748 self.process_user_written_ty(input)
761749 }
762750 None => self.table.next_ty_var(),
763751 });
......@@ -779,7 +767,7 @@ impl<'db> InferenceContext<'db> {
779767 decl_inputs: &[Option<TypeRefId>],
780768 decl_output: Option<TypeRefId>,
781769 ) -> PolyFnSig<'db> {
782 let interner = self.table.interner;
770 let interner = self.interner();
783771 let err_ty = Ty::new_error(interner, ErrorGuaranteed);
784772
785773 if let Some(output) = decl_output {
src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs+96-133
......@@ -2,10 +2,6 @@
22
33use std::{cmp, convert::Infallible, mem};
44
5use chalk_ir::{
6 BoundVar, DebruijnIndex, Mutability, TyKind,
7 fold::{FallibleTypeFolder, TypeFoldable},
8};
95use either::Either;
106use hir_def::{
117 DefWithBodyId, FieldId, HasModule, TupleFieldId, TupleId, VariantId,
......@@ -20,39 +16,37 @@ use hir_def::{
2016};
2117use hir_expand::name::Name;
2218use intern::sym;
19use rustc_ast_ir::Mutability;
2320use rustc_hash::{FxHashMap, FxHashSet};
21use rustc_type_ir::inherent::{IntoKind, SliceLike, Ty as _};
2422use smallvec::{SmallVec, smallvec};
2523use stdx::{format_to, never};
2624use syntax::utils::is_raw_identifier;
2725
28use crate::db::InternedClosureId;
29use crate::infer::InferenceContext;
3026use crate::{
31 Adjust, Adjustment, Binders, BindingMode, ClosureId, Interner, Substitution, Ty, TyExt,
32 db::{HirDatabase, InternedClosure},
33 error_lifetime, from_placeholder_idx,
34 generics::Generics,
35 make_binders,
27 Adjust, Adjustment, BindingMode,
28 db::{HirDatabase, InternedClosure, InternedClosureId},
29 infer::InferenceContext,
3630 mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
31 next_solver::{DbInterner, EarlyBinder, GenericArgs, Ty, TyKind},
3732 traits::FnTrait,
38 utils,
3933};
4034
4135// The below functions handle capture and closure kind (Fn, FnMut, ..)
4236
4337#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44pub(crate) struct HirPlace {
38pub(crate) struct HirPlace<'db> {
4539 pub(crate) local: BindingId,
46 pub(crate) projections: Vec<ProjectionElem<Infallible, Ty>>,
40 pub(crate) projections: Vec<ProjectionElem<Infallible, Ty<'db>>>,
4741}
4842
49impl HirPlace {
50 fn ty(&self, ctx: &mut InferenceContext<'_>) -> Ty {
51 let mut ty = ctx.table.resolve_completely(ctx.result[self.local].clone());
43impl<'db> HirPlace<'db> {
44 fn ty(&self, ctx: &mut InferenceContext<'_, 'db>) -> Ty<'db> {
45 let mut ty = ctx.table.resolve_completely(ctx.result[self.local]);
5246 for p in &self.projections {
5347 ty = p.projected_ty(
48 &ctx.table.infer_ctxt,
5449 ty,
55 ctx.db,
5650 |_, _, _| {
5751 unreachable!("Closure field only happens in MIR");
5852 },
......@@ -86,8 +80,8 @@ pub enum CaptureKind {
8680}
8781
8882#[derive(Debug, Clone, PartialEq, Eq)]
89pub struct CapturedItem {
90 pub(crate) place: HirPlace,
83pub struct CapturedItem<'db> {
84 pub(crate) place: HirPlace<'db>,
9185 pub(crate) kind: CaptureKind,
9286 /// The inner vec is the stacks; the outer vec is for each capture reference.
9387 ///
......@@ -96,10 +90,10 @@ pub struct CapturedItem {
9690 /// copy all captures of the inner closure to the outer closure, and then we may
9791 /// truncate them, and we want the correct span to be reported.
9892 span_stacks: SmallVec<[SmallVec<[MirSpan; 3]>; 3]>,
99 pub(crate) ty: Binders<Ty>,
93 pub(crate) ty: EarlyBinder<'db, Ty<'db>>,
10094}
10195
102impl CapturedItem {
96impl<'db> CapturedItem<'db> {
10397 pub fn local(&self) -> BindingId {
10498 self.place.local
10599 }
......@@ -109,8 +103,9 @@ impl CapturedItem {
109103 self.place.projections.iter().any(|it| !matches!(it, ProjectionElem::Deref))
110104 }
111105
112 pub fn ty(&self, db: &dyn HirDatabase, subst: &Substitution) -> Ty {
113 self.ty.clone().substitute(Interner, &utils::ClosureSubst(subst).parent_subst(db))
106 pub fn ty(&self, db: &'db dyn HirDatabase, subst: GenericArgs<'db>) -> Ty<'db> {
107 let interner = DbInterner::new_with(db, None, None);
108 self.ty.instantiate(interner, subst.split_closure_args_untupled().parent_args)
114109 }
115110
116111 pub fn kind(&self) -> CaptureKind {
......@@ -279,15 +274,15 @@ impl CapturedItem {
279274}
280275
281276#[derive(Debug, Clone, PartialEq, Eq)]
282pub(crate) struct CapturedItemWithoutTy {
283 pub(crate) place: HirPlace,
277pub(crate) struct CapturedItemWithoutTy<'db> {
278 pub(crate) place: HirPlace<'db>,
284279 pub(crate) kind: CaptureKind,
285280 /// The inner vec is the stacks; the outer vec is for each capture reference.
286281 pub(crate) span_stacks: SmallVec<[SmallVec<[MirSpan; 3]>; 3]>,
287282}
288283
289impl CapturedItemWithoutTy {
290 fn with_ty(self, ctx: &mut InferenceContext<'_>) -> CapturedItem {
284impl<'db> CapturedItemWithoutTy<'db> {
285 fn with_ty(self, ctx: &mut InferenceContext<'_, 'db>) -> CapturedItem<'db> {
291286 let ty = self.place.ty(ctx);
292287 let ty = match &self.kind {
293288 CaptureKind::ByValue => ty,
......@@ -296,66 +291,20 @@ impl CapturedItemWithoutTy {
296291 BorrowKind::Mut { .. } => Mutability::Mut,
297292 _ => Mutability::Not,
298293 };
299 TyKind::Ref(m, error_lifetime(), ty).intern(Interner)
294 Ty::new_ref(ctx.interner(), ctx.types.re_error, ty, m)
300295 }
301296 };
302 return CapturedItem {
297 CapturedItem {
303298 place: self.place,
304299 kind: self.kind,
305300 span_stacks: self.span_stacks,
306 ty: replace_placeholder_with_binder(ctx, ty),
307 };
308
309 fn replace_placeholder_with_binder(ctx: &mut InferenceContext<'_>, ty: Ty) -> Binders<Ty> {
310 struct Filler<'a> {
311 db: &'a dyn HirDatabase,
312 generics: &'a Generics,
313 }
314 impl FallibleTypeFolder<Interner> for Filler<'_> {
315 type Error = ();
316
317 fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<Interner, Error = Self::Error> {
318 self
319 }
320
321 fn interner(&self) -> Interner {
322 Interner
323 }
324
325 fn try_fold_free_placeholder_const(
326 &mut self,
327 ty: chalk_ir::Ty<Interner>,
328 idx: chalk_ir::PlaceholderIndex,
329 outer_binder: DebruijnIndex,
330 ) -> Result<chalk_ir::Const<Interner>, Self::Error> {
331 let x = from_placeholder_idx(self.db, idx).0;
332 let Some(idx) = self.generics.type_or_const_param_idx(x) else {
333 return Err(());
334 };
335 Ok(BoundVar::new(outer_binder, idx).to_const(Interner, ty))
336 }
337
338 fn try_fold_free_placeholder_ty(
339 &mut self,
340 idx: chalk_ir::PlaceholderIndex,
341 outer_binder: DebruijnIndex,
342 ) -> std::result::Result<Ty, Self::Error> {
343 let x = from_placeholder_idx(self.db, idx).0;
344 let Some(idx) = self.generics.type_or_const_param_idx(x) else {
345 return Err(());
346 };
347 Ok(BoundVar::new(outer_binder, idx).to_ty(Interner))
348 }
349 }
350 let filler = &mut Filler { db: ctx.db, generics: ctx.generics() };
351 let result = ty.clone().try_fold_with(filler, DebruijnIndex::INNERMOST).unwrap_or(ty);
352 make_binders(ctx.db, filler.generics, result)
301 ty: EarlyBinder::bind(ty),
353302 }
354303 }
355304}
356305
357impl InferenceContext<'_> {
358 fn place_of_expr(&mut self, tgt_expr: ExprId) -> Option<HirPlace> {
306impl<'db> InferenceContext<'_, 'db> {
307 fn place_of_expr(&mut self, tgt_expr: ExprId) -> Option<HirPlace<'db>> {
359308 let r = self.place_of_expr_without_adjust(tgt_expr)?;
360309 let adjustments =
361310 self.result.expr_adjustments.get(&tgt_expr).map(|it| &**it).unwrap_or_default();
......@@ -363,7 +312,7 @@ impl InferenceContext<'_> {
363312 }
364313
365314 /// Pushes the span into `current_capture_span_stack`, *without clearing it first*.
366 fn path_place(&mut self, path: &Path, id: ExprOrPatId) -> Option<HirPlace> {
315 fn path_place(&mut self, path: &Path, id: ExprOrPatId) -> Option<HirPlace<'db>> {
367316 if path.type_anchor().is_some() {
368317 return None;
369318 }
......@@ -384,7 +333,7 @@ impl InferenceContext<'_> {
384333 }
385334
386335 /// Changes `current_capture_span_stack` to contain the stack of spans for this expr.
387 fn place_of_expr_without_adjust(&mut self, tgt_expr: ExprId) -> Option<HirPlace> {
336 fn place_of_expr_without_adjust(&mut self, tgt_expr: ExprId) -> Option<HirPlace<'db>> {
388337 self.current_capture_span_stack.clear();
389338 match &self.body[tgt_expr] {
390339 Expr::Path(p) => {
......@@ -403,8 +352,8 @@ impl InferenceContext<'_> {
403352 }
404353 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
405354 if matches!(
406 self.expr_ty_after_adjustments(*expr).kind(Interner),
407 TyKind::Ref(..) | TyKind::Raw(..)
355 self.expr_ty_after_adjustments(*expr).kind(),
356 TyKind::Ref(..) | TyKind::RawPtr(..)
408357 ) {
409358 let mut place = self.place_of_expr(*expr)?;
410359 self.current_capture_span_stack.push(MirSpan::ExprId(tgt_expr));
......@@ -417,7 +366,7 @@ impl InferenceContext<'_> {
417366 None
418367 }
419368
420 fn push_capture(&mut self, place: HirPlace, kind: CaptureKind) {
369 fn push_capture(&mut self, place: HirPlace<'db>, kind: CaptureKind) {
421370 self.current_captures.push(CapturedItemWithoutTy {
422371 place,
423372 kind,
......@@ -425,7 +374,11 @@ impl InferenceContext<'_> {
425374 });
426375 }
427376
428 fn truncate_capture_spans(&self, capture: &mut CapturedItemWithoutTy, mut truncate_to: usize) {
377 fn truncate_capture_spans(
378 &self,
379 capture: &mut CapturedItemWithoutTy<'db>,
380 mut truncate_to: usize,
381 ) {
429382 // The first span is the identifier, and it must always remain.
430383 truncate_to += 1;
431384 for span_stack in &mut capture.span_stacks {
......@@ -450,14 +403,14 @@ impl InferenceContext<'_> {
450403 }
451404 }
452405
453 fn ref_expr(&mut self, expr: ExprId, place: Option<HirPlace>) {
406 fn ref_expr(&mut self, expr: ExprId, place: Option<HirPlace<'db>>) {
454407 if let Some(place) = place {
455408 self.add_capture(place, CaptureKind::ByRef(BorrowKind::Shared));
456409 }
457410 self.walk_expr(expr);
458411 }
459412
460 fn add_capture(&mut self, place: HirPlace, kind: CaptureKind) {
413 fn add_capture(&mut self, place: HirPlace<'db>, kind: CaptureKind) {
461414 if self.is_upvar(&place) {
462415 self.push_capture(place, kind);
463416 }
......@@ -473,7 +426,7 @@ impl InferenceContext<'_> {
473426 }
474427 }
475428
476 fn mutate_expr(&mut self, expr: ExprId, place: Option<HirPlace>) {
429 fn mutate_expr(&mut self, expr: ExprId, place: Option<HirPlace<'db>>) {
477430 if let Some(place) = place {
478431 self.add_capture(
479432 place,
......@@ -490,7 +443,7 @@ impl InferenceContext<'_> {
490443 self.walk_expr(expr);
491444 }
492445
493 fn consume_place(&mut self, place: HirPlace) {
446 fn consume_place(&mut self, place: HirPlace<'db>) {
494447 if self.is_upvar(&place) {
495448 let ty = place.ty(self);
496449 let kind = if self.is_ty_copy(ty) {
......@@ -502,7 +455,7 @@ impl InferenceContext<'_> {
502455 }
503456 }
504457
505 fn walk_expr_with_adjust(&mut self, tgt_expr: ExprId, adjustment: &[Adjustment]) {
458 fn walk_expr_with_adjust(&mut self, tgt_expr: ExprId, adjustment: &[Adjustment<'db>]) {
506459 if let Some((last, rest)) = adjustment.split_last() {
507460 match &last.kind {
508461 Adjust::NeverToAny | Adjust::Deref(None) | Adjust::Pointer(_) => {
......@@ -523,7 +476,12 @@ impl InferenceContext<'_> {
523476 }
524477 }
525478
526 fn ref_capture_with_adjusts(&mut self, m: Mutability, tgt_expr: ExprId, rest: &[Adjustment]) {
479 fn ref_capture_with_adjusts(
480 &mut self,
481 m: Mutability,
482 tgt_expr: ExprId,
483 rest: &[Adjustment<'db>],
484 ) {
527485 let capture_kind = match m {
528486 Mutability::Mut => CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::Default }),
529487 Mutability::Not => CaptureKind::ByRef(BorrowKind::Shared),
......@@ -652,8 +610,8 @@ impl InferenceContext<'_> {
652610 Expr::Field { expr, name: _ } => self.select_from_expr(*expr),
653611 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
654612 if matches!(
655 self.expr_ty_after_adjustments(*expr).kind(Interner),
656 TyKind::Ref(..) | TyKind::Raw(..)
613 self.expr_ty_after_adjustments(*expr).kind(),
614 TyKind::Ref(..) | TyKind::RawPtr(..)
657615 ) {
658616 self.select_from_expr(*expr);
659617 } else if let Some((f, _)) = self.result.method_resolution(tgt_expr) {
......@@ -728,12 +686,12 @@ impl InferenceContext<'_> {
728686 }
729687 Expr::Closure { .. } => {
730688 let ty = self.expr_ty(tgt_expr);
731 let TyKind::Closure(id, _) = ty.kind(Interner) else {
689 let TyKind::Closure(id, _) = ty.kind() else {
732690 never!("closure type is always closure");
733691 return;
734692 };
735693 let (captures, _) =
736 self.result.closure_info.get(id).expect(
694 self.result.closure_info.get(&id.0).expect(
737695 "We sort closures, so we should always have data for inner closures",
738696 );
739697 let mut cc = mem::take(&mut self.current_captures);
......@@ -830,7 +788,7 @@ impl InferenceContext<'_> {
830788 }
831789 Pat::Bind { id, .. } => match self.result.binding_modes[p] {
832790 crate::BindingMode::Move => {
833 if self.is_ty_copy(self.result.type_of_binding[*id].clone()) {
791 if self.is_ty_copy(self.result.type_of_binding[*id]) {
834792 update_result(CaptureKind::ByRef(BorrowKind::Shared));
835793 } else {
836794 update_result(CaptureKind::ByValue);
......@@ -848,21 +806,21 @@ impl InferenceContext<'_> {
848806 self.body.walk_pats_shallow(p, |p| self.walk_pat_inner(p, update_result, for_mut));
849807 }
850808
851 fn expr_ty(&self, expr: ExprId) -> Ty {
852 self.result[expr].clone()
809 fn expr_ty(&self, expr: ExprId) -> Ty<'db> {
810 self.result[expr]
853811 }
854812
855 fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty {
813 fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db> {
856814 let mut ty = None;
857815 if let Some(it) = self.result.expr_adjustments.get(&e)
858816 && let Some(it) = it.last()
859817 {
860 ty = Some(it.target.clone());
818 ty = Some(it.target);
861819 }
862820 ty.unwrap_or_else(|| self.expr_ty(e))
863821 }
864822
865 fn is_upvar(&self, place: &HirPlace) -> bool {
823 fn is_upvar(&self, place: &HirPlace<'db>) -> bool {
866824 if let Some(c) = self.current_closure {
867825 let InternedClosure(_, root) = self.db.lookup_intern_closure(c);
868826 return self.body.is_binding_upvar(place.local, root);
......@@ -870,14 +828,20 @@ impl InferenceContext<'_> {
870828 false
871829 }
872830
873 fn is_ty_copy(&mut self, ty: Ty) -> bool {
874 if let TyKind::Closure(id, _) = ty.kind(Interner) {
831 fn is_ty_copy(&mut self, ty: Ty<'db>) -> bool {
832 if let TyKind::Closure(id, _) = ty.kind() {
875833 // FIXME: We handle closure as a special case, since chalk consider every closure as copy. We
876834 // should probably let chalk know which closures are copy, but I don't know how doing it
877835 // without creating query cycles.
878 return self.result.closure_info.get(id).map(|it| it.1 == FnTrait::Fn).unwrap_or(true);
836 return self
837 .result
838 .closure_info
839 .get(&id.0)
840 .map(|it| it.1 == FnTrait::Fn)
841 .unwrap_or(true);
879842 }
880 self.table.resolve_completely(ty).is_copy(self.db, self.owner)
843 let ty = self.table.resolve_completely(ty);
844 self.table.type_is_copy_modulo_regions(ty)
881845 }
882846
883847 fn select_from_expr(&mut self, expr: ExprId) {
......@@ -888,8 +852,8 @@ impl InferenceContext<'_> {
888852 // FIXME: Borrow checker problems without this.
889853 let mut current_captures = std::mem::take(&mut self.current_captures);
890854 for capture in &mut current_captures {
891 let mut ty = self.table.resolve_completely(self.result[capture.place.local].clone());
892 if ty.as_raw_ptr().is_some() || ty.is_union() {
855 let mut ty = self.table.resolve_completely(self.result[capture.place.local]);
856 if ty.is_raw_ptr() || ty.is_union() {
893857 capture.kind = CaptureKind::ByRef(BorrowKind::Shared);
894858 self.truncate_capture_spans(capture, 0);
895859 capture.place.projections.truncate(0);
......@@ -897,14 +861,14 @@ impl InferenceContext<'_> {
897861 }
898862 for (i, p) in capture.place.projections.iter().enumerate() {
899863 ty = p.projected_ty(
864 &self.table.infer_ctxt,
900865 ty,
901 self.db,
902866 |_, _, _| {
903867 unreachable!("Closure field only happens in MIR");
904868 },
905869 self.owner.module(self.db).krate(),
906870 );
907 if ty.as_raw_ptr().is_some() || ty.is_union() {
871 if ty.is_raw_ptr() || ty.is_union() {
908872 capture.kind = CaptureKind::ByRef(BorrowKind::Shared);
909873 self.truncate_capture_spans(capture, i + 1);
910874 capture.place.projections.truncate(i + 1);
......@@ -932,7 +896,7 @@ impl InferenceContext<'_> {
932896
933897 fn minimize_captures(&mut self) {
934898 self.current_captures.sort_unstable_by_key(|it| it.place.projections.len());
935 let mut hash_map = FxHashMap::<HirPlace, usize>::default();
899 let mut hash_map = FxHashMap::<HirPlace<'db>, usize>::default();
936900 let result = mem::take(&mut self.current_captures);
937901 for mut item in result {
938902 let mut lookup_place = HirPlace { local: item.place.local, projections: vec![] };
......@@ -967,7 +931,7 @@ impl InferenceContext<'_> {
967931 }
968932 }
969933
970 fn consume_with_pat(&mut self, mut place: HirPlace, tgt_pat: PatId) {
934 fn consume_with_pat(&mut self, mut place: HirPlace<'db>, tgt_pat: PatId) {
971935 let adjustments_count =
972936 self.result.pat_adjustments.get(&tgt_pat).map(|it| it.len()).unwrap_or_default();
973937 place.projections.extend((0..adjustments_count).map(|_| ProjectionElem::Deref));
......@@ -978,8 +942,8 @@ impl InferenceContext<'_> {
978942 Pat::Missing | Pat::Wild => (),
979943 Pat::Tuple { args, ellipsis } => {
980944 let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
981 let field_count = match self.result[tgt_pat].kind(Interner) {
982 TyKind::Tuple(_, s) => s.len(Interner),
945 let field_count = match self.result[tgt_pat].kind() {
946 TyKind::Tuple(s) => s.len(),
983947 _ => break 'reset_span_stack,
984948 };
985949 let fields = 0..field_count;
......@@ -1125,9 +1089,9 @@ impl InferenceContext<'_> {
11251089 r
11261090 }
11271091
1128 fn analyze_closure(&mut self, closure: ClosureId) -> FnTrait {
1129 let InternedClosure(_, root) = self.db.lookup_intern_closure(closure.into());
1130 self.current_closure = Some(closure.into());
1092 fn analyze_closure(&mut self, closure: InternedClosureId) -> FnTrait {
1093 let InternedClosure(_, root) = self.db.lookup_intern_closure(closure);
1094 self.current_closure = Some(closure);
11311095 let Expr::Closure { body, capture_by, .. } = &self.body[root] else {
11321096 unreachable!("Closure expression id is always closure");
11331097 };
......@@ -1193,9 +1157,9 @@ impl InferenceContext<'_> {
11931157 self.result.expr_adjustments.remove(&callee).unwrap_or_default().into_vec();
11941158 self.write_fn_trait_method_resolution(
11951159 kind,
1196 &derefed_callee,
1160 derefed_callee,
11971161 &mut adjustments,
1198 &callee_ty,
1162 callee_ty,
11991163 &params,
12001164 expr,
12011165 );
......@@ -1213,27 +1177,26 @@ impl InferenceContext<'_> {
12131177 ///
12141178 /// These dependencies are collected in the main inference. We do a topological sort in this function. It
12151179 /// will consume the `deferred_closures` field and return its content in a sorted vector.
1216 fn sort_closures(&mut self) -> Vec<(ClosureId, Vec<(Ty, Ty, Vec<Ty>, ExprId)>)> {
1180 fn sort_closures(
1181 &mut self,
1182 ) -> Vec<(InternedClosureId, Vec<(Ty<'db>, Ty<'db>, Vec<Ty<'db>>, ExprId)>)> {
12171183 let mut deferred_closures = mem::take(&mut self.deferred_closures);
1218 let mut dependents_count: FxHashMap<ClosureId, usize> =
1219 deferred_closures.keys().map(|it| ((*it).into(), 0)).collect();
1184 let mut dependents_count: FxHashMap<InternedClosureId, usize> =
1185 deferred_closures.keys().map(|it| (*it, 0)).collect();
12201186 for deps in self.closure_dependencies.values() {
12211187 for dep in deps {
1222 *dependents_count.entry((*dep).into()).or_default() += 1;
1188 *dependents_count.entry(*dep).or_default() += 1;
12231189 }
12241190 }
1225 let mut queue: Vec<_> = deferred_closures
1226 .keys()
1227 .copied()
1228 .filter(|&it| dependents_count[&it.into()] == 0)
1229 .collect();
1191 let mut queue: Vec<_> =
1192 deferred_closures.keys().copied().filter(|&it| dependents_count[&it] == 0).collect();
12301193 let mut result = vec![];
12311194 while let Some(it) = queue.pop() {
12321195 if let Some(d) = deferred_closures.remove(&it) {
1233 result.push((it.into(), d));
1196 result.push((it, d));
12341197 }
12351198 for &dep in self.closure_dependencies.get(&it).into_iter().flat_map(|it| it.iter()) {
1236 let cnt = dependents_count.get_mut(&dep.into()).unwrap();
1199 let cnt = dependents_count.get_mut(&dep).unwrap();
12371200 *cnt -= 1;
12381201 if *cnt == 0 {
12391202 queue.push(dep);
......@@ -1279,11 +1242,11 @@ impl InferenceContext<'_> {
12791242}
12801243
12811244/// Call this only when the last span in the stack isn't a split.
1282fn apply_adjusts_to_place(
1245fn apply_adjusts_to_place<'db>(
12831246 current_capture_span_stack: &mut Vec<MirSpan>,
1284 mut r: HirPlace,
1285 adjustments: &[Adjustment],
1286) -> Option<HirPlace> {
1247 mut r: HirPlace<'db>,
1248 adjustments: &[Adjustment<'db>],
1249) -> Option<HirPlace<'db>> {
12871250 let span = *current_capture_span_stack.last().expect("empty capture span stack");
12881251 for adj in adjustments {
12891252 match &adj.kind {
src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs+115-130
......@@ -35,7 +35,6 @@
3535//! // and are then unable to coerce `&7i32` to `&mut i32`.
3636//! ```
3737
38use chalk_ir::cast::Cast;
3938use hir_def::{
4039 CallableDefId,
4140 hir::{ExprId, ExprOrPatId},
......@@ -45,29 +44,30 @@ use hir_def::{
4544use intern::sym;
4645use rustc_ast_ir::Mutability;
4746use rustc_type_ir::{
48 TypeAndMut,
47 BoundVar, TypeAndMut,
4948 error::TypeError,
50 inherent::{IntoKind, Safety, Ty as _},
49 inherent::{Const as _, GenericArg as _, IntoKind, Safety, SliceLike, Ty as _},
5150};
5251use smallvec::{SmallVec, smallvec};
5352use tracing::{debug, instrument};
5453use triomphe::Arc;
5554
5655use crate::{
57 Adjust, Adjustment, AutoBorrow, Interner, PointerCast, TargetFeatures, TraitEnvironment,
56 Adjust, Adjustment, AutoBorrow, PointerCast, TargetFeatures, TraitEnvironment,
5857 autoderef::Autoderef,
5958 db::{HirDatabase, InternedClosureId},
6059 infer::{AllowTwoPhase, InferenceContext, TypeMismatch, unify::InferenceTable},
6160 next_solver::{
62 Binder, CallableIdWrapper, ClauseKind, CoercePredicate, DbInterner, ErrorGuaranteed,
63 GenericArgs, PolyFnSig, PredicateKind, Region, SolverDefId, TraitRef, Ty, TyKind,
61 Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, CallableIdWrapper,
62 Canonical, ClauseKind, CoercePredicate, Const, ConstKind, DbInterner, ErrorGuaranteed,
63 GenericArgs, PolyFnSig, PredicateKind, Region, RegionKind, SolverDefId, TraitRef, Ty,
64 TyKind,
6465 infer::{
6566 DefineOpaqueTypes, InferCtxt, InferOk, InferResult,
6667 relate::RelateResult,
6768 select::{ImplSource, SelectionError},
6869 traits::{Obligation, ObligationCause, PredicateObligation, PredicateObligations},
6970 },
70 mapping::{ChalkToNextSolver, NextSolverToChalk},
7171 obligation_ctxt::ObligationCtxt,
7272 },
7373 utils::TargetFeatureIsSafeInTarget,
......@@ -93,7 +93,7 @@ struct Coerce<'a, 'b, 'db> {
9393 cause: ObligationCause,
9494}
9595
96type CoerceResult<'db> = InferResult<'db, (Vec<Adjustment>, Ty<'db>)>;
96type CoerceResult<'db> = InferResult<'db, (Vec<Adjustment<'db>>, Ty<'db>)>;
9797
9898/// Coercing a mutable reference to an immutable works, while
9999/// coercing `&T` to `&mut T` should be forbidden.
......@@ -103,7 +103,7 @@ fn coerce_mutbls<'db>(from_mutbl: Mutability, to_mutbl: Mutability) -> RelateRes
103103
104104/// This always returns `Ok(...)`.
105105fn success<'db>(
106 adj: Vec<Adjustment>,
106 adj: Vec<Adjustment<'db>>,
107107 target: Ty<'db>,
108108 obligations: PredicateObligations<'db>,
109109) -> CoerceResult<'db> {
......@@ -118,7 +118,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
118118
119119 #[inline]
120120 fn interner(&self) -> DbInterner<'db> {
121 self.table.interner
121 self.table.interner()
122122 }
123123
124124 #[inline]
......@@ -182,17 +182,14 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
182182 &mut self,
183183 a: Ty<'db>,
184184 b: Ty<'db>,
185 adjustments: impl IntoIterator<Item = Adjustment>,
186 final_adjustment: Adjust,
185 adjustments: impl IntoIterator<Item = Adjustment<'db>>,
186 final_adjustment: Adjust<'db>,
187187 ) -> CoerceResult<'db> {
188188 self.unify_raw(a, b).and_then(|InferOk { value: ty, obligations }| {
189189 success(
190190 adjustments
191191 .into_iter()
192 .chain(std::iter::once(Adjustment {
193 target: ty.to_chalk(self.interner()),
194 kind: final_adjustment,
195 }))
192 .chain(std::iter::once(Adjustment { target: ty, kind: final_adjustment }))
196193 .collect(),
197194 ty,
198195 obligations,
......@@ -216,10 +213,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
216213
217214 if self.coerce_never {
218215 return success(
219 vec![Adjustment {
220 kind: Adjust::NeverToAny,
221 target: b.to_chalk(self.interner()),
222 }],
216 vec![Adjustment { kind: Adjust::NeverToAny, target: b }],
223217 b,
224218 PredicateObligations::new(),
225219 );
......@@ -241,10 +235,9 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
241235 && let TyKind::Alias(rustc_type_ir::Opaque, opaque_ty) = b.kind()
242236 && let SolverDefId::InternedOpaqueTyId(opaque_ty_id) = opaque_ty.def_id
243237 && !matches!(a.kind(), TyKind::Infer(..) | TyKind::Alias(rustc_type_ir::Opaque, _))
244 && let Some(ty) = tait_table.get(&opaque_ty_id.into())
238 && let Some(ty) = tait_table.get(&opaque_ty_id)
245239 {
246 b = ty.to_nextsolver(self.interner());
247 b = self.table.shallow_resolve(b);
240 b = self.table.shallow_resolve(*ty);
248241 }
249242 let b = b;
250243
......@@ -474,7 +467,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
474467 r_borrow_var.unwrap()
475468 };
476469 let derefd_ty_a = Ty::new_ref(
477 autoderef.table.interner,
470 autoderef.table.interner(),
478471 r,
479472 referent_ty,
480473 mutbl_b, // [1] above
......@@ -547,11 +540,8 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
547540 panic!("expected a ref type, got {:?}", ty);
548541 };
549542 adjustments.push(Adjustment {
550 kind: Adjust::Borrow(AutoBorrow::Ref(
551 region.to_chalk(self.interner()),
552 mutbl_b.to_chalk(self.interner()),
553 )),
554 target: ty.to_chalk(self.interner()),
543 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl_b)),
544 target: ty,
555545 });
556546
557547 debug!("coerce_borrowed_pointer: succeeded ty={:?} adjustments={:?}", ty, adjustments);
......@@ -655,20 +645,13 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
655645 // implementation. If it happens that this coercion is a function argument,
656646 // the reborrow in coerce_borrowed_ptr will pick it up.
657647 // let mutbl = AutoBorrowMutability::new(mutbl_b, AllowTwoPhase::No);
658 let mutbl = mutbl_b.to_chalk(self.interner());
648 let mutbl = mutbl_b;
659649
660650 Some((
651 Adjustment { kind: Adjust::Deref(None), target: ty_a },
661652 Adjustment {
662 kind: Adjust::Deref(None),
663 target: ty_a.to_chalk(self.interner()),
664 },
665 Adjustment {
666 kind: Adjust::Borrow(AutoBorrow::Ref(
667 r_borrow.to_chalk(self.interner()),
668 mutbl,
669 )),
670 target: Ty::new_ref(self.interner(), r_borrow, ty_a, mutbl_b)
671 .to_chalk(self.interner()),
653 kind: Adjust::Borrow(AutoBorrow::Ref(r_borrow, mutbl)),
654 target: Ty::new_ref(self.interner(), r_borrow, ty_a, mutbl_b),
672655 },
673656 ))
674657 }
......@@ -676,20 +659,16 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
676659 coerce_mutbls(mt_a, mt_b)?;
677660
678661 Some((
662 Adjustment { kind: Adjust::Deref(None), target: ty_a },
679663 Adjustment {
680 kind: Adjust::Deref(None),
681 target: ty_a.to_chalk(self.interner()),
682 },
683 Adjustment {
684 kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b.to_chalk(self.interner()))),
685 target: Ty::new_ptr(self.interner(), ty_a, mt_b).to_chalk(self.interner()),
664 kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b)),
665 target: Ty::new_ptr(self.interner(), ty_a, mt_b),
686666 },
687667 ))
688668 }
689669 _ => None,
690670 };
691 let coerce_source =
692 reborrow.as_ref().map_or(source, |(_, r)| r.target.to_nextsolver(self.interner()));
671 let coerce_source = reborrow.as_ref().map_or(source, |(_, r)| r.target);
693672
694673 // Setup either a subtyping or a LUB relationship between
695674 // the `CoerceUnsized` target type and the expected type.
......@@ -834,7 +813,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
834813 &mut self,
835814 fn_ty_a: PolyFnSig<'db>,
836815 b: Ty<'db>,
837 adjustment: Option<Adjust>,
816 adjustment: Option<Adjust<'db>>,
838817 ) -> CoerceResult<'db> {
839818 debug_assert!(self.table.shallow_resolve(b) == b);
840819
......@@ -849,7 +828,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
849828 b,
850829 adjustment.map(|kind| Adjustment {
851830 kind,
852 target: Ty::new_fn_ptr(this.interner(), fn_ty_a).to_chalk(this.interner()),
831 target: Ty::new_fn_ptr(this.interner(), fn_ty_a),
853832 }),
854833 Adjust::Pointer(PointerCast::UnsafeFnPointer),
855834 )
......@@ -961,9 +940,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
961940 pointer_ty,
962941 b,
963942 [],
964 Adjust::Pointer(PointerCast::ClosureFnPointer(
965 safety.to_chalk(self.interner()),
966 )),
943 Adjust::Pointer(PointerCast::ClosureFnPointer(safety)),
967944 )
968945 }
969946 _ => self.unify(a, b),
......@@ -991,11 +968,8 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
991968 self.unify_and(
992969 a_raw,
993970 b,
994 [Adjustment {
995 kind: Adjust::Deref(None),
996 target: mt_a.ty.to_chalk(self.interner()),
997 }],
998 Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b.to_chalk(self.interner()))),
971 [Adjustment { kind: Adjust::Deref(None), target: mt_a.ty }],
972 Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b)),
999973 )
1000974 } else if mt_a.mutbl != mutbl_b {
1001975 self.unify_and(a_raw, b, [], Adjust::Pointer(PointerCast::MutToConstPointer))
......@@ -1011,7 +985,7 @@ pub(crate) enum CoerceNever {
1011985 Yes,
1012986}
1013987
1014impl<'db> InferenceContext<'db> {
988impl<'db> InferenceContext<'_, 'db> {
1015989 /// Attempt to coerce an expression to a type, and return the
1016990 /// adjusted type of the expression, if successful.
1017991 /// Adjustments are only recorded if the coercion succeeded.
......@@ -1128,13 +1102,13 @@ impl<'db> InferenceContext<'db> {
11281102 // We have a LUB of prev_ty and new_ty, just return it.
11291103 Ok(ok) => return Ok(self.table.register_infer_ok(ok)),
11301104 Err(_) => (
1131 Some(prev_ty.fn_sig(self.table.interner)),
1132 Some(new_ty.fn_sig(self.table.interner)),
1105 Some(prev_ty.fn_sig(self.table.interner())),
1106 Some(new_ty.fn_sig(self.table.interner())),
11331107 ),
11341108 }
11351109 }
11361110 (TyKind::Closure(_, args), TyKind::FnDef(..)) => {
1137 let b_sig = new_ty.fn_sig(self.table.interner);
1111 let b_sig = new_ty.fn_sig(self.table.interner());
11381112 let a_sig = args.closure_sig_untupled().map_bound(|mut sig| {
11391113 sig.safety = b_sig.safety();
11401114 sig
......@@ -1142,7 +1116,7 @@ impl<'db> InferenceContext<'db> {
11421116 (Some(a_sig), Some(b_sig))
11431117 }
11441118 (TyKind::FnDef(..), TyKind::Closure(_, args)) => {
1145 let a_sig = prev_ty.fn_sig(self.table.interner);
1119 let a_sig = prev_ty.fn_sig(self.table.interner());
11461120 let b_sig = args.closure_sig_untupled().map_bound(|mut sig| {
11471121 sig.safety = a_sig.safety();
11481122 sig
......@@ -1166,36 +1140,30 @@ impl<'db> InferenceContext<'db> {
11661140 .map(|ok| self.table.register_infer_ok(ok))?;
11671141
11681142 // Reify both sides and return the reified fn pointer type.
1169 let fn_ptr = Ty::new_fn_ptr(self.table.interner, sig);
1143 let fn_ptr = Ty::new_fn_ptr(self.table.interner(), sig);
11701144 let prev_adjustment = match prev_ty.kind() {
1171 TyKind::Closure(..) => Adjust::Pointer(PointerCast::ClosureFnPointer(
1172 a_sig.safety().to_chalk(self.table.interner),
1173 )),
1145 TyKind::Closure(..) => {
1146 Adjust::Pointer(PointerCast::ClosureFnPointer(a_sig.safety()))
1147 }
11741148 TyKind::FnDef(..) => Adjust::Pointer(PointerCast::ReifyFnPointer),
11751149 _ => panic!("should not try to coerce a {prev_ty:?} to a fn pointer"),
11761150 };
11771151 let next_adjustment = match new_ty.kind() {
1178 TyKind::Closure(..) => Adjust::Pointer(PointerCast::ClosureFnPointer(
1179 b_sig.safety().to_chalk(self.table.interner),
1180 )),
1152 TyKind::Closure(..) => {
1153 Adjust::Pointer(PointerCast::ClosureFnPointer(b_sig.safety()))
1154 }
11811155 TyKind::FnDef(..) => Adjust::Pointer(PointerCast::ReifyFnPointer),
11821156 _ => panic!("should not try to coerce a {new_ty:?} to a fn pointer"),
11831157 };
11841158 for &expr in exprs {
11851159 self.write_expr_adj(
11861160 expr,
1187 Box::new([Adjustment {
1188 kind: prev_adjustment.clone(),
1189 target: fn_ptr.to_chalk(self.table.interner),
1190 }]),
1161 Box::new([Adjustment { kind: prev_adjustment.clone(), target: fn_ptr }]),
11911162 );
11921163 }
11931164 self.write_expr_adj(
11941165 new,
1195 Box::new([Adjustment {
1196 kind: next_adjustment,
1197 target: fn_ptr.to_chalk(self.table.interner),
1198 }]),
1166 Box::new([Adjustment { kind: next_adjustment, target: fn_ptr }]),
11991167 );
12001168 return Ok(fn_ptr);
12011169 }
......@@ -1382,7 +1350,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
13821350 /// if necessary.
13831351 pub(crate) fn coerce(
13841352 &mut self,
1385 icx: &mut InferenceContext<'db>,
1353 icx: &mut InferenceContext<'_, 'db>,
13861354 cause: &ObligationCause,
13871355 expression: ExprId,
13881356 expression_ty: Ty<'db>,
......@@ -1404,19 +1372,12 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
14041372 /// removing a `;`).
14051373 pub(crate) fn coerce_forced_unit(
14061374 &mut self,
1407 icx: &mut InferenceContext<'db>,
1375 icx: &mut InferenceContext<'_, 'db>,
14081376 expr: ExprId,
14091377 cause: &ObligationCause,
14101378 label_unit_as_expected: bool,
14111379 ) {
1412 self.coerce_inner(
1413 icx,
1414 cause,
1415 expr,
1416 icx.result.standard_types.unit.to_nextsolver(icx.table.interner),
1417 true,
1418 label_unit_as_expected,
1419 )
1380 self.coerce_inner(icx, cause, expr, icx.types.unit, true, label_unit_as_expected)
14201381 }
14211382
14221383 /// The inner coercion "engine". If `expression` is `None`, this
......@@ -1424,7 +1385,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
14241385 /// `Nil`.
14251386 pub(crate) fn coerce_inner(
14261387 &mut self,
1427 icx: &mut InferenceContext<'db>,
1388 icx: &mut InferenceContext<'_, 'db>,
14281389 cause: &ObligationCause,
14291390 expression: ExprId,
14301391 mut expression_ty: Ty<'db>,
......@@ -1533,20 +1494,14 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
15331494 // emit or provide suggestions on how to fix the initial error.
15341495 icx.set_tainted_by_errors();
15351496
1536 self.final_ty = Some(Ty::new_error(icx.table.interner, ErrorGuaranteed));
1497 self.final_ty = Some(icx.types.error);
15371498
15381499 icx.result.type_mismatches.insert(
15391500 expression.into(),
15401501 if label_expression_as_expected {
1541 TypeMismatch {
1542 expected: found.to_chalk(icx.table.interner),
1543 actual: expected.to_chalk(icx.table.interner),
1544 }
1502 TypeMismatch { expected: found, actual: expected }
15451503 } else {
1546 TypeMismatch {
1547 expected: expected.to_chalk(icx.table.interner),
1548 actual: found.to_chalk(icx.table.interner),
1549 }
1504 TypeMismatch { expected, actual: found }
15501505 },
15511506 );
15521507 }
......@@ -1555,14 +1510,14 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
15551510 self.pushed += 1;
15561511 }
15571512
1558 pub(crate) fn complete(self, icx: &mut InferenceContext<'db>) -> Ty<'db> {
1513 pub(crate) fn complete(self, icx: &mut InferenceContext<'_, 'db>) -> Ty<'db> {
15591514 if let Some(final_ty) = self.final_ty {
15601515 final_ty
15611516 } else {
15621517 // If we only had inputs that were of type `!` (or no
15631518 // inputs at all), then the final type is `!`.
15641519 assert_eq!(self.pushed, 0);
1565 icx.result.standard_types.never.to_nextsolver(icx.table.interner)
1520 icx.types.never
15661521 }
15671522 }
15681523}
......@@ -1570,7 +1525,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
15701525pub fn could_coerce<'db>(
15711526 db: &'db dyn HirDatabase,
15721527 env: Arc<TraitEnvironment<'db>>,
1573 tys: &crate::Canonical<(crate::Ty, crate::Ty)>,
1528 tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>,
15741529) -> bool {
15751530 coerce(db, env, tys).is_ok()
15761531}
......@@ -1578,12 +1533,11 @@ pub fn could_coerce<'db>(
15781533fn coerce<'db>(
15791534 db: &'db dyn HirDatabase,
15801535 env: Arc<TraitEnvironment<'db>>,
1581 tys: &crate::Canonical<(crate::Ty, crate::Ty)>,
1582) -> Result<(Vec<Adjustment>, crate::Ty), TypeError<DbInterner<'db>>> {
1536 tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>,
1537) -> Result<(Vec<Adjustment<'db>>, Ty<'db>), TypeError<DbInterner<'db>>> {
15831538 let mut table = InferenceTable::new(db, env);
1584 let vars = table.fresh_subst(tys.binders.as_slice(Interner));
1585 let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner);
1586 let ty2_with_vars = vars.apply(tys.value.1.clone(), Interner);
1539 let interner = table.interner();
1540 let ((ty1_with_vars, ty2_with_vars), vars) = table.infer_ctxt.instantiate_canonical(tys);
15871541
15881542 let cause = ObligationCause::new();
15891543 // FIXME: Target features.
......@@ -1597,36 +1551,67 @@ fn coerce<'db>(
15971551 use_lub: false,
15981552 target_features: &mut || (&target_features, TargetFeatureIsSafeInTarget::No),
15991553 };
1600 let InferOk { value: (adjustments, ty), obligations } = coerce.coerce(
1601 ty1_with_vars.to_nextsolver(coerce.table.interner),
1602 ty2_with_vars.to_nextsolver(coerce.table.interner),
1603 )?;
1554 let InferOk { value: (adjustments, ty), obligations } =
1555 coerce.coerce(ty1_with_vars, ty2_with_vars)?;
16041556 table.register_predicates(obligations);
16051557
16061558 // default any type vars that weren't unified back to their original bound vars
16071559 // (kind of hacky)
1608 let find_var = |iv| {
1609 vars.iter(Interner).position(|v| match v.interned() {
1610 chalk_ir::GenericArgData::Ty(ty) => ty.inference_var(Interner),
1611 chalk_ir::GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
1612 chalk_ir::GenericArgData::Const(c) => c.inference_var(Interner),
1613 } == Some(iv))
1560 let mut fallback_ty = |debruijn, infer| {
1561 let var = vars.var_values.iter().position(|arg| {
1562 arg.as_type().is_some_and(|ty| match ty.kind() {
1563 TyKind::Infer(it) => infer == it,
1564 _ => false,
1565 })
1566 });
1567 var.map_or_else(
1568 || Ty::new_error(interner, ErrorGuaranteed),
1569 |i| {
1570 Ty::new_bound(
1571 interner,
1572 debruijn,
1573 BoundTy { kind: BoundTyKind::Anon, var: BoundVar::from_usize(i) },
1574 )
1575 },
1576 )
1577 };
1578 let mut fallback_const = |debruijn, infer| {
1579 let var = vars.var_values.iter().position(|arg| {
1580 arg.as_const().is_some_and(|ty| match ty.kind() {
1581 ConstKind::Infer(it) => infer == it,
1582 _ => false,
1583 })
1584 });
1585 var.map_or_else(
1586 || Const::new_error(interner, ErrorGuaranteed),
1587 |i| Const::new_bound(interner, debruijn, BoundConst { var: BoundVar::from_usize(i) }),
1588 )
16141589 };
1615 let fallback = |iv, kind, binder| match kind {
1616 chalk_ir::VariableKind::Ty(_ty_kind) => find_var(iv).map_or_else(
1617 || chalk_ir::TyKind::Error.intern(Interner).cast(Interner),
1618 |i| crate::BoundVar::new(binder, i).to_ty(Interner).cast(Interner),
1619 ),
1620 chalk_ir::VariableKind::Lifetime => find_var(iv).map_or_else(
1621 || crate::LifetimeData::Error.intern(Interner).cast(Interner),
1622 |i| crate::BoundVar::new(binder, i).to_lifetime(Interner).cast(Interner),
1623 ),
1624 chalk_ir::VariableKind::Const(ty) => find_var(iv).map_or_else(
1625 || crate::unknown_const(ty.clone()).cast(Interner),
1626 |i| crate::BoundVar::new(binder, i).to_const(Interner, ty.clone()).cast(Interner),
1627 ),
1590 let mut fallback_region = |debruijn, infer| {
1591 let var = vars.var_values.iter().position(|arg| {
1592 arg.as_region().is_some_and(|ty| match ty.kind() {
1593 RegionKind::ReVar(it) => infer == it,
1594 _ => false,
1595 })
1596 });
1597 var.map_or_else(
1598 || Region::error(interner),
1599 |i| {
1600 Region::new_bound(
1601 interner,
1602 debruijn,
1603 BoundRegion { kind: BoundRegionKind::Anon, var: BoundVar::from_usize(i) },
1604 )
1605 },
1606 )
16281607 };
16291608 // FIXME also map the types in the adjustments
16301609 // FIXME: We don't fallback correctly since this is done on `InferenceContext` and we only have `InferenceTable`.
1631 Ok((adjustments, table.resolve_with_fallback(ty.to_chalk(table.interner), &fallback)))
1610 let ty = table.resolve_with_fallback(
1611 ty,
1612 &mut fallback_ty,
1613 &mut fallback_const,
1614 &mut fallback_region,
1615 );
1616 Ok((adjustments, ty))
16321617}
src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs+23-23
......@@ -12,11 +12,11 @@ use hir_def::expr_store::path::Path;
1212use hir_def::{hir::ExprOrPatId, resolver::Resolver};
1313use la_arena::{Idx, RawIdx};
1414
15use crate::lower::LifetimeElisionKind;
1615use crate::{
17 InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringContext, TyLoweringDiagnostic,
16 InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringDiagnostic,
1817 db::HirDatabase,
19 lower::path::{PathDiagnosticCallback, PathLoweringContext},
18 lower_nextsolver::path::{PathDiagnosticCallback, PathLoweringContext},
19 lower_nextsolver::{LifetimeElisionKind, TyLoweringContext},
2020};
2121
2222// Unfortunately, this struct needs to use interior mutability (but we encapsulate it)
......@@ -24,10 +24,10 @@ use crate::{
2424// to our resolver and so we cannot have mutable reference, but we really want to have
2525// ability to dispatch diagnostics during this work otherwise the code becomes a complete mess.
2626#[derive(Debug, Default, Clone)]
27pub(super) struct Diagnostics(RefCell<Vec<InferenceDiagnostic>>);
27pub(super) struct Diagnostics<'db>(RefCell<Vec<InferenceDiagnostic<'db>>>);
2828
29impl Diagnostics {
30 pub(super) fn push(&self, diagnostic: InferenceDiagnostic) {
29impl<'db> Diagnostics<'db> {
30 pub(super) fn push(&self, diagnostic: InferenceDiagnostic<'db>) {
3131 self.0.borrow_mut().push(diagnostic);
3232 }
3333
......@@ -41,32 +41,32 @@ impl Diagnostics {
4141 );
4242 }
4343
44 pub(super) fn finish(self) -> Vec<InferenceDiagnostic> {
44 pub(super) fn finish(self) -> Vec<InferenceDiagnostic<'db>> {
4545 self.0.into_inner()
4646 }
4747}
4848
49pub(crate) struct PathDiagnosticCallbackData<'a> {
49pub(crate) struct PathDiagnosticCallbackData<'a, 'db> {
5050 node: ExprOrPatId,
51 diagnostics: &'a Diagnostics,
51 diagnostics: &'a Diagnostics<'db>,
5252}
5353
54pub(super) struct InferenceTyLoweringContext<'a> {
55 ctx: TyLoweringContext<'a>,
56 diagnostics: &'a Diagnostics,
54pub(super) struct InferenceTyLoweringContext<'db, 'a> {
55 ctx: TyLoweringContext<'db, 'a>,
56 diagnostics: &'a Diagnostics<'db>,
5757 source: InferenceTyDiagnosticSource,
5858}
5959
60impl<'a> InferenceTyLoweringContext<'a> {
60impl<'db, 'a> InferenceTyLoweringContext<'db, 'a> {
6161 #[inline]
6262 pub(super) fn new(
63 db: &'a dyn HirDatabase,
64 resolver: &'a Resolver<'_>,
63 db: &'db dyn HirDatabase,
64 resolver: &'a Resolver<'db>,
6565 store: &'a ExpressionStore,
66 diagnostics: &'a Diagnostics,
66 diagnostics: &'a Diagnostics<'db>,
6767 source: InferenceTyDiagnosticSource,
6868 generic_def: GenericDefId,
69 lifetime_elision: LifetimeElisionKind,
69 lifetime_elision: LifetimeElisionKind<'db>,
7070 ) -> Self {
7171 Self {
7272 ctx: TyLoweringContext::new(db, resolver, store, generic_def, lifetime_elision),
......@@ -80,7 +80,7 @@ impl<'a> InferenceTyLoweringContext<'a> {
8080 &'b mut self,
8181 path: &'b Path,
8282 node: ExprOrPatId,
83 ) -> PathLoweringContext<'b, 'a> {
83 ) -> PathLoweringContext<'b, 'a, 'db> {
8484 let on_diagnostic = PathDiagnosticCallback {
8585 data: Either::Right(PathDiagnosticCallbackData { diagnostics: self.diagnostics, node }),
8686 callback: |data, _, diag| {
......@@ -96,7 +96,7 @@ impl<'a> InferenceTyLoweringContext<'a> {
9696 pub(super) fn at_path_forget_diagnostics<'b>(
9797 &'b mut self,
9898 path: &'b Path,
99 ) -> PathLoweringContext<'b, 'a> {
99 ) -> PathLoweringContext<'b, 'a, 'db> {
100100 let on_diagnostic = PathDiagnosticCallback {
101101 data: Either::Right(PathDiagnosticCallbackData {
102102 diagnostics: self.diagnostics,
......@@ -113,8 +113,8 @@ impl<'a> InferenceTyLoweringContext<'a> {
113113 }
114114}
115115
116impl<'a> Deref for InferenceTyLoweringContext<'a> {
117 type Target = TyLoweringContext<'a>;
116impl<'db, 'a> Deref for InferenceTyLoweringContext<'db, 'a> {
117 type Target = TyLoweringContext<'db, 'a>;
118118
119119 #[inline]
120120 fn deref(&self) -> &Self::Target {
......@@ -122,14 +122,14 @@ impl<'a> Deref for InferenceTyLoweringContext<'a> {
122122 }
123123}
124124
125impl DerefMut for InferenceTyLoweringContext<'_> {
125impl DerefMut for InferenceTyLoweringContext<'_, '_> {
126126 #[inline]
127127 fn deref_mut(&mut self) -> &mut Self::Target {
128128 &mut self.ctx
129129 }
130130}
131131
132impl Drop for InferenceTyLoweringContext<'_> {
132impl Drop for InferenceTyLoweringContext<'_, '_> {
133133 #[inline]
134134 fn drop(&mut self) {
135135 self.diagnostics
src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs+531-707
......@@ -2,12 +2,11 @@
22
33use std::{iter::repeat_with, mem};
44
5use chalk_ir::{DebruijnIndex, Mutability, TyVariableKind, cast::Cast};
65use either::Either;
76use hir_def::hir::ClosureKind;
87use hir_def::{
98 BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId,
10 expr_store::path::{GenericArg, GenericArgs, Path},
9 expr_store::path::{GenericArg as HirGenericArg, GenericArgs as HirGenericArgs, Path},
1110 hir::{
1211 ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, Expr, ExprId, ExprOrPatId, LabelId,
1312 Literal, Pat, PatId, Statement, UnaryOp, generics::GenericParamDataRef,
......@@ -17,19 +16,19 @@ use hir_def::{
1716};
1817use hir_expand::name::Name;
1918use intern::sym;
20use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike, Ty as _};
21use stdx::always;
19use rustc_ast_ir::Mutability;
20use rustc_type_ir::{
21 AliasTyKind, InferTy, Interner,
22 inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Ty as _},
23};
2224use syntax::ast::RangeOp;
2325use tracing::debug;
2426
25use crate::autoderef::overloaded_deref_ty;
26use crate::next_solver::infer::DefineOpaqueTypes;
27use crate::next_solver::obligation_ctxt::ObligationCtxt;
28use crate::next_solver::{DbInterner, ErrorGuaranteed};
2927use crate::{
30 Adjust, Adjustment, AdtId, AutoBorrow, CallableDefId, CallableSig, DeclContext, DeclOrigin,
31 IncorrectGenericsLenKind, Interner, LifetimeElisionKind, Rawness, Scalar, Substitution,
32 TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, consteval,
28 Adjust, Adjustment, AutoBorrow, CallableDefId, DeclContext, DeclOrigin,
29 IncorrectGenericsLenKind, Rawness, TraitEnvironment,
30 autoderef::overloaded_deref_ty,
31 consteval,
3332 generics::generics,
3433 infer::{
3534 AllowTwoPhase, BreakableKind,
......@@ -38,18 +37,20 @@ use crate::{
3837 pat::contains_explicit_ref_binding,
3938 },
4039 lang_items::lang_items_for_bin_op,
41 lower::{
42 ParamLoweringMode, lower_to_chalk_mutability,
40 lower_nextsolver::{
41 LifetimeElisionKind, lower_mutability,
4342 path::{GenericArgsLowerer, TypeLikeConst, substs_from_args_and_bindings},
4443 },
45 mapping::{ToChalk, from_chalk},
4644 method_resolution::{self, VisibleFromModule},
4745 next_solver::{
48 infer::traits::ObligationCause,
49 mapping::{ChalkToNextSolver, NextSolverToChalk},
46 AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, TraitRef, Ty, TyKind,
47 TypeError,
48 infer::{
49 DefineOpaqueTypes, InferOk,
50 traits::{Obligation, ObligationCause},
51 },
52 obligation_ctxt::ObligationCtxt,
5053 },
51 primitive::{self, UintTy},
52 static_lifetime, to_chalk_trait_id,
5354 traits::FnTrait,
5455};
5556
......@@ -64,27 +65,30 @@ pub(crate) enum ExprIsRead {
6465 No,
6566}
6667
67impl<'db> InferenceContext<'db> {
68impl<'db> InferenceContext<'_, 'db> {
6869 pub(crate) fn infer_expr(
6970 &mut self,
7071 tgt_expr: ExprId,
71 expected: &Expectation,
72 expected: &Expectation<'db>,
7273 is_read: ExprIsRead,
73 ) -> Ty {
74 ) -> Ty<'db> {
7475 let ty = self.infer_expr_inner(tgt_expr, expected, is_read);
7576 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
76 let could_unify = self.unify(&ty, &expected_ty);
77 let could_unify = self.unify(ty, expected_ty);
7778 if !could_unify {
78 self.result.type_mismatches.insert(
79 tgt_expr.into(),
80 TypeMismatch { expected: expected_ty, actual: ty.clone() },
81 );
79 self.result
80 .type_mismatches
81 .insert(tgt_expr.into(), TypeMismatch { expected: expected_ty, actual: ty });
8282 }
8383 }
8484 ty
8585 }
8686
87 pub(crate) fn infer_expr_no_expect(&mut self, tgt_expr: ExprId, is_read: ExprIsRead) -> Ty {
87 pub(crate) fn infer_expr_no_expect(
88 &mut self,
89 tgt_expr: ExprId,
90 is_read: ExprIsRead,
91 ) -> Ty<'db> {
8892 self.infer_expr_inner(tgt_expr, &Expectation::None, is_read)
8993 }
9094
......@@ -93,9 +97,9 @@ impl<'db> InferenceContext<'db> {
9397 pub(super) fn infer_expr_coerce(
9498 &mut self,
9599 expr: ExprId,
96 expected: &Expectation,
100 expected: &Expectation<'db>,
97101 is_read: ExprIsRead,
98 ) -> Ty {
102 ) -> Ty<'db> {
99103 let ty = self.infer_expr_inner(expr, expected, is_read);
100104 if let Some(target) = expected.only_has_type(&mut self.table) {
101105 let coerce_never = if self.expr_guaranteed_to_constitute_read_for_never(expr, is_read) {
......@@ -103,19 +107,12 @@ impl<'db> InferenceContext<'db> {
103107 } else {
104108 CoerceNever::No
105109 };
106 match self.coerce(
107 expr.into(),
108 ty.to_nextsolver(self.table.interner),
109 target.to_nextsolver(self.table.interner),
110 AllowTwoPhase::No,
111 coerce_never,
112 ) {
113 Ok(res) => res.to_chalk(self.table.interner),
110 match self.coerce(expr.into(), ty, target, AllowTwoPhase::No, coerce_never) {
111 Ok(res) => res,
114112 Err(_) => {
115 self.result.type_mismatches.insert(
116 expr.into(),
117 TypeMismatch { expected: target.clone(), actual: ty.clone() },
118 );
113 self.result
114 .type_mismatches
115 .insert(expr.into(), TypeMismatch { expected: target, actual: ty });
119116 target
120117 }
121118 }
......@@ -255,42 +252,34 @@ impl<'db> InferenceContext<'db> {
255252 fn infer_expr_coerce_never(
256253 &mut self,
257254 expr: ExprId,
258 expected: &Expectation,
255 expected: &Expectation<'db>,
259256 is_read: ExprIsRead,
260 ) -> Ty {
257 ) -> Ty<'db> {
261258 let ty = self.infer_expr_inner(expr, expected, is_read);
262259 // While we don't allow *arbitrary* coercions here, we *do* allow
263260 // coercions from `!` to `expected`.
264261 if ty.is_never() {
265262 if let Some(adjustments) = self.result.expr_adjustments.get(&expr) {
266263 return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments {
267 target.clone()
264 *target
268265 } else {
269266 self.err_ty()
270267 };
271268 }
272269
273270 if let Some(target) = expected.only_has_type(&mut self.table) {
274 self.coerce(
275 expr.into(),
276 ty.to_nextsolver(self.table.interner),
277 target.to_nextsolver(self.table.interner),
278 AllowTwoPhase::No,
279 CoerceNever::Yes,
280 )
281 .expect("never-to-any coercion should always succeed")
282 .to_chalk(self.table.interner)
271 self.coerce(expr.into(), ty, target, AllowTwoPhase::No, CoerceNever::Yes)
272 .expect("never-to-any coercion should always succeed")
283273 } else {
284274 ty
285275 }
286276 } else {
287277 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
288 let could_unify = self.unify(&ty, &expected_ty);
278 let could_unify = self.unify(ty, expected_ty);
289279 if !could_unify {
290 self.result.type_mismatches.insert(
291 expr.into(),
292 TypeMismatch { expected: expected_ty, actual: ty.clone() },
293 );
280 self.result
281 .type_mismatches
282 .insert(expr.into(), TypeMismatch { expected: expected_ty, actual: ty });
294283 }
295284 }
296285 ty
......@@ -301,9 +290,9 @@ impl<'db> InferenceContext<'db> {
301290 fn infer_expr_inner(
302291 &mut self,
303292 tgt_expr: ExprId,
304 expected: &Expectation,
293 expected: &Expectation<'db>,
305294 is_read: ExprIsRead,
306 ) -> Ty {
295 ) -> Ty<'db> {
307296 self.db.unwind_if_revision_cancelled();
308297
309298 let expr = &self.body[tgt_expr];
......@@ -314,7 +303,7 @@ impl<'db> InferenceContext<'db> {
314303 let expected = &expected.adjust_for_branches(&mut self.table);
315304 self.infer_expr_coerce_never(
316305 condition,
317 &Expectation::HasType(self.result.standard_types.bool_.clone()),
306 &Expectation::HasType(self.types.bool),
318307 ExprIsRead::Yes,
319308 );
320309
......@@ -327,27 +316,15 @@ impl<'db> InferenceContext<'db> {
327316 coercion_sites[1] = else_branch;
328317 }
329318 let mut coerce = CoerceMany::with_coercion_sites(
330 expected
331 .coercion_target_type(&mut self.table)
332 .to_nextsolver(self.table.interner),
319 expected.coercion_target_type(&mut self.table),
333320 &coercion_sites,
334321 );
335 coerce.coerce(
336 self,
337 &ObligationCause::new(),
338 then_branch,
339 then_ty.to_nextsolver(self.table.interner),
340 );
322 coerce.coerce(self, &ObligationCause::new(), then_branch, then_ty);
341323 match else_branch {
342324 Some(else_branch) => {
343325 let else_ty = self.infer_expr_inner(else_branch, expected, ExprIsRead::Yes);
344326 let else_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
345 coerce.coerce(
346 self,
347 &ObligationCause::new(),
348 else_branch,
349 else_ty.to_nextsolver(self.table.interner),
350 );
327 coerce.coerce(self, &ObligationCause::new(), else_branch, else_ty);
351328 self.diverges = condition_diverges | then_diverges & else_diverges;
352329 }
353330 None => {
......@@ -356,7 +333,7 @@ impl<'db> InferenceContext<'db> {
356333 }
357334 }
358335
359 coerce.complete(self).to_chalk(self.table.interner)
336 coerce.complete(self)
360337 }
361338 &Expr::Let { pat, expr } => {
362339 let child_is_read = if self.pat_guaranteed_to_constitute_read_for_never(pat) {
......@@ -367,10 +344,10 @@ impl<'db> InferenceContext<'db> {
367344 let input_ty = self.infer_expr(expr, &Expectation::none(), child_is_read);
368345 self.infer_top_pat(
369346 pat,
370 &input_ty,
347 input_ty,
371348 Some(DeclContext { origin: DeclOrigin::LetExpr }),
372349 );
373 self.result.standard_types.bool_.clone()
350 self.types.bool
374351 }
375352 Expr::Block { statements, tail, label, id } => {
376353 self.infer_block(tgt_expr, *id, statements, *tail, *label, expected)
......@@ -390,12 +367,12 @@ impl<'db> InferenceContext<'db> {
390367 &Expr::Loop { body, label } => {
391368 // FIXME: should be:
392369 // let ty = expected.coercion_target_type(&mut self.table);
393 let ty = self.table.new_type_var();
370 let ty = self.table.next_ty_var();
394371 let (breaks, ()) =
395372 self.with_breakable_ctx(BreakableKind::Loop, Some(ty), label, |this| {
396373 this.infer_expr(
397374 body,
398 &Expectation::HasType(TyBuilder::unit()),
375 &Expectation::HasType(this.types.unit),
399376 ExprIsRead::Yes,
400377 );
401378 });
......@@ -405,7 +382,7 @@ impl<'db> InferenceContext<'db> {
405382 self.diverges = Diverges::Maybe;
406383 breaks
407384 }
408 None => self.result.standard_types.never.clone(),
385 None => self.types.never,
409386 }
410387 }
411388 Expr::Closure { body, args, ret_type, arg_types, closure_kind, capture_by: _ } => self
......@@ -438,32 +415,30 @@ impl<'db> InferenceContext<'db> {
438415
439416 if arms.is_empty() {
440417 self.diverges = Diverges::Always;
441 self.result.standard_types.never.clone()
418 self.types.never
442419 } else {
443420 let matchee_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
444421 let mut all_arms_diverge = Diverges::Always;
445422 for arm in arms.iter() {
446 let input_ty = self.table.structurally_resolve_type(&input_ty);
447 self.infer_top_pat(arm.pat, &input_ty, None);
423 let input_ty = self.table.structurally_resolve_type(input_ty);
424 self.infer_top_pat(arm.pat, input_ty, None);
448425 }
449426
450427 let expected = expected.adjust_for_branches(&mut self.table);
451428 let result_ty = match &expected {
452429 // We don't coerce to `()` so that if the match expression is a
453430 // statement it's branches can have any consistent type.
454 Expectation::HasType(ty) if *ty != self.result.standard_types.unit => {
455 ty.clone()
456 }
457 _ => self.table.new_type_var(),
431 Expectation::HasType(ty) if *ty != self.types.unit => *ty,
432 _ => self.table.next_ty_var(),
458433 };
459 let mut coerce = CoerceMany::new(result_ty.to_nextsolver(self.table.interner));
434 let mut coerce = CoerceMany::new(result_ty);
460435
461436 for arm in arms.iter() {
462437 if let Some(guard_expr) = arm.guard {
463438 self.diverges = Diverges::Maybe;
464439 self.infer_expr_coerce_never(
465440 guard_expr,
466 &Expectation::HasType(self.result.standard_types.bool_.clone()),
441 &Expectation::HasType(self.types.bool),
467442 ExprIsRead::Yes,
468443 );
469444 }
......@@ -471,17 +446,12 @@ impl<'db> InferenceContext<'db> {
471446
472447 let arm_ty = self.infer_expr_inner(arm.expr, &expected, ExprIsRead::Yes);
473448 all_arms_diverge &= self.diverges;
474 coerce.coerce(
475 self,
476 &ObligationCause::new(),
477 arm.expr,
478 arm_ty.to_nextsolver(self.table.interner),
479 );
449 coerce.coerce(self, &ObligationCause::new(), arm.expr, arm_ty);
480450 }
481451
482452 self.diverges = matchee_diverges | all_arms_diverge;
483453
484 coerce.complete(self).to_chalk(self.table.interner)
454 coerce.complete(self)
485455 }
486456 }
487457 Expr::Path(p) => self.infer_expr_path(p, tgt_expr.into(), tgt_expr),
......@@ -493,13 +463,13 @@ impl<'db> InferenceContext<'db> {
493463 bad_value_break: false,
494464 });
495465 };
496 self.result.standard_types.never.clone()
466 self.types.never
497467 }
498468 &Expr::Break { expr, label } => {
499469 let val_ty = if let Some(expr) = expr {
500470 let opt_coerce_to = match find_breakable(&mut self.breakables, label) {
501471 Some(ctxt) => match &ctxt.coerce {
502 Some(coerce) => coerce.expected_ty().to_chalk(self.table.interner),
472 Some(coerce) => coerce.expected_ty(),
503473 None => {
504474 self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
505475 expr: tgt_expr,
......@@ -517,7 +487,7 @@ impl<'db> InferenceContext<'db> {
517487 ExprIsRead::Yes,
518488 )
519489 } else {
520 TyBuilder::unit()
490 self.types.unit
521491 };
522492
523493 match find_breakable(&mut self.breakables, label) {
......@@ -527,7 +497,7 @@ impl<'db> InferenceContext<'db> {
527497 self,
528498 &ObligationCause::new(),
529499 expr.unwrap_or(tgt_expr),
530 val_ty.to_nextsolver(self.table.interner),
500 val_ty,
531501 );
532502
533503 // Avoiding borrowck
......@@ -546,12 +516,12 @@ impl<'db> InferenceContext<'db> {
546516 });
547517 }
548518 }
549 self.result.standard_types.never.clone()
519 self.types.never
550520 }
551521 &Expr::Return { expr } => self.infer_expr_return(tgt_expr, expr),
552522 &Expr::Become { expr } => self.infer_expr_become(expr),
553523 Expr::Yield { expr } => {
554 if let Some((resume_ty, yield_ty)) = self.resume_yield_tys.clone() {
524 if let Some((resume_ty, yield_ty)) = self.resume_yield_tys {
555525 if let Some(expr) = expr {
556526 self.infer_expr_coerce(
557527 *expr,
......@@ -559,11 +529,11 @@ impl<'db> InferenceContext<'db> {
559529 ExprIsRead::Yes,
560530 );
561531 } else {
562 let unit = self.result.standard_types.unit.clone();
532 let unit = self.types.unit;
563533 let _ = self.coerce(
564534 tgt_expr.into(),
565 unit.to_nextsolver(self.table.interner),
566 yield_ty.to_nextsolver(self.table.interner),
535 unit,
536 yield_ty,
567537 AllowTwoPhase::No,
568538 CoerceNever::Yes,
569539 );
......@@ -571,33 +541,30 @@ impl<'db> InferenceContext<'db> {
571541 resume_ty
572542 } else {
573543 // FIXME: report error (yield expr in non-coroutine)
574 self.result.standard_types.unknown.clone()
544 self.types.error
575545 }
576546 }
577547 Expr::Yeet { expr } => {
578548 if let &Some(expr) = expr {
579549 self.infer_expr_no_expect(expr, ExprIsRead::Yes);
580550 }
581 self.result.standard_types.never.clone()
551 self.types.never
582552 }
583553 Expr::RecordLit { path, fields, spread, .. } => {
584554 let (ty, def_id) = self.resolve_variant(tgt_expr.into(), path.as_deref(), false);
585555
586556 if let Some(t) = expected.only_has_type(&mut self.table) {
587 self.unify(&ty, &t);
557 self.unify(ty, t);
588558 }
589559
590 let substs = ty
591 .as_adt()
592 .map(|(_, s)| s.clone())
593 .unwrap_or_else(|| Substitution::empty(Interner));
560 let substs = ty.as_adt().map(|(_, s)| s).unwrap_or(self.types.empty_args);
594561 if let Some(variant) = def_id {
595562 self.write_variant_resolution(tgt_expr.into(), variant);
596563 }
597564 match def_id {
598565 _ if fields.is_empty() => {}
599566 Some(def) => {
600 let field_types = self.db.field_types(def);
567 let field_types = self.db.field_types_ns(def);
601568 let variant_data = def.fields(self.db);
602569 let visibilities = self.db.field_visibilities(def);
603570 for field in fields.iter() {
......@@ -628,7 +595,7 @@ impl<'db> InferenceContext<'db> {
628595 }
629596 };
630597 let field_ty = field_def.map_or(self.err_ty(), |it| {
631 field_types[it].clone().substitute(Interner, &substs)
598 field_types[it].instantiate(self.interner(), &substs)
632599 });
633600
634601 // Field type might have some unknown types
......@@ -649,7 +616,7 @@ impl<'db> InferenceContext<'db> {
649616 }
650617 }
651618 if let Some(expr) = spread {
652 self.infer_expr(*expr, &Expectation::has_type(ty.clone()), ExprIsRead::Yes);
619 self.infer_expr(*expr, &Expectation::has_type(ty), ExprIsRead::Yes);
653620 }
654621 ty
655622 }
......@@ -660,21 +627,13 @@ impl<'db> InferenceContext<'db> {
660627 }
661628 Expr::Cast { expr, type_ref } => {
662629 let cast_ty = self.make_body_ty(*type_ref);
663 let expr_ty = self.infer_expr(
664 *expr,
665 &Expectation::Castable(cast_ty.clone()),
666 ExprIsRead::Yes,
667 );
668 self.deferred_cast_checks.push(CastCheck::new(
669 tgt_expr,
670 *expr,
671 expr_ty,
672 cast_ty.clone(),
673 ));
630 let expr_ty =
631 self.infer_expr(*expr, &Expectation::Castable(cast_ty), ExprIsRead::Yes);
632 self.deferred_cast_checks.push(CastCheck::new(tgt_expr, *expr, expr_ty, cast_ty));
674633 cast_ty
675634 }
676635 Expr::Ref { expr, rawness, mutability } => {
677 let mutability = lower_to_chalk_mutability(*mutability);
636 let mutability = lower_mutability(*mutability);
678637 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = expected
679638 .only_has_type(&mut self.table)
680639 .as_ref()
......@@ -688,24 +647,23 @@ impl<'db> InferenceContext<'db> {
688647 // FIXME: record type error - expected reference but found ptr,
689648 // which cannot be coerced
690649 }
691 Expectation::rvalue_hint(self, Ty::clone(exp_inner))
650 Expectation::rvalue_hint(self, exp_inner)
692651 } else {
693652 Expectation::none()
694653 };
695654 let inner_ty = self.infer_expr_inner(*expr, &expectation, ExprIsRead::Yes);
696655 match rawness {
697 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
656 Rawness::RawPtr => Ty::new_ptr(self.interner(), inner_ty, mutability),
698657 Rawness::Ref => {
699 let lt = self.table.new_lifetime_var();
700 TyKind::Ref(mutability, lt, inner_ty)
658 let lt = self.table.next_region_var();
659 Ty::new_ref(self.interner(), lt, inner_ty, mutability)
701660 }
702661 }
703 .intern(Interner)
704662 }
705663 &Expr::Box { expr } => self.infer_expr_box(expr, expected),
706664 Expr::UnaryOp { expr, op } => {
707665 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none(), ExprIsRead::Yes);
708 let inner_ty = self.table.structurally_resolve_type(&inner_ty);
666 let inner_ty = self.table.try_structurally_resolve_type(inner_ty);
709667 // FIXME: Note down method resolution her
710668 match op {
711669 UnaryOp::Deref => {
......@@ -716,49 +674,38 @@ impl<'db> InferenceContext<'db> {
716674 {
717675 // FIXME: this is wrong in multiple ways, subst is empty, and we emit it even for builtin deref (note that
718676 // the mutability is not wrong, and will be fixed in `self.infer_mut`).
719 self.write_method_resolution(
720 tgt_expr,
721 deref_fn,
722 Substitution::empty(Interner),
723 );
677 self.write_method_resolution(tgt_expr, deref_fn, self.types.empty_args);
724678 }
725 if let Some(derefed) =
726 inner_ty.to_nextsolver(self.table.interner).builtin_deref(self.db, true)
727 {
728 self.table
729 .structurally_resolve_type(&derefed.to_chalk(self.table.interner))
679 if let Some(derefed) = inner_ty.builtin_deref(self.db, true) {
680 self.table.try_structurally_resolve_type(derefed)
730681 } else {
731 let infer_ok = overloaded_deref_ty(
732 &self.table,
733 inner_ty.to_nextsolver(self.table.interner),
734 );
682 let infer_ok = overloaded_deref_ty(&self.table, inner_ty);
735683 match infer_ok {
736 Some(infer_ok) => self
737 .table
738 .register_infer_ok(infer_ok)
739 .to_chalk(self.table.interner),
684 Some(infer_ok) => self.table.register_infer_ok(infer_ok),
740685 None => self.err_ty(),
741686 }
742687 }
743688 }
744689 UnaryOp::Neg => {
745 match inner_ty.kind(Interner) {
690 match inner_ty.kind() {
746691 // Fast path for builtins
747 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_))
748 | TyKind::InferenceVar(
749 _,
750 TyVariableKind::Integer | TyVariableKind::Float,
751 ) => inner_ty,
692 TyKind::Int(_)
693 | TyKind::Uint(_)
694 | TyKind::Float(_)
695 | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_)) => inner_ty,
752696 // Otherwise we resolve via the std::ops::Neg trait
753697 _ => self
754698 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
755699 }
756700 }
757701 UnaryOp::Not => {
758 match inner_ty.kind(Interner) {
702 match inner_ty.kind() {
759703 // Fast path for builtins
760 TyKind::Scalar(Scalar::Bool | Scalar::Int(_) | Scalar::Uint(_))
761 | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
704 TyKind::Bool
705 | TyKind::Int(_)
706 | TyKind::Uint(_)
707 | TyKind::Float(_)
708 | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_)) => inner_ty,
762709 // Otherwise we resolve via the std::ops::Not trait
763710 _ => self
764711 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
......@@ -768,18 +715,10 @@ impl<'db> InferenceContext<'db> {
768715 }
769716 Expr::BinaryOp { lhs, rhs, op } => match op {
770717 Some(BinaryOp::LogicOp(_)) => {
771 let bool_ty = self.result.standard_types.bool_.clone();
772 self.infer_expr_coerce(
773 *lhs,
774 &Expectation::HasType(bool_ty.clone()),
775 ExprIsRead::Yes,
776 );
718 let bool_ty = self.types.bool;
719 self.infer_expr_coerce(*lhs, &Expectation::HasType(bool_ty), ExprIsRead::Yes);
777720 let lhs_diverges = self.diverges;
778 self.infer_expr_coerce(
779 *rhs,
780 &Expectation::HasType(bool_ty.clone()),
781 ExprIsRead::Yes,
782 );
721 self.infer_expr_coerce(*rhs, &Expectation::HasType(bool_ty), ExprIsRead::Yes);
783722 // Depending on the LHS' value, the RHS can never execute.
784723 self.diverges = lhs_diverges;
785724 bool_ty
......@@ -826,14 +765,14 @@ impl<'db> InferenceContext<'db> {
826765 let is_destructuring_assignment = lhs_ty.is_none();
827766
828767 if let Some(lhs_ty) = lhs_ty {
829 self.write_pat_ty(target, lhs_ty.clone());
768 self.write_pat_ty(target, lhs_ty);
830769 self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::No);
831770 } else {
832771 let rhs_ty = self.infer_expr(value, &Expectation::none(), ExprIsRead::Yes);
833772 let resolver_guard =
834773 self.resolver.update_to_inner_scope(self.db, self.owner, tgt_expr);
835774 self.inside_assignment = true;
836 self.infer_top_pat(target, &rhs_ty, None);
775 self.infer_top_pat(target, rhs_ty, None);
837776 self.inside_assignment = false;
838777 self.resolver.reset_to_guard(resolver_guard);
839778 }
......@@ -844,43 +783,49 @@ impl<'db> InferenceContext<'db> {
844783 // assignments into blocks.
845784 self.table.new_maybe_never_var()
846785 } else {
847 self.result.standard_types.unit.clone()
786 self.types.unit
848787 }
849788 }
850789 Expr::Range { lhs, rhs, range_type } => {
851790 let lhs_ty =
852791 lhs.map(|e| self.infer_expr_inner(e, &Expectation::none(), ExprIsRead::Yes));
853 let rhs_expect = lhs_ty
854 .as_ref()
855 .map_or_else(Expectation::none, |ty| Expectation::has_type(ty.clone()));
792 let rhs_expect =
793 lhs_ty.as_ref().map_or_else(Expectation::none, |ty| Expectation::has_type(*ty));
856794 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect, ExprIsRead::Yes));
795 let single_arg_adt = |adt, ty: Ty<'db>| {
796 Ty::new_adt(
797 self.interner(),
798 adt,
799 GenericArgs::new_from_iter(self.interner(), [ty.into()]),
800 )
801 };
857802 match (range_type, lhs_ty, rhs_ty) {
858803 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
859 Some(adt) => TyBuilder::adt(self.db, adt).build(),
804 Some(adt) => Ty::new_adt(self.interner(), adt, self.types.empty_args),
860805 None => self.err_ty(),
861806 },
862807 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
863 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
808 Some(adt) => single_arg_adt(adt, ty),
864809 None => self.err_ty(),
865810 },
866811 (RangeOp::Inclusive, None, Some(ty)) => {
867812 match self.resolve_range_to_inclusive() {
868 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
813 Some(adt) => single_arg_adt(adt, ty),
869814 None => self.err_ty(),
870815 }
871816 }
872817 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
873 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
818 Some(adt) => single_arg_adt(adt, ty),
874819 None => self.err_ty(),
875820 },
876821 (RangeOp::Inclusive, Some(_), Some(ty)) => {
877822 match self.resolve_range_inclusive() {
878 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
823 Some(adt) => single_arg_adt(adt, ty),
879824 None => self.err_ty(),
880825 }
881826 }
882827 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
883 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
828 Some(adt) => single_arg_adt(adt, ty),
884829 None => self.err_ty(),
885830 },
886831 (RangeOp::Inclusive, _, None) => self.err_ty(),
......@@ -891,8 +836,7 @@ impl<'db> InferenceContext<'db> {
891836 let index_ty = self.infer_expr(*index, &Expectation::none(), ExprIsRead::Yes);
892837
893838 if let Some(index_trait) = self.resolve_lang_trait(LangItem::Index) {
894 let canonicalized =
895 self.canonicalize(base_ty.clone().to_nextsolver(self.table.interner));
839 let canonicalized = self.canonicalize(base_ty);
896840 let receiver_adjustments = method_resolution::resolve_indexing_op(
897841 &mut self.table,
898842 canonicalized,
......@@ -905,66 +849,52 @@ impl<'db> InferenceContext<'db> {
905849
906850 // mutability will be fixed up in `InferenceContext::infer_mut`;
907851 adj.push(Adjustment::borrow(
852 self.interner(),
908853 Mutability::Not,
909 self_ty.clone(),
910 self.table.new_lifetime_var(),
854 self_ty,
855 self.table.next_region_var(),
911856 ));
912857 self.write_expr_adj(*base, adj.into_boxed_slice());
913858 if let Some(func) = index_trait
914859 .trait_items(self.db)
915860 .method_by_name(&Name::new_symbol_root(sym::index))
916861 {
917 let subst = TyBuilder::subst_for_def(self.db, index_trait, None);
918 if subst.remaining() != 2 {
919 return self.err_ty();
920 }
921 let subst = subst.push(self_ty.clone()).push(index_ty.clone()).build();
862 let subst = GenericArgs::new_from_iter(
863 self.interner(),
864 [self_ty.into(), index_ty.into()],
865 );
922866 self.write_method_resolution(tgt_expr, func, subst);
923867 }
924868 let assoc = self.resolve_ops_index_output();
925 self.resolve_associated_type_with_params(
926 self_ty,
927 assoc,
928 &[index_ty.cast(Interner)],
929 )
869 self.resolve_associated_type_with_params(self_ty, assoc, &[index_ty.into()])
930870 } else {
931871 self.err_ty()
932872 }
933873 }
934874 Expr::Tuple { exprs, .. } => {
935 let mut tys = match expected
936 .only_has_type(&mut self.table)
937 .as_ref()
938 .map(|t| t.kind(Interner))
939 {
940 Some(TyKind::Tuple(_, substs)) => substs
941 .iter(Interner)
942 .map(|a| a.assert_ty_ref(Interner).clone())
943 .chain(repeat_with(|| self.table.new_type_var()))
944 .take(exprs.len())
945 .collect::<Vec<_>>(),
946 _ => (0..exprs.len()).map(|_| self.table.new_type_var()).collect(),
947 };
875 let mut tys =
876 match expected.only_has_type(&mut self.table).as_ref().map(|t| t.kind()) {
877 Some(TyKind::Tuple(substs)) => substs
878 .iter()
879 .chain(repeat_with(|| self.table.next_ty_var()))
880 .take(exprs.len())
881 .collect::<Vec<_>>(),
882 _ => (0..exprs.len()).map(|_| self.table.next_ty_var()).collect(),
883 };
948884
949885 for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
950 *ty = self.infer_expr_coerce(
951 *expr,
952 &Expectation::has_type(ty.clone()),
953 ExprIsRead::Yes,
954 );
886 *ty =
887 self.infer_expr_coerce(*expr, &Expectation::has_type(*ty), ExprIsRead::Yes);
955888 }
956889
957 TyKind::Tuple(tys.len(), Substitution::from_iter(Interner, tys)).intern(Interner)
890 Ty::new_tup(self.interner(), &tys)
958891 }
959892 Expr::Array(array) => self.infer_expr_array(array, expected),
960893 Expr::Literal(lit) => match lit {
961 Literal::Bool(..) => self.result.standard_types.bool_.clone(),
962 Literal::String(..) => {
963 TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(Interner))
964 .intern(Interner)
965 }
894 Literal::Bool(..) => self.types.bool,
895 Literal::String(..) => self.types.static_str_ref,
966896 Literal::ByteString(bs) => {
967 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner);
897 let byte_type = self.types.u8;
968898
969899 let len = consteval::usize_const(
970900 self.db,
......@@ -972,75 +902,80 @@ impl<'db> InferenceContext<'db> {
972902 self.resolver.krate(),
973903 );
974904
975 let array_type = TyKind::Array(byte_type, len).intern(Interner);
976 TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(Interner)
905 let array_type = Ty::new_array_with_const_len(self.interner(), byte_type, len);
906 Ty::new_ref(self.interner(), self.types.re_static, array_type, Mutability::Not)
977907 }
978 Literal::CString(..) => TyKind::Ref(
979 Mutability::Not,
980 static_lifetime(),
908 Literal::CString(..) => Ty::new_ref(
909 self.interner(),
910 self.types.re_static,
981911 self.resolve_lang_item(LangItem::CStr)
982912 .and_then(LangItemTarget::as_struct)
983913 .map_or_else(
984914 || self.err_ty(),
985915 |strukt| {
986 TyKind::Adt(AdtId(strukt.into()), Substitution::empty(Interner))
987 .intern(Interner)
916 Ty::new_adt(self.interner(), strukt.into(), self.types.empty_args)
988917 },
989918 ),
990 )
991 .intern(Interner),
992 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(Interner),
919 Mutability::Not,
920 ),
921 Literal::Char(..) => self.types.char,
993922 Literal::Int(_v, ty) => match ty {
994 Some(int_ty) => {
995 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
996 .intern(Interner)
997 }
923 Some(int_ty) => match int_ty {
924 hir_def::builtin_type::BuiltinInt::Isize => self.types.isize,
925 hir_def::builtin_type::BuiltinInt::I8 => self.types.i8,
926 hir_def::builtin_type::BuiltinInt::I16 => self.types.i16,
927 hir_def::builtin_type::BuiltinInt::I32 => self.types.i32,
928 hir_def::builtin_type::BuiltinInt::I64 => self.types.i64,
929 hir_def::builtin_type::BuiltinInt::I128 => self.types.i128,
930 },
998931 None => {
999932 let expected_ty = expected.to_option(&mut self.table);
1000933 tracing::debug!(?expected_ty);
1001 let opt_ty = match expected_ty.as_ref().map(|it| it.kind(Interner)) {
1002 Some(TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))) => expected_ty,
1003 Some(TyKind::Scalar(Scalar::Char)) => {
1004 Some(TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner))
1005 }
1006 Some(TyKind::Raw(..) | TyKind::FnDef(..) | TyKind::Function(..)) => {
1007 Some(TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner))
934 let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
935 Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
936 Some(TyKind::Char) => Some(self.types.u8),
937 Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
938 Some(self.types.usize)
1008939 }
1009940 _ => None,
1010941 };
1011 opt_ty.unwrap_or_else(|| self.table.new_integer_var())
942 opt_ty.unwrap_or_else(|| self.table.next_int_var())
1012943 }
1013944 },
1014945 Literal::Uint(_v, ty) => match ty {
1015 Some(int_ty) => {
1016 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
1017 .intern(Interner)
1018 }
946 Some(int_ty) => match int_ty {
947 hir_def::builtin_type::BuiltinUint::Usize => self.types.usize,
948 hir_def::builtin_type::BuiltinUint::U8 => self.types.u8,
949 hir_def::builtin_type::BuiltinUint::U16 => self.types.u16,
950 hir_def::builtin_type::BuiltinUint::U32 => self.types.u32,
951 hir_def::builtin_type::BuiltinUint::U64 => self.types.u64,
952 hir_def::builtin_type::BuiltinUint::U128 => self.types.u128,
953 },
1019954 None => {
1020955 let expected_ty = expected.to_option(&mut self.table);
1021 let opt_ty = match expected_ty.as_ref().map(|it| it.kind(Interner)) {
1022 Some(TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))) => expected_ty,
1023 Some(TyKind::Scalar(Scalar::Char)) => {
1024 Some(TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner))
1025 }
1026 Some(TyKind::Raw(..) | TyKind::FnDef(..) | TyKind::Function(..)) => {
1027 Some(TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner))
956 let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
957 Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
958 Some(TyKind::Char) => Some(self.types.u8),
959 Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
960 Some(self.types.usize)
1028961 }
1029962 _ => None,
1030963 };
1031 opt_ty.unwrap_or_else(|| self.table.new_integer_var())
964 opt_ty.unwrap_or_else(|| self.table.next_int_var())
1032965 }
1033966 },
1034967 Literal::Float(_v, ty) => match ty {
1035 Some(float_ty) => {
1036 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
1037 .intern(Interner)
1038 }
968 Some(float_ty) => match float_ty {
969 hir_def::builtin_type::BuiltinFloat::F16 => self.types.f16,
970 hir_def::builtin_type::BuiltinFloat::F32 => self.types.f32,
971 hir_def::builtin_type::BuiltinFloat::F64 => self.types.f64,
972 hir_def::builtin_type::BuiltinFloat::F128 => self.types.f128,
973 },
1039974 None => {
1040 let opt_ty = expected.to_option(&mut self.table).filter(|ty| {
1041 matches!(ty.kind(Interner), TyKind::Scalar(Scalar::Float(_)))
1042 });
1043 opt_ty.unwrap_or_else(|| self.table.new_float_var())
975 let opt_ty = expected
976 .to_option(&mut self.table)
977 .filter(|ty| matches!(ty.kind(), TyKind::Float(_)));
978 opt_ty.unwrap_or_else(|| self.table.next_float_var())
1044979 }
1045980 },
1046981 },
......@@ -1048,13 +983,10 @@ impl<'db> InferenceContext<'db> {
1048983 // Underscore expression is an error, we render a specialized diagnostic
1049984 // to let the user know what type is expected though.
1050985 let expected = expected.to_option(&mut self.table).unwrap_or_else(|| self.err_ty());
1051 self.push_diagnostic(InferenceDiagnostic::TypedHole {
1052 expr: tgt_expr,
1053 expected: expected.clone(),
1054 });
986 self.push_diagnostic(InferenceDiagnostic::TypedHole { expr: tgt_expr, expected });
1055987 expected
1056988 }
1057 Expr::OffsetOf(_) => TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
989 Expr::OffsetOf(_) => self.types.usize,
1058990 Expr::InlineAsm(asm) => {
1059991 let check_expr_asm_operand = |this: &mut Self, expr, is_input: bool| {
1060992 let ty = this.infer_expr_no_expect(expr, ExprIsRead::Yes);
......@@ -1067,27 +999,29 @@ impl<'db> InferenceContext<'db> {
1067999 // allows them to be inferred based on how they are used later in the
10681000 // function.
10691001 if is_input {
1070 let ty = this.table.structurally_resolve_type(&ty);
1071 match ty.kind(Interner) {
1002 let ty = this.table.structurally_resolve_type(ty);
1003 match ty.kind() {
10721004 TyKind::FnDef(def, parameters) => {
1073 let fnptr_ty = TyKind::Function(
1074 CallableSig::from_def(this.db, *def, parameters).to_fn_ptr(),
1075 )
1076 .intern(Interner);
1005 let fnptr_ty = Ty::new_fn_ptr(
1006 this.interner(),
1007 this.interner()
1008 .fn_sig(def)
1009 .instantiate(this.interner(), parameters),
1010 );
10771011 _ = this.coerce(
10781012 expr.into(),
1079 ty.to_nextsolver(this.table.interner),
1080 fnptr_ty.to_nextsolver(this.table.interner),
1013 ty,
1014 fnptr_ty,
10811015 AllowTwoPhase::No,
10821016 CoerceNever::Yes,
10831017 );
10841018 }
1085 TyKind::Ref(mutbl, _, base_ty) => {
1086 let ptr_ty = TyKind::Raw(*mutbl, base_ty.clone()).intern(Interner);
1019 TyKind::Ref(_, base_ty, mutbl) => {
1020 let ptr_ty = Ty::new_ptr(this.interner(), base_ty, mutbl);
10871021 _ = this.coerce(
10881022 expr.into(),
1089 ty.to_nextsolver(this.table.interner),
1090 ptr_ty.to_nextsolver(this.table.interner),
1023 ty,
1024 ptr_ty,
10911025 AllowTwoPhase::No,
10921026 CoerceNever::Yes,
10931027 );
......@@ -1113,7 +1047,7 @@ impl<'db> InferenceContext<'db> {
11131047 AsmOperand::Label(expr) => {
11141048 self.infer_expr(
11151049 expr,
1116 &Expectation::HasType(self.result.standard_types.unit.clone()),
1050 &Expectation::HasType(self.types.unit),
11171051 ExprIsRead::No,
11181052 );
11191053 }
......@@ -1123,17 +1057,13 @@ impl<'db> InferenceContext<'db> {
11231057 // FIXME: `sym` should report for things that are not functions or statics.
11241058 AsmOperand::Sym(_) => (),
11251059 });
1126 if diverge {
1127 self.result.standard_types.never.clone()
1128 } else {
1129 self.result.standard_types.unit.clone()
1130 }
1060 if diverge { self.types.never } else { self.types.unit }
11311061 }
11321062 };
11331063 // use a new type variable if we got unknown here
11341064 let ty = self.insert_type_vars_shallow(ty);
1135 self.write_expr_ty(tgt_expr, ty.clone());
1136 if self.resolve_ty_shallow(&ty).is_never()
1065 self.write_expr_ty(tgt_expr, ty);
1066 if self.shallow_resolve(ty).is_never()
11371067 && self.expr_guaranteed_to_constitute_read_for_never(tgt_expr, is_read)
11381068 {
11391069 // Any expression that produces a value of type `!` must have diverged
......@@ -1142,7 +1072,7 @@ impl<'db> InferenceContext<'db> {
11421072 ty
11431073 }
11441074
1145 fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatId, scope_id: ExprId) -> Ty {
1075 fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatId, scope_id: ExprId) -> Ty<'db> {
11461076 let g = self.resolver.update_to_inner_scope(self.db, self.owner, scope_id);
11471077 let ty = match self.infer_path(path, id) {
11481078 Some(ty) => ty,
......@@ -1164,32 +1094,24 @@ impl<'db> InferenceContext<'db> {
11641094 id: &Option<BlockId>,
11651095 statements: &[Statement],
11661096 tail: &Option<ExprId>,
1167 ) -> Ty {
1168 let ret_ty = self.table.new_type_var();
1097 ) -> Ty<'db> {
1098 let ret_ty = self.table.next_ty_var();
11691099 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
1170 let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
1171 let prev_ret_coercion = self
1172 .return_coercion
1173 .replace(CoerceMany::new(ret_ty.to_nextsolver(self.table.interner)));
1100 let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty);
1101 let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(ret_ty));
11741102
11751103 // FIXME: We should handle async blocks like we handle closures
11761104 let expected = &Expectation::has_type(ret_ty);
11771105 let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
11781106 let ty = this.infer_block(tgt_expr, *id, statements, *tail, None, expected);
11791107 if let Some(target) = expected.only_has_type(&mut this.table) {
1180 match this.coerce(
1181 tgt_expr.into(),
1182 ty.to_nextsolver(this.table.interner),
1183 target.to_nextsolver(this.table.interner),
1184 AllowTwoPhase::No,
1185 CoerceNever::Yes,
1186 ) {
1187 Ok(res) => res.to_chalk(this.table.interner),
1108 match this.coerce(tgt_expr.into(), ty, target, AllowTwoPhase::No, CoerceNever::Yes)
1109 {
1110 Ok(res) => res,
11881111 Err(_) => {
1189 this.result.type_mismatches.insert(
1190 tgt_expr.into(),
1191 TypeMismatch { expected: target.clone(), actual: ty.clone() },
1192 );
1112 this.result
1113 .type_mismatches
1114 .insert(tgt_expr.into(), TypeMismatch { expected: target, actual: ty });
11931115 target
11941116 }
11951117 }
......@@ -1207,57 +1129,67 @@ impl<'db> InferenceContext<'db> {
12071129
12081130 pub(crate) fn lower_async_block_type_impl_trait(
12091131 &mut self,
1210 inner_ty: Ty,
1132 inner_ty: Ty<'db>,
12111133 tgt_expr: ExprId,
1212 ) -> Ty {
1134 ) -> Ty<'db> {
12131135 // Use the first type parameter as the output type of future.
12141136 // existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
12151137 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, tgt_expr);
12161138 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
1217 TyKind::OpaqueType(opaque_ty_id, Substitution::from1(Interner, inner_ty)).intern(Interner)
1139 Ty::new_alias(
1140 self.interner(),
1141 AliasTyKind::Opaque,
1142 AliasTy::new(
1143 self.interner(),
1144 opaque_ty_id,
1145 GenericArgs::new_from_iter(self.interner(), [inner_ty.into()]),
1146 ),
1147 )
12181148 }
12191149
12201150 pub(crate) fn write_fn_trait_method_resolution(
12211151 &mut self,
12221152 fn_x: FnTrait,
1223 derefed_callee: &Ty,
1224 adjustments: &mut Vec<Adjustment>,
1225 callee_ty: &Ty,
1226 params: &[Ty],
1153 derefed_callee: Ty<'db>,
1154 adjustments: &mut Vec<Adjustment<'db>>,
1155 callee_ty: Ty<'db>,
1156 params: &[Ty<'db>],
12271157 tgt_expr: ExprId,
12281158 ) {
12291159 match fn_x {
12301160 FnTrait::FnOnce | FnTrait::AsyncFnOnce => (),
12311161 FnTrait::FnMut | FnTrait::AsyncFnMut => {
1232 if let TyKind::Ref(Mutability::Mut, lt, inner) = derefed_callee.kind(Interner) {
1162 if let TyKind::Ref(lt, inner, Mutability::Mut) = derefed_callee.kind() {
12331163 if adjustments
12341164 .last()
12351165 .map(|it| matches!(it.kind, Adjust::Borrow(_)))
12361166 .unwrap_or(true)
12371167 {
12381168 // prefer reborrow to move
1239 adjustments
1240 .push(Adjustment { kind: Adjust::Deref(None), target: inner.clone() });
1169 adjustments.push(Adjustment { kind: Adjust::Deref(None), target: inner });
12411170 adjustments.push(Adjustment::borrow(
1171 self.interner(),
12421172 Mutability::Mut,
1243 inner.clone(),
1244 lt.clone(),
1173 inner,
1174 lt,
12451175 ))
12461176 }
12471177 } else {
12481178 adjustments.push(Adjustment::borrow(
1179 self.interner(),
12491180 Mutability::Mut,
1250 derefed_callee.clone(),
1251 self.table.new_lifetime_var(),
1181 derefed_callee,
1182 self.table.next_region_var(),
12521183 ));
12531184 }
12541185 }
12551186 FnTrait::Fn | FnTrait::AsyncFn => {
1256 if !matches!(derefed_callee.kind(Interner), TyKind::Ref(Mutability::Not, _, _)) {
1187 if !matches!(derefed_callee.kind(), TyKind::Ref(_, _, Mutability::Not)) {
12571188 adjustments.push(Adjustment::borrow(
1189 self.interner(),
12581190 Mutability::Not,
1259 derefed_callee.clone(),
1260 self.table.new_lifetime_var(),
1191 derefed_callee,
1192 self.table.next_region_var(),
12611193 ));
12621194 }
12631195 }
......@@ -1267,57 +1199,48 @@ impl<'db> InferenceContext<'db> {
12671199 };
12681200 let trait_data = trait_.trait_items(self.db);
12691201 if let Some(func) = trait_data.method_by_name(&fn_x.method_name()) {
1270 let subst = TyBuilder::subst_for_def(self.db, trait_, None)
1271 .push(callee_ty.clone())
1272 .push(TyBuilder::tuple_with(params.iter().cloned()))
1273 .build();
1202 let subst = GenericArgs::new_from_iter(
1203 self.interner(),
1204 [
1205 callee_ty.into(),
1206 Ty::new_tup_from_iter(self.interner(), params.iter().copied()).into(),
1207 ],
1208 );
12741209 self.write_method_resolution(tgt_expr, func, subst);
12751210 }
12761211 }
12771212
1278 fn infer_expr_array(
1279 &mut self,
1280 array: &Array,
1281 expected: &Expectation,
1282 ) -> chalk_ir::Ty<Interner> {
1283 let elem_ty = match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(Interner)) {
1284 Some(TyKind::Array(st, _) | TyKind::Slice(st)) => st.clone(),
1285 _ => self.table.new_type_var(),
1213 fn infer_expr_array(&mut self, array: &Array, expected: &Expectation<'db>) -> Ty<'db> {
1214 let elem_ty = match expected.to_option(&mut self.table).as_ref().map(|t| t.kind()) {
1215 Some(TyKind::Array(st, _) | TyKind::Slice(st)) => st,
1216 _ => self.table.next_ty_var(),
12861217 };
12871218
12881219 let krate = self.resolver.krate();
12891220
1290 let expected = Expectation::has_type(elem_ty.clone());
1221 let expected = Expectation::has_type(elem_ty);
12911222 let (elem_ty, len) = match array {
12921223 Array::ElementList { elements, .. } if elements.is_empty() => {
12931224 (elem_ty, consteval::usize_const(self.db, Some(0), krate))
12941225 }
12951226 Array::ElementList { elements, .. } => {
1296 let mut coerce = CoerceMany::with_coercion_sites(
1297 elem_ty.to_nextsolver(self.table.interner),
1298 elements,
1299 );
1227 let mut coerce = CoerceMany::with_coercion_sites(elem_ty, elements);
13001228 for &expr in elements.iter() {
13011229 let cur_elem_ty = self.infer_expr_inner(expr, &expected, ExprIsRead::Yes);
1302 coerce.coerce(
1303 self,
1304 &ObligationCause::new(),
1305 expr,
1306 cur_elem_ty.to_nextsolver(self.table.interner),
1307 );
1230 coerce.coerce(self, &ObligationCause::new(), expr, cur_elem_ty);
13081231 }
13091232 (
1310 coerce.complete(self).to_chalk(self.table.interner),
1233 coerce.complete(self),
13111234 consteval::usize_const(self.db, Some(elements.len() as u128), krate),
13121235 )
13131236 }
13141237 &Array::Repeat { initializer, repeat } => {
13151238 self.infer_expr_coerce(
13161239 initializer,
1317 &Expectation::has_type(elem_ty.clone()),
1240 &Expectation::has_type(elem_ty),
13181241 ExprIsRead::Yes,
13191242 );
1320 let usize = TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner);
1243 let usize = self.types.usize;
13211244 match self.body[repeat] {
13221245 Expr::Underscore => {
13231246 self.write_expr_ty(repeat, usize);
......@@ -1325,20 +1248,12 @@ impl<'db> InferenceContext<'db> {
13251248 _ => _ = self.infer_expr(repeat, &Expectation::HasType(usize), ExprIsRead::Yes),
13261249 }
13271250
1328 (
1329 elem_ty,
1330 consteval::eval_to_const(
1331 repeat,
1332 ParamLoweringMode::Placeholder,
1333 self,
1334 DebruijnIndex::INNERMOST,
1335 ),
1336 )
1251 (elem_ty, consteval::eval_to_const(repeat, self))
13371252 }
13381253 };
13391254 // Try to evaluate unevaluated constant, and insert variable if is not possible.
13401255 let len = self.table.insert_const_vars_shallow(len);
1341 TyKind::Array(elem_ty, len).intern(Interner)
1256 Ty::new_array_with_const_len(self.interner(), elem_ty, len)
13421257 }
13431258
13441259 pub(super) fn infer_return(&mut self, expr: ExprId) {
......@@ -1346,21 +1261,15 @@ impl<'db> InferenceContext<'db> {
13461261 .return_coercion
13471262 .as_mut()
13481263 .expect("infer_return called outside function body")
1349 .expected_ty()
1350 .to_chalk(self.table.interner);
1264 .expected_ty();
13511265 let return_expr_ty =
13521266 self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
13531267 let mut coerce_many = self.return_coercion.take().unwrap();
1354 coerce_many.coerce(
1355 self,
1356 &ObligationCause::new(),
1357 expr,
1358 return_expr_ty.to_nextsolver(self.table.interner),
1359 );
1268 coerce_many.coerce(self, &ObligationCause::new(), expr, return_expr_ty);
13601269 self.return_coercion = Some(coerce_many);
13611270 }
13621271
1363 fn infer_expr_return(&mut self, ret: ExprId, expr: Option<ExprId>) -> Ty {
1272 fn infer_expr_return(&mut self, ret: ExprId, expr: Option<ExprId>) -> Ty<'db> {
13641273 match self.return_coercion {
13651274 Some(_) => {
13661275 if let Some(expr) = expr {
......@@ -1378,23 +1287,20 @@ impl<'db> InferenceContext<'db> {
13781287 }
13791288 }
13801289 }
1381 self.result.standard_types.never.clone()
1290 self.types.never
13821291 }
13831292
1384 fn infer_expr_become(&mut self, expr: ExprId) -> Ty {
1293 fn infer_expr_become(&mut self, expr: ExprId) -> Ty<'db> {
13851294 match &self.return_coercion {
13861295 Some(return_coercion) => {
1387 let ret_ty = return_coercion.expected_ty().to_chalk(self.table.interner);
1296 let ret_ty = return_coercion.expected_ty();
13881297
1389 let call_expr_ty = self.infer_expr_inner(
1390 expr,
1391 &Expectation::HasType(ret_ty.clone()),
1392 ExprIsRead::Yes,
1393 );
1298 let call_expr_ty =
1299 self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
13941300
13951301 // NB: this should *not* coerce.
13961302 // tail calls don't support any coercions except lifetimes ones (like `&'static u8 -> &'a u8`).
1397 self.unify(&call_expr_ty, &ret_ty);
1303 self.unify(call_expr_ty, ret_ty);
13981304 }
13991305 None => {
14001306 // FIXME: diagnose `become` outside of functions
......@@ -1402,10 +1308,10 @@ impl<'db> InferenceContext<'db> {
14021308 }
14031309 }
14041310
1405 self.result.standard_types.never.clone()
1311 self.types.never
14061312 }
14071313
1408 fn infer_expr_box(&mut self, inner_expr: ExprId, expected: &Expectation) -> Ty {
1314 fn infer_expr_box(&mut self, inner_expr: ExprId, expected: &Expectation<'db>) -> Ty<'db> {
14091315 if let Some(box_id) = self.resolve_boxed_box() {
14101316 let table = &mut self.table;
14111317 let inner_exp = expected
......@@ -1414,16 +1320,22 @@ impl<'db> InferenceContext<'db> {
14141320 .and_then(|e| e.as_adt())
14151321 .filter(|(e_adt, _)| e_adt == &box_id)
14161322 .map(|(_, subts)| {
1417 let g = subts.at(Interner, 0);
1418 Expectation::rvalue_hint(self, Ty::clone(g.assert_ty_ref(Interner)))
1323 let g = subts.type_at(0);
1324 Expectation::rvalue_hint(self, g)
14191325 })
14201326 .unwrap_or_else(Expectation::none);
14211327
14221328 let inner_ty = self.infer_expr_inner(inner_expr, &inner_exp, ExprIsRead::Yes);
1423 TyBuilder::adt(self.db, box_id)
1424 .push(inner_ty)
1425 .fill_with_defaults(self.db, || self.table.new_type_var())
1426 .build()
1329 Ty::new_adt(
1330 self.interner(),
1331 box_id,
1332 GenericArgs::fill_with_defaults(
1333 self.interner(),
1334 box_id.into(),
1335 [inner_ty.into()],
1336 |_, _, id, _| self.table.next_var_for_param(id),
1337 ),
1338 )
14271339 } else {
14281340 self.err_ty()
14291341 }
......@@ -1435,7 +1347,7 @@ impl<'db> InferenceContext<'db> {
14351347 op: BinaryOp,
14361348 rhs: ExprId,
14371349 tgt_expr: ExprId,
1438 ) -> Ty {
1350 ) -> Ty<'db> {
14391351 let lhs_expectation = Expectation::none();
14401352 let is_read = if matches!(op, BinaryOp::Assignment { .. }) {
14411353 ExprIsRead::Yes
......@@ -1443,24 +1355,24 @@ impl<'db> InferenceContext<'db> {
14431355 ExprIsRead::No
14441356 };
14451357 let lhs_ty = self.infer_expr(lhs, &lhs_expectation, is_read);
1446 let rhs_ty = self.table.new_type_var();
1358 let rhs_ty = self.table.next_ty_var();
14471359
14481360 let trait_func = lang_items_for_bin_op(op).and_then(|(name, lang_item)| {
14491361 let trait_id = self.resolve_lang_item(lang_item)?.as_trait()?;
14501362 let func = trait_id.trait_items(self.db).method_by_name(&name)?;
14511363 Some((trait_id, func))
14521364 });
1453 let (trait_, func) = match trait_func {
1454 Some(it) => it,
1365 let func = match trait_func {
1366 Some((_, it)) => it,
14551367 None => {
14561368 // HACK: `rhs_ty` is a general inference variable with no clue at all at this
14571369 // point. Passing `lhs_ty` as both operands just to check if `lhs_ty` is a builtin
14581370 // type applicable to `op`.
1459 let ret_ty = if self.is_builtin_binop(&lhs_ty, &lhs_ty, op) {
1371 let ret_ty = if self.is_builtin_binop(lhs_ty, lhs_ty, op) {
14601372 // Assume both operands are builtin so we can continue inference. No guarantee
14611373 // on the correctness, rustc would complain as necessary lang items don't seem
14621374 // to exist anyway.
1463 self.enforce_builtin_binop_types(&lhs_ty, &rhs_ty, op)
1375 self.enforce_builtin_binop_types(lhs_ty, rhs_ty, op)
14641376 } else {
14651377 self.err_ty()
14661378 };
......@@ -1473,59 +1385,53 @@ impl<'db> InferenceContext<'db> {
14731385
14741386 // HACK: We can use this substitution for the function because the function itself doesn't
14751387 // have its own generic parameters.
1476 let subst = TyBuilder::subst_for_def(self.db, trait_, None);
1477 if subst.remaining() != 2 {
1478 return Ty::new(Interner, TyKind::Error);
1479 }
1480 let subst = subst.push(lhs_ty.clone()).push(rhs_ty.clone()).build();
1388 let args = GenericArgs::new_from_iter(self.interner(), [lhs_ty.into(), rhs_ty.into()]);
14811389
1482 self.write_method_resolution(tgt_expr, func, subst.clone());
1390 self.write_method_resolution(tgt_expr, func, args);
14831391
1484 let interner = DbInterner::new_with(self.db, None, None);
1485 let args: crate::next_solver::GenericArgs<'_> = subst.to_nextsolver(interner);
1486 let method_ty =
1487 self.db.value_ty(func.into()).unwrap().instantiate(interner, args).to_chalk(interner);
1488 self.register_obligations_for_call(&method_ty);
1392 let method_ty = self.db.value_ty(func.into()).unwrap().instantiate(self.interner(), args);
1393 self.register_obligations_for_call(method_ty);
14891394
1490 self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty.clone()), ExprIsRead::Yes);
1395 self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty), ExprIsRead::Yes);
14911396
1492 let ret_ty = match method_ty.callable_sig(self.db) {
1397 let ret_ty = match method_ty.callable_sig(self.interner()) {
14931398 Some(sig) => {
1494 let p_left = &sig.params()[0];
1399 let sig = sig.skip_binder();
1400 let p_left = sig.inputs_and_output.as_slice()[0];
14951401 if matches!(op, BinaryOp::CmpOp(..) | BinaryOp::Assignment { .. })
1496 && let TyKind::Ref(mtbl, lt, _) = p_left.kind(Interner)
1402 && let TyKind::Ref(lt, _, mtbl) = p_left.kind()
14971403 {
14981404 self.write_expr_adj(
14991405 lhs,
15001406 Box::new([Adjustment {
1501 kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
1502 target: p_left.clone(),
1407 kind: Adjust::Borrow(AutoBorrow::Ref(lt, mtbl)),
1408 target: p_left,
15031409 }]),
15041410 );
15051411 }
1506 let p_right = &sig.params()[1];
1412 let p_right = sig.inputs_and_output.as_slice()[1];
15071413 if matches!(op, BinaryOp::CmpOp(..))
1508 && let TyKind::Ref(mtbl, lt, _) = p_right.kind(Interner)
1414 && let TyKind::Ref(lt, _, mtbl) = p_right.kind()
15091415 {
15101416 self.write_expr_adj(
15111417 rhs,
15121418 Box::new([Adjustment {
1513 kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
1514 target: p_right.clone(),
1419 kind: Adjust::Borrow(AutoBorrow::Ref(lt, mtbl)),
1420 target: p_right,
15151421 }]),
15161422 );
15171423 }
1518 sig.ret().clone()
1424 sig.output()
15191425 }
15201426 None => self.err_ty(),
15211427 };
15221428
15231429 let ret_ty = self.process_remote_user_written_ty(ret_ty);
15241430
1525 if self.is_builtin_binop(&lhs_ty, &rhs_ty, op) {
1431 if self.is_builtin_binop(lhs_ty, rhs_ty, op) {
15261432 // use knowledge of built-in binary ops, which can sometimes help inference
1527 let builtin_ret = self.enforce_builtin_binop_types(&lhs_ty, &rhs_ty, op);
1528 self.unify(&builtin_ret, &ret_ty);
1433 let builtin_ret = self.enforce_builtin_binop_types(lhs_ty, rhs_ty, op);
1434 self.unify(builtin_ret, ret_ty);
15291435 builtin_ret
15301436 } else {
15311437 ret_ty
......@@ -1539,8 +1445,8 @@ impl<'db> InferenceContext<'db> {
15391445 statements: &[Statement],
15401446 tail: Option<ExprId>,
15411447 label: Option<LabelId>,
1542 expected: &Expectation,
1543 ) -> Ty {
1448 expected: &Expectation<'db>,
1449 ) -> Ty<'db> {
15441450 let coerce_ty = expected.coercion_target_type(&mut self.table);
15451451 let g = self.resolver.update_to_inner_scope(self.db, self.owner, expr);
15461452 let prev_env = block_id.map(|block_id| {
......@@ -1557,7 +1463,7 @@ impl<'db> InferenceContext<'db> {
15571463 let decl_ty = type_ref
15581464 .as_ref()
15591465 .map(|&tr| this.make_body_ty(tr))
1560 .unwrap_or_else(|| this.table.new_type_var());
1466 .unwrap_or_else(|| this.table.next_ty_var());
15611467
15621468 let ty = if let Some(expr) = initializer {
15631469 // If we have a subpattern that performs a read, we want to consider this
......@@ -1571,13 +1477,13 @@ impl<'db> InferenceContext<'db> {
15711477 let ty = if contains_explicit_ref_binding(this.body, *pat) {
15721478 this.infer_expr(
15731479 *expr,
1574 &Expectation::has_type(decl_ty.clone()),
1480 &Expectation::has_type(decl_ty),
15751481 target_is_read,
15761482 )
15771483 } else {
15781484 this.infer_expr_coerce(
15791485 *expr,
1580 &Expectation::has_type(decl_ty.clone()),
1486 &Expectation::has_type(decl_ty),
15811487 target_is_read,
15821488 )
15831489 };
......@@ -1590,13 +1496,13 @@ impl<'db> InferenceContext<'db> {
15901496 origin: DeclOrigin::LocalDecl { has_else: else_branch.is_some() },
15911497 };
15921498
1593 this.infer_top_pat(*pat, &ty, Some(decl));
1499 this.infer_top_pat(*pat, ty, Some(decl));
15941500 if let Some(expr) = else_branch {
15951501 let previous_diverges =
15961502 mem::replace(&mut this.diverges, Diverges::Maybe);
15971503 this.infer_expr_coerce(
15981504 *expr,
1599 &Expectation::HasType(this.result.standard_types.never.clone()),
1505 &Expectation::HasType(this.types.never),
16001506 ExprIsRead::Yes,
16011507 );
16021508 this.diverges = previous_diverges;
......@@ -1608,7 +1514,7 @@ impl<'db> InferenceContext<'db> {
16081514 } else {
16091515 this.infer_expr_coerce(
16101516 expr,
1611 &Expectation::HasType(this.result.standard_types.unit.clone()),
1517 &Expectation::HasType(this.types.unit),
16121518 ExprIsRead::Yes,
16131519 );
16141520 }
......@@ -1642,8 +1548,8 @@ impl<'db> InferenceContext<'db> {
16421548 if this
16431549 .coerce(
16441550 expr.into(),
1645 this.result.standard_types.unit.to_nextsolver(this.table.interner),
1646 t.to_nextsolver(this.table.interner),
1551 this.types.unit,
1552 t,
16471553 AllowTwoPhase::No,
16481554 coerce_never,
16491555 )
......@@ -1651,15 +1557,12 @@ impl<'db> InferenceContext<'db> {
16511557 {
16521558 this.result.type_mismatches.insert(
16531559 expr.into(),
1654 TypeMismatch {
1655 expected: t.clone(),
1656 actual: this.result.standard_types.unit.clone(),
1657 },
1560 TypeMismatch { expected: t, actual: this.types.unit },
16581561 );
16591562 }
16601563 t
16611564 } else {
1662 this.result.standard_types.unit.clone()
1565 this.types.unit
16631566 }
16641567 }
16651568 });
......@@ -1673,32 +1576,30 @@ impl<'db> InferenceContext<'db> {
16731576
16741577 fn lookup_field(
16751578 &mut self,
1676 receiver_ty: &Ty,
1579 receiver_ty: Ty<'db>,
16771580 name: &Name,
1678 ) -> Option<(Ty, Either<FieldId, TupleFieldId>, Vec<Adjustment>, bool)> {
1679 let interner = self.table.interner;
1680 let mut autoderef = self.table.autoderef(receiver_ty.to_nextsolver(self.table.interner));
1581 ) -> Option<(Ty<'db>, Either<FieldId, TupleFieldId>, Vec<Adjustment<'db>>, bool)> {
1582 let interner = self.interner();
1583 let mut autoderef = self.table.autoderef(receiver_ty);
16811584 let mut private_field = None;
16821585 let res = autoderef.by_ref().find_map(|(derefed_ty, _)| {
16831586 let (field_id, parameters) = match derefed_ty.kind() {
1684 crate::next_solver::TyKind::Tuple(substs) => {
1587 TyKind::Tuple(substs) => {
16851588 return name.as_tuple_index().and_then(|idx| {
16861589 substs.as_slice().get(idx).copied().map(|ty| {
16871590 (
16881591 Either::Right(TupleFieldId {
16891592 tuple: TupleId(
1690 self.tuple_field_accesses_rev
1691 .insert_full(substs.to_chalk(interner))
1692 .0 as u32,
1593 self.tuple_field_accesses_rev.insert_full(substs).0 as u32,
16931594 ),
16941595 index: idx as u32,
16951596 }),
1696 ty.to_chalk(interner),
1597 ty,
16971598 )
16981599 })
16991600 });
17001601 }
1701 crate::next_solver::TyKind::Adt(adt, parameters) => match adt.def_id().0 {
1602 TyKind::Adt(adt, parameters) => match adt.def_id().0 {
17021603 hir_def::AdtId::StructId(s) => {
17031604 let local_id = s.fields(self.db).field(name)?;
17041605 let field = FieldId { parent: s.into(), local_id };
......@@ -1713,18 +1614,16 @@ impl<'db> InferenceContext<'db> {
17131614 },
17141615 _ => return None,
17151616 };
1716 let parameters: crate::Substitution = parameters.to_chalk(interner);
17171617 let is_visible = self.db.field_visibilities(field_id.parent)[field_id.local_id]
17181618 .is_visible_from(self.db, self.resolver.module());
17191619 if !is_visible {
17201620 if private_field.is_none() {
1721 private_field = Some((field_id, parameters.clone()));
1621 private_field = Some((field_id, parameters));
17221622 }
17231623 return None;
17241624 }
1725 let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1726 .clone()
1727 .substitute(Interner, &parameters);
1625 let ty = self.db.field_types_ns(field_id.parent)[field_id.local_id]
1626 .instantiate(interner, parameters);
17281627 Some((Either::Left(field_id), ty))
17291628 });
17301629
......@@ -1738,9 +1637,8 @@ impl<'db> InferenceContext<'db> {
17381637 None => {
17391638 let (field_id, subst) = private_field?;
17401639 let adjustments = autoderef.adjust_steps();
1741 let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1742 .clone()
1743 .substitute(Interner, &subst);
1640 let ty = self.db.field_types_ns(field_id.parent)[field_id.local_id]
1641 .instantiate(self.interner(), subst);
17441642 let ty = self.process_remote_user_written_ty(ty);
17451643
17461644 (ty, Either::Left(field_id), adjustments, false)
......@@ -1753,8 +1651,8 @@ impl<'db> InferenceContext<'db> {
17531651 tgt_expr: ExprId,
17541652 receiver: ExprId,
17551653 name: &Name,
1756 expected: &Expectation,
1757 ) -> Ty {
1654 expected: &Expectation<'db>,
1655 ) -> Ty<'db> {
17581656 // Field projections don't constitute reads.
17591657 let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::No);
17601658
......@@ -1764,7 +1662,7 @@ impl<'db> InferenceContext<'db> {
17641662 return self.err_ty();
17651663 }
17661664
1767 match self.lookup_field(&receiver_ty, name) {
1665 match self.lookup_field(receiver_ty, name) {
17681666 Some((ty, field_id, adjustments, is_public)) => {
17691667 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
17701668 self.result.field_resolutions.insert(tgt_expr, field_id);
......@@ -1780,8 +1678,7 @@ impl<'db> InferenceContext<'db> {
17801678 None => {
17811679 // no field found, lets attempt to resolve it like a function so that IDE things
17821680 // work out while people are typing
1783 let canonicalized_receiver =
1784 self.canonicalize(receiver_ty.clone().to_nextsolver(self.table.interner));
1681 let canonicalized_receiver = self.canonicalize(receiver_ty);
17851682 let resolved = method_resolution::lookup_method(
17861683 self.db,
17871684 &canonicalized_receiver,
......@@ -1792,28 +1689,24 @@ impl<'db> InferenceContext<'db> {
17921689 );
17931690 self.push_diagnostic(InferenceDiagnostic::UnresolvedField {
17941691 expr: tgt_expr,
1795 receiver: receiver_ty.clone(),
1692 receiver: receiver_ty,
17961693 name: name.clone(),
17971694 method_with_same_name_exists: resolved.is_some(),
17981695 });
17991696 match resolved {
18001697 Some((adjust, func, _)) => {
18011698 let (ty, adjustments) = adjust.apply(&mut self.table, receiver_ty);
1802 let substs = self.substs_for_method_call(tgt_expr, func.into(), None);
1699 let args = self.substs_for_method_call(tgt_expr, func.into(), None);
18031700 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1804 self.write_method_resolution(tgt_expr, func, substs.clone());
1701 self.write_method_resolution(tgt_expr, func, args);
18051702
1806 let interner = DbInterner::new_with(self.db, None, None);
1807 let args: crate::next_solver::GenericArgs<'_> =
1808 substs.to_nextsolver(interner);
18091703 self.check_method_call(
18101704 tgt_expr,
18111705 &[],
18121706 self.db
18131707 .value_ty(func.into())
18141708 .unwrap()
1815 .instantiate(interner, args)
1816 .to_chalk(interner),
1709 .instantiate(self.interner(), args),
18171710 ty,
18181711 expected,
18191712 )
......@@ -1829,47 +1722,42 @@ impl<'db> InferenceContext<'db> {
18291722 tgt_expr: ExprId,
18301723 callee: ExprId,
18311724 args: &[ExprId],
1832 expected: &Expectation,
1833 ) -> Ty {
1725 expected: &Expectation<'db>,
1726 ) -> Ty<'db> {
18341727 let callee_ty = self.infer_expr(callee, &Expectation::none(), ExprIsRead::Yes);
1835 let interner = self.table.interner;
1836 let mut derefs = self.table.autoderef(callee_ty.to_nextsolver(interner));
1728 let interner = self.interner();
1729 let mut derefs = self.table.autoderef(callee_ty);
18371730 let (res, derefed_callee) = loop {
18381731 let Some((callee_deref_ty, _)) = derefs.next() else {
1839 break (None, callee_ty.clone());
1732 break (None, callee_ty);
18401733 };
1841 let callee_deref_ty = callee_deref_ty.to_chalk(interner);
1842 if let Some(res) = derefs.table.callable_sig(&callee_deref_ty, args.len()) {
1734 if let Some(res) = derefs.table.callable_sig(callee_deref_ty, args.len()) {
18431735 break (Some(res), callee_deref_ty);
18441736 }
18451737 };
18461738 // if the function is unresolved, we use is_varargs=true to
18471739 // suppress the arg count diagnostic here
1848 let is_varargs =
1849 derefed_callee.callable_sig(self.db).is_some_and(|sig| sig.is_varargs) || res.is_none();
1740 let is_varargs = derefed_callee.callable_sig(interner).is_some_and(|sig| sig.c_variadic())
1741 || res.is_none();
18501742 let (param_tys, ret_ty) = match res {
18511743 Some((func, params, ret_ty)) => {
1852 let params_chalk =
1853 params.iter().map(|param| param.to_chalk(interner)).collect::<Vec<_>>();
18541744 let mut adjustments = derefs.adjust_steps();
18551745 if let Some(fn_x) = func {
18561746 self.write_fn_trait_method_resolution(
18571747 fn_x,
1858 &derefed_callee,
1748 derefed_callee,
18591749 &mut adjustments,
1860 &callee_ty,
1861 &params_chalk,
1750 callee_ty,
1751 &params,
18621752 tgt_expr,
18631753 );
18641754 }
1865 if let &TyKind::Closure(c, _) =
1866 self.table.resolve_completely(callee_ty.clone()).kind(Interner)
1867 {
1755 if let TyKind::Closure(c, _) = self.table.resolve_completely(callee_ty).kind() {
18681756 self.add_current_closure_dependency(c.into());
18691757 self.deferred_closures.entry(c.into()).or_default().push((
1870 derefed_callee.clone(),
1871 callee_ty.clone(),
1872 params_chalk,
1758 derefed_callee,
1759 callee_ty,
1760 params.clone(),
18731761 tgt_expr,
18741762 ));
18751763 }
......@@ -1879,9 +1767,9 @@ impl<'db> InferenceContext<'db> {
18791767 None => {
18801768 self.push_diagnostic(InferenceDiagnostic::ExpectedFunction {
18811769 call_expr: tgt_expr,
1882 found: callee_ty.clone(),
1770 found: callee_ty,
18831771 });
1884 (Vec::new(), crate::next_solver::Ty::new_error(interner, ErrorGuaranteed))
1772 (Vec::new(), Ty::new_error(interner, ErrorGuaranteed))
18851773 }
18861774 };
18871775 let indices_to_skip = self.check_legacy_const_generics(derefed_callee, args);
......@@ -1901,14 +1789,14 @@ impl<'db> InferenceContext<'db> {
19011789 &mut self,
19021790 tgt_expr: ExprId,
19031791 args: &[ExprId],
1904 callee_ty: Ty,
1905 param_tys: &[crate::next_solver::Ty<'db>],
1906 ret_ty: crate::next_solver::Ty<'db>,
1792 callee_ty: Ty<'db>,
1793 param_tys: &[Ty<'db>],
1794 ret_ty: Ty<'db>,
19071795 indices_to_skip: &[u32],
19081796 is_varargs: bool,
1909 expected: &Expectation,
1910 ) -> Ty {
1911 self.register_obligations_for_call(&callee_ty);
1797 expected: &Expectation<'db>,
1798 ) -> Ty<'db> {
1799 self.register_obligations_for_call(callee_ty);
19121800
19131801 self.check_call_arguments(
19141802 tgt_expr,
......@@ -1919,7 +1807,7 @@ impl<'db> InferenceContext<'db> {
19191807 indices_to_skip,
19201808 is_varargs,
19211809 );
1922 self.table.normalize_associated_types_in_ns(ret_ty).to_chalk(self.table.interner)
1810 self.table.normalize_associated_types_in(ret_ty)
19231811 }
19241812
19251813 fn infer_method_call(
......@@ -1928,16 +1816,13 @@ impl<'db> InferenceContext<'db> {
19281816 receiver: ExprId,
19291817 args: &[ExprId],
19301818 method_name: &Name,
1931 generic_args: Option<&GenericArgs>,
1932 expected: &Expectation,
1933 ) -> Ty {
1819 generic_args: Option<&HirGenericArgs>,
1820 expected: &Expectation<'db>,
1821 ) -> Ty<'db> {
19341822 let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::Yes);
1935 let receiver_ty = self.table.structurally_resolve_type(&receiver_ty);
1823 let receiver_ty = self.table.try_structurally_resolve_type(receiver_ty);
19361824
1937 if matches!(
1938 receiver_ty.kind(Interner),
1939 TyKind::Error | TyKind::InferenceVar(_, TyVariableKind::General)
1940 ) {
1825 if matches!(receiver_ty.kind(), TyKind::Error(_) | TyKind::Infer(InferTy::TyVar(_))) {
19411826 // Don't probe on error type, or on a fully unresolved infer var.
19421827 // FIXME: Emit an error if we're probing on an infer var (type annotations needed).
19431828 for &arg in args {
......@@ -1947,8 +1832,7 @@ impl<'db> InferenceContext<'db> {
19471832 return receiver_ty;
19481833 }
19491834
1950 let canonicalized_receiver =
1951 self.canonicalize(receiver_ty.clone().to_nextsolver(self.table.interner));
1835 let canonicalized_receiver = self.canonicalize(receiver_ty);
19521836
19531837 let resolved = method_resolution::lookup_method(
19541838 self.db,
......@@ -1970,18 +1854,16 @@ impl<'db> InferenceContext<'db> {
19701854 let (ty, adjustments) = adjust.apply(&mut self.table, receiver_ty);
19711855 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
19721856
1973 let substs = self.substs_for_method_call(tgt_expr, func.into(), generic_args);
1974 self.write_method_resolution(tgt_expr, func, substs.clone());
1857 let gen_args = self.substs_for_method_call(tgt_expr, func.into(), generic_args);
1858 self.write_method_resolution(tgt_expr, func, gen_args);
19751859 let interner = DbInterner::new_with(self.db, None, None);
1976 let gen_args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
19771860 self.check_method_call(
19781861 tgt_expr,
19791862 args,
19801863 self.db
19811864 .value_ty(func.into())
19821865 .expect("we have a function def")
1983 .instantiate(interner, gen_args)
1984 .to_chalk(interner),
1866 .instantiate(interner, gen_args),
19851867 ty,
19861868 expected,
19871869 )
......@@ -1989,7 +1871,7 @@ impl<'db> InferenceContext<'db> {
19891871 // Failed to resolve, report diagnostic and try to resolve as call to field access or
19901872 // assoc function
19911873 None => {
1992 let field_with_same_name_exists = match self.lookup_field(&receiver_ty, method_name)
1874 let field_with_same_name_exists = match self.lookup_field(receiver_ty, method_name)
19931875 {
19941876 Some((ty, field_id, adjustments, _public)) => {
19951877 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
......@@ -2017,48 +1899,46 @@ impl<'db> InferenceContext<'db> {
20171899
20181900 self.push_diagnostic(InferenceDiagnostic::UnresolvedMethodCall {
20191901 expr: tgt_expr,
2020 receiver: receiver_ty.clone(),
1902 receiver: receiver_ty,
20211903 name: method_name.clone(),
2022 field_with_same_name: field_with_same_name_exists.clone(),
1904 field_with_same_name: field_with_same_name_exists,
20231905 assoc_func_with_same_name,
20241906 });
20251907
20261908 let recovered = match assoc_func_with_same_name {
20271909 Some(f) => {
2028 let substs = self.substs_for_method_call(tgt_expr, f.into(), generic_args);
1910 let args = self.substs_for_method_call(tgt_expr, f.into(), generic_args);
20291911 let interner = DbInterner::new_with(self.db, None, None);
2030 let args: crate::next_solver::GenericArgs<'_> =
2031 substs.to_nextsolver(interner);
20321912 let f = self
20331913 .db
20341914 .value_ty(f.into())
20351915 .expect("we have a function def")
2036 .instantiate(interner, args)
2037 .to_chalk(interner);
2038 let sig = f.callable_sig(self.db).expect("we have a function def");
1916 .instantiate(interner, args);
1917 let sig = f.callable_sig(self.interner()).expect("we have a function def");
20391918 Some((f, sig, true))
20401919 }
20411920 None => field_with_same_name_exists.and_then(|field_ty| {
2042 let callable_sig = field_ty.callable_sig(self.db)?;
1921 let callable_sig = field_ty.callable_sig(self.interner())?;
20431922 Some((field_ty, callable_sig, false))
20441923 }),
20451924 };
20461925 match recovered {
2047 Some((callee_ty, sig, strip_first)) => self.check_call(
2048 tgt_expr,
2049 args,
2050 callee_ty,
2051 &sig.params()
2052 .get(strip_first as usize..)
2053 .unwrap_or(&[])
2054 .iter()
2055 .map(|param| param.to_nextsolver(self.table.interner))
2056 .collect::<Vec<_>>(),
2057 sig.ret().to_nextsolver(self.table.interner),
2058 &[],
2059 true,
2060 expected,
2061 ),
1926 Some((callee_ty, sig, strip_first)) => {
1927 let sig = sig.skip_binder();
1928 self.check_call(
1929 tgt_expr,
1930 args,
1931 callee_ty,
1932 sig.inputs_and_output
1933 .inputs()
1934 .get(strip_first as usize..)
1935 .unwrap_or(&[]),
1936 sig.output(),
1937 &[],
1938 true,
1939 expected,
1940 )
1941 }
20621942 None => {
20631943 for &arg in args.iter() {
20641944 self.infer_expr_no_expect(arg, ExprIsRead::Yes);
......@@ -2074,39 +1954,38 @@ impl<'db> InferenceContext<'db> {
20741954 &mut self,
20751955 tgt_expr: ExprId,
20761956 args: &[ExprId],
2077 method_ty: Ty,
2078 receiver_ty: Ty,
2079 expected: &Expectation,
2080 ) -> Ty {
2081 self.register_obligations_for_call(&method_ty);
2082 let interner = self.table.interner;
1957 method_ty: Ty<'db>,
1958 receiver_ty: Ty<'db>,
1959 expected: &Expectation<'db>,
1960 ) -> Ty<'db> {
1961 self.register_obligations_for_call(method_ty);
20831962 let ((formal_receiver_ty, param_tys), ret_ty, is_varargs) =
2084 match method_ty.callable_sig(self.db) {
2085 Some(sig) => (
2086 if !sig.params().is_empty() {
2087 (
2088 sig.params()[0].to_nextsolver(interner),
2089 sig.params()[1..]
2090 .iter()
2091 .map(|param| param.to_nextsolver(interner))
2092 .collect(),
2093 )
2094 } else {
2095 (crate::next_solver::Ty::new_error(interner, ErrorGuaranteed), Vec::new())
2096 },
2097 sig.ret().to_nextsolver(interner),
2098 sig.is_varargs,
2099 ),
1963 match method_ty.callable_sig(self.interner()) {
1964 Some(sig) => {
1965 let sig = sig.skip_binder();
1966 (
1967 if !sig.inputs_and_output.inputs().is_empty() {
1968 (
1969 sig.inputs_and_output.as_slice()[0],
1970 sig.inputs_and_output.inputs()[1..].to_vec(),
1971 )
1972 } else {
1973 (self.types.error, Vec::new())
1974 },
1975 sig.output(),
1976 sig.c_variadic,
1977 )
1978 }
21001979 None => {
21011980 let formal_receiver_ty = self.table.next_ty_var();
21021981 let ret_ty = self.table.next_ty_var();
21031982 ((formal_receiver_ty, Vec::new()), ret_ty, true)
21041983 }
21051984 };
2106 self.table.unify_ns(formal_receiver_ty, receiver_ty.to_nextsolver(interner));
1985 self.table.unify(formal_receiver_ty, receiver_ty);
21071986
21081987 self.check_call_arguments(tgt_expr, &param_tys, ret_ty, expected, args, &[], is_varargs);
2109 self.table.normalize_associated_types_in_ns(ret_ty).to_chalk(interner)
1988 self.table.normalize_associated_types_in(ret_ty)
21101989 }
21111990
21121991 /// Generic function that factors out common logic from function calls,
......@@ -2115,18 +1994,16 @@ impl<'db> InferenceContext<'db> {
21151994 &mut self,
21161995 call_expr: ExprId,
21171996 // Types (as defined in the *signature* of the target function)
2118 formal_input_tys: &[crate::next_solver::Ty<'db>],
2119 formal_output: crate::next_solver::Ty<'db>,
1997 formal_input_tys: &[Ty<'db>],
1998 formal_output: Ty<'db>,
21201999 // Expected output from the parent expression or statement
2121 expectation: &Expectation,
2000 expectation: &Expectation<'db>,
21222001 // The expressions for each provided argument
21232002 provided_args: &[ExprId],
21242003 skip_indices: &[u32],
21252004 // Whether the function is variadic, for example when imported from C
21262005 c_variadic: bool,
21272006 ) {
2128 let interner = self.table.interner;
2129
21302007 // First, let's unify the formal method signature with the expectation eagerly.
21312008 // We use this to guide coercion inference; it's output is "fudged" which means
21322009 // any remaining type variables are assigned to new, unrelated variables. This
......@@ -2145,14 +2022,9 @@ impl<'db> InferenceContext<'db> {
21452022 // is polymorphic) and the expected return type.
21462023 // No argument expectations are produced if unification fails.
21472024 let origin = ObligationCause::new();
2148 ocx.sup(
2149 &origin,
2150 self.table.trait_env.env,
2151 expected_output.to_nextsolver(interner),
2152 formal_output,
2153 )?;
2025 ocx.sup(&origin, self.table.trait_env.env, expected_output, formal_output)?;
21542026 if !ocx.try_evaluate_obligations().is_empty() {
2155 return Err(crate::next_solver::TypeError::Mismatch);
2027 return Err(TypeError::Mismatch);
21562028 }
21572029
21582030 // Record all the argument types, with the args
......@@ -2200,9 +2072,9 @@ impl<'db> InferenceContext<'db> {
22002072 // We introduce a helper function to demand that a given argument satisfy a given input
22012073 // This is more complicated than just checking type equality, as arguments could be coerced
22022074 // This version writes those types back so further type checking uses the narrowed types
2203 let demand_compatible = |this: &mut InferenceContext<'db>, idx| {
2204 let formal_input_ty: crate::next_solver::Ty<'db> = formal_input_tys[idx];
2205 let expected_input_ty: crate::next_solver::Ty<'db> = expected_input_tys[idx];
2075 let demand_compatible = |this: &mut InferenceContext<'_, 'db>, idx| {
2076 let formal_input_ty: Ty<'db> = formal_input_tys[idx];
2077 let expected_input_ty: Ty<'db> = expected_input_tys[idx];
22062078 let provided_arg = provided_args[idx];
22072079
22082080 debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
......@@ -2210,19 +2082,14 @@ impl<'db> InferenceContext<'db> {
22102082 // We're on the happy path here, so we'll do a more involved check and write back types
22112083 // To check compatibility, we'll do 3 things:
22122084 // 1. Unify the provided argument with the expected type
2213 let expectation = Expectation::rvalue_hint(this, expected_input_ty.to_chalk(interner));
2085 let expectation = Expectation::rvalue_hint(this, expected_input_ty);
22142086
2215 let checked_ty = this
2216 .infer_expr_inner(provided_arg, &expectation, ExprIsRead::Yes)
2217 .to_nextsolver(interner);
2087 let checked_ty = this.infer_expr_inner(provided_arg, &expectation, ExprIsRead::Yes);
22182088
22192089 // 2. Coerce to the most detailed type that could be coerced
22202090 // to, which is `expected_ty` if `rvalue_hint` returns an
22212091 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2222 let coerced_ty = expectation
2223 .only_has_type(&mut this.table)
2224 .map(|it| it.to_nextsolver(interner))
2225 .unwrap_or(formal_input_ty);
2092 let coerced_ty = expectation.only_has_type(&mut this.table).unwrap_or(formal_input_ty);
22262093
22272094 // Cause selection errors caused by resolving a single argument to point at the
22282095 // argument and not the call. This lets us customize the span pointed to in the
......@@ -2259,7 +2126,7 @@ impl<'db> InferenceContext<'db> {
22592126
22602127 // If neither check failed, the types are compatible
22612128 match formal_ty_error {
2262 Ok(crate::next_solver::infer::InferOk { obligations, value: () }) => {
2129 Ok(InferOk { obligations, value: () }) => {
22632130 this.table.register_predicates(obligations);
22642131 Ok(())
22652132 }
......@@ -2313,13 +2180,9 @@ impl<'db> InferenceContext<'db> {
23132180 && args_count_matches
23142181 {
23152182 // Don't report type mismatches if there is a mismatch in args count.
2316 self.result.type_mismatches.insert(
2317 (*arg).into(),
2318 TypeMismatch {
2319 expected: expected.to_chalk(interner),
2320 actual: found.to_chalk(interner),
2321 },
2322 );
2183 self.result
2184 .type_mismatches
2185 .insert((*arg).into(), TypeMismatch { expected, actual: found });
23232186 }
23242187 }
23252188 }
......@@ -2331,14 +2194,14 @@ impl<'db> InferenceContext<'db> {
23312194 &mut self,
23322195 expr: ExprId,
23332196 def: GenericDefId,
2334 generic_args: Option<&GenericArgs>,
2335 ) -> Substitution {
2336 struct LowererCtx<'a, 'b> {
2337 ctx: &'a mut InferenceContext<'b>,
2197 generic_args: Option<&HirGenericArgs>,
2198 ) -> GenericArgs<'db> {
2199 struct LowererCtx<'a, 'b, 'db> {
2200 ctx: &'a mut InferenceContext<'b, 'db>,
23382201 expr: ExprId,
23392202 }
23402203
2341 impl GenericArgsLowerer for LowererCtx<'_, '_> {
2204 impl<'db> GenericArgsLowerer<'db> for LowererCtx<'_, '_, 'db> {
23422205 fn report_len_mismatch(
23432206 &mut self,
23442207 def: GenericDefId,
......@@ -2373,21 +2236,22 @@ impl<'db> InferenceContext<'db> {
23732236 &mut self,
23742237 param_id: GenericParamId,
23752238 param: GenericParamDataRef<'_>,
2376 arg: &GenericArg,
2377 ) -> crate::GenericArg {
2239 arg: &HirGenericArg,
2240 ) -> GenericArg<'db> {
23782241 match (param, arg) {
2379 (GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => {
2380 self.ctx.make_body_lifetime(*lifetime).cast(Interner)
2242 (
2243 GenericParamDataRef::LifetimeParamData(_),
2244 HirGenericArg::Lifetime(lifetime),
2245 ) => self.ctx.make_body_lifetime(*lifetime).into(),
2246 (GenericParamDataRef::TypeParamData(_), HirGenericArg::Type(type_ref)) => {
2247 self.ctx.make_body_ty(*type_ref).into()
23812248 }
2382 (GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => {
2383 self.ctx.make_body_ty(*type_ref).cast(Interner)
2384 }
2385 (GenericParamDataRef::ConstParamData(_), GenericArg::Const(konst)) => {
2249 (GenericParamDataRef::ConstParamData(_), HirGenericArg::Const(konst)) => {
23862250 let GenericParamId::ConstParamId(const_id) = param_id else {
23872251 unreachable!("non-const param ID for const param");
23882252 };
2389 let const_ty = self.ctx.db.const_param_ty(const_id);
2390 self.ctx.make_body_const(*konst, const_ty).cast(Interner)
2253 let const_ty = self.ctx.db.const_param_ty_ns(const_id);
2254 self.ctx.make_body_const(*konst, const_ty).into()
23912255 }
23922256 _ => unreachable!("unmatching param kinds were passed to `provided_kind()`"),
23932257 }
......@@ -2395,12 +2259,12 @@ impl<'db> InferenceContext<'db> {
23952259
23962260 fn provided_type_like_const(
23972261 &mut self,
2398 const_ty: Ty,
2262 const_ty: Ty<'db>,
23992263 arg: TypeLikeConst<'_>,
2400 ) -> crate::Const {
2264 ) -> Const<'db> {
24012265 match arg {
24022266 TypeLikeConst::Path(path) => self.ctx.make_path_as_body_const(path, const_ty),
2403 TypeLikeConst::Infer => self.ctx.table.new_const_var(const_ty),
2267 TypeLikeConst::Infer => self.ctx.table.next_const_var(),
24042268 }
24052269 }
24062270
......@@ -2410,35 +2274,15 @@ impl<'db> InferenceContext<'db> {
24102274 param_id: GenericParamId,
24112275 _param: GenericParamDataRef<'_>,
24122276 _infer_args: bool,
2413 _preceding_args: &[crate::GenericArg],
2414 ) -> crate::GenericArg {
2277 _preceding_args: &[GenericArg<'db>],
2278 ) -> GenericArg<'db> {
24152279 // Always create an inference var, even when `infer_args == false`. This helps with diagnostics,
24162280 // and I think it's also required in the presence of `impl Trait` (that must be inferred).
2417 match param_id {
2418 GenericParamId::TypeParamId(_) => self.ctx.table.new_type_var().cast(Interner),
2419 GenericParamId::ConstParamId(const_id) => self
2420 .ctx
2421 .table
2422 .new_const_var(self.ctx.db.const_param_ty(const_id))
2423 .cast(Interner),
2424 GenericParamId::LifetimeParamId(_) => {
2425 self.ctx.table.new_lifetime_var().cast(Interner)
2426 }
2427 }
2281 self.ctx.table.next_var_for_param(param_id)
24282282 }
24292283
2430 fn parent_arg(&mut self, param_id: GenericParamId) -> crate::GenericArg {
2431 match param_id {
2432 GenericParamId::TypeParamId(_) => self.ctx.table.new_type_var().cast(Interner),
2433 GenericParamId::ConstParamId(const_id) => self
2434 .ctx
2435 .table
2436 .new_const_var(self.ctx.db.const_param_ty(const_id))
2437 .cast(Interner),
2438 GenericParamId::LifetimeParamId(_) => {
2439 self.ctx.table.new_lifetime_var().cast(Interner)
2440 }
2441 }
2284 fn parent_arg(&mut self, param_id: GenericParamId) -> GenericArg<'db> {
2285 self.ctx.table.next_var_for_param(param_id)
24422286 }
24432287
24442288 fn report_elided_lifetimes_in_path(
......@@ -2472,36 +2316,34 @@ impl<'db> InferenceContext<'db> {
24722316 )
24732317 }
24742318
2475 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
2476 let callable_ty = self.table.structurally_resolve_type(callable_ty);
2477 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(Interner) {
2478 let def: CallableDefId = from_chalk(self.db, *fn_def);
2319 fn register_obligations_for_call(&mut self, callable_ty: Ty<'db>) {
2320 let callable_ty = self.table.try_structurally_resolve_type(callable_ty);
2321 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind() {
24792322 let generic_predicates =
2480 self.db.generic_predicates(GenericDefId::from_callable(self.db, def));
2481 for predicate in generic_predicates.iter() {
2482 let (predicate, binders) = predicate
2483 .clone()
2484 .substitute(Interner, parameters)
2485 .into_value_and_skipped_binders();
2486 always!(binders.len(Interner) == 0); // quantified where clauses not yet handled
2487 self.push_obligation(predicate.cast(Interner));
2323 self.db.generic_predicates_ns(GenericDefId::from_callable(self.db, fn_def.0));
2324 if let Some(predicates) = generic_predicates.instantiate(self.interner(), parameters) {
2325 let interner = self.interner();
2326 let param_env = self.table.trait_env.env;
2327 self.table.register_predicates(predicates.map(|predicate| {
2328 Obligation::new(interner, ObligationCause::new(), param_env, predicate)
2329 }));
24882330 }
24892331 // add obligation for trait implementation, if this is a trait method
2490 match def {
2332 match fn_def.0 {
24912333 CallableDefId::FunctionId(f) => {
24922334 if let ItemContainerId::TraitId(trait_) = f.lookup(self.db).container {
24932335 // construct a TraitRef
24942336 let trait_params_len = generics(self.db, trait_.into()).len();
2495 let substs = Substitution::from_iter(
2496 Interner,
2497 // The generic parameters for the trait come after those for the
2498 // function.
2499 &parameters.as_slice(Interner)[..trait_params_len],
2500 );
2501 self.push_obligation(
2502 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
2503 .cast(Interner),
2337 let substs = GenericArgs::new_from_iter(
2338 self.interner(),
2339 parameters.as_slice()[..trait_params_len].iter().copied(),
25042340 );
2341 self.table.register_predicate(Obligation::new(
2342 self.interner(),
2343 ObligationCause::new(),
2344 self.table.trait_env.env,
2345 TraitRef::new(self.interner(), trait_.into(), substs),
2346 ));
25052347 }
25062348 }
25072349 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
......@@ -2510,11 +2352,10 @@ impl<'db> InferenceContext<'db> {
25102352 }
25112353
25122354 /// Returns the argument indices to skip.
2513 fn check_legacy_const_generics(&mut self, callee: Ty, args: &[ExprId]) -> Box<[u32]> {
2514 let (func, subst) = match callee.kind(Interner) {
2515 TyKind::FnDef(fn_id, subst) => {
2516 let callable = CallableDefId::from_chalk(self.db, *fn_id);
2517 let func = match callable {
2355 fn check_legacy_const_generics(&mut self, callee: Ty<'db>, args: &[ExprId]) -> Box<[u32]> {
2356 let (func, _subst) = match callee.kind() {
2357 TyKind::FnDef(callable, subst) => {
2358 let func = match callable.0 {
25182359 CallableDefId::FunctionId(f) => f,
25192360 _ => return Default::default(),
25202361 };
......@@ -2542,15 +2383,10 @@ impl<'db> InferenceContext<'db> {
25422383 }
25432384
25442385 // check legacy const parameters
2545 for (subst_idx, arg_idx) in legacy_const_generics_indices.iter().copied().enumerate() {
2546 let arg = match subst.at(Interner, subst_idx).constant(Interner) {
2547 Some(c) => c,
2548 None => continue, // not a const parameter?
2549 };
2386 for arg_idx in legacy_const_generics_indices.iter().copied() {
25502387 if arg_idx >= args.len() as u32 {
25512388 continue;
25522389 }
2553 let _ty = arg.data(Interner).ty.clone();
25542390 let expected = Expectation::none(); // FIXME use actual const ty, when that is lowered correctly
25552391 self.infer_expr(args[arg_idx as usize], &expected, ExprIsRead::Yes);
25562392 // FIXME: evaluate and unify with the const
......@@ -2561,17 +2397,19 @@ impl<'db> InferenceContext<'db> {
25612397 }
25622398
25632399 /// Dereferences a single level of immutable referencing.
2564 fn deref_ty_if_possible(&mut self, ty: &Ty) -> Ty {
2565 let ty = self.table.structurally_resolve_type(ty);
2566 match ty.kind(Interner) {
2567 TyKind::Ref(Mutability::Not, _, inner) => self.table.structurally_resolve_type(inner),
2400 fn deref_ty_if_possible(&mut self, ty: Ty<'db>) -> Ty<'db> {
2401 let ty = self.table.try_structurally_resolve_type(ty);
2402 match ty.kind() {
2403 TyKind::Ref(_, inner, Mutability::Not) => {
2404 self.table.try_structurally_resolve_type(inner)
2405 }
25682406 _ => ty,
25692407 }
25702408 }
25712409
25722410 /// Enforces expectations on lhs type and rhs type depending on the operator and returns the
25732411 /// output type of the binary op.
2574 fn enforce_builtin_binop_types(&mut self, lhs: &Ty, rhs: &Ty, op: BinaryOp) -> Ty {
2412 fn enforce_builtin_binop_types(&mut self, lhs: Ty<'db>, rhs: Ty<'db>, op: BinaryOp) -> Ty<'db> {
25752413 // Special-case a single layer of referencing, so that things like `5.0 + &6.0f32` work (See rust-lang/rust#57447).
25762414 let lhs = self.deref_ty_if_possible(lhs);
25772415 let rhs = self.deref_ty_if_possible(rhs);
......@@ -2583,9 +2421,9 @@ impl<'db> InferenceContext<'db> {
25832421
25842422 let output_ty = match op {
25852423 BinaryOp::LogicOp(_) => {
2586 let bool_ = self.result.standard_types.bool_.clone();
2587 self.unify(&lhs, &bool_);
2588 self.unify(&rhs, &bool_);
2424 let bool_ = self.types.bool;
2425 self.unify(lhs, bool_);
2426 self.unify(rhs, bool_);
25892427 bool_
25902428 }
25912429
......@@ -2596,14 +2434,14 @@ impl<'db> InferenceContext<'db> {
25962434
25972435 BinaryOp::ArithOp(_) => {
25982436 // LHS, RHS, and result will have the same type
2599 self.unify(&lhs, &rhs);
2437 self.unify(lhs, rhs);
26002438 lhs
26012439 }
26022440
26032441 BinaryOp::CmpOp(_) => {
26042442 // LHS and RHS will have the same type
2605 self.unify(&lhs, &rhs);
2606 self.result.standard_types.bool_.clone()
2443 self.unify(lhs, rhs);
2444 self.types.bool
26072445 }
26082446
26092447 BinaryOp::Assignment { op: None } => {
......@@ -2614,10 +2452,10 @@ impl<'db> InferenceContext<'db> {
26142452 BinaryOp::Assignment { .. } => unreachable!("handled above"),
26152453 };
26162454
2617 if is_assign { self.result.standard_types.unit.clone() } else { output_ty }
2455 if is_assign { self.types.unit } else { output_ty }
26182456 }
26192457
2620 fn is_builtin_binop(&mut self, lhs: &Ty, rhs: &Ty, op: BinaryOp) -> bool {
2458 fn is_builtin_binop(&mut self, lhs: Ty<'db>, rhs: Ty<'db>, op: BinaryOp) -> bool {
26212459 // Special-case a single layer of referencing, so that things like `5.0 + &6.0f32` work (See rust-lang/rust#57447).
26222460 let lhs = self.deref_ty_if_possible(lhs);
26232461 let rhs = self.deref_ty_if_possible(rhs);
......@@ -2644,27 +2482,25 @@ impl<'db> InferenceContext<'db> {
26442482 BinaryOp::ArithOp(ArithOp::BitAnd | ArithOp::BitOr | ArithOp::BitXor) => {
26452483 lhs.is_integral() && rhs.is_integral()
26462484 || lhs.is_floating_point() && rhs.is_floating_point()
2647 || matches!(
2648 (lhs.kind(Interner), rhs.kind(Interner)),
2649 (TyKind::Scalar(Scalar::Bool), TyKind::Scalar(Scalar::Bool))
2650 )
2485 || matches!((lhs.kind(), rhs.kind()), (TyKind::Bool, TyKind::Bool))
26512486 }
26522487
26532488 BinaryOp::CmpOp(_) => {
26542489 let is_scalar = |kind| {
26552490 matches!(
26562491 kind,
2657 &TyKind::Scalar(_)
2492 TyKind::Bool
2493 | TyKind::Char
2494 | TyKind::Int(_)
2495 | TyKind::Uint(_)
2496 | TyKind::Float(_)
26582497 | TyKind::FnDef(..)
2659 | TyKind::Function(_)
2660 | TyKind::Raw(..)
2661 | TyKind::InferenceVar(
2662 _,
2663 TyVariableKind::Integer | TyVariableKind::Float
2664 )
2498 | TyKind::FnPtr(..)
2499 | TyKind::RawPtr(..)
2500 | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_))
26652501 )
26662502 };
2667 is_scalar(lhs.kind(Interner)) && is_scalar(rhs.kind(Interner))
2503 is_scalar(lhs.kind()) && is_scalar(rhs.kind())
26682504 }
26692505
26702506 BinaryOp::Assignment { op: None } => {
......@@ -2679,27 +2515,15 @@ impl<'db> InferenceContext<'db> {
26792515 pub(super) fn with_breakable_ctx<T>(
26802516 &mut self,
26812517 kind: BreakableKind,
2682 ty: Option<Ty>,
2518 ty: Option<Ty<'db>>,
26832519 label: Option<LabelId>,
26842520 cb: impl FnOnce(&mut Self) -> T,
2685 ) -> (Option<Ty>, T) {
2521 ) -> (Option<Ty<'db>>, T) {
26862522 self.breakables.push({
2687 BreakableContext {
2688 kind,
2689 may_break: false,
2690 coerce: ty.map(|ty| CoerceMany::new(ty.to_nextsolver(self.table.interner))),
2691 label,
2692 }
2523 BreakableContext { kind, may_break: false, coerce: ty.map(CoerceMany::new), label }
26932524 });
26942525 let res = cb(self);
26952526 let ctx = self.breakables.pop().expect("breakable stack broken");
2696 (
2697 if ctx.may_break {
2698 ctx.coerce.map(|ctx| ctx.complete(self).to_chalk(self.table.interner))
2699 } else {
2700 None
2701 },
2702 res,
2703 )
2527 (if ctx.may_break { ctx.coerce.map(|ctx| ctx.complete(self)) } else { None }, res)
27042528 }
27052529}
src/tools/rust-analyzer/crates/hir-ty/src/infer/fallback.rs+2-2
......@@ -28,7 +28,7 @@ pub(crate) enum DivergingFallbackBehavior {
2828 ToNever,
2929}
3030
31impl<'db> InferenceContext<'db> {
31impl<'db> InferenceContext<'_, 'db> {
3232 pub(super) fn type_inference_fallback(&mut self) {
3333 debug!(
3434 "type-inference-fallback start obligations: {:#?}",
......@@ -324,7 +324,7 @@ impl<'db> InferenceContext<'db> {
324324 FxHashMap::with_capacity_and_hasher(diverging_vids.len(), FxBuildHasher);
325325
326326 for &diverging_vid in &diverging_vids {
327 let diverging_ty = Ty::new_var(self.table.interner, diverging_vid);
327 let diverging_ty = Ty::new_var(self.interner(), diverging_vid);
328328 let root_vid = self.table.infer_ctxt.root_var(diverging_vid);
329329 let can_reach_non_diverging = Dfs::new(&coercion_graph, root_vid.as_u32().into())
330330 .iter(&coercion_graph)
src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs+28-15
......@@ -1,7 +1,6 @@
11//! Finds if an expression is an immutable context or a mutable context, which is used in selecting
22//! between `Deref` and `DerefMut` or `Index` and `IndexMut` or similar.
33
4use chalk_ir::{Mutability, cast::Cast};
54use hir_def::{
65 hir::{
76 Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, Pat, PatId, Statement,
......@@ -11,14 +10,19 @@ use hir_def::{
1110};
1211use hir_expand::name::Name;
1312use intern::sym;
13use rustc_ast_ir::Mutability;
14use rustc_type_ir::inherent::IntoKind;
1415
16use crate::next_solver::infer::traits::{Obligation, ObligationCause};
17use crate::next_solver::{GenericArgs, TraitRef};
1518use crate::{
16 Adjust, Adjustment, AutoBorrow, Interner, OverloadedDeref, TyBuilder, TyKind,
19 Adjust, Adjustment, AutoBorrow, OverloadedDeref,
1720 infer::{Expectation, InferenceContext, expr::ExprIsRead},
18 lower::lower_to_chalk_mutability,
21 lower_nextsolver::lower_mutability,
22 next_solver::TyKind,
1923};
2024
21impl InferenceContext<'_> {
25impl<'db> InferenceContext<'_, 'db> {
2226 pub(crate) fn infer_mut_body(&mut self) {
2327 self.infer_mut_expr(self.body.body_expr, Mutability::Not);
2428 }
......@@ -141,8 +145,8 @@ impl InferenceContext<'_> {
141145 target,
142146 }) = base_adjustments
143147 {
144 if let TyKind::Ref(_, _, ty) = target.kind(Interner) {
145 base_ty = Some(ty.clone());
148 if let TyKind::Ref(_, ty, _) = target.kind() {
149 base_ty = Some(ty);
146150 }
147151 *mutability = Mutability::Mut;
148152 }
......@@ -150,15 +154,24 @@ impl InferenceContext<'_> {
150154 // Apply `IndexMut` obligation for non-assignee expr
151155 if let Some(base_ty) = base_ty {
152156 let index_ty = if let Some(ty) = self.result.type_of_expr.get(index) {
153 ty.clone()
157 *ty
154158 } else {
155159 self.infer_expr(index, &Expectation::none(), ExprIsRead::Yes)
156160 };
157 let trait_ref = TyBuilder::trait_ref(self.db, index_trait)
158 .push(base_ty)
159 .fill(|_| index_ty.clone().cast(Interner))
160 .build();
161 self.push_obligation(trait_ref.cast(Interner));
161 let trait_ref = TraitRef::new(
162 self.interner(),
163 index_trait.into(),
164 GenericArgs::new_from_iter(
165 self.interner(),
166 [base_ty.into(), index_ty.into()],
167 ),
168 );
169 self.table.register_predicate(Obligation::new(
170 self.interner(),
171 ObligationCause::new(),
172 self.table.trait_env.env,
173 trait_ref,
174 ));
162175 }
163176 }
164177 self.infer_mut_expr(base, mutability);
......@@ -173,8 +186,8 @@ impl InferenceContext<'_> {
173186 {
174187 let ty = self.result.type_of_expr.get(*expr);
175188 let is_mut_ptr = ty.is_some_and(|ty| {
176 let ty = self.table.resolve_ty_shallow(ty);
177 matches!(ty.kind(Interner), chalk_ir::TyKind::Raw(Mutability::Mut, _))
189 let ty = self.table.shallow_resolve(*ty);
190 matches!(ty.kind(), TyKind::RawPtr(_, Mutability::Mut))
178191 });
179192 if is_mut_ptr {
180193 mutability = Mutability::Not;
......@@ -200,7 +213,7 @@ impl InferenceContext<'_> {
200213 self.infer_mut_expr(*expr, Mutability::Not);
201214 }
202215 Expr::Ref { expr, rawness: _, mutability } => {
203 let mutability = lower_to_chalk_mutability(*mutability);
216 let mutability = lower_mutability(*mutability);
204217 self.infer_mut_expr(*expr, mutability);
205218 }
206219 Expr::BinaryOp { lhs, rhs, op: Some(BinaryOp::Assignment { .. }) } => {
src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs+152-161
......@@ -8,37 +8,35 @@ use hir_def::{
88 hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, Literal, Pat, PatId},
99};
1010use hir_expand::name::Name;
11use rustc_ast_ir::Mutability;
12use rustc_type_ir::inherent::{GenericArg as _, GenericArgs as _, IntoKind, SliceLike, Ty as _};
1113use stdx::TupleExt;
1214
13use crate::infer::AllowTwoPhase;
14use crate::next_solver::mapping::{ChalkToNextSolver, NextSolverToChalk};
1515use crate::{
16 DeclContext, DeclOrigin, InferenceDiagnostic, Interner, Mutability, Scalar, Substitution, Ty,
17 TyBuilder, TyExt, TyKind,
16 DeclContext, DeclOrigin, InferenceDiagnostic,
1817 consteval::{self, try_const_usize, usize_const},
1918 infer::{
20 BindingMode, Expectation, InferenceContext, TypeMismatch, coerce::CoerceNever,
21 expr::ExprIsRead,
19 AllowTwoPhase, BindingMode, Expectation, InferenceContext, TypeMismatch,
20 coerce::CoerceNever, expr::ExprIsRead,
2221 },
23 lower::lower_to_chalk_mutability,
24 primitive::UintTy,
25 static_lifetime,
22 lower_nextsolver::lower_mutability,
23 next_solver::{GenericArgs, Ty, TyKind},
2624};
2725
28impl InferenceContext<'_> {
26impl<'db> InferenceContext<'_, 'db> {
2927 /// Infers type for tuple struct pattern or its corresponding assignee expression.
3028 ///
3129 /// Ellipses found in the original pattern or expression must be filtered out.
3230 pub(super) fn infer_tuple_struct_pat_like(
3331 &mut self,
3432 path: Option<&Path>,
35 expected: &Ty,
33 expected: Ty<'db>,
3634 default_bm: BindingMode,
3735 id: PatId,
3836 ellipsis: Option<u32>,
3937 subs: &[PatId],
4038 decl: Option<DeclContext>,
41 ) -> Ty {
39 ) -> Ty<'db> {
4240 let (ty, def) = self.resolve_variant(id.into(), path, true);
4341 let var_data = def.map(|it| it.fields(self.db));
4442 if let Some(variant) = def {
......@@ -56,12 +54,12 @@ impl InferenceContext<'_> {
5654 }
5755 }
5856
59 self.unify(&ty, expected);
57 self.unify(ty, expected);
6058
6159 match def {
6260 _ if subs.is_empty() => {}
6361 Some(def) => {
64 let field_types = self.db.field_types(def);
62 let field_types = self.db.field_types_ns(def);
6563 let variant_data = def.fields(self.db);
6664 let visibilities = self.db.field_visibilities(def);
6765
......@@ -85,10 +83,10 @@ impl InferenceContext<'_> {
8583 {
8684 // FIXME(DIAGNOSE): private tuple field
8785 }
88 let f = field_types[local_id].clone();
86 let f = field_types[local_id];
8987 let expected_ty = match substs {
90 Some(substs) => f.substitute(Interner, substs),
91 None => f.substitute(Interner, &Substitution::empty(Interner)),
88 Some(substs) => f.instantiate(self.interner(), substs),
89 None => f.instantiate(self.interner(), &[]),
9290 };
9391 self.process_remote_user_written_ty(expected_ty)
9492 }
......@@ -96,13 +94,13 @@ impl InferenceContext<'_> {
9694 }
9795 };
9896
99 self.infer_pat(subpat, &expected_ty, default_bm, decl);
97 self.infer_pat(subpat, expected_ty, default_bm, decl);
10098 }
10199 }
102100 None => {
103101 let err_ty = self.err_ty();
104102 for &inner in subs {
105 self.infer_pat(inner, &err_ty, default_bm, decl);
103 self.infer_pat(inner, err_ty, default_bm, decl);
106104 }
107105 }
108106 }
......@@ -114,23 +112,23 @@ impl InferenceContext<'_> {
114112 pub(super) fn infer_record_pat_like(
115113 &mut self,
116114 path: Option<&Path>,
117 expected: &Ty,
115 expected: Ty<'db>,
118116 default_bm: BindingMode,
119117 id: PatId,
120118 subs: impl ExactSizeIterator<Item = (Name, PatId)>,
121119 decl: Option<DeclContext>,
122 ) -> Ty {
120 ) -> Ty<'db> {
123121 let (ty, def) = self.resolve_variant(id.into(), path, false);
124122 if let Some(variant) = def {
125123 self.write_variant_resolution(id.into(), variant);
126124 }
127125
128 self.unify(&ty, expected);
126 self.unify(ty, expected);
129127
130128 match def {
131129 _ if subs.len() == 0 => {}
132130 Some(def) => {
133 let field_types = self.db.field_types(def);
131 let field_types = self.db.field_types_ns(def);
134132 let variant_data = def.fields(self.db);
135133 let visibilities = self.db.field_visibilities(def);
136134
......@@ -149,10 +147,10 @@ impl InferenceContext<'_> {
149147 variant: def,
150148 });
151149 }
152 let f = field_types[local_id].clone();
150 let f = field_types[local_id];
153151 let expected_ty = match substs {
154 Some(substs) => f.substitute(Interner, substs),
155 None => f.substitute(Interner, &Substitution::empty(Interner)),
152 Some(substs) => f.instantiate(self.interner(), substs),
153 None => f.instantiate(self.interner(), &[]),
156154 };
157155 self.process_remote_user_written_ty(expected_ty)
158156 }
......@@ -167,13 +165,13 @@ impl InferenceContext<'_> {
167165 }
168166 };
169167
170 self.infer_pat(inner, &expected_ty, default_bm, decl);
168 self.infer_pat(inner, expected_ty, default_bm, decl);
171169 }
172170 }
173171 None => {
174172 let err_ty = self.err_ty();
175173 for (_, inner) in subs {
176 self.infer_pat(inner, &err_ty, default_bm, decl);
174 self.infer_pat(inner, err_ty, default_bm, decl);
177175 }
178176 }
179177 }
......@@ -186,16 +184,16 @@ impl InferenceContext<'_> {
186184 /// Ellipses found in the original pattern or expression must be filtered out.
187185 pub(super) fn infer_tuple_pat_like(
188186 &mut self,
189 expected: &Ty,
187 expected: Ty<'db>,
190188 default_bm: BindingMode,
191189 ellipsis: Option<u32>,
192190 subs: &[PatId],
193191 decl: Option<DeclContext>,
194 ) -> Ty {
192 ) -> Ty<'db> {
195193 let expected = self.table.structurally_resolve_type(expected);
196 let expectations = match expected.as_tuple() {
197 Some(parameters) => parameters.as_slice(Interner),
198 _ => &[],
194 let expectations = match expected.kind() {
195 TyKind::Tuple(parameters) => parameters,
196 _ => self.types.empty_tys,
199197 };
200198
201199 let ((pre, post), n_uncovered_patterns) = match ellipsis {
......@@ -204,10 +202,8 @@ impl InferenceContext<'_> {
204202 }
205203 None => ((subs, &[][..]), 0),
206204 };
207 let mut expectations_iter = expectations
208 .iter()
209 .map(|a| a.assert_ty_ref(Interner).clone())
210 .chain(repeat_with(|| self.table.new_type_var()));
205 let mut expectations_iter =
206 expectations.iter().chain(repeat_with(|| self.table.next_ty_var()));
211207
212208 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + subs.len());
213209
......@@ -215,31 +211,35 @@ impl InferenceContext<'_> {
215211
216212 // Process pre
217213 for (ty, pat) in inner_tys.iter_mut().zip(pre) {
218 *ty = self.infer_pat(*pat, ty, default_bm, decl);
214 *ty = self.infer_pat(*pat, *ty, default_bm, decl);
219215 }
220216
221217 // Process post
222218 for (ty, pat) in inner_tys.iter_mut().skip(pre.len() + n_uncovered_patterns).zip(post) {
223 *ty = self.infer_pat(*pat, ty, default_bm, decl);
219 *ty = self.infer_pat(*pat, *ty, default_bm, decl);
224220 }
225221
226 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
227 .intern(Interner)
222 Ty::new_tup_from_iter(self.interner(), inner_tys.into_iter())
228223 }
229224
230225 /// The resolver needs to be updated to the surrounding expression when inside assignment
231226 /// (because there, `Pat::Path` can refer to a variable).
232 pub(super) fn infer_top_pat(&mut self, pat: PatId, expected: &Ty, decl: Option<DeclContext>) {
227 pub(super) fn infer_top_pat(
228 &mut self,
229 pat: PatId,
230 expected: Ty<'db>,
231 decl: Option<DeclContext>,
232 ) {
233233 self.infer_pat(pat, expected, BindingMode::default(), decl);
234234 }
235235
236236 fn infer_pat(
237237 &mut self,
238238 pat: PatId,
239 expected: &Ty,
239 expected: Ty<'db>,
240240 mut default_bm: BindingMode,
241241 decl: Option<DeclContext>,
242 ) -> Ty {
242 ) -> Ty<'db> {
243243 let mut expected = self.table.structurally_resolve_type(expected);
244244
245245 if matches!(&self.body[pat], Pat::Ref { .. }) || self.inside_assignment {
......@@ -251,9 +251,9 @@ impl InferenceContext<'_> {
251251 default_bm = BindingMode::Move;
252252 } else if self.is_non_ref_pat(self.body, pat) {
253253 let mut pat_adjustments = Vec::new();
254 while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
255 pat_adjustments.push(expected.clone());
256 expected = self.table.structurally_resolve_type(inner);
254 while let TyKind::Ref(_lifetime, inner, mutability) = expected.kind() {
255 pat_adjustments.push(expected);
256 expected = self.table.try_structurally_resolve_type(inner);
257257 default_bm = match default_bm {
258258 BindingMode::Move => BindingMode::Ref(mutability),
259259 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not),
......@@ -273,25 +273,21 @@ impl InferenceContext<'_> {
273273
274274 let ty = match &self.body[pat] {
275275 Pat::Tuple { args, ellipsis } => {
276 self.infer_tuple_pat_like(&expected, default_bm, *ellipsis, args, decl)
276 self.infer_tuple_pat_like(expected, default_bm, *ellipsis, args, decl)
277277 }
278278 Pat::Or(pats) => {
279279 for pat in pats.iter() {
280 self.infer_pat(*pat, &expected, default_bm, decl);
280 self.infer_pat(*pat, expected, default_bm, decl);
281281 }
282 expected.clone()
282 expected
283 }
284 &Pat::Ref { pat, mutability } => {
285 self.infer_ref_pat(pat, lower_mutability(mutability), expected, default_bm, decl)
283286 }
284 &Pat::Ref { pat, mutability } => self.infer_ref_pat(
285 pat,
286 lower_to_chalk_mutability(mutability),
287 &expected,
288 default_bm,
289 decl,
290 ),
291287 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self
292288 .infer_tuple_struct_pat_like(
293289 p.as_deref(),
294 &expected,
290 expected,
295291 default_bm,
296292 pat,
297293 *ellipsis,
......@@ -300,29 +296,26 @@ impl InferenceContext<'_> {
300296 ),
301297 Pat::Record { path: p, args: fields, ellipsis: _ } => {
302298 let subs = fields.iter().map(|f| (f.name.clone(), f.pat));
303 self.infer_record_pat_like(p.as_deref(), &expected, default_bm, pat, subs, decl)
299 self.infer_record_pat_like(p.as_deref(), expected, default_bm, pat, subs, decl)
304300 }
305301 Pat::Path(path) => {
306302 let ty = self.infer_path(path, pat.into()).unwrap_or_else(|| self.err_ty());
307 let ty_inserted_vars = self.insert_type_vars_shallow(ty.clone());
303 let ty_inserted_vars = self.insert_type_vars_shallow(ty);
308304 match self.coerce(
309305 pat.into(),
310 expected.to_nextsolver(self.table.interner),
311 ty_inserted_vars.to_nextsolver(self.table.interner),
306 expected,
307 ty_inserted_vars,
312308 AllowTwoPhase::No,
313309 CoerceNever::Yes,
314310 ) {
315311 Ok(coerced_ty) => {
316 self.write_pat_ty(pat, coerced_ty.to_chalk(self.table.interner));
312 self.write_pat_ty(pat, coerced_ty);
317313 return self.pat_ty_after_adjustment(pat);
318314 }
319315 Err(_) => {
320316 self.result.type_mismatches.insert(
321317 pat.into(),
322 TypeMismatch {
323 expected: expected.clone(),
324 actual: ty_inserted_vars.clone(),
325 },
318 TypeMismatch { expected, actual: ty_inserted_vars },
326319 );
327320 self.write_pat_ty(pat, ty);
328321 // We return `expected` to prevent cascading errors. I guess an alternative is to
......@@ -332,81 +325,77 @@ impl InferenceContext<'_> {
332325 }
333326 }
334327 Pat::Bind { id, subpat } => {
335 return self.infer_bind_pat(pat, *id, default_bm, *subpat, &expected, decl);
328 return self.infer_bind_pat(pat, *id, default_bm, *subpat, expected, decl);
336329 }
337330 Pat::Slice { prefix, slice, suffix } => {
338 self.infer_slice_pat(&expected, prefix, slice, suffix, default_bm, decl)
331 self.infer_slice_pat(expected, prefix, *slice, suffix, default_bm, decl)
339332 }
340 Pat::Wild => expected.clone(),
333 Pat::Wild => expected,
341334 Pat::Range { .. } => {
342335 // FIXME: do some checks here.
343 expected.clone()
336 expected
344337 }
345338 &Pat::Lit(expr) => {
346339 // Don't emit type mismatches again, the expression lowering already did that.
347 let ty = self.infer_lit_pat(expr, &expected);
340 let ty = self.infer_lit_pat(expr, expected);
348341 self.write_pat_ty(pat, ty);
349342 return self.pat_ty_after_adjustment(pat);
350343 }
351344 Pat::Box { inner } => match self.resolve_boxed_box() {
352345 Some(box_adt) => {
353346 let (inner_ty, alloc_ty) = match expected.as_adt() {
354 Some((adt, subst)) if adt == box_adt => (
355 subst.at(Interner, 0).assert_ty_ref(Interner).clone(),
356 subst.as_slice(Interner).get(1).and_then(|a| a.ty(Interner).cloned()),
357 ),
358 _ => (self.result.standard_types.unknown.clone(), None),
347 Some((adt, subst)) if adt == box_adt => {
348 (subst.type_at(0), subst.as_slice().get(1).and_then(|a| a.as_type()))
349 }
350 _ => (self.types.error, None),
359351 };
360352
361 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm, decl);
362 let mut b = TyBuilder::adt(self.db, box_adt).push(inner_ty);
363
364 if let Some(alloc_ty) = alloc_ty {
365 b = b.push(alloc_ty);
366 }
367 b.fill_with_defaults(self.db, || self.table.new_type_var()).build()
353 let inner_ty = self.infer_pat(*inner, inner_ty, default_bm, decl);
354 Ty::new_adt(
355 self.interner(),
356 box_adt,
357 GenericArgs::fill_with_defaults(
358 self.interner(),
359 box_adt.into(),
360 std::iter::once(inner_ty.into()).chain(alloc_ty.map(Into::into)),
361 |_, _, id, _| self.table.next_var_for_param(id),
362 ),
363 )
368364 }
369365 None => self.err_ty(),
370366 },
371367 Pat::ConstBlock(expr) => {
372368 let old_inside_assign = std::mem::replace(&mut self.inside_assignment, false);
373 let result = self.infer_expr(
374 *expr,
375 &Expectation::has_type(expected.clone()),
376 ExprIsRead::Yes,
377 );
369 let result =
370 self.infer_expr(*expr, &Expectation::has_type(expected), ExprIsRead::Yes);
378371 self.inside_assignment = old_inside_assign;
379372 result
380373 }
381374 Pat::Expr(expr) => {
382375 let old_inside_assign = std::mem::replace(&mut self.inside_assignment, false);
383376 // LHS of assignment doesn't constitute reads.
384 let result = self.infer_expr_coerce(
385 *expr,
386 &Expectation::has_type(expected.clone()),
387 ExprIsRead::No,
388 );
377 let result =
378 self.infer_expr_coerce(*expr, &Expectation::has_type(expected), ExprIsRead::No);
389379 // We are returning early to avoid the unifiability check below.
390380 let lhs_ty = self.insert_type_vars_shallow(result);
391381 let ty = match self.coerce(
392382 pat.into(),
393 expected.to_nextsolver(self.table.interner),
394 lhs_ty.to_nextsolver(self.table.interner),
383 expected,
384 lhs_ty,
395385 AllowTwoPhase::No,
396386 CoerceNever::Yes,
397387 ) {
398 Ok(ty) => ty.to_chalk(self.table.interner),
388 Ok(ty) => ty,
399389 Err(_) => {
400 self.result.type_mismatches.insert(
401 pat.into(),
402 TypeMismatch { expected: expected.clone(), actual: lhs_ty.clone() },
403 );
390 self.result
391 .type_mismatches
392 .insert(pat.into(), TypeMismatch { expected, actual: lhs_ty });
404393 // `rhs_ty` is returned so no further type mismatches are
405394 // reported because of this mismatch.
406395 expected
407396 }
408397 };
409 self.write_pat_ty(pat, ty.clone());
398 self.write_pat_ty(pat, ty);
410399 self.inside_assignment = old_inside_assign;
411400 return ty;
412401 }
......@@ -415,46 +404,43 @@ impl InferenceContext<'_> {
415404 // use a new type variable if we got error type here
416405 let ty = self.insert_type_vars_shallow(ty);
417406 // FIXME: This never check is odd, but required with out we do inference right now
418 if !expected.is_never() && !self.unify(&ty, &expected) {
419 self.result
420 .type_mismatches
421 .insert(pat.into(), TypeMismatch { expected, actual: ty.clone() });
407 if !expected.is_never() && !self.unify(ty, expected) {
408 self.result.type_mismatches.insert(pat.into(), TypeMismatch { expected, actual: ty });
422409 }
423410 self.write_pat_ty(pat, ty);
424411 self.pat_ty_after_adjustment(pat)
425412 }
426413
427 fn pat_ty_after_adjustment(&self, pat: PatId) -> Ty {
428 self.result
414 fn pat_ty_after_adjustment(&self, pat: PatId) -> Ty<'db> {
415 *self
416 .result
429417 .pat_adjustments
430418 .get(&pat)
431419 .and_then(|it| it.first())
432420 .unwrap_or(&self.result.type_of_pat[pat])
433 .clone()
434421 }
435422
436423 fn infer_ref_pat(
437424 &mut self,
438425 inner_pat: PatId,
439426 mutability: Mutability,
440 expected: &Ty,
427 expected: Ty<'db>,
441428 default_bm: BindingMode,
442429 decl: Option<DeclContext>,
443 ) -> Ty {
444 let (expectation_type, expectation_lt) = match expected.as_reference() {
445 Some((inner_ty, lifetime, _exp_mut)) => (inner_ty.clone(), lifetime),
446 None => {
447 let inner_ty = self.table.new_type_var();
448 let inner_lt = self.table.new_lifetime_var();
449 let ref_ty =
450 TyKind::Ref(mutability, inner_lt.clone(), inner_ty.clone()).intern(Interner);
430 ) -> Ty<'db> {
431 let (expectation_type, expectation_lt) = match expected.kind() {
432 TyKind::Ref(lifetime, inner_ty, _exp_mut) => (inner_ty, lifetime),
433 _ => {
434 let inner_ty = self.table.next_ty_var();
435 let inner_lt = self.table.next_region_var();
436 let ref_ty = Ty::new_ref(self.interner(), inner_lt, inner_ty, mutability);
451437 // Unification failure will be reported by the caller.
452 self.unify(&ref_ty, expected);
438 self.unify(ref_ty, expected);
453439 (inner_ty, inner_lt)
454440 }
455441 };
456 let subty = self.infer_pat(inner_pat, &expectation_type, default_bm, decl);
457 TyKind::Ref(mutability, expectation_lt, subty).intern(Interner)
442 let subty = self.infer_pat(inner_pat, expectation_type, default_bm, decl);
443 Ty::new_ref(self.interner(), expectation_lt, subty, mutability)
458444 }
459445
460446 fn infer_bind_pat(
......@@ -463,9 +449,9 @@ impl InferenceContext<'_> {
463449 binding: BindingId,
464450 default_bm: BindingMode,
465451 subpat: Option<PatId>,
466 expected: &Ty,
452 expected: Ty<'db>,
467453 decl: Option<DeclContext>,
468 ) -> Ty {
454 ) -> Ty<'db> {
469455 let Binding { mode, .. } = self.body[binding];
470456 let mode = if mode == BindingAnnotation::Unannotated {
471457 default_bm
......@@ -476,31 +462,31 @@ impl InferenceContext<'_> {
476462
477463 let inner_ty = match subpat {
478464 Some(subpat) => self.infer_pat(subpat, expected, default_bm, decl),
479 None => expected.clone(),
465 None => expected,
480466 };
481467 let inner_ty = self.insert_type_vars_shallow(inner_ty);
482468
483469 let bound_ty = match mode {
484470 BindingMode::Ref(mutability) => {
485 let inner_lt = self.table.new_lifetime_var();
486 TyKind::Ref(mutability, inner_lt, inner_ty.clone()).intern(Interner)
471 let inner_lt = self.table.next_region_var();
472 Ty::new_ref(self.interner(), inner_lt, inner_ty, mutability)
487473 }
488 BindingMode::Move => inner_ty.clone(),
474 BindingMode::Move => inner_ty,
489475 };
490 self.write_pat_ty(pat, inner_ty.clone());
476 self.write_pat_ty(pat, inner_ty);
491477 self.write_binding_ty(binding, bound_ty);
492478 inner_ty
493479 }
494480
495481 fn infer_slice_pat(
496482 &mut self,
497 expected: &Ty,
483 expected: Ty<'db>,
498484 prefix: &[PatId],
499 slice: &Option<PatId>,
485 slice: Option<PatId>,
500486 suffix: &[PatId],
501487 default_bm: BindingMode,
502488 decl: Option<DeclContext>,
503 ) -> Ty {
489 ) -> Ty<'db> {
504490 let expected = self.table.structurally_resolve_type(expected);
505491
506492 // If `expected` is an infer ty, we try to equate it to an array if the given pattern
......@@ -510,56 +496,61 @@ impl InferenceContext<'_> {
510496 && let Some(resolved_array_ty) =
511497 self.try_resolve_slice_ty_to_array_ty(prefix, suffix, slice)
512498 {
513 self.unify(&expected, &resolved_array_ty);
499 self.unify(expected, resolved_array_ty);
514500 }
515501
516 let expected = self.table.structurally_resolve_type(&expected);
517 let elem_ty = match expected.kind(Interner) {
518 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
502 let expected = self.table.try_structurally_resolve_type(expected);
503 let elem_ty = match expected.kind() {
504 TyKind::Array(st, _) | TyKind::Slice(st) => st,
519505 _ => self.err_ty(),
520506 };
521507
522508 for &pat_id in prefix.iter().chain(suffix.iter()) {
523 self.infer_pat(pat_id, &elem_ty, default_bm, decl);
509 self.infer_pat(pat_id, elem_ty, default_bm, decl);
524510 }
525511
526 if let &Some(slice_pat_id) = slice {
527 let rest_pat_ty = match expected.kind(Interner) {
512 if let Some(slice_pat_id) = slice {
513 let rest_pat_ty = match expected.kind() {
528514 TyKind::Array(_, length) => {
529515 let len = try_const_usize(self.db, length);
530516 let len =
531517 len.and_then(|len| len.checked_sub((prefix.len() + suffix.len()) as u128));
532 TyKind::Array(elem_ty.clone(), usize_const(self.db, len, self.resolver.krate()))
518 Ty::new_array_with_const_len(
519 self.interner(),
520 elem_ty,
521 usize_const(self.db, len, self.resolver.krate()),
522 )
533523 }
534 _ => TyKind::Slice(elem_ty.clone()),
535 }
536 .intern(Interner);
537 self.infer_pat(slice_pat_id, &rest_pat_ty, default_bm, decl);
524 _ => Ty::new_slice(self.interner(), elem_ty),
525 };
526 self.infer_pat(slice_pat_id, rest_pat_ty, default_bm, decl);
538527 }
539528
540 match expected.kind(Interner) {
541 TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()),
542 _ => TyKind::Slice(elem_ty),
529 match expected.kind() {
530 TyKind::Array(_, const_) => {
531 Ty::new_array_with_const_len(self.interner(), elem_ty, const_)
532 }
533 _ => Ty::new_slice(self.interner(), elem_ty),
543534 }
544 .intern(Interner)
545535 }
546536
547 fn infer_lit_pat(&mut self, expr: ExprId, expected: &Ty) -> Ty {
537 fn infer_lit_pat(&mut self, expr: ExprId, expected: Ty<'db>) -> Ty<'db> {
548538 // Like slice patterns, byte string patterns can denote both `&[u8; N]` and `&[u8]`.
549539 if let Expr::Literal(Literal::ByteString(_)) = self.body[expr]
550 && let Some((inner, ..)) = expected.as_reference()
540 && let TyKind::Ref(_, inner, _) = expected.kind()
551541 {
552 let inner = self.table.structurally_resolve_type(inner);
553 if matches!(inner.kind(Interner), TyKind::Slice(_)) {
554 let elem_ty = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner);
555 let slice_ty = TyKind::Slice(elem_ty).intern(Interner);
556 let ty = TyKind::Ref(Mutability::Not, static_lifetime(), slice_ty).intern(Interner);
557 self.write_expr_ty(expr, ty.clone());
542 let inner = self.table.try_structurally_resolve_type(inner);
543 if matches!(inner.kind(), TyKind::Slice(_)) {
544 let elem_ty = self.types.u8;
545 let slice_ty = Ty::new_slice(self.interner(), elem_ty);
546 let ty =
547 Ty::new_ref(self.interner(), self.types.re_static, slice_ty, Mutability::Not);
548 self.write_expr_ty(expr, ty);
558549 return ty;
559550 }
560551 }
561552
562 self.infer_expr(expr, &Expectation::has_type(expected.clone()), ExprIsRead::Yes)
553 self.infer_expr(expr, &Expectation::has_type(expected), ExprIsRead::Yes)
563554 }
564555
565556 fn is_non_ref_pat(&mut self, body: &hir_def::expr_store::Body, pat: PatId) -> bool {
......@@ -593,17 +584,17 @@ impl InferenceContext<'_> {
593584 &mut self,
594585 before: &[PatId],
595586 suffix: &[PatId],
596 slice: &Option<PatId>,
597 ) -> Option<Ty> {
598 if !slice.is_none() {
587 slice: Option<PatId>,
588 ) -> Option<Ty<'db>> {
589 if slice.is_some() {
599590 return None;
600591 }
601592
602593 let len = before.len() + suffix.len();
603594 let size = consteval::usize_const(self.db, Some(len as u128), self.owner.krate(self.db));
604595
605 let elem_ty = self.table.new_type_var();
606 let array_ty = TyKind::Array(elem_ty, size).intern(Interner);
596 let elem_ty = self.table.next_ty_var();
597 let array_ty = Ty::new_array_with_const_len(self.interner(), elem_ty, size);
607598 Some(array_ty)
608599 }
609600
src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs+106-124
......@@ -1,52 +1,50 @@
11//! Path expression resolution.
22
3use chalk_ir::cast::Cast;
43use hir_def::{
54 AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup,
65 expr_store::path::{Path, PathSegment},
76 resolver::{ResolveValueResult, TypeNs, ValueNs},
87};
98use hir_expand::name::Name;
9use rustc_type_ir::inherent::{SliceLike, Ty as _};
1010use stdx::never;
1111
1212use crate::{
13 InferenceDiagnostic, Interner, LifetimeElisionKind, Substitution, TraitRef, TraitRefExt, Ty,
14 TyBuilder, TyExt, TyKind, ValueTyDefId,
15 builder::ParamKind,
16 consteval, error_lifetime,
13 InferenceDiagnostic, ValueTyDefId,
1714 generics::generics,
1815 infer::diagnostics::InferenceTyLoweringContext as TyLoweringContext,
16 lower_nextsolver::LifetimeElisionKind,
1917 method_resolution::{self, VisibleFromModule},
2018 next_solver::{
21 DbInterner,
22 mapping::{ChalkToNextSolver, NextSolverToChalk},
19 GenericArg, GenericArgs, TraitRef, Ty,
20 infer::traits::{Obligation, ObligationCause},
2321 },
24 to_chalk_trait_id,
2522};
2623
2724use super::{ExprOrPatId, InferenceContext, InferenceTyDiagnosticSource};
2825
29impl<'db> InferenceContext<'db> {
30 pub(super) fn infer_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<Ty> {
26impl<'db> InferenceContext<'_, 'db> {
27 pub(super) fn infer_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<Ty<'db>> {
3128 let (value_def, generic_def, substs) = match self.resolve_value_path(path, id)? {
3229 ValuePathResolution::GenericDef(value_def, generic_def, substs) => {
3330 (value_def, generic_def, substs)
3431 }
3532 ValuePathResolution::NonGeneric(ty) => return Some(ty),
3633 };
37 let substs =
38 self.process_remote_user_written_ty::<_, crate::next_solver::GenericArgs<'db>>(substs);
34 let args = self.process_remote_user_written_ty(substs);
3935
40 self.add_required_obligations_for_value_path(generic_def, &substs);
36 self.add_required_obligations_for_value_path(generic_def, args);
4137
42 let interner = DbInterner::new_with(self.db, None, None);
43 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
44 let ty = self.db.value_ty(value_def)?.instantiate(interner, args).to_chalk(interner);
38 let ty = self.db.value_ty(value_def)?.instantiate(self.interner(), args);
4539 let ty = self.process_remote_user_written_ty(ty);
4640 Some(ty)
4741 }
4842
49 fn resolve_value_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<ValuePathResolution> {
43 fn resolve_value_path(
44 &mut self,
45 path: &Path,
46 id: ExprOrPatId,
47 ) -> Option<ValuePathResolution<'db>> {
5048 let (value, self_subst) = self.resolve_value_path_inner(path, id, false)?;
5149
5250 let value_def: ValueTyDefId = match value {
......@@ -65,7 +63,7 @@ impl<'db> InferenceContext<'db> {
6563 }
6664 ValueNs::LocalBinding(pat) => {
6765 return match self.result.type_of_binding.get(pat) {
68 Some(ty) => Some(ValuePathResolution::NonGeneric(ty.clone())),
66 Some(ty) => Some(ValuePathResolution::NonGeneric(*ty)),
6967 None => {
7068 never!("uninferred pattern?");
7169 None
......@@ -73,17 +71,12 @@ impl<'db> InferenceContext<'db> {
7371 };
7472 }
7573 ValueNs::ImplSelf(impl_id) => {
76 let generics = crate::generics::generics(self.db, impl_id.into());
77 let interner = DbInterner::new_with(self.db, None, None);
78 let substs = generics.placeholder_subst(self.db);
79 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
80 let ty =
81 self.db.impl_self_ty(impl_id).instantiate(interner, args).to_chalk(interner);
74 let ty = self.db.impl_self_ty(impl_id).instantiate_identity();
8275 return if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
8376 Some(ValuePathResolution::GenericDef(
8477 struct_id.into(),
8578 struct_id.into(),
86 substs.clone(),
79 substs,
8780 ))
8881 } else {
8982 // FIXME: report error, invalid Self reference
......@@ -91,67 +84,42 @@ impl<'db> InferenceContext<'db> {
9184 };
9285 }
9386 ValueNs::GenericParam(it) => {
94 return Some(ValuePathResolution::NonGeneric(self.db.const_param_ty(it)));
87 return Some(ValuePathResolution::NonGeneric(self.db.const_param_ty_ns(it)));
9588 }
9689 };
9790
9891 let generic_def = value_def.to_generic_def_id(self.db);
9992 if let GenericDefId::StaticId(_) = generic_def {
100 let interner = DbInterner::new_with(self.db, None, None);
10193 // `Static` is the kind of item that can never be generic currently. We can just skip the binders to get its type.
102 let ty = self.db.value_ty(value_def)?.skip_binder().to_chalk(interner);
94 let ty = self.db.value_ty(value_def)?.skip_binder();
10395 return Some(ValuePathResolution::NonGeneric(ty));
10496 };
10597
106 let substs = self.with_body_ty_lowering(|ctx| {
107 let mut path_ctx = ctx.at_path(path, id);
108 let last_segment = path.segments().len().checked_sub(1);
109 if let Some(last_segment) = last_segment {
110 path_ctx.set_current_segment(last_segment)
111 }
112 path_ctx.substs_from_path(value_def, true, false)
113 });
114 let substs = substs.as_slice(Interner);
115
116 if let ValueNs::EnumVariantId(_) = value {
117 let mut it = substs
118 .iter()
119 .chain(self_subst.as_ref().map_or(&[][..], |s| s.as_slice(Interner)))
120 .cloned();
121 let builder = TyBuilder::subst_for_def(self.db, generic_def, None);
122 let substs = builder
123 .fill(|x| {
124 it.next().unwrap_or_else(|| match x {
125 ParamKind::Type => {
126 self.result.standard_types.unknown.clone().cast(Interner)
127 }
128 ParamKind::Const(ty) => consteval::unknown_const_as_generic(ty.clone()),
129 ParamKind::Lifetime => error_lifetime().cast(Interner),
130 })
131 })
132 .build();
133
134 return Some(ValuePathResolution::GenericDef(value_def, generic_def, substs));
135 }
136
137 let parent_substs = self_subst.or_else(|| {
138 let generics = generics(self.db, generic_def);
139 let parent_params_len = generics.parent_generics()?.len();
140 let parent_args = &substs[..parent_params_len];
141 Some(Substitution::from_iter(Interner, parent_args))
142 });
143 let parent_substs_len = parent_substs.as_ref().map_or(0, |s| s.len(Interner));
144 let mut it = substs.iter().skip(parent_substs_len).cloned();
145 let builder = TyBuilder::subst_for_def(self.db, generic_def, parent_substs);
146 let substs = builder
147 .fill(|x| {
148 it.next().unwrap_or_else(|| match x {
149 ParamKind::Type => self.result.standard_types.unknown.clone().cast(Interner),
150 ParamKind::Const(ty) => consteval::unknown_const_as_generic(ty.clone()),
151 ParamKind::Lifetime => error_lifetime().cast(Interner),
152 })
98 let substs = if self_subst.is_some_and(|it| !it.is_empty())
99 && matches!(value_def, ValueTyDefId::EnumVariantId(_))
100 {
101 // This is something like `TypeAlias::<Args>::EnumVariant`. Do not call `substs_from_path()`,
102 // as it'll try to re-lower the previous segment assuming it refers to the enum, but it refers
103 // to the type alias and they may have different generics.
104 self.types.empty_args
105 } else {
106 self.with_body_ty_lowering(|ctx| {
107 let mut path_ctx = ctx.at_path(path, id);
108 let last_segment = path.segments().len().checked_sub(1);
109 if let Some(last_segment) = last_segment {
110 path_ctx.set_current_segment(last_segment)
111 }
112 path_ctx.substs_from_path(value_def, true, false)
153113 })
154 .build();
114 };
115
116 let parent_substs_len = self_subst.map_or(0, |it| it.len());
117 let substs = GenericArgs::fill_rest(
118 self.interner(),
119 generic_def.into(),
120 self_subst.iter().flat_map(|it| it.iter()).chain(substs.iter().skip(parent_substs_len)),
121 |_, _, id, _| GenericArg::error_from_id(self.interner(), id),
122 );
155123
156124 Some(ValuePathResolution::GenericDef(value_def, generic_def, substs))
157125 }
......@@ -161,7 +129,7 @@ impl<'db> InferenceContext<'db> {
161129 path: &Path,
162130 id: ExprOrPatId,
163131 no_diagnostics: bool,
164 ) -> Option<(ValueNs, Option<chalk_ir::Substitution<Interner>>)> {
132 ) -> Option<(ValueNs, Option<GenericArgs<'db>>)> {
165133 // Don't use `self.make_ty()` here as we need `orig_ns`.
166134 let mut ctx = TyLoweringContext::new(
167135 self.db,
......@@ -211,7 +179,7 @@ impl<'db> InferenceContext<'db> {
211179
212180 let (resolution, substs) = match (def, is_before_last) {
213181 (TypeNs::TraitId(trait_), true) => {
214 let self_ty = self.table.new_type_var();
182 let self_ty = self.table.next_ty_var();
215183 let trait_ref =
216184 path_ctx.lower_trait_ref_from_resolved_path(trait_, self_ty, true);
217185 drop_ctx(ctx, no_diagnostics);
......@@ -225,7 +193,7 @@ impl<'db> InferenceContext<'db> {
225193 path_ctx.ignore_last_segment();
226194 let (ty, _) = path_ctx.lower_partly_resolved_path(def, true);
227195 drop_ctx(ctx, no_diagnostics);
228 if ty.is_unknown() {
196 if ty.is_ty_error() {
229197 return None;
230198 }
231199
......@@ -241,21 +209,25 @@ impl<'db> InferenceContext<'db> {
241209 return Some((value, self_subst));
242210
243211 #[inline]
244 fn drop_ctx(mut ctx: TyLoweringContext<'_>, no_diagnostics: bool) {
212 fn drop_ctx(mut ctx: TyLoweringContext<'_, '_>, no_diagnostics: bool) {
245213 if no_diagnostics {
246214 ctx.forget_diagnostics();
247215 }
248216 }
249217 }
250218
251 fn add_required_obligations_for_value_path(&mut self, def: GenericDefId, subst: &Substitution) {
252 let predicates = self.db.generic_predicates(def);
253 for predicate in predicates.iter() {
254 let (predicate, binders) =
255 predicate.clone().substitute(Interner, &subst).into_value_and_skipped_binders();
256 // Quantified where clauses are not yet handled.
257 stdx::always!(binders.is_empty(Interner));
258 self.push_obligation(predicate.cast(Interner));
219 fn add_required_obligations_for_value_path(
220 &mut self,
221 def: GenericDefId,
222 subst: GenericArgs<'db>,
223 ) {
224 let predicates = self.db.generic_predicates_ns(def);
225 let interner = self.interner();
226 let param_env = self.table.trait_env.env;
227 if let Some(predicates) = predicates.instantiate(self.interner(), subst) {
228 self.table.register_predicates(predicates.map(|predicate| {
229 Obligation::new(interner, ObligationCause::new(), param_env, predicate)
230 }));
259231 }
260232
261233 // We need to add `Self: Trait` obligation when `def` is a trait assoc item.
......@@ -267,21 +239,27 @@ impl<'db> InferenceContext<'db> {
267239
268240 if let ItemContainerId::TraitId(trait_) = container {
269241 let parent_len = generics(self.db, def).parent_generics().map_or(0, |g| g.len_self());
270 let parent_subst =
271 Substitution::from_iter(Interner, subst.iter(Interner).take(parent_len));
272 let trait_ref =
273 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: parent_subst };
274 self.push_obligation(trait_ref.cast(Interner));
242 let parent_subst = GenericArgs::new_from_iter(
243 interner,
244 subst.as_slice()[..parent_len].iter().copied(),
245 );
246 let trait_ref = TraitRef::new(interner, trait_.into(), parent_subst);
247 self.table.register_predicate(Obligation::new(
248 interner,
249 ObligationCause::new(),
250 param_env,
251 trait_ref,
252 ));
275253 }
276254 }
277255
278256 fn resolve_trait_assoc_item(
279257 &mut self,
280 trait_ref: TraitRef,
258 trait_ref: TraitRef<'db>,
281259 segment: PathSegment<'_>,
282260 id: ExprOrPatId,
283 ) -> Option<(ValueNs, Substitution)> {
284 let trait_ = trait_ref.hir_trait_id();
261 ) -> Option<(ValueNs, GenericArgs<'db>)> {
262 let trait_ = trait_ref.def_id.0;
285263 let item =
286264 trait_.trait_items(self.db).items.iter().map(|(_name, id)| *id).find_map(|item| {
287265 match item {
......@@ -309,25 +287,25 @@ impl<'db> InferenceContext<'db> {
309287 AssocItemId::TypeAliasId(_) => unreachable!(),
310288 };
311289
312 self.write_assoc_resolution(id, item, trait_ref.substitution.clone());
313 Some((def, trait_ref.substitution))
290 self.write_assoc_resolution(id, item, trait_ref.args);
291 Some((def, trait_ref.args))
314292 }
315293
316294 fn resolve_ty_assoc_item(
317295 &mut self,
318 ty: Ty,
296 ty: Ty<'db>,
319297 name: &Name,
320298 id: ExprOrPatId,
321 ) -> Option<(ValueNs, Substitution)> {
322 if let TyKind::Error = ty.kind(Interner) {
299 ) -> Option<(ValueNs, GenericArgs<'db>)> {
300 if ty.is_ty_error() {
323301 return None;
324302 }
325303
326 if let Some(result) = self.resolve_enum_variant_on_ty(&ty, name, id) {
304 if let Some(result) = self.resolve_enum_variant_on_ty(ty, name, id) {
327305 return Some(result);
328306 }
329307
330 let canonical_ty = self.canonicalize(ty.clone().to_nextsolver(self.table.interner));
308 let canonical_ty = self.canonicalize(ty);
331309
332310 let mut not_visible = None;
333311 let res = method_resolution::iterate_method_candidates(
......@@ -362,24 +340,28 @@ impl<'db> InferenceContext<'db> {
362340 };
363341 let substs = match container {
364342 ItemContainerId::ImplId(impl_id) => {
365 let interner = DbInterner::new_with(self.db, None, None);
366 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id, None)
367 .fill_with_inference_vars(&mut self.table)
368 .build();
369 let args: crate::next_solver::GenericArgs<'_> = impl_substs.to_nextsolver(interner);
343 let impl_substs = self.table.fresh_args_for_item(impl_id.into());
370344 let impl_self_ty =
371 self.db.impl_self_ty(impl_id).instantiate(interner, args).to_chalk(interner);
372 self.unify(&impl_self_ty, &ty);
345 self.db.impl_self_ty(impl_id).instantiate(self.interner(), impl_substs);
346 self.unify(impl_self_ty, ty);
373347 impl_substs
374348 }
375349 ItemContainerId::TraitId(trait_) => {
376350 // we're picking this method
377 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
378 .push(ty.clone())
379 .fill_with_inference_vars(&mut self.table)
380 .build();
381 self.push_obligation(trait_ref.clone().cast(Interner));
382 trait_ref.substitution
351 let args = GenericArgs::fill_rest(
352 self.interner(),
353 trait_.into(),
354 [ty.into()],
355 |_, _, id, _| self.table.next_var_for_param(id),
356 );
357 let trait_ref = TraitRef::new(self.interner(), trait_.into(), args);
358 self.table.register_predicate(Obligation::new(
359 self.interner(),
360 ObligationCause::new(),
361 self.table.trait_env.env,
362 trait_ref,
363 ));
364 args
383365 }
384366 ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
385367 never!("assoc item contained in module/extern block");
......@@ -387,7 +369,7 @@ impl<'db> InferenceContext<'db> {
387369 }
388370 };
389371
390 self.write_assoc_resolution(id, item, substs.clone());
372 self.write_assoc_resolution(id, item, substs);
391373 if !visible {
392374 self.push_diagnostic(InferenceDiagnostic::PrivateAssocItem { id, item });
393375 }
......@@ -396,11 +378,11 @@ impl<'db> InferenceContext<'db> {
396378
397379 fn resolve_enum_variant_on_ty(
398380 &mut self,
399 ty: &Ty,
381 ty: Ty<'db>,
400382 name: &Name,
401383 id: ExprOrPatId,
402 ) -> Option<(ValueNs, Substitution)> {
403 let ty = self.table.structurally_resolve_type(ty);
384 ) -> Option<(ValueNs, GenericArgs<'db>)> {
385 let ty = self.table.try_structurally_resolve_type(ty);
404386 let (enum_id, subst) = match ty.as_adt() {
405387 Some((AdtId::EnumId(e), subst)) => (e, subst),
406388 _ => return None,
......@@ -408,14 +390,14 @@ impl<'db> InferenceContext<'db> {
408390 let enum_data = enum_id.enum_variants(self.db);
409391 let variant = enum_data.variant(name)?;
410392 self.write_variant_resolution(id, variant.into());
411 Some((ValueNs::EnumVariantId(variant), subst.clone()))
393 Some((ValueNs::EnumVariantId(variant), subst))
412394 }
413395}
414396
415397#[derive(Debug)]
416enum ValuePathResolution {
398enum ValuePathResolution<'db> {
417399 // It's awkward to wrap a single ID in two enums, but we need both and this saves fallible
418400 // conversion between them + `unwrap()`.
419 GenericDef(ValueTyDefId, GenericDefId, Substitution),
420 NonGeneric(Ty),
401 GenericDef(ValueTyDefId, GenericDefId, GenericArgs<'db>),
402 NonGeneric(Ty<'db>),
421403}
src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs+276-697
......@@ -2,49 +2,43 @@
22
33use std::fmt;
44
5use chalk_ir::{
6 CanonicalVarKind, TyVariableKind, cast::Cast, fold::TypeFoldable, interner::HasInterner,
7};
8use either::Either;
9use hir_def::{AdtId, lang_item::LangItem};
5use hir_def::{AdtId, GenericParamId, lang_item::LangItem};
106use hir_expand::name::Name;
117use intern::sym;
128use rustc_hash::{FxHashMap, FxHashSet};
139use rustc_type_ir::{
14 TyVid, TypeVisitableExt, UpcastFrom,
15 inherent::{IntoKind, Span, Term as _, Ty as _},
16 relate::{Relate, solver_relating::RelateExt},
10 DebruijnIndex, InferConst, InferTy, RegionVid, TyVid, TypeFoldable, TypeFolder,
11 TypeSuperFoldable, TypeVisitableExt, UpcastFrom,
12 inherent::{Const as _, IntoKind, Ty as _},
1713 solve::{Certainty, GoalSource},
1814};
1915use smallvec::SmallVec;
2016use triomphe::Arc;
2117
22use super::{InferResult, InferenceContext, TypeError};
2318use crate::{
24 AliasTy, BoundVar, Canonical, Const, ConstValue, DebruijnIndex, GenericArg, GenericArgData,
25 InferenceVar, Interner, Lifetime, OpaqueTyId, ProjectionTy, Substitution, TraitEnvironment, Ty,
26 TyExt, TyKind, VariableKind,
27 consteval::unknown_const,
28 db::HirDatabase,
29 fold_generic_args, fold_tys_and_consts,
19 TraitEnvironment,
20 db::{HirDatabase, InternedOpaqueTyId},
21 infer::InferenceContext,
3022 next_solver::{
31 self, ClauseKind, DbInterner, ErrorGuaranteed, Predicate, PredicateKind, SolverDefIds,
32 Term, TraitRef,
33 fulfill::FulfillmentCtxt,
23 self, AliasTy, Binder, Canonical, ClauseKind, Const, ConstKind, DbInterner,
24 ErrorGuaranteed, GenericArg, GenericArgs, Predicate, PredicateKind, Region, RegionKind,
25 SolverDefId, SolverDefIds, TraitRef, Ty, TyKind, TypingMode,
26 fulfill::{FulfillmentCtxt, NextSolverError},
3427 infer::{
35 DbInternerInferExt, InferCtxt, InferOk,
28 DbInternerInferExt, DefineOpaqueTypes, InferCtxt, InferOk, InferResult,
29 at::ToTrace,
3630 snapshot::CombinedSnapshot,
37 traits::{Obligation, ObligationCause},
31 traits::{Obligation, ObligationCause, PredicateObligation},
3832 },
3933 inspect::{InspectConfig, InspectGoal, ProofTreeVisitor},
40 mapping::{ChalkToNextSolver, NextSolverToChalk},
34 obligation_ctxt::ObligationCtxt,
4135 },
4236 traits::{
4337 FnTrait, NextTraitSolveResult, next_trait_solve_canonical_in_ctxt, next_trait_solve_in_ctxt,
4438 },
4539};
4640
47impl<'db> InferenceContext<'db> {
41impl<'db> InferenceContext<'_, 'db> {
4842 pub(super) fn canonicalize<T>(&mut self, t: T) -> rustc_type_ir::Canonical<DbInterner<'db>, T>
4943 where
5044 T: rustc_type_ir::TypeFoldable<DbInterner<'db>>,
......@@ -77,7 +71,7 @@ impl<'a, 'db> ProofTreeVisitor<'db> for NestedObligationsForSelfTy<'a, 'db> {
7771 return;
7872 }
7973
80 let db = self.ctx.interner;
74 let db = self.ctx.interner();
8175 let goal = inspect_goal.goal();
8276 if self.ctx.predicate_has_self_ty(goal.predicate, self.self_ty)
8377 // We do not push the instantiated forms of goals as it would cause any
......@@ -118,109 +112,56 @@ impl<'a, 'db> ProofTreeVisitor<'db> for NestedObligationsForSelfTy<'a, 'db> {
118112/// This means that there may be some unresolved goals that actually set bounds for the placeholder
119113/// type for the types to unify. For example `Option<T>` and `Option<U>` unify although there is
120114/// unresolved goal `T = U`.
121pub fn could_unify(
122 db: &dyn HirDatabase,
123 env: Arc<TraitEnvironment<'_>>,
124 tys: &Canonical<(Ty, Ty)>,
115pub fn could_unify<'db>(
116 db: &'db dyn HirDatabase,
117 env: Arc<TraitEnvironment<'db>>,
118 tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>,
125119) -> bool {
126 unify(db, env, tys).is_some()
120 could_unify_impl(db, env, tys, |ctxt| ctxt.try_evaluate_obligations())
127121}
128122
129123/// Check if types unify eagerly making sure there are no unresolved goals.
130124///
131125/// This means that placeholder types are not considered to unify if there are any bounds set on
132126/// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U`
133pub fn could_unify_deeply(
134 db: &dyn HirDatabase,
135 env: Arc<TraitEnvironment<'_>>,
136 tys: &Canonical<(Ty, Ty)>,
127pub fn could_unify_deeply<'db>(
128 db: &'db dyn HirDatabase,
129 env: Arc<TraitEnvironment<'db>>,
130 tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>,
137131) -> bool {
138 let mut table = InferenceTable::new(db, env);
139 let vars = make_substitutions(tys, &mut table);
140 let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner);
141 let ty2_with_vars = vars.apply(tys.value.1.clone(), Interner);
142 let ty1_with_vars = table.normalize_associated_types_in(ty1_with_vars);
143 let ty2_with_vars = table.normalize_associated_types_in(ty2_with_vars);
144 table.select_obligations_where_possible();
145 let ty1_with_vars = table.resolve_completely(ty1_with_vars);
146 let ty2_with_vars = table.resolve_completely(ty2_with_vars);
147 table.unify_deeply(&ty1_with_vars, &ty2_with_vars)
132 could_unify_impl(db, env, tys, |ctxt| ctxt.evaluate_obligations_error_on_ambiguity())
148133}
149134
150pub(crate) fn unify(
151 db: &dyn HirDatabase,
152 env: Arc<TraitEnvironment<'_>>,
153 tys: &Canonical<(Ty, Ty)>,
154) -> Option<Substitution> {
155 let mut table = InferenceTable::new(db, env);
156 let vars = make_substitutions(tys, &mut table);
157 let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner);
158 let ty2_with_vars = vars.apply(tys.value.1.clone(), Interner);
159 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
160 return None;
161 }
162 // default any type vars that weren't unified back to their original bound vars
163 // (kind of hacky)
164 let find_var = |iv| {
165 vars.iter(Interner).position(|v| match v.data(Interner) {
166 GenericArgData::Ty(ty) => ty.inference_var(Interner),
167 GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
168 GenericArgData::Const(c) => c.inference_var(Interner),
169 } == Some(iv))
170 };
171 let fallback = |iv, kind, binder| match kind {
172 chalk_ir::VariableKind::Ty(_ty_kind) => find_var(iv).map_or_else(
173 || TyKind::Error.intern(Interner).cast(Interner),
174 |i| BoundVar::new(binder, i).to_ty(Interner).cast(Interner),
175 ),
176 chalk_ir::VariableKind::Lifetime => find_var(iv).map_or_else(
177 || crate::error_lifetime().cast(Interner),
178 |i| BoundVar::new(binder, i).to_lifetime(Interner).cast(Interner),
179 ),
180 chalk_ir::VariableKind::Const(ty) => find_var(iv).map_or_else(
181 || crate::unknown_const(ty.clone()).cast(Interner),
182 |i| BoundVar::new(binder, i).to_const(Interner, ty.clone()).cast(Interner),
183 ),
184 };
185 Some(Substitution::from_iter(
186 Interner,
187 vars.iter(Interner).map(|v| table.resolve_with_fallback(v.clone(), &fallback)),
188 ))
189}
190
191fn make_substitutions(
192 tys: &chalk_ir::Canonical<(chalk_ir::Ty<Interner>, chalk_ir::Ty<Interner>)>,
193 table: &mut InferenceTable<'_>,
194) -> chalk_ir::Substitution<Interner> {
195 Substitution::from_iter(
196 Interner,
197 tys.binders.iter(Interner).map(|it| match &it.kind {
198 chalk_ir::VariableKind::Ty(_) => table.new_type_var().cast(Interner),
199 // FIXME: maybe wrong?
200 chalk_ir::VariableKind::Lifetime => table.new_type_var().cast(Interner),
201 chalk_ir::VariableKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
202 }),
203 )
204}
205
206bitflags::bitflags! {
207 #[derive(Default, Clone, Copy)]
208 pub(crate) struct TypeVariableFlags: u8 {
209 const DIVERGING = 1 << 0;
210 const INTEGER = 1 << 1;
211 const FLOAT = 1 << 2;
212 }
135fn could_unify_impl<'db>(
136 db: &'db dyn HirDatabase,
137 env: Arc<TraitEnvironment<'db>>,
138 tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>,
139 select: for<'a> fn(&mut ObligationCtxt<'a, 'db>) -> Vec<NextSolverError<'db>>,
140) -> bool {
141 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
142 // FIXME(next-solver): I believe this should use `PostAnalysis` (this is only used for IDE things),
143 // but this causes some bug because of our incorrect impl of `type_of_opaque_hir_typeck()` for TAIT
144 // and async blocks.
145 let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
146 let cause = ObligationCause::dummy();
147 let at = infcx.at(&cause, env.env);
148 let ((ty1_with_vars, ty2_with_vars), _) = infcx.instantiate_canonical(tys);
149 let mut ctxt = ObligationCtxt::new(&infcx);
150 let can_unify = at
151 .eq(DefineOpaqueTypes::No, ty1_with_vars, ty2_with_vars)
152 .map(|infer_ok| ctxt.register_infer_ok_obligations(infer_ok))
153 .is_ok();
154 can_unify && select(&mut ctxt).is_empty()
213155}
214156
215157#[derive(Clone)]
216158pub(crate) struct InferenceTable<'db> {
217159 pub(crate) db: &'db dyn HirDatabase,
218 pub(crate) interner: DbInterner<'db>,
219160 pub(crate) trait_env: Arc<TraitEnvironment<'db>>,
220 pub(crate) tait_coercion_table: Option<FxHashMap<OpaqueTyId, Ty>>,
161 pub(crate) tait_coercion_table: Option<FxHashMap<InternedOpaqueTyId, Ty<'db>>>,
221162 pub(crate) infer_ctxt: InferCtxt<'db>,
222163 pub(super) fulfillment_cx: FulfillmentCtxt<'db>,
223 pub(super) diverging_type_vars: FxHashSet<crate::next_solver::Ty<'db>>,
164 pub(super) diverging_type_vars: FxHashSet<Ty<'db>>,
224165}
225166
226167pub(crate) struct InferenceTableSnapshot<'db> {
......@@ -236,7 +177,6 @@ impl<'db> InferenceTable<'db> {
236177 });
237178 InferenceTable {
238179 db,
239 interner,
240180 trait_env,
241181 tait_coercion_table: None,
242182 fulfillment_cx: FulfillmentCtxt::new(&infer_ctxt),
......@@ -245,15 +185,22 @@ impl<'db> InferenceTable<'db> {
245185 }
246186 }
247187
188 #[inline]
189 pub(crate) fn interner(&self) -> DbInterner<'db> {
190 self.infer_ctxt.interner
191 }
192
193 pub(crate) fn type_is_copy_modulo_regions(&self, ty: Ty<'db>) -> bool {
194 self.infer_ctxt.type_is_copy_modulo_regions(self.trait_env.env, ty)
195 }
196
248197 pub(crate) fn type_var_is_sized(&self, self_ty: TyVid) -> bool {
249198 let Some(sized_did) = LangItem::Sized.resolve_trait(self.db, self.trait_env.krate) else {
250199 return true;
251200 };
252201 self.obligations_for_self_ty(self_ty).into_iter().any(|obligation| {
253202 match obligation.predicate.kind().skip_binder() {
254 crate::next_solver::PredicateKind::Clause(
255 crate::next_solver::ClauseKind::Trait(data),
256 ) => data.def_id().0 == sized_did,
203 PredicateKind::Clause(ClauseKind::Trait(data)) => data.def_id().0 == sized_did,
257204 _ => false,
258205 }
259206 })
......@@ -309,28 +256,24 @@ impl<'db> InferenceTable<'db> {
309256 }
310257 }
311258
312 fn type_matches_expected_vid(
313 &self,
314 expected_vid: TyVid,
315 ty: crate::next_solver::Ty<'db>,
316 ) -> bool {
259 fn type_matches_expected_vid(&self, expected_vid: TyVid, ty: Ty<'db>) -> bool {
317260 let ty = self.shallow_resolve(ty);
318261
319262 match ty.kind() {
320 crate::next_solver::TyKind::Infer(rustc_type_ir::TyVar(found_vid)) => {
263 TyKind::Infer(rustc_type_ir::TyVar(found_vid)) => {
321264 self.infer_ctxt.root_var(expected_vid) == self.infer_ctxt.root_var(found_vid)
322265 }
323266 _ => false,
324267 }
325268 }
326269
327 pub(super) fn set_diverging(&mut self, ty: crate::next_solver::Ty<'db>) {
270 pub(super) fn set_diverging(&mut self, ty: Ty<'db>) {
328271 self.diverging_type_vars.insert(ty);
329272 }
330273
331274 pub(crate) fn canonicalize<T>(&mut self, t: T) -> rustc_type_ir::Canonical<DbInterner<'db>, T>
332275 where
333 T: rustc_type_ir::TypeFoldable<DbInterner<'db>>,
276 T: TypeFoldable<DbInterner<'db>>,
334277 {
335278 // try to resolve obligations before canonicalizing, since this might
336279 // result in new knowledge about variables
......@@ -338,26 +281,11 @@ impl<'db> InferenceTable<'db> {
338281 self.infer_ctxt.canonicalize_response(t)
339282 }
340283
341 /// Recurses through the given type, normalizing associated types mentioned
342 /// in it by replacing them by type variables and registering obligations to
343 /// resolve later. This should be done once for every type we get from some
344 /// type annotation (e.g. from a let type annotation, field type or function
345 /// call). `make_ty` handles this already, but e.g. for field types we need
346 /// to do it as well.
347 pub(crate) fn normalize_associated_types_in<T, U>(&mut self, ty: T) -> T
348 where
349 T: ChalkToNextSolver<'db, U>,
350 U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
351 {
352 self.normalize_associated_types_in_ns(ty.to_nextsolver(self.interner))
353 .to_chalk(self.interner)
354 }
355
356284 // FIXME: We should get rid of this method. We cannot deeply normalize during inference, only when finishing.
357285 // Inference should use shallow normalization (`try_structurally_resolve_type()`) only, when needed.
358 pub(crate) fn normalize_associated_types_in_ns<T>(&mut self, ty: T) -> T
286 pub(crate) fn normalize_associated_types_in<T>(&mut self, ty: T) -> T
359287 where
360 T: rustc_type_ir::TypeFoldable<DbInterner<'db>> + Clone,
288 T: TypeFoldable<DbInterner<'db>> + Clone,
361289 {
362290 let ty = self.resolve_vars_with_obligations(ty);
363291 self.infer_ctxt
......@@ -370,176 +298,130 @@ impl<'db> InferenceTable<'db> {
370298 /// the inference variables
371299 pub(crate) fn eagerly_normalize_and_resolve_shallow_in<T>(&mut self, ty: T) -> T
372300 where
373 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
301 T: TypeFoldable<DbInterner<'db>>,
374302 {
375 fn eagerly_resolve_ty<const N: usize>(
376 table: &mut InferenceTable<'_>,
377 ty: Ty,
378 mut tys: SmallVec<[Ty; N]>,
379 ) -> Ty {
380 if tys.contains(&ty) {
381 return ty;
382 }
383 tys.push(ty.clone());
384
385 match ty.kind(Interner) {
386 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
387 let ty = table.normalize_projection_ty(proj_ty.clone());
388 eagerly_resolve_ty(table, ty, tys)
389 }
390 TyKind::InferenceVar(..) => {
391 let ty = table.resolve_ty_shallow(&ty);
392 eagerly_resolve_ty(table, ty, tys)
393 }
394 _ => ty,
395 }
396 }
397
398 fold_tys_and_consts(
399 ty,
400 |e, _| match e {
401 Either::Left(ty) => {
402 Either::Left(eagerly_resolve_ty::<8>(self, ty, SmallVec::new()))
403 }
404 Either::Right(c) => Either::Right(match &c.data(Interner).value {
405 chalk_ir::ConstValue::Concrete(cc) => match &cc.interned {
406 crate::ConstScalar::UnevaluatedConst(c_id, subst) => {
407 // FIXME: same as `normalize_associated_types_in`
408 if subst.len(Interner) == 0 {
409 if let Ok(eval) = self.db.const_eval(*c_id, subst.clone(), None) {
410 eval
411 } else {
412 unknown_const(c.data(Interner).ty.clone())
413 }
414 } else {
415 unknown_const(c.data(Interner).ty.clone())
416 }
417 }
418 _ => c,
419 },
420 _ => c,
421 }),
422 },
423 DebruijnIndex::INNERMOST,
424 )
425 }
426
427 pub(crate) fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
428 let ty = TyKind::Alias(chalk_ir::AliasTy::Projection(proj_ty))
429 .intern(Interner)
430 .to_nextsolver(self.interner);
431 self.normalize_alias_ty(ty).to_chalk(self.interner)
432 }
433
434 pub(crate) fn normalize_alias_ty(
435 &mut self,
436 alias: crate::next_solver::Ty<'db>,
437 ) -> crate::next_solver::Ty<'db> {
438 let infer_term = self.infer_ctxt.next_ty_var();
439 let obligation = crate::next_solver::Predicate::new(
440 self.interner,
441 crate::next_solver::Binder::dummy(crate::next_solver::PredicateKind::AliasRelate(
442 alias.into(),
443 infer_term.into(),
444 rustc_type_ir::AliasRelationDirection::Equate,
445 )),
446 );
447 self.register_obligation(obligation);
448 self.resolve_vars_with_obligations(infer_term)
449 }
450
451 fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
452 let var = match kind {
453 TyVariableKind::General => {
454 let var = self.infer_ctxt.next_ty_vid();
455 InferenceVar::from(var.as_u32())
456 }
457 TyVariableKind::Integer => {
458 let var = self.infer_ctxt.next_int_vid();
459 InferenceVar::from(var.as_u32())
460 }
461 TyVariableKind::Float => {
462 let var = self.infer_ctxt.next_float_vid();
463 InferenceVar::from(var.as_u32())
464 }
465 };
466
467 let ty = var.to_ty(Interner, kind);
468 if diverging {
469 self.diverging_type_vars.insert(ty.to_nextsolver(self.interner));
470 }
471 ty
303 let ty = self.resolve_vars_with_obligations(ty);
304 let ty = self.normalize_associated_types_in(ty);
305 self.resolve_vars_with_obligations(ty)
472306 }
473307
474 pub(crate) fn new_type_var(&mut self) -> Ty {
475 self.new_var(TyVariableKind::General, false)
308 pub(crate) fn normalize_alias_ty(&mut self, alias: Ty<'db>) -> Ty<'db> {
309 self.infer_ctxt
310 .at(&ObligationCause::new(), self.trait_env.env)
311 .structurally_normalize_ty(alias, &mut self.fulfillment_cx)
312 .unwrap_or(alias)
476313 }
477314
478 pub(crate) fn next_ty_var(&mut self) -> crate::next_solver::Ty<'db> {
315 pub(crate) fn next_ty_var(&mut self) -> Ty<'db> {
479316 self.infer_ctxt.next_ty_var()
480317 }
481318
482 pub(crate) fn new_integer_var(&mut self) -> Ty {
483 self.new_var(TyVariableKind::Integer, false)
319 pub(crate) fn next_const_var(&mut self) -> Const<'db> {
320 self.infer_ctxt.next_const_var()
484321 }
485322
486 pub(crate) fn new_float_var(&mut self) -> Ty {
487 self.new_var(TyVariableKind::Float, false)
323 pub(crate) fn next_int_var(&mut self) -> Ty<'db> {
324 self.infer_ctxt.next_int_var()
488325 }
489326
490 pub(crate) fn new_maybe_never_var(&mut self) -> Ty {
491 self.new_var(TyVariableKind::General, true)
327 pub(crate) fn next_float_var(&mut self) -> Ty<'db> {
328 self.infer_ctxt.next_float_var()
492329 }
493330
494 pub(crate) fn new_const_var(&mut self, ty: Ty) -> Const {
495 let var = self.infer_ctxt.next_const_vid();
496 let var = InferenceVar::from(var.as_u32());
497 var.to_const(Interner, ty)
331 pub(crate) fn new_maybe_never_var(&mut self) -> Ty<'db> {
332 let var = self.next_ty_var();
333 self.set_diverging(var);
334 var
498335 }
499336
500 pub(crate) fn new_lifetime_var(&mut self) -> Lifetime {
501 let var = self.infer_ctxt.next_region_vid();
502 let var = InferenceVar::from(var.as_u32());
503 var.to_lifetime(Interner)
337 pub(crate) fn next_region_var(&mut self) -> Region<'db> {
338 self.infer_ctxt.next_region_var()
504339 }
505340
506 pub(crate) fn next_region_var(&mut self) -> crate::next_solver::Region<'db> {
507 self.infer_ctxt.next_region_var()
341 pub(crate) fn next_var_for_param(&mut self, id: GenericParamId) -> GenericArg<'db> {
342 match id {
343 GenericParamId::TypeParamId(_) => self.next_ty_var().into(),
344 GenericParamId::ConstParamId(_) => self.next_const_var().into(),
345 GenericParamId::LifetimeParamId(_) => self.next_region_var().into(),
346 }
508347 }
509348
510349 pub(crate) fn resolve_with_fallback<T>(
511350 &mut self,
512351 t: T,
513 fallback: &dyn Fn(InferenceVar, VariableKind, DebruijnIndex) -> GenericArg,
352 fallback_ty: &mut dyn FnMut(DebruijnIndex, InferTy) -> Ty<'db>,
353 fallback_const: &mut dyn FnMut(DebruijnIndex, InferConst) -> Const<'db>,
354 fallback_region: &mut dyn FnMut(DebruijnIndex, RegionVid) -> Region<'db>,
514355 ) -> T
515356 where
516 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
357 T: TypeFoldable<DbInterner<'db>>,
517358 {
518 self.resolve_with_fallback_inner(t, &fallback)
519 }
359 struct Resolver<'a, 'db> {
360 table: &'a mut InferenceTable<'db>,
361 binder: DebruijnIndex,
362 fallback_ty: &'a mut dyn FnMut(DebruijnIndex, InferTy) -> Ty<'db>,
363 fallback_const: &'a mut dyn FnMut(DebruijnIndex, InferConst) -> Const<'db>,
364 fallback_region: &'a mut dyn FnMut(DebruijnIndex, RegionVid) -> Region<'db>,
365 }
520366
521 pub(crate) fn fresh_subst(&mut self, binders: &[CanonicalVarKind<Interner>]) -> Substitution {
522 Substitution::from_iter(
523 Interner,
524 binders.iter().map(|kind| match &kind.kind {
525 chalk_ir::VariableKind::Ty(ty_variable_kind) => {
526 self.new_var(*ty_variable_kind, false).cast(Interner)
367 impl<'db> TypeFolder<DbInterner<'db>> for Resolver<'_, 'db> {
368 fn cx(&self) -> DbInterner<'db> {
369 self.table.interner()
370 }
371
372 fn fold_binder<T>(&mut self, t: Binder<'db, T>) -> Binder<'db, T>
373 where
374 T: TypeFoldable<DbInterner<'db>>,
375 {
376 self.binder.shift_in(1);
377 let result = t.super_fold_with(self);
378 self.binder.shift_out(1);
379 result
380 }
381
382 fn fold_ty(&mut self, t: Ty<'db>) -> Ty<'db> {
383 if !t.has_infer() {
384 return t;
527385 }
528 chalk_ir::VariableKind::Lifetime => self.new_lifetime_var().cast(Interner),
529 chalk_ir::VariableKind::Const(ty) => self.new_const_var(ty.clone()).cast(Interner),
530 }),
531 )
532 }
533386
534 pub(crate) fn instantiate_canonical<T>(&mut self, canonical: Canonical<T>) -> T
535 where
536 T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + std::fmt::Debug,
537 {
538 let subst = self.fresh_subst(canonical.binders.as_slice(Interner));
539 subst.apply(canonical.value, Interner)
387 if let TyKind::Infer(infer) = t.kind() {
388 (self.fallback_ty)(self.binder, infer)
389 } else {
390 t.super_fold_with(self)
391 }
392 }
393
394 fn fold_const(&mut self, c: Const<'db>) -> Const<'db> {
395 if !c.has_infer() {
396 return c;
397 }
398
399 if let ConstKind::Infer(infer) = c.kind() {
400 (self.fallback_const)(self.binder, infer)
401 } else {
402 c.super_fold_with(self)
403 }
404 }
405
406 fn fold_region(&mut self, r: Region<'db>) -> Region<'db> {
407 if let RegionKind::ReVar(infer) = r.kind() {
408 (self.fallback_region)(self.binder, infer)
409 } else {
410 r
411 }
412 }
413 }
414
415 t.fold_with(&mut Resolver {
416 table: self,
417 binder: DebruijnIndex::ZERO,
418 fallback_ty,
419 fallback_const,
420 fallback_region,
421 })
540422 }
541423
542 pub(crate) fn instantiate_canonical_ns<T>(
424 pub(crate) fn instantiate_canonical<T>(
543425 &mut self,
544426 canonical: rustc_type_ir::Canonical<DbInterner<'db>, T>,
545427 ) -> T
......@@ -549,112 +431,35 @@ impl<'db> InferenceTable<'db> {
549431 self.infer_ctxt.instantiate_canonical(&canonical).0
550432 }
551433
552 fn resolve_with_fallback_inner<T>(
553 &mut self,
554 t: T,
555 fallback: &dyn Fn(InferenceVar, VariableKind, DebruijnIndex) -> GenericArg,
556 ) -> T
434 pub(crate) fn resolve_completely<T>(&mut self, value: T) -> T
557435 where
558 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
436 T: TypeFoldable<DbInterner<'db>>,
559437 {
560 let var_stack = &mut vec![];
561 t.fold_with(
562 &mut resolve::Resolver { table: self, var_stack, fallback },
563 DebruijnIndex::INNERMOST,
564 )
565 }
566
567 pub(crate) fn resolve_completely<T, U>(&mut self, t: T) -> T
568 where
569 T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + ChalkToNextSolver<'db, U>,
570 U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
571 {
572 let value = t.to_nextsolver(self.interner);
573438 let value = self.infer_ctxt.resolve_vars_if_possible(value);
574439
575440 let mut goals = vec![];
576 let value = value.fold_with(&mut resolve_completely::Resolver::new(self, true, &mut goals));
577441
578442 // FIXME(next-solver): Handle `goals`.
579443
580 value.to_chalk(self.interner)
444 value.fold_with(&mut resolve_completely::Resolver::new(self, true, &mut goals))
581445 }
582446
583447 /// Unify two relatable values (e.g. `Ty`) and register new trait goals that arise from that.
584 pub(crate) fn unify<T: ChalkToNextSolver<'db, U>, U: Relate<DbInterner<'db>>>(
585 &mut self,
586 ty1: &T,
587 ty2: &T,
588 ) -> bool {
589 let result = match self.try_unify(ty1, ty2) {
590 Ok(r) => r,
591 Err(_) => return false,
592 };
593 self.register_obligations(result.goals);
594 true
595 }
596
597 pub(crate) fn unify_ns<T: Relate<DbInterner<'db>>>(&mut self, lhs: T, rhs: T) -> bool {
598 let Ok(infer_ok) = self.try_unify_ns(lhs, rhs) else {
599 return false;
600 };
601 self.register_obligations(infer_ok.goals);
602 true
603 }
604
605 /// Unify two relatable values (e.g. `Ty`) and check whether trait goals which arise from that could be fulfilled
606 pub(crate) fn unify_deeply<T: ChalkToNextSolver<'db, U>, U: Relate<DbInterner<'db>>>(
607 &mut self,
608 ty1: &T,
609 ty2: &T,
610 ) -> bool {
611 let result = match self.try_unify(ty1, ty2) {
612 Ok(r) => r,
613 Err(_) => return false,
614 };
615 result.goals.into_iter().all(|goal| {
616 matches!(next_trait_solve_in_ctxt(&self.infer_ctxt, goal), Ok((_, Certainty::Yes)))
617 })
448 pub(crate) fn unify<T: ToTrace<'db>>(&mut self, ty1: T, ty2: T) -> bool {
449 self.try_unify(ty1, ty2).map(|infer_ok| self.register_infer_ok(infer_ok)).is_ok()
618450 }
619451
620452 /// Unify two relatable values (e.g. `Ty`) and return new trait goals arising from it, so the
621453 /// caller needs to deal with them.
622 pub(crate) fn try_unify<T: ChalkToNextSolver<'db, U>, U: Relate<DbInterner<'db>>>(
623 &mut self,
624 t1: &T,
625 t2: &T,
626 ) -> InferResult<'db, ()> {
627 let lhs = t1.to_nextsolver(self.interner);
628 let rhs = t2.to_nextsolver(self.interner);
629 self.try_unify_ns(lhs, rhs)
630 }
631
632 /// Unify two relatable values (e.g. `Ty`) and return new trait goals arising from it, so the
633 /// caller needs to deal with them.
634 pub(crate) fn try_unify_ns<T: Relate<DbInterner<'db>>>(
635 &mut self,
636 lhs: T,
637 rhs: T,
638 ) -> InferResult<'db, ()> {
639 let variance = rustc_type_ir::Variance::Invariant;
640 let span = crate::next_solver::Span::dummy();
641 match self.infer_ctxt.relate(self.trait_env.env, lhs, variance, rhs, span) {
642 Ok(goals) => Ok(crate::infer::InferOk { goals, value: () }),
643 Err(_) => Err(TypeError),
644 }
645 }
646
647 /// If `ty` is a type variable with known type, returns that type;
648 /// otherwise, return ty.
649 #[tracing::instrument(skip(self))]
650 pub(crate) fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
651 self.shallow_resolve(ty.to_nextsolver(self.interner)).to_chalk(self.interner)
454 pub(crate) fn try_unify<T: ToTrace<'db>>(&mut self, t1: T, t2: T) -> InferResult<'db, ()> {
455 self.infer_ctxt.at(&ObligationCause::new(), self.trait_env.env).eq(
456 DefineOpaqueTypes::Yes,
457 t1,
458 t2,
459 )
652460 }
653461
654 pub(crate) fn shallow_resolve(
655 &self,
656 ty: crate::next_solver::Ty<'db>,
657 ) -> crate::next_solver::Ty<'db> {
462 pub(crate) fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {
658463 self.infer_ctxt.shallow_resolve(ty)
659464 }
660465
......@@ -662,8 +467,6 @@ impl<'db> InferenceTable<'db> {
662467 where
663468 T: rustc_type_ir::TypeFoldable<DbInterner<'db>>,
664469 {
665 use rustc_type_ir::TypeVisitableExt;
666
667470 if !t.has_non_region_infer() {
668471 return t;
669472 }
......@@ -678,26 +481,18 @@ impl<'db> InferenceTable<'db> {
678481 self.infer_ctxt.resolve_vars_if_possible(t)
679482 }
680483
681 pub(crate) fn structurally_resolve_type(&mut self, ty: &Ty) -> Ty {
682 if let TyKind::Alias(chalk_ir::AliasTy::Projection(..)) = ty.kind(Interner) {
683 self.structurally_normalize_ty(ty)
684 } else {
685 self.resolve_vars_with_obligations(ty.to_nextsolver(self.interner))
686 .to_chalk(self.interner)
687 }
688 }
689
690 fn structurally_normalize_ty(&mut self, ty: &Ty) -> Ty {
691 self.structurally_normalize_term(ty.to_nextsolver(self.interner).into())
692 .expect_ty()
693 .to_chalk(self.interner)
484 /// Create a `GenericArgs` full of infer vars for `def`.
485 pub(crate) fn fresh_args_for_item(&self, def: SolverDefId) -> GenericArgs<'db> {
486 self.infer_ctxt.fresh_args_for_item(def)
694487 }
695488
696 fn structurally_normalize_term(&mut self, term: Term<'db>) -> Term<'db> {
697 self.infer_ctxt
698 .at(&ObligationCause::new(), self.trait_env.env)
699 .structurally_normalize_term(term, &mut self.fulfillment_cx)
700 .unwrap_or(term)
489 /// Like `fresh_args_for_item()`, but first uses the args from `first`.
490 pub(crate) fn fill_rest_fresh_args(
491 &self,
492 def_id: SolverDefId,
493 first: impl IntoIterator<Item = GenericArg<'db>>,
494 ) -> GenericArgs<'db> {
495 self.infer_ctxt.fill_rest_fresh_args(def_id, first)
701496 }
702497
703498 /// Try to resolve `ty` to a structural type, normalizing aliases.
......@@ -705,11 +500,8 @@ impl<'db> InferenceTable<'db> {
705500 /// In case there is still ambiguity, the returned type may be an inference
706501 /// variable. This is different from `structurally_resolve_type` which errors
707502 /// in this case.
708 pub(crate) fn try_structurally_resolve_type(
709 &mut self,
710 ty: crate::next_solver::Ty<'db>,
711 ) -> crate::next_solver::Ty<'db> {
712 if let crate::next_solver::TyKind::Alias(..) = ty.kind() {
503 pub(crate) fn try_structurally_resolve_type(&mut self, ty: Ty<'db>) -> Ty<'db> {
504 if let TyKind::Alias(..) = ty.kind() {
713505 // We need to use a separate variable here as otherwise the temporary for
714506 // `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting
715507 // in a reentrant borrow, causing an ICE.
......@@ -719,13 +511,18 @@ impl<'db> InferenceTable<'db> {
719511 .structurally_normalize_ty(ty, &mut self.fulfillment_cx);
720512 match result {
721513 Ok(normalized_ty) => normalized_ty,
722 Err(_errors) => crate::next_solver::Ty::new_error(self.interner, ErrorGuaranteed),
514 Err(_errors) => Ty::new_error(self.interner(), ErrorGuaranteed),
723515 }
724516 } else {
725517 self.resolve_vars_with_obligations(ty)
726518 }
727519 }
728520
521 pub(crate) fn structurally_resolve_type(&mut self, ty: Ty<'db>) -> Ty<'db> {
522 self.try_structurally_resolve_type(ty)
523 // FIXME: Err if it still contain infer vars.
524 }
525
729526 pub(crate) fn snapshot(&mut self) -> InferenceTableSnapshot<'db> {
730527 let ctxt_snapshot = self.infer_ctxt.start_snapshot();
731528 let obligations = self.fulfillment_cx.clone();
......@@ -794,7 +591,7 @@ impl<'db> InferenceTable<'db> {
794591 self.fulfillment_cx.register_predicate_obligation(
795592 &self.infer_ctxt,
796593 Obligation::new(
797 self.interner,
594 self.interner(),
798595 ObligationCause::new(),
799596 goal.param_env,
800597 goal.predicate,
......@@ -810,21 +607,11 @@ impl<'db> InferenceTable<'db> {
810607 value
811608 }
812609
813 pub(crate) fn register_obligations(
814 &mut self,
815 obligations: Vec<crate::next_solver::Goal<'db, crate::next_solver::Predicate<'db>>>,
816 ) {
817 obligations.into_iter().for_each(|goal| self.register_obligation_in_env(goal));
818 }
819
820610 pub(crate) fn select_obligations_where_possible(&mut self) {
821611 self.fulfillment_cx.try_evaluate_obligations(&self.infer_ctxt);
822612 }
823613
824 pub(super) fn register_predicate(
825 &mut self,
826 obligation: crate::next_solver::infer::traits::PredicateObligation<'db>,
827 ) {
614 pub(super) fn register_predicate(&mut self, obligation: PredicateObligation<'db>) {
828615 if obligation.has_escaping_bound_vars() {
829616 panic!("escaping bound vars in predicate {:?}", obligation);
830617 }
......@@ -834,7 +621,7 @@ impl<'db> InferenceTable<'db> {
834621
835622 pub(super) fn register_predicates<I>(&mut self, obligations: I)
836623 where
837 I: IntoIterator<Item = crate::next_solver::infer::traits::PredicateObligation<'db>>,
624 I: IntoIterator<Item = PredicateObligation<'db>>,
838625 {
839626 obligations.into_iter().for_each(|obligation| {
840627 self.register_predicate(obligation);
......@@ -843,16 +630,14 @@ impl<'db> InferenceTable<'db> {
843630
844631 pub(crate) fn callable_sig(
845632 &mut self,
846 ty: &Ty,
633 ty: Ty<'db>,
847634 num_args: usize,
848 ) -> Option<(Option<FnTrait>, Vec<crate::next_solver::Ty<'db>>, crate::next_solver::Ty<'db>)>
849 {
850 match ty.callable_sig(self.db) {
851 Some(sig) => Some((
852 None,
853 sig.params().iter().map(|param| param.to_nextsolver(self.interner)).collect(),
854 sig.ret().to_nextsolver(self.interner),
855 )),
635 ) -> Option<(Option<FnTrait>, Vec<Ty<'db>>, Ty<'db>)> {
636 match ty.callable_sig(self.interner()) {
637 Some(sig) => {
638 let sig = sig.skip_binder();
639 Some((None, sig.inputs_and_output.inputs().to_vec(), sig.output()))
640 }
856641 None => {
857642 let (f, args_ty, return_ty) = self.callable_sig_from_fn_trait(ty, num_args)?;
858643 Some((Some(f), args_ty, return_ty))
......@@ -862,9 +647,9 @@ impl<'db> InferenceTable<'db> {
862647
863648 fn callable_sig_from_fn_trait(
864649 &mut self,
865 ty: &Ty,
650 ty: Ty<'db>,
866651 num_args: usize,
867 ) -> Option<(FnTrait, Vec<next_solver::Ty<'db>>, next_solver::Ty<'db>)> {
652 ) -> Option<(FnTrait, Vec<Ty<'db>>, Ty<'db>)> {
868653 for (fn_trait_name, output_assoc_name, subtraits) in [
869654 (FnTrait::FnOnce, sym::Output, &[FnTrait::Fn, FnTrait::FnMut][..]),
870655 (FnTrait::AsyncFnMut, sym::CallRefFuture, &[FnTrait::AsyncFn]),
......@@ -877,8 +662,8 @@ impl<'db> InferenceTable<'db> {
877662 trait_data.associated_type_by_name(&Name::new_symbol_root(output_assoc_name))?;
878663
879664 let mut arg_tys = Vec::with_capacity(num_args);
880 let arg_ty = next_solver::Ty::new_tup_from_iter(
881 self.interner,
665 let arg_ty = Ty::new_tup_from_iter(
666 self.interner(),
882667 std::iter::repeat_with(|| {
883668 let ty = self.next_ty_var();
884669 arg_tys.push(ty);
......@@ -886,24 +671,23 @@ impl<'db> InferenceTable<'db> {
886671 })
887672 .take(num_args),
888673 );
889 let args = [ty.to_nextsolver(self.interner), arg_ty];
890 let trait_ref = crate::next_solver::TraitRef::new(self.interner, fn_trait.into(), args);
674 let args = [ty, arg_ty];
675 let trait_ref = TraitRef::new(self.interner(), fn_trait.into(), args);
891676
892 let projection = crate::next_solver::Ty::new_alias(
893 self.interner,
677 let projection = Ty::new_alias(
678 self.interner(),
894679 rustc_type_ir::AliasTyKind::Projection,
895 crate::next_solver::AliasTy::new(self.interner, output_assoc_type.into(), args),
680 AliasTy::new(self.interner(), output_assoc_type.into(), args),
896681 );
897682
898 let pred = crate::next_solver::Predicate::upcast_from(trait_ref, self.interner);
683 let pred = Predicate::upcast_from(trait_ref, self.interner());
899684 if !self.try_obligation(pred).no_solution() {
900685 self.register_obligation(pred);
901686 let return_ty = self.normalize_alias_ty(projection);
902687 for &fn_x in subtraits {
903688 let fn_x_trait = fn_x.get_id(self.db, krate)?;
904 let trait_ref =
905 crate::next_solver::TraitRef::new(self.interner, fn_x_trait.into(), args);
906 let pred = crate::next_solver::Predicate::upcast_from(trait_ref, self.interner);
689 let trait_ref = TraitRef::new(self.interner(), fn_x_trait.into(), args);
690 let pred = Predicate::upcast_from(trait_ref, self.interner());
907691 if !self.try_obligation(pred).no_solution() {
908692 return Some((fn_x, arg_tys, return_ty));
909693 }
......@@ -916,40 +700,53 @@ impl<'db> InferenceTable<'db> {
916700
917701 pub(super) fn insert_type_vars<T>(&mut self, ty: T) -> T
918702 where
919 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
703 T: TypeFoldable<DbInterner<'db>>,
920704 {
921 fold_generic_args(
922 ty,
923 |arg, _| match arg {
924 GenericArgData::Ty(ty) => GenericArgData::Ty(self.insert_type_vars_shallow(ty)),
925 // FIXME: insert lifetime vars once LifetimeData::InferenceVar
926 // and specific error variant for lifetimes start being constructed
927 GenericArgData::Lifetime(lt) => GenericArgData::Lifetime(lt),
928 GenericArgData::Const(c) => {
929 GenericArgData::Const(self.insert_const_vars_shallow(c))
705 struct Folder<'a, 'db> {
706 table: &'a mut InferenceTable<'db>,
707 }
708 impl<'db> TypeFolder<DbInterner<'db>> for Folder<'_, 'db> {
709 fn cx(&self) -> DbInterner<'db> {
710 self.table.interner()
711 }
712
713 fn fold_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
714 if !ty.references_error() {
715 return ty;
930716 }
931 },
932 DebruijnIndex::INNERMOST,
933 )
934 }
935717
936 /// Replaces `Ty::Error` by a new type var, so we can maybe still infer it.
937 pub(super) fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
938 match ty.kind(Interner) {
939 TyKind::Error => self.new_type_var(),
940 TyKind::InferenceVar(..) => {
941 let ty_resolved = self.structurally_resolve_type(&ty);
942 if ty_resolved.is_unknown() { self.new_type_var() } else { ty }
718 if ty.is_ty_error() { self.table.next_ty_var() } else { ty.super_fold_with(self) }
719 }
720
721 fn fold_const(&mut self, ct: Const<'db>) -> Const<'db> {
722 if !ct.references_error() {
723 return ct;
724 }
725
726 if ct.is_ct_error() {
727 self.table.next_const_var()
728 } else {
729 ct.super_fold_with(self)
730 }
731 }
732
733 fn fold_region(&mut self, r: Region<'db>) -> Region<'db> {
734 if r.is_error() { self.table.next_region_var() } else { r }
943735 }
944 _ => ty,
945736 }
737
738 ty.fold_with(&mut Folder { table: self })
739 }
740
741 /// Replaces `Ty::Error` by a new type var, so we can maybe still infer it.
742 pub(super) fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {
743 if ty.is_ty_error() { self.next_ty_var() } else { ty }
946744 }
947745
948746 /// Whenever you lower a user-written type, you should call this.
949 pub(crate) fn process_user_written_ty<T, U>(&mut self, ty: T) -> T
747 pub(crate) fn process_user_written_ty<T>(&mut self, ty: T) -> T
950748 where
951 T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + ChalkToNextSolver<'db, U>,
952 U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
749 T: TypeFoldable<DbInterner<'db>>,
953750 {
954751 self.process_remote_user_written_ty(ty)
955752 // FIXME: Register a well-formed obligation.
......@@ -957,10 +754,9 @@ impl<'db> InferenceTable<'db> {
957754
958755 /// The difference of this method from `process_user_written_ty()` is that this method doesn't register a well-formed obligation,
959756 /// while `process_user_written_ty()` should (but doesn't currently).
960 pub(crate) fn process_remote_user_written_ty<T, U>(&mut self, ty: T) -> T
757 pub(crate) fn process_remote_user_written_ty<T>(&mut self, ty: T) -> T
961758 where
962 T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + ChalkToNextSolver<'db, U>,
963 U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
759 T: TypeFoldable<DbInterner<'db>>,
964760 {
965761 let ty = self.insert_type_vars(ty);
966762 // See https://github.com/rust-lang/rust/blob/cdb45c87e2cd43495379f7e867e3cc15dcee9f93/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs#L487-L495:
......@@ -971,44 +767,33 @@ impl<'db> InferenceTable<'db> {
971767 }
972768
973769 /// Replaces ConstScalar::Unknown by a new type var, so we can maybe still infer it.
974 pub(super) fn insert_const_vars_shallow(&mut self, c: Const) -> Const {
975 let data = c.data(Interner);
976 match &data.value {
977 ConstValue::Concrete(cc) => match &cc.interned {
978 crate::ConstScalar::Unknown => self.new_const_var(data.ty.clone()),
979 // try to evaluate unevaluated const. Replace with new var if const eval failed.
980 crate::ConstScalar::UnevaluatedConst(id, subst) => {
981 if let Ok(eval) = self.db.const_eval(*id, subst.clone(), None) {
982 eval
983 } else {
984 self.new_const_var(data.ty.clone())
985 }
986 }
987 _ => c,
988 },
989 _ => c,
990 }
770 pub(super) fn insert_const_vars_shallow(&mut self, c: Const<'db>) -> Const<'db> {
771 if c.is_ct_error() { self.next_const_var() } else { c }
991772 }
992773
993774 /// Check if given type is `Sized` or not
994 pub(crate) fn is_sized(&mut self, ty: &Ty) -> bool {
995 fn short_circuit_trivial_tys(ty: &Ty) -> Option<bool> {
996 match ty.kind(Interner) {
997 TyKind::Scalar(..)
775 pub(crate) fn is_sized(&mut self, ty: Ty<'db>) -> bool {
776 fn short_circuit_trivial_tys(ty: Ty<'_>) -> Option<bool> {
777 match ty.kind() {
778 TyKind::Bool
779 | TyKind::Char
780 | TyKind::Int(_)
781 | TyKind::Uint(_)
782 | TyKind::Float(_)
998783 | TyKind::Ref(..)
999 | TyKind::Raw(..)
784 | TyKind::RawPtr(..)
1000785 | TyKind::Never
1001786 | TyKind::FnDef(..)
1002787 | TyKind::Array(..)
1003 | TyKind::Function(..) => Some(true),
1004 TyKind::Slice(..) | TyKind::Str | TyKind::Dyn(..) => Some(false),
788 | TyKind::FnPtr(..) => Some(true),
789 TyKind::Slice(..) | TyKind::Str | TyKind::Dynamic(..) => Some(false),
1005790 _ => None,
1006791 }
1007792 }
1008793
1009 let mut ty = ty.clone();
794 let mut ty = ty;
1010795 ty = self.eagerly_normalize_and_resolve_shallow_in(ty);
1011 if let Some(sized) = short_circuit_trivial_tys(&ty) {
796 if let Some(sized) = short_circuit_trivial_tys(ty) {
1012797 return sized;
1013798 }
1014799
......@@ -1019,9 +804,8 @@ impl<'db> InferenceTable<'db> {
1019804 while let Some((AdtId::StructId(id), subst)) = ty.as_adt() {
1020805 let struct_data = id.fields(self.db);
1021806 if let Some((last_field, _)) = struct_data.fields().iter().next_back() {
1022 let last_field_ty = self.db.field_types(id.into())[last_field]
1023 .clone()
1024 .substitute(Interner, subst);
807 let last_field_ty = self.db.field_types_ns(id.into())[last_field]
808 .instantiate(self.interner(), subst);
1025809 if structs.contains(&ty) {
1026810 // A struct recursively contains itself as a tail field somewhere.
1027811 return true; // Don't overload the users with too many errors.
......@@ -1031,7 +815,7 @@ impl<'db> InferenceTable<'db> {
1031815 // as unsized by the chalk, so we do this manually.
1032816 ty = last_field_ty;
1033817 ty = self.eagerly_normalize_and_resolve_shallow_in(ty);
1034 if let Some(sized) = short_circuit_trivial_tys(&ty) {
818 if let Some(sized) = short_circuit_trivial_tys(ty) {
1035819 return sized;
1036820 }
1037821 } else {
......@@ -1044,8 +828,8 @@ impl<'db> InferenceTable<'db> {
1044828 return false;
1045829 };
1046830 let sized_pred = Predicate::upcast_from(
1047 TraitRef::new(self.interner, sized.into(), [ty.to_nextsolver(self.interner)]),
1048 self.interner,
831 TraitRef::new(self.interner(), sized.into(), [ty]),
832 self.interner(),
1049833 );
1050834 self.try_obligation(sized_pred).certain()
1051835 }
......@@ -1060,189 +844,14 @@ impl fmt::Debug for InferenceTable<'_> {
1060844 }
1061845}
1062846
1063mod resolve {
1064 use super::InferenceTable;
1065 use crate::{
1066 Const, DebruijnIndex, GenericArg, InferenceVar, Interner, Lifetime, Ty, TyVariableKind,
1067 VariableKind, next_solver::mapping::NextSolverToChalk,
1068 };
1069 use chalk_ir::fold::{TypeFoldable, TypeFolder};
1070 use rustc_type_ir::{FloatVid, IntVid, TyVid};
1071
1072 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
1073 pub(super) enum VarKind {
1074 Ty(TyVariableKind),
1075 Const,
1076 }
1077
1078 #[derive(chalk_derive::FallibleTypeFolder)]
1079 #[has_interner(Interner)]
1080 pub(super) struct Resolver<
1081 'a,
1082 'b,
1083 F: Fn(InferenceVar, VariableKind, DebruijnIndex) -> GenericArg,
1084 > {
1085 pub(super) table: &'a mut InferenceTable<'b>,
1086 pub(super) var_stack: &'a mut Vec<(InferenceVar, VarKind)>,
1087 pub(super) fallback: F,
1088 }
1089 impl<F> TypeFolder<Interner> for Resolver<'_, '_, F>
1090 where
1091 F: Fn(InferenceVar, VariableKind, DebruijnIndex) -> GenericArg,
1092 {
1093 fn as_dyn(&mut self) -> &mut dyn TypeFolder<Interner> {
1094 self
1095 }
1096
1097 fn interner(&self) -> Interner {
1098 Interner
1099 }
1100
1101 fn fold_inference_ty(
1102 &mut self,
1103 var: InferenceVar,
1104 kind: TyVariableKind,
1105 outer_binder: DebruijnIndex,
1106 ) -> Ty {
1107 match kind {
1108 TyVariableKind::General => {
1109 let vid = self.table.infer_ctxt.root_var(TyVid::from(var.index()));
1110 let var = InferenceVar::from(vid.as_u32());
1111 if self.var_stack.contains(&(var, VarKind::Ty(kind))) {
1112 // recursive type
1113 return (self.fallback)(var, VariableKind::Ty(kind), outer_binder)
1114 .assert_ty_ref(Interner)
1115 .clone();
1116 }
1117 if let Ok(known_ty) = self.table.infer_ctxt.probe_ty_var(vid) {
1118 let known_ty: Ty = known_ty.to_chalk(self.table.interner);
1119 // known_ty may contain other variables that are known by now
1120 self.var_stack.push((var, VarKind::Ty(kind)));
1121 let result = known_ty.fold_with(self, outer_binder);
1122 self.var_stack.pop();
1123 result
1124 } else {
1125 (self.fallback)(var, VariableKind::Ty(kind), outer_binder)
1126 .assert_ty_ref(Interner)
1127 .clone()
1128 }
1129 }
1130 TyVariableKind::Integer => {
1131 let vid = self
1132 .table
1133 .infer_ctxt
1134 .inner
1135 .borrow_mut()
1136 .int_unification_table()
1137 .find(IntVid::from(var.index()));
1138 let var = InferenceVar::from(vid.as_u32());
1139 if self.var_stack.contains(&(var, VarKind::Ty(kind))) {
1140 // recursive type
1141 return (self.fallback)(var, VariableKind::Ty(kind), outer_binder)
1142 .assert_ty_ref(Interner)
1143 .clone();
1144 }
1145 if let Some(known_ty) = self.table.infer_ctxt.resolve_int_var(vid) {
1146 let known_ty: Ty = known_ty.to_chalk(self.table.interner);
1147 // known_ty may contain other variables that are known by now
1148 self.var_stack.push((var, VarKind::Ty(kind)));
1149 let result = known_ty.fold_with(self, outer_binder);
1150 self.var_stack.pop();
1151 result
1152 } else {
1153 (self.fallback)(var, VariableKind::Ty(kind), outer_binder)
1154 .assert_ty_ref(Interner)
1155 .clone()
1156 }
1157 }
1158 TyVariableKind::Float => {
1159 let vid = self
1160 .table
1161 .infer_ctxt
1162 .inner
1163 .borrow_mut()
1164 .float_unification_table()
1165 .find(FloatVid::from(var.index()));
1166 let var = InferenceVar::from(vid.as_u32());
1167 if self.var_stack.contains(&(var, VarKind::Ty(kind))) {
1168 // recursive type
1169 return (self.fallback)(var, VariableKind::Ty(kind), outer_binder)
1170 .assert_ty_ref(Interner)
1171 .clone();
1172 }
1173 if let Some(known_ty) = self.table.infer_ctxt.resolve_float_var(vid) {
1174 let known_ty: Ty = known_ty.to_chalk(self.table.interner);
1175 // known_ty may contain other variables that are known by now
1176 self.var_stack.push((var, VarKind::Ty(kind)));
1177 let result = known_ty.fold_with(self, outer_binder);
1178 self.var_stack.pop();
1179 result
1180 } else {
1181 (self.fallback)(var, VariableKind::Ty(kind), outer_binder)
1182 .assert_ty_ref(Interner)
1183 .clone()
1184 }
1185 }
1186 }
1187 }
1188
1189 fn fold_inference_const(
1190 &mut self,
1191 ty: Ty,
1192 var: InferenceVar,
1193 outer_binder: DebruijnIndex,
1194 ) -> Const {
1195 let vid = self
1196 .table
1197 .infer_ctxt
1198 .root_const_var(rustc_type_ir::ConstVid::from_u32(var.index()));
1199 let var = InferenceVar::from(vid.as_u32());
1200 if self.var_stack.contains(&(var, VarKind::Const)) {
1201 // recursive
1202 return (self.fallback)(var, VariableKind::Const(ty), outer_binder)
1203 .assert_const_ref(Interner)
1204 .clone();
1205 }
1206 if let Ok(known_const) = self.table.infer_ctxt.probe_const_var(vid) {
1207 let known_const: Const = known_const.to_chalk(self.table.interner);
1208 // known_ty may contain other variables that are known by now
1209 self.var_stack.push((var, VarKind::Const));
1210 let result = known_const.fold_with(self, outer_binder);
1211 self.var_stack.pop();
1212 result
1213 } else {
1214 (self.fallback)(var, VariableKind::Const(ty), outer_binder)
1215 .assert_const_ref(Interner)
1216 .clone()
1217 }
1218 }
1219
1220 fn fold_inference_lifetime(
1221 &mut self,
1222 _var: InferenceVar,
1223 _outer_binder: DebruijnIndex,
1224 ) -> Lifetime {
1225 // fall back all lifetimes to 'error -- currently we don't deal
1226 // with any lifetimes, but we can sometimes get some lifetime
1227 // variables through Chalk's unification, and this at least makes
1228 // sure we don't leak them outside of inference
1229 crate::error_lifetime()
1230 }
1231 }
1232}
1233
1234847mod resolve_completely {
1235 use rustc_type_ir::{
1236 DebruijnIndex, Flags, TypeFolder, TypeSuperFoldable,
1237 inherent::{Const as _, Ty as _},
1238 };
848 use rustc_type_ir::{DebruijnIndex, Flags, TypeFolder, TypeSuperFoldable};
1239849
1240 use crate::next_solver::Region;
1241850 use crate::{
1242851 infer::unify::InferenceTable,
1243852 next_solver::{
1244 Const, DbInterner, ErrorGuaranteed, Goal, Predicate, Term, Ty,
1245 infer::traits::ObligationCause,
853 Const, DbInterner, Goal, Predicate, Region, Term, Ty,
854 infer::{resolve::ReplaceInferWithError, traits::ObligationCause},
1246855 normalize::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals,
1247856 },
1248857 };
......@@ -1291,17 +900,17 @@ mod resolve_completely {
1291900 value
1292901 };
1293902
1294 value.fold_with(&mut ReplaceInferWithError { interner: self.ctx.interner })
903 value.fold_with(&mut ReplaceInferWithError::new(self.ctx.interner()))
1295904 }
1296905 }
1297906
1298907 impl<'cx, 'db> TypeFolder<DbInterner<'db>> for Resolver<'cx, 'db> {
1299908 fn cx(&self) -> DbInterner<'db> {
1300 self.ctx.interner
909 self.ctx.interner()
1301910 }
1302911
1303912 fn fold_region(&mut self, r: Region<'db>) -> Region<'db> {
1304 if r.is_var() { Region::error(self.ctx.interner) } else { r }
913 if r.is_var() { Region::error(self.ctx.interner()) } else { r }
1305914 }
1306915
1307916 fn fold_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
......@@ -1320,34 +929,4 @@ mod resolve_completely {
1320929 predicate.super_fold_with(self)
1321930 }
1322931 }
1323
1324 struct ReplaceInferWithError<'db> {
1325 interner: DbInterner<'db>,
1326 }
1327
1328 impl<'db> TypeFolder<DbInterner<'db>> for ReplaceInferWithError<'db> {
1329 fn cx(&self) -> DbInterner<'db> {
1330 self.interner
1331 }
1332
1333 fn fold_ty(&mut self, t: Ty<'db>) -> Ty<'db> {
1334 if t.is_infer() {
1335 Ty::new_error(self.interner, ErrorGuaranteed)
1336 } else {
1337 t.super_fold_with(self)
1338 }
1339 }
1340
1341 fn fold_const(&mut self, c: Const<'db>) -> Const<'db> {
1342 if c.is_ct_infer() {
1343 Const::new_error(self.interner, ErrorGuaranteed)
1344 } else {
1345 c.super_fold_with(self)
1346 }
1347 }
1348
1349 fn fold_region(&mut self, r: Region<'db>) -> Region<'db> {
1350 if r.is_var() { Region::error(self.interner) } else { r }
1351 }
1352 }
1353932}
src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs+10-5
......@@ -11,7 +11,9 @@ use triomphe::Arc;
1111
1212use crate::{
1313 AliasTy, Binders, Interner, Substitution, TraitEnvironment, Ty, TyKind,
14 consteval::try_const_usize, db::HirDatabase,
14 consteval::try_const_usize,
15 db::HirDatabase,
16 next_solver::{DbInterner, mapping::ChalkToNextSolver},
1517};
1618
1719// FIXME: Turn this into a query, it can be quite slow
......@@ -79,14 +81,17 @@ impl TypeVisitor<Interner> for UninhabitedFrom<'_> {
7981 }
8082 self.recursive_ty.insert(ty.clone());
8183 self.max_depth -= 1;
84 let interner = DbInterner::new_with(self.db, None, None);
8285 let r = match ty.kind(Interner) {
8386 TyKind::Adt(adt, subst) => self.visit_adt(adt.0, subst),
8487 TyKind::Never => BREAK_VISIBLY_UNINHABITED,
8588 TyKind::Tuple(..) => ty.super_visit_with(self, outer_binder),
86 TyKind::Array(item_ty, len) => match try_const_usize(self.db, len) {
87 Some(0) | None => CONTINUE_OPAQUELY_INHABITED,
88 Some(1..) => item_ty.super_visit_with(self, outer_binder),
89 },
89 TyKind::Array(item_ty, len) => {
90 match try_const_usize(self.db, len.to_nextsolver(interner)) {
91 Some(0) | None => CONTINUE_OPAQUELY_INHABITED,
92 Some(1..) => item_ty.super_visit_with(self, outer_binder),
93 }
94 }
9095 TyKind::Alias(AliasTy::Projection(projection)) => {
9196 // FIXME: I think this currently isn't used for monomorphized bodies, so there is no need to handle
9297 // `TyKind::AssociatedType`, but perhaps in the future it will.
src/tools/rust-analyzer/crates/hir-ty/src/layout.rs+6-15
......@@ -19,15 +19,13 @@ use rustc_type_ir::{
1919};
2020use triomphe::Arc;
2121
22use crate::utils::ClosureSubst;
2322use crate::{
24 Interner, TraitEnvironment,
25 consteval_nextsolver::try_const_usize,
23 TraitEnvironment,
24 consteval::try_const_usize,
2625 db::HirDatabase,
2726 next_solver::{
2827 DbInterner, GenericArgs, ParamEnv, Ty, TyKind, TypingMode,
2928 infer::{DbInternerInferExt, traits::ObligationCause},
30 mapping::{ChalkToNextSolver, convert_args_for_result},
3129 },
3230};
3331
......@@ -325,19 +323,12 @@ pub fn layout_of_ty_query<'db>(
325323 TyKind::Closure(id, args) => {
326324 let def = db.lookup_intern_closure(id.0);
327325 let infer = db.infer(def.0);
328 let (captures, _) = infer.closure_info(&id.0.into());
326 let (captures, _) = infer.closure_info(id.0);
329327 let fields = captures
330328 .iter()
331329 .map(|it| {
332 let ty = it
333 .ty
334 .clone()
335 .substitute(
336 Interner,
337 &ClosureSubst(&convert_args_for_result(interner, args.inner()))
338 .parent_subst(db),
339 )
340 .to_nextsolver(interner);
330 let ty =
331 it.ty.instantiate(interner, args.split_closure_args_untupled().parent_args);
341332 db.layout_of_ty(ty, trait_env.clone())
342333 })
343334 .collect::<Result<Vec<_>, _>>()?;
......@@ -394,7 +385,7 @@ fn struct_tail_erasing_lifetimes<'a>(db: &'a dyn HirDatabase, pointee: Ty<'a>) -
394385 }
395386 }
396387 TyKind::Tuple(tys) => {
397 if let Some(last_field_ty) = tys.iter().last() {
388 if let Some(last_field_ty) = tys.iter().next_back() {
398389 struct_tail_erasing_lifetimes(db, last_field_ty)
399390 } else {
400391 pointee
src/tools/rust-analyzer/crates/hir-ty/src/layout/target.rs+1-1
......@@ -39,7 +39,7 @@ pub fn target_data_layout_query(
3939 target,
4040 } => format!(r#"inconsistent target specification: "data-layout" claims pointers are {pointer_size}-bit, while "target-pointer-width" is `{target}`"#),
4141 TargetDataLayoutErrors::InvalidBitsSize { err } => err,
42 TargetDataLayoutErrors::UnknownPointerSpecification { err } => format!(r#"use of unknown pointer specifer in "data-layout": {err}"#),
42 TargetDataLayoutErrors::UnknownPointerSpecification { err } => format!(r#"use of unknown pointer specifier in "data-layout": {err}"#),
4343 }.into())
4444 }
4545 },
src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs+31-29
......@@ -3,7 +3,7 @@ use either::Either;
33use hir_def::db::DefDatabase;
44use project_model::{Sysroot, toolchain_info::QueryConfig};
55use rustc_hash::FxHashMap;
6use rustc_type_ir::inherent::{GenericArgs as _, Ty as _};
6use rustc_type_ir::inherent::GenericArgs as _;
77use syntax::ToSmolStr;
88use test_fixture::WithFixture;
99use triomphe::Arc;
......@@ -11,7 +11,7 @@ use triomphe::Arc;
1111use crate::{
1212 db::HirDatabase,
1313 layout::{Layout, LayoutError},
14 next_solver::{AdtDef, DbInterner, GenericArgs, mapping::ChalkToNextSolver},
14 next_solver::{DbInterner, GenericArgs},
1515 setup_tracing,
1616 test_db::TestDB,
1717};
......@@ -79,12 +79,12 @@ fn eval_goal(
7979 Some(adt_or_type_alias_id)
8080 })
8181 .unwrap();
82 salsa::attach(&db, || {
82 crate::attach_db(&db, || {
8383 let interner = DbInterner::new_with(&db, None, None);
8484 let goal_ty = match adt_or_type_alias_id {
8585 Either::Left(adt_id) => crate::next_solver::Ty::new_adt(
8686 interner,
87 AdtDef::new(adt_id, interner),
87 adt_id,
8888 GenericArgs::identity_for_item(interner, adt_id.into()),
8989 ),
9090 Either::Right(ty_id) => db.ty(ty_id.into()).instantiate_identity(),
......@@ -112,31 +112,33 @@ fn eval_expr(
112112 );
113113
114114 let (db, file_id) = TestDB::with_single_file(&ra_fixture);
115 let module_id = db.module_for_file(file_id.file_id(&db));
116 let def_map = module_id.def_map(&db);
117 let scope = &def_map[module_id.local_id].scope;
118 let function_id = scope
119 .declarations()
120 .find_map(|x| match x {
121 hir_def::ModuleDefId::FunctionId(x) => {
122 let name =
123 db.function_signature(x).name.display_no_db(file_id.edition(&db)).to_smolstr();
124 (name == "main").then_some(x)
125 }
126 _ => None,
127 })
128 .unwrap();
129 let hir_body = db.body(function_id.into());
130 let b = hir_body
131 .bindings()
132 .find(|x| x.1.name.display_no_db(file_id.edition(&db)).to_smolstr() == "goal")
133 .unwrap()
134 .0;
135 let infer = db.infer(function_id.into());
136 let goal_ty = infer.type_of_binding[b].clone();
137 salsa::attach(&db, || {
138 let interner = DbInterner::new_with(&db, None, None);
139 db.layout_of_ty(goal_ty.to_nextsolver(interner), db.trait_environment(function_id.into()))
115 crate::attach_db(&db, || {
116 let module_id = db.module_for_file(file_id.file_id(&db));
117 let def_map = module_id.def_map(&db);
118 let scope = &def_map[module_id.local_id].scope;
119 let function_id = scope
120 .declarations()
121 .find_map(|x| match x {
122 hir_def::ModuleDefId::FunctionId(x) => {
123 let name = db
124 .function_signature(x)
125 .name
126 .display_no_db(file_id.edition(&db))
127 .to_smolstr();
128 (name == "main").then_some(x)
129 }
130 _ => None,
131 })
132 .unwrap();
133 let hir_body = db.body(function_id.into());
134 let b = hir_body
135 .bindings()
136 .find(|x| x.1.name.display_no_db(file_id.edition(&db)).to_smolstr() == "goal")
137 .unwrap()
138 .0;
139 let infer = db.infer(function_id.into());
140 let goal_ty = infer.type_of_binding[b];
141 db.layout_of_ty(goal_ty, db.trait_environment(function_id.into()))
140142 })
141143}
142144
src/tools/rust-analyzer/crates/hir-ty/src/lib.rs+217-300
......@@ -21,10 +21,11 @@ extern crate ra_ap_rustc_type_ir as rustc_type_ir;
2121
2222extern crate ra_ap_rustc_next_trait_solver as rustc_next_trait_solver;
2323
24extern crate self as hir_ty;
25
2426mod builder;
2527mod chalk_db;
2628mod chalk_ext;
27mod drop;
2829mod infer;
2930mod inhabitedness;
3031mod interner;
......@@ -38,10 +39,11 @@ mod utils;
3839
3940pub mod autoderef;
4041pub mod consteval;
41pub mod consteval_nextsolver;
42mod consteval_chalk;
4243pub mod db;
4344pub mod diagnostics;
4445pub mod display;
46pub mod drop;
4547pub mod dyn_compatibility;
4648pub mod generics;
4749pub mod lang_items;
......@@ -60,11 +62,10 @@ mod variance;
6062use std::hash::Hash;
6163
6264use chalk_ir::{
63 NoSolution, VariableKinds,
65 VariableKinds,
6466 fold::{Shift, TypeFoldable},
6567 interner::HasInterner,
6668};
67use either::Either;
6869use hir_def::{CallableDefId, GeneralConstId, TypeOrConstParamId, hir::ExprId, type_ref::Rawness};
6970use hir_expand::name::Name;
7071use indexmap::{IndexMap, map::Entry};
......@@ -73,15 +74,16 @@ use la_arena::{Arena, Idx};
7374use mir::{MirEvalError, VTableMap};
7475use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
7576use rustc_type_ir::{
76 UpcastFrom,
77 inherent::{SliceLike, Ty as _},
77 TypeSuperVisitable, TypeVisitableExt, UpcastFrom,
78 inherent::{IntoKind, SliceLike, Ty as _},
7879};
7980use syntax::ast::{ConstArg, make};
8081use traits::FnTrait;
8182use triomphe::Arc;
8283
84#[cfg(not(debug_assertions))]
85use crate::next_solver::ErrorGuaranteed;
8386use crate::{
84 consteval::unknown_const,
8587 db::HirDatabase,
8688 display::{DisplayTarget, HirDisplay},
8789 generics::Generics,
......@@ -95,7 +97,6 @@ use crate::{
9597pub use autoderef::autoderef;
9698pub use builder::{ParamKind, TyBuilder};
9799pub use chalk_ext::*;
98pub use drop::DropGlue;
99100pub use infer::{
100101 Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic, InferenceResult,
101102 InferenceTyDiagnosticSource, OverloadedDeref, PointerCast,
......@@ -104,17 +105,17 @@ pub use infer::{
104105 could_coerce, could_unify, could_unify_deeply,
105106};
106107pub use interner::Interner;
107pub use lower::{
108 ImplTraitLoweringMode, LifetimeElisionKind, ParamLoweringMode, TyDefId, TyLoweringContext,
109 ValueTyDefId, diagnostics::*,
108pub use lower::{ImplTraitLoweringMode, ParamLoweringMode, TyDefId, ValueTyDefId, diagnostics::*};
109pub use lower_nextsolver::{
110 LifetimeElisionKind, TyLoweringContext, associated_type_shorthand_candidates,
110111};
111pub use lower_nextsolver::associated_type_shorthand_candidates;
112112pub use mapping::{
113113 ToChalk, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
114114 lt_from_placeholder_idx, lt_to_placeholder_idx, to_assoc_type_id, to_chalk_trait_id,
115115 to_foreign_def_id, to_placeholder_idx, to_placeholder_idx_no_index,
116116};
117117pub use method_resolution::check_orphan_rules;
118pub use next_solver::interner::{attach_db, attach_db_allow_change, with_attached_db};
118119pub use target_feature::TargetFeatures;
119120pub use traits::TraitEnvironment;
120121pub use utils::{
......@@ -123,20 +124,16 @@ pub use utils::{
123124};
124125pub use variance::Variance;
125126
126pub use chalk_ir::{
127 AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
128 cast::Cast,
129 visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
130};
127use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Safety, Scalar};
131128
132pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
133pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
134pub type FnDefId = chalk_ir::FnDefId<Interner>;
135pub type ClosureId = chalk_ir::ClosureId<Interner>;
136pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
137pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
129pub(crate) type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
130pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
131pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>;
132pub(crate) type ClosureId = chalk_ir::ClosureId<Interner>;
133pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
134pub(crate) type PlaceholderIndex = chalk_ir::PlaceholderIndex;
138135
139pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
136pub(crate) type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
140137
141138pub(crate) type VariableKind = chalk_ir::VariableKind<Interner>;
142139/// Represents generic parameters and an item bound by them. When the item has parent, the binders
......@@ -147,49 +144,48 @@ pub(crate) type VariableKind = chalk_ir::VariableKind<Interner>;
147144/// parameters/arguments for an item MUST come before those for its parent. This is to facilitate
148145/// the integration with chalk-solve, which mildly puts constraints as such. See #13335 for its
149146/// motivation in detail.
150pub type Binders<T> = chalk_ir::Binders<T>;
147pub(crate) type Binders<T> = chalk_ir::Binders<T>;
151148/// Interned list of generic arguments for an item. When an item has parent, the `Substitution` for
152149/// it contains generic arguments for both its parent and itself. See chalk's documentation for
153150/// details.
154151///
155152/// See `Binders` for the constraint on the ordering.
156pub type Substitution = chalk_ir::Substitution<Interner>;
157pub type GenericArg = chalk_ir::GenericArg<Interner>;
158pub type GenericArgData = chalk_ir::GenericArgData<Interner>;
153pub(crate) type Substitution = chalk_ir::Substitution<Interner>;
154pub(crate) type GenericArg = chalk_ir::GenericArg<Interner>;
155pub(crate) type GenericArgData = chalk_ir::GenericArgData<Interner>;
159156
160pub type Ty = chalk_ir::Ty<Interner>;
157pub(crate) type Ty = chalk_ir::Ty<Interner>;
161158pub type TyKind = chalk_ir::TyKind<Interner>;
162pub type TypeFlags = chalk_ir::TypeFlags;
159pub(crate) type TypeFlags = chalk_ir::TypeFlags;
163160pub(crate) type DynTy = chalk_ir::DynTy<Interner>;
164pub type FnPointer = chalk_ir::FnPointer<Interner>;
161pub(crate) type FnPointer = chalk_ir::FnPointer<Interner>;
165162pub(crate) use chalk_ir::FnSubst; // a re-export so we don't lose the tuple constructor
166163
167164pub type AliasTy = chalk_ir::AliasTy<Interner>;
168165
169pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
166pub(crate) type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
170167pub(crate) type OpaqueTy = chalk_ir::OpaqueTy<Interner>;
171pub(crate) type InferenceVar = chalk_ir::InferenceVar;
172168
173169pub(crate) type Lifetime = chalk_ir::Lifetime<Interner>;
174170pub(crate) type LifetimeData = chalk_ir::LifetimeData<Interner>;
175171pub(crate) type LifetimeOutlives = chalk_ir::LifetimeOutlives<Interner>;
176172
177pub type ConstValue = chalk_ir::ConstValue<Interner>;
173pub(crate) type ConstValue = chalk_ir::ConstValue<Interner>;
178174
179pub type Const = chalk_ir::Const<Interner>;
175pub(crate) type Const = chalk_ir::Const<Interner>;
180176pub(crate) type ConstData = chalk_ir::ConstData<Interner>;
181177pub(crate) type ConcreteConst = chalk_ir::ConcreteConst<Interner>;
182178
183pub type TraitRef = chalk_ir::TraitRef<Interner>;
184pub type QuantifiedWhereClause = Binders<WhereClause>;
185pub type Canonical<T> = chalk_ir::Canonical<T>;
179pub(crate) type TraitRef = chalk_ir::TraitRef<Interner>;
180pub(crate) type QuantifiedWhereClause = Binders<WhereClause>;
181pub(crate) type Canonical<T> = chalk_ir::Canonical<T>;
186182
187183pub(crate) type ChalkTraitId = chalk_ir::TraitId<Interner>;
188184pub(crate) type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>;
189185
190186pub(crate) type FnSig = chalk_ir::FnSig<Interner>;
191187
192pub type InEnvironment<T> = chalk_ir::InEnvironment<T>;
188pub(crate) type InEnvironment<T> = chalk_ir::InEnvironment<T>;
193189pub type AliasEq = chalk_ir::AliasEq<Interner>;
194190pub type WhereClause = chalk_ir::WhereClause<Interner>;
195191
......@@ -233,7 +229,7 @@ impl ComplexMemoryMap<'_> {
233229}
234230
235231impl<'db> MemoryMap<'db> {
236 pub fn vtable_ty(&self, id: usize) -> Result<crate::next_solver::Ty<'db>, MirEvalError> {
232 pub fn vtable_ty(&self, id: usize) -> Result<crate::next_solver::Ty<'db>, MirEvalError<'db>> {
237233 match self {
238234 MemoryMap::Empty | MemoryMap::Simple(_) => Err(MirEvalError::InvalidVTableId(id)),
239235 MemoryMap::Complex(cm) => cm.vtable.ty(id),
......@@ -249,8 +245,8 @@ impl<'db> MemoryMap<'db> {
249245 /// allocator function as `f` and it will return a mapping of old addresses to new addresses.
250246 fn transform_addresses(
251247 &self,
252 mut f: impl FnMut(&[u8], usize) -> Result<usize, MirEvalError>,
253 ) -> Result<FxHashMap<usize, usize>, MirEvalError> {
248 mut f: impl FnMut(&[u8], usize) -> Result<usize, MirEvalError<'db>>,
249 ) -> Result<FxHashMap<usize, usize>, MirEvalError<'db>> {
254250 let mut transform = |(addr, val): (&usize, &[u8])| {
255251 let addr = *addr;
256252 let align = if addr == 0 { 64 } else { (addr - (addr & (addr - 1))).min(64) };
......@@ -646,7 +642,7 @@ impl TypeFoldable<Interner> for CallableSig {
646642
647643#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
648644pub enum ImplTraitId {
649 ReturnTypeImplTrait(hir_def::FunctionId, ImplTraitIdx),
645 ReturnTypeImplTrait(hir_def::FunctionId, ImplTraitIdx), // FIXME(next-solver): Should be crate::nextsolver::ImplTraitIdx.
650646 TypeAliasImplTrait(hir_def::TypeAliasId, ImplTraitIdx),
651647 AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId),
652648}
......@@ -713,219 +709,170 @@ pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + TypeFoldable<
713709 t.fold_with(&mut FreeVarFolder(for_ty, for_const), DebruijnIndex::INNERMOST)
714710}
715711
716pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
717 t: T,
718 mut for_ty: impl FnMut(Ty, DebruijnIndex) -> Ty,
719 binders: DebruijnIndex,
720) -> T {
721 fold_tys_and_consts(
722 t,
723 |x, d| match x {
724 Either::Left(x) => Either::Left(for_ty(x, d)),
725 Either::Right(x) => Either::Right(x),
726 },
727 binders,
728 )
729}
730
731pub(crate) fn fold_tys_and_consts<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
732 t: T,
733 f: impl FnMut(Either<Ty, Const>, DebruijnIndex) -> Either<Ty, Const>,
734 binders: DebruijnIndex,
735) -> T {
736 use chalk_ir::fold::{TypeFolder, TypeSuperFoldable};
737 #[derive(chalk_derive::FallibleTypeFolder)]
738 #[has_interner(Interner)]
739 struct TyFolder<F: FnMut(Either<Ty, Const>, DebruijnIndex) -> Either<Ty, Const>>(F);
740 impl<F: FnMut(Either<Ty, Const>, DebruijnIndex) -> Either<Ty, Const>> TypeFolder<Interner>
741 for TyFolder<F>
742 {
743 fn as_dyn(&mut self) -> &mut dyn TypeFolder<Interner> {
744 self
745 }
746
747 fn interner(&self) -> Interner {
748 Interner
749 }
750
751 fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Ty {
752 let ty = ty.super_fold_with(self.as_dyn(), outer_binder);
753 self.0(Either::Left(ty), outer_binder).left().unwrap()
754 }
755
756 fn fold_const(&mut self, c: Const, outer_binder: DebruijnIndex) -> Const {
757 self.0(Either::Right(c), outer_binder).right().unwrap()
758 }
759 }
760 t.fold_with(&mut TyFolder(f), binders)
761}
762
763pub(crate) fn fold_generic_args<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
764 t: T,
765 f: impl FnMut(GenericArgData, DebruijnIndex) -> GenericArgData,
766 binders: DebruijnIndex,
767) -> T {
768 use chalk_ir::fold::{TypeFolder, TypeSuperFoldable};
769 #[derive(chalk_derive::FallibleTypeFolder)]
770 #[has_interner(Interner)]
771 struct TyFolder<F: FnMut(GenericArgData, DebruijnIndex) -> GenericArgData>(F);
772 impl<F: FnMut(GenericArgData, DebruijnIndex) -> GenericArgData> TypeFolder<Interner>
773 for TyFolder<F>
774 {
775 fn as_dyn(&mut self) -> &mut dyn TypeFolder<Interner> {
776 self
777 }
778
779 fn interner(&self) -> Interner {
780 Interner
781 }
782
783 fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Ty {
784 let ty = ty.super_fold_with(self.as_dyn(), outer_binder);
785 self.0(GenericArgData::Ty(ty), outer_binder)
786 .intern(Interner)
787 .ty(Interner)
788 .unwrap()
789 .clone()
790 }
791
792 fn fold_const(&mut self, c: Const, outer_binder: DebruijnIndex) -> Const {
793 self.0(GenericArgData::Const(c), outer_binder)
794 .intern(Interner)
795 .constant(Interner)
796 .unwrap()
797 .clone()
798 }
799
800 fn fold_lifetime(&mut self, lt: Lifetime, outer_binder: DebruijnIndex) -> Lifetime {
801 let lt = lt.super_fold_with(self.as_dyn(), outer_binder);
802 self.0(GenericArgData::Lifetime(lt), outer_binder)
803 .intern(Interner)
804 .lifetime(Interner)
805 .unwrap()
806 .clone()
807 }
808 }
809 t.fold_with(&mut TyFolder(f), binders)
810}
811
812712/// 'Canonicalizes' the `t` by replacing any errors with new variables. Also
813713/// ensures there are no unbound variables or inference variables anywhere in
814714/// the `t`.
815pub fn replace_errors_with_variables<T>(t: &T) -> Canonical<T>
715pub fn replace_errors_with_variables<'db, T>(
716 interner: DbInterner<'db>,
717 t: &T,
718) -> crate::next_solver::Canonical<'db, T>
816719where
817 T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + Clone,
720 T: rustc_type_ir::TypeFoldable<DbInterner<'db>> + Clone,
818721{
819 use chalk_ir::{
820 Fallible,
821 fold::{FallibleTypeFolder, TypeSuperFoldable},
822 };
823 struct ErrorReplacer {
824 vars: usize,
722 use rustc_type_ir::{FallibleTypeFolder, TypeSuperFoldable};
723 struct ErrorReplacer<'db> {
724 interner: DbInterner<'db>,
725 vars: Vec<crate::next_solver::CanonicalVarKind<'db>>,
726 binder: rustc_type_ir::DebruijnIndex,
825727 }
826 impl FallibleTypeFolder<Interner> for ErrorReplacer {
827 type Error = NoSolution;
828
829 fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<Interner, Error = Self::Error> {
830 self
831 }
832
833 fn interner(&self) -> Interner {
834 Interner
835 }
728 impl<'db> FallibleTypeFolder<DbInterner<'db>> for ErrorReplacer<'db> {
729 #[cfg(debug_assertions)]
730 type Error = ();
731 #[cfg(not(debug_assertions))]
732 type Error = std::convert::Infallible;
836733
837 fn try_fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> {
838 if let TyKind::Error = ty.kind(Interner) {
839 let index = self.vars;
840 self.vars += 1;
841 Ok(TyKind::BoundVar(BoundVar::new(outer_binder, index)).intern(Interner))
842 } else {
843 ty.try_super_fold_with(self.as_dyn(), outer_binder)
844 }
734 fn cx(&self) -> DbInterner<'db> {
735 self.interner
845736 }
846737
847 fn try_fold_inference_ty(
738 fn try_fold_binder<T>(
848739 &mut self,
849 _var: InferenceVar,
850 _kind: TyVariableKind,
851 _outer_binder: DebruijnIndex,
852 ) -> Fallible<Ty> {
853 if cfg!(debug_assertions) {
854 // we don't want to just panic here, because then the error message
855 // won't contain the whole thing, which would not be very helpful
856 Err(NoSolution)
857 } else {
858 Ok(TyKind::Error.intern(Interner))
859 }
860 }
861
862 fn try_fold_free_var_ty(
740 t: crate::next_solver::Binder<'db, T>,
741 ) -> Result<crate::next_solver::Binder<'db, T>, Self::Error>
742 where
743 T: rustc_type_ir::TypeFoldable<DbInterner<'db>>,
744 {
745 self.binder.shift_in(1);
746 let result = t.try_super_fold_with(self);
747 self.binder.shift_out(1);
748 result
749 }
750
751 fn try_fold_ty(
863752 &mut self,
864 _bound_var: BoundVar,
865 _outer_binder: DebruijnIndex,
866 ) -> Fallible<Ty> {
867 if cfg!(debug_assertions) {
868 // we don't want to just panic here, because then the error message
869 // won't contain the whole thing, which would not be very helpful
870 Err(NoSolution)
871 } else {
872 Ok(TyKind::Error.intern(Interner))
753 t: crate::next_solver::Ty<'db>,
754 ) -> Result<crate::next_solver::Ty<'db>, Self::Error> {
755 if !t.has_type_flags(
756 rustc_type_ir::TypeFlags::HAS_ERROR
757 | rustc_type_ir::TypeFlags::HAS_TY_INFER
758 | rustc_type_ir::TypeFlags::HAS_CT_INFER
759 | rustc_type_ir::TypeFlags::HAS_RE_INFER,
760 ) {
761 return Ok(t);
873762 }
874 }
875763
876 fn try_fold_inference_const(
877 &mut self,
878 ty: Ty,
879 _var: InferenceVar,
880 _outer_binder: DebruijnIndex,
881 ) -> Fallible<Const> {
882 if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(unknown_const(ty)) }
764 #[cfg(debug_assertions)]
765 let error = || Err(());
766 #[cfg(not(debug_assertions))]
767 let error = || Ok(crate::next_solver::Ty::new_error(self.interner, ErrorGuaranteed));
768
769 match t.kind() {
770 crate::next_solver::TyKind::Error(_) => {
771 let var = rustc_type_ir::BoundVar::from_usize(self.vars.len());
772 self.vars.push(crate::next_solver::CanonicalVarKind::Ty {
773 ui: rustc_type_ir::UniverseIndex::ZERO,
774 sub_root: var,
775 });
776 Ok(crate::next_solver::Ty::new_bound(
777 self.interner,
778 self.binder,
779 crate::next_solver::BoundTy {
780 var,
781 kind: crate::next_solver::BoundTyKind::Anon,
782 },
783 ))
784 }
785 crate::next_solver::TyKind::Infer(_) => error(),
786 crate::next_solver::TyKind::Bound(index, _) if index > self.binder => error(),
787 _ => t.try_super_fold_with(self),
788 }
883789 }
884790
885 fn try_fold_free_var_const(
791 fn try_fold_const(
886792 &mut self,
887 ty: Ty,
888 _bound_var: BoundVar,
889 _outer_binder: DebruijnIndex,
890 ) -> Fallible<Const> {
891 if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(unknown_const(ty)) }
892 }
793 ct: crate::next_solver::Const<'db>,
794 ) -> Result<crate::next_solver::Const<'db>, Self::Error> {
795 if !ct.has_type_flags(
796 rustc_type_ir::TypeFlags::HAS_ERROR
797 | rustc_type_ir::TypeFlags::HAS_TY_INFER
798 | rustc_type_ir::TypeFlags::HAS_CT_INFER
799 | rustc_type_ir::TypeFlags::HAS_RE_INFER,
800 ) {
801 return Ok(ct);
802 }
893803
894 fn try_fold_inference_lifetime(
895 &mut self,
896 _var: InferenceVar,
897 _outer_binder: DebruijnIndex,
898 ) -> Fallible<Lifetime> {
899 if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(error_lifetime()) }
804 #[cfg(debug_assertions)]
805 let error = || Err(());
806 #[cfg(not(debug_assertions))]
807 let error = || Ok(crate::next_solver::Const::error(self.interner));
808
809 match ct.kind() {
810 crate::next_solver::ConstKind::Error(_) => {
811 let var = rustc_type_ir::BoundVar::from_usize(self.vars.len());
812 self.vars.push(crate::next_solver::CanonicalVarKind::Const(
813 rustc_type_ir::UniverseIndex::ZERO,
814 ));
815 Ok(crate::next_solver::Const::new_bound(
816 self.interner,
817 self.binder,
818 crate::next_solver::BoundConst { var },
819 ))
820 }
821 crate::next_solver::ConstKind::Infer(_) => error(),
822 crate::next_solver::ConstKind::Bound(index, _) if index > self.binder => error(),
823 _ => ct.try_super_fold_with(self),
824 }
900825 }
901826
902 fn try_fold_free_var_lifetime(
827 fn try_fold_region(
903828 &mut self,
904 _bound_var: BoundVar,
905 _outer_binder: DebruijnIndex,
906 ) -> Fallible<Lifetime> {
907 if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(error_lifetime()) }
829 region: crate::next_solver::Region<'db>,
830 ) -> Result<crate::next_solver::Region<'db>, Self::Error> {
831 #[cfg(debug_assertions)]
832 let error = || Err(());
833 #[cfg(not(debug_assertions))]
834 let error = || Ok(crate::next_solver::Region::error(self.interner));
835
836 match region.kind() {
837 crate::next_solver::RegionKind::ReError(_) => {
838 let var = rustc_type_ir::BoundVar::from_usize(self.vars.len());
839 self.vars.push(crate::next_solver::CanonicalVarKind::Region(
840 rustc_type_ir::UniverseIndex::ZERO,
841 ));
842 Ok(crate::next_solver::Region::new_bound(
843 self.interner,
844 self.binder,
845 crate::next_solver::BoundRegion {
846 var,
847 kind: crate::next_solver::BoundRegionKind::Anon,
848 },
849 ))
850 }
851 crate::next_solver::RegionKind::ReVar(_) => error(),
852 crate::next_solver::RegionKind::ReBound(index, _) if index > self.binder => error(),
853 _ => Ok(region),
854 }
908855 }
909856 }
910 let mut error_replacer = ErrorReplacer { vars: 0 };
911 let value = match t.clone().try_fold_with(&mut error_replacer, DebruijnIndex::INNERMOST) {
857
858 let mut error_replacer =
859 ErrorReplacer { vars: Vec::new(), binder: rustc_type_ir::DebruijnIndex::ZERO, interner };
860 let value = match t.clone().try_fold_with(&mut error_replacer) {
912861 Ok(t) => t,
913862 Err(_) => panic!("Encountered unbound or inference vars in {t:?}"),
914863 };
915 let kinds = (0..error_replacer.vars).map(|_| {
916 chalk_ir::CanonicalVarKind::new(
917 chalk_ir::VariableKind::Ty(TyVariableKind::General),
918 chalk_ir::UniverseIndex::ROOT,
919 )
920 });
921 Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(Interner, kinds) }
864 crate::next_solver::Canonical {
865 value,
866 max_universe: rustc_type_ir::UniverseIndex::ZERO,
867 variables: crate::next_solver::CanonicalVars::new_from_iter(interner, error_replacer.vars),
868 }
922869}
923870
924871pub fn callable_sig_from_fn_trait<'db>(
925 self_ty: &Ty,
872 self_ty: crate::next_solver::Ty<'db>,
926873 trait_env: Arc<TraitEnvironment<'db>>,
927874 db: &'db dyn HirDatabase,
928) -> Option<(FnTrait, CallableSig)> {
875) -> Option<(FnTrait, crate::next_solver::PolyFnSig<'db>)> {
929876 let krate = trait_env.krate;
930877 let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
931878 let output_assoc_type = fn_once_trait
......@@ -942,46 +889,47 @@ pub fn callable_sig_from_fn_trait<'db>(
942889 // - Self: FnOnce<?args_ty>
943890 // - <Self as FnOnce<?args_ty>>::Output == ?ret_ty
944891 let args_ty = table.next_ty_var();
945 let args = [self_ty.to_nextsolver(table.interner), args_ty];
946 let trait_ref = crate::next_solver::TraitRef::new(table.interner, fn_once_trait.into(), args);
892 let args = [self_ty, args_ty];
893 let trait_ref = crate::next_solver::TraitRef::new(table.interner(), fn_once_trait.into(), args);
947894 let projection = crate::next_solver::Ty::new_alias(
948 table.interner,
895 table.interner(),
949896 rustc_type_ir::AliasTyKind::Projection,
950 crate::next_solver::AliasTy::new(table.interner, output_assoc_type.into(), args),
897 crate::next_solver::AliasTy::new(table.interner(), output_assoc_type.into(), args),
951898 );
952899
953 let pred = crate::next_solver::Predicate::upcast_from(trait_ref, table.interner);
900 let pred = crate::next_solver::Predicate::upcast_from(trait_ref, table.interner());
954901 if !table.try_obligation(pred).no_solution() {
955902 table.register_obligation(pred);
956903 let return_ty = table.normalize_alias_ty(projection);
957904 for fn_x in [FnTrait::Fn, FnTrait::FnMut, FnTrait::FnOnce] {
958905 let fn_x_trait = fn_x.get_id(db, krate)?;
959906 let trait_ref =
960 crate::next_solver::TraitRef::new(table.interner, fn_x_trait.into(), args);
907 crate::next_solver::TraitRef::new(table.interner(), fn_x_trait.into(), args);
961908 if !table
962909 .try_obligation(crate::next_solver::Predicate::upcast_from(
963910 trait_ref,
964 table.interner,
911 table.interner(),
965912 ))
966913 .no_solution()
967914 {
968 let ret_ty = table.resolve_completely(return_ty.to_chalk(table.interner));
969 let args_ty = table.resolve_completely(args_ty.to_chalk(table.interner));
970 let params = args_ty
971 .as_tuple()?
972 .iter(Interner)
973 .map(|it| it.assert_ty_ref(Interner))
974 .cloned();
915 let ret_ty = table.resolve_completely(return_ty);
916 let args_ty = table.resolve_completely(args_ty);
917 let crate::next_solver::TyKind::Tuple(params) = args_ty.kind() else {
918 return None;
919 };
920 let inputs_and_output = crate::next_solver::Tys::new_from_iter(
921 table.interner(),
922 params.iter().chain(std::iter::once(ret_ty)),
923 );
975924
976925 return Some((
977926 fn_x,
978 CallableSig::from_params_and_return(
979 params,
980 ret_ty,
981 false,
982 Safety::Safe,
983 FnAbi::RustCall,
984 ),
927 crate::next_solver::Binder::dummy(crate::next_solver::FnSig {
928 inputs_and_output,
929 c_variadic: false,
930 safety: crate::next_solver::abi::Safety::Safe,
931 abi: FnAbi::RustCall,
932 }),
985933 ));
986934 }
987935 }
......@@ -991,74 +939,43 @@ pub fn callable_sig_from_fn_trait<'db>(
991939 }
992940}
993941
994struct PlaceholderCollector<'db> {
995 db: &'db dyn HirDatabase,
996 placeholders: FxHashSet<TypeOrConstParamId>,
997}
998
999impl PlaceholderCollector<'_> {
1000 fn collect(&mut self, idx: PlaceholderIndex) {
1001 let id = from_placeholder_idx(self.db, idx).0;
1002 self.placeholders.insert(id);
1003 }
942struct ParamCollector {
943 params: FxHashSet<TypeOrConstParamId>,
1004944}
1005945
1006impl TypeVisitor<Interner> for PlaceholderCollector<'_> {
1007 type BreakTy = ();
1008
1009 fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
1010 self
1011 }
1012
1013 fn interner(&self) -> Interner {
1014 Interner
1015 }
946impl<'db> rustc_type_ir::TypeVisitor<DbInterner<'db>> for ParamCollector {
947 type Result = ();
1016948
1017 fn visit_ty(
1018 &mut self,
1019 ty: &Ty,
1020 outer_binder: DebruijnIndex,
1021 ) -> std::ops::ControlFlow<Self::BreakTy> {
1022 let has_placeholder_bits = TypeFlags::HAS_TY_PLACEHOLDER | TypeFlags::HAS_CT_PLACEHOLDER;
1023 let chalk_ir::TyData { kind, flags } = ty.data(Interner);
1024
1025 if let TyKind::Placeholder(idx) = kind {
1026 self.collect(*idx);
1027 } else if flags.intersects(has_placeholder_bits) {
1028 return ty.super_visit_with(self, outer_binder);
1029 } else {
1030 // Fast path: don't visit inner types (e.g. generic arguments) when `flags` indicate
1031 // that there are no placeholders.
949 fn visit_ty(&mut self, ty: crate::next_solver::Ty<'db>) -> Self::Result {
950 if let crate::next_solver::TyKind::Param(param) = ty.kind() {
951 self.params.insert(param.id.into());
1032952 }
1033953
1034 std::ops::ControlFlow::Continue(())
954 ty.super_visit_with(self);
1035955 }
1036956
1037 fn visit_const(
1038 &mut self,
1039 constant: &chalk_ir::Const<Interner>,
1040 _outer_binder: DebruijnIndex,
1041 ) -> std::ops::ControlFlow<Self::BreakTy> {
1042 if let chalk_ir::ConstValue::Placeholder(idx) = constant.data(Interner).value {
1043 self.collect(idx);
957 fn visit_const(&mut self, konst: crate::next_solver::Const<'db>) -> Self::Result {
958 if let crate::next_solver::ConstKind::Param(param) = konst.kind() {
959 self.params.insert(param.id.into());
1044960 }
1045 std::ops::ControlFlow::Continue(())
961
962 konst.super_visit_with(self);
1046963 }
1047964}
1048965
1049/// Returns unique placeholders for types and consts contained in `value`.
1050pub fn collect_placeholders<T>(value: &T, db: &dyn HirDatabase) -> Vec<TypeOrConstParamId>
966/// Returns unique params for types and consts contained in `value`.
967pub fn collect_params<'db, T>(value: &T) -> Vec<TypeOrConstParamId>
1051968where
1052 T: ?Sized + TypeVisitable<Interner>,
969 T: ?Sized + rustc_type_ir::TypeVisitable<DbInterner<'db>>,
1053970{
1054 let mut collector = PlaceholderCollector { db, placeholders: FxHashSet::default() };
1055 _ = value.visit_with(&mut collector, DebruijnIndex::INNERMOST);
1056 collector.placeholders.into_iter().collect()
971 let mut collector = ParamCollector { params: FxHashSet::default() };
972 value.visit_with(&mut collector);
973 Vec::from_iter(collector.params)
1057974}
1058975
1059pub fn known_const_to_ast(
1060 konst: &Const,
1061 db: &dyn HirDatabase,
976pub fn known_const_to_ast<'db>(
977 konst: crate::next_solver::Const<'db>,
978 db: &'db dyn HirDatabase,
1062979 display_target: DisplayTarget,
1063980) -> Option<ConstArg> {
1064981 Some(make::expr_const_value(konst.display(db, display_target).to_string().as_str()))
src/tools/rust-analyzer/crates/hir-ty/src/lower.rs+23-61
......@@ -25,14 +25,14 @@ use chalk_ir::{
2525use either::Either;
2626use hir_def::{
2727 AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
28 GenericParamId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TypeAliasId,
29 TypeOrConstParamId, UnionId, VariantId,
28 GenericParamId, LocalFieldId, Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId,
29 UnionId, VariantId,
3030 builtin_type::BuiltinType,
3131 expr_store::{ExpressionStore, path::Path},
3232 hir::generics::{GenericParamDataRef, TypeOrConstParamData, WherePredicate},
3333 lang_item::LangItem,
3434 resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
35 signatures::{FunctionSignature, TraitFlags},
35 signatures::TraitFlags,
3636 type_ref::{
3737 ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier, TypeBound, TypeRef,
3838 TypeRefId,
......@@ -49,7 +49,7 @@ use crate::{
4949 ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime, LifetimeData, LifetimeOutlives,
5050 QuantifiedWhereClause, QuantifiedWhereClauses, Substitution, TraitRef, TraitRefExt, Ty,
5151 TyBuilder, TyKind, WhereClause, all_super_traits,
52 consteval::{intern_const_ref, path_to_const, unknown_const, unknown_const_as_generic},
52 consteval_chalk::{intern_const_ref, path_to_const, unknown_const, unknown_const_as_generic},
5353 db::HirDatabase,
5454 error_lifetime,
5555 generics::{Generics, generics, trait_self_param_idx},
......@@ -86,7 +86,7 @@ impl ImplTraitLoweringState {
8686pub(crate) struct PathDiagnosticCallbackData(pub(crate) TypeRefId);
8787
8888#[derive(Debug, Clone)]
89pub enum LifetimeElisionKind {
89pub(crate) enum LifetimeElisionKind {
9090 /// Create a new anonymous lifetime parameter and reference it.
9191 ///
9292 /// If `report_in_path`, report an error when encountering lifetime elision in a path:
......@@ -111,39 +111,11 @@ pub enum LifetimeElisionKind {
111111 /// error on default object bounds (e.g., `Box<dyn Foo>`).
112112 AnonymousReportError,
113113
114 /// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope,
115 /// otherwise give a warning that the previous behavior of introducing a new early-bound
116 /// lifetime is a bug and will be removed (if `only_lint` is enabled).
117 StaticIfNoLifetimeInScope { only_lint: bool },
118
119 /// Signal we cannot find which should be the anonymous lifetime.
120 ElisionFailure,
121
122114 /// Infer all elided lifetimes.
123115 Infer,
124116}
125117
126118impl LifetimeElisionKind {
127 #[inline]
128 pub(crate) fn for_const(const_parent: ItemContainerId) -> LifetimeElisionKind {
129 match const_parent {
130 ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
131 LifetimeElisionKind::Elided(static_lifetime())
132 }
133 ItemContainerId::ImplId(_) => {
134 LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: true }
135 }
136 ItemContainerId::TraitId(_) => {
137 LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: false }
138 }
139 }
140 }
141
142 #[inline]
143 pub(crate) fn for_fn_params(data: &FunctionSignature) -> LifetimeElisionKind {
144 LifetimeElisionKind::AnonymousCreateParameter { report_in_path: data.is_async() }
145 }
146
147119 #[inline]
148120 pub(crate) fn for_fn_ret() -> LifetimeElisionKind {
149121 // FIXME: We should use the elided lifetime here, or `ElisionFailure`.
......@@ -152,7 +124,7 @@ impl LifetimeElisionKind {
152124}
153125
154126#[derive(Debug)]
155pub struct TyLoweringContext<'db> {
127pub(crate) struct TyLoweringContext<'db> {
156128 pub db: &'db dyn HirDatabase,
157129 resolver: &'db Resolver<'db>,
158130 store: &'db ExpressionStore,
......@@ -172,7 +144,7 @@ pub struct TyLoweringContext<'db> {
172144}
173145
174146impl<'db> TyLoweringContext<'db> {
175 pub fn new(
147 pub(crate) fn new(
176148 db: &'db dyn HirDatabase,
177149 resolver: &'db Resolver<'db>,
178150 store: &'db ExpressionStore,
......@@ -197,7 +169,7 @@ impl<'db> TyLoweringContext<'db> {
197169 }
198170 }
199171
200 pub fn with_debruijn<T>(
172 pub(crate) fn with_debruijn<T>(
201173 &mut self,
202174 debruijn: DebruijnIndex,
203175 f: impl FnOnce(&mut TyLoweringContext<'_>) -> T,
......@@ -208,7 +180,7 @@ impl<'db> TyLoweringContext<'db> {
208180 result
209181 }
210182
211 pub fn with_shifted_in<T>(
183 pub(crate) fn with_shifted_in<T>(
212184 &mut self,
213185 debruijn: DebruijnIndex,
214186 f: impl FnOnce(&mut TyLoweringContext<'_>) -> T,
......@@ -227,25 +199,15 @@ impl<'db> TyLoweringContext<'db> {
227199 result
228200 }
229201
230 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
202 pub(crate) fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
231203 Self { impl_trait_mode: ImplTraitLoweringState::new(impl_trait_mode), ..self }
232204 }
233205
234 pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
206 pub(crate) fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
235207 Self { type_param_mode, ..self }
236208 }
237209
238 pub fn impl_trait_mode(&mut self, impl_trait_mode: ImplTraitLoweringMode) -> &mut Self {
239 self.impl_trait_mode = ImplTraitLoweringState::new(impl_trait_mode);
240 self
241 }
242
243 pub fn type_param_mode(&mut self, type_param_mode: ParamLoweringMode) -> &mut Self {
244 self.type_param_mode = type_param_mode;
245 self
246 }
247
248 pub fn push_diagnostic(&mut self, type_ref: TypeRefId, kind: TyLoweringDiagnosticKind) {
210 pub(crate) fn push_diagnostic(&mut self, type_ref: TypeRefId, kind: TyLoweringDiagnosticKind) {
249211 self.diagnostics.push(TyLoweringDiagnostic { source: type_ref, kind });
250212 }
251213}
......@@ -268,12 +230,12 @@ pub enum ParamLoweringMode {
268230 Variable,
269231}
270232
271impl<'a> TyLoweringContext<'a> {
272 pub fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty {
233impl<'db> TyLoweringContext<'db> {
234 pub(crate) fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty {
273235 self.lower_ty_ext(type_ref).0
274236 }
275237
276 pub fn lower_const(&mut self, const_ref: &ConstRef, const_type: Ty) -> Const {
238 pub(crate) fn lower_const(&mut self, const_ref: &ConstRef, const_type: Ty) -> Const {
277239 let const_ref = &self.store[const_ref.expr];
278240 match const_ref {
279241 hir_def::hir::Expr::Path(path) => path_to_const(
......@@ -328,7 +290,7 @@ impl<'a> TyLoweringContext<'a> {
328290 }
329291 }
330292
331 pub fn lower_path_as_const(&mut self, path: &Path, const_type: Ty) -> Const {
293 pub(crate) fn lower_path_as_const(&mut self, path: &Path, const_type: Ty) -> Const {
332294 path_to_const(
333295 self.db,
334296 self.resolver,
......@@ -345,7 +307,7 @@ impl<'a> TyLoweringContext<'a> {
345307 self.generics.get_or_init(|| generics(self.db, self.def))
346308 }
347309
348 pub fn lower_ty_ext(&mut self, type_ref_id: TypeRefId) -> (Ty, Option<TypeNs>) {
310 pub(crate) fn lower_ty_ext(&mut self, type_ref_id: TypeRefId) -> (Ty, Option<TypeNs>) {
349311 let mut res = None;
350312 let type_ref = &self.store[type_ref_id];
351313 let ty = match type_ref {
......@@ -512,7 +474,7 @@ impl<'a> TyLoweringContext<'a> {
512474 }
513475
514476 #[inline]
515 fn on_path_diagnostic_callback(type_ref: TypeRefId) -> PathDiagnosticCallback<'static> {
477 fn on_path_diagnostic_callback<'a>(type_ref: TypeRefId) -> PathDiagnosticCallback<'a, 'db> {
516478 PathDiagnosticCallback {
517479 data: Either::Left(PathDiagnosticCallbackData(type_ref)),
518480 callback: |data, this, diag| {
......@@ -523,7 +485,7 @@ impl<'a> TyLoweringContext<'a> {
523485 }
524486
525487 #[inline]
526 fn at_path(&mut self, path_id: PathId) -> PathLoweringContext<'_, 'a> {
488 fn at_path(&mut self, path_id: PathId) -> PathLoweringContext<'_, 'db> {
527489 PathLoweringContext::new(
528490 self,
529491 Self::on_path_diagnostic_callback(path_id.type_ref()),
......@@ -559,7 +521,7 @@ impl<'a> TyLoweringContext<'a> {
559521 &mut self,
560522 path_id: PathId,
561523 explicit_self_ty: Ty,
562 ) -> Option<(TraitRef, PathLoweringContext<'_, 'a>)> {
524 ) -> Option<(TraitRef, PathLoweringContext<'_, 'db>)> {
563525 let mut ctx = self.at_path(path_id);
564526 let resolved = match ctx.resolve_path_in_type_ns_fully()? {
565527 // FIXME(trait_alias): We need to handle trait alias here.
......@@ -576,7 +538,7 @@ impl<'a> TyLoweringContext<'a> {
576538 &'b mut self,
577539 where_predicate: &'b WherePredicate,
578540 ignore_bindings: bool,
579 ) -> impl Iterator<Item = QuantifiedWhereClause> + use<'a, 'b> {
541 ) -> impl Iterator<Item = QuantifiedWhereClause> + use<'db, 'b> {
580542 match where_predicate {
581543 WherePredicate::ForLifetime { target, bound, .. }
582544 | WherePredicate::TypeBound { target, bound } => {
......@@ -598,7 +560,7 @@ impl<'a> TyLoweringContext<'a> {
598560 bound: &'b TypeBound,
599561 self_ty: Ty,
600562 ignore_bindings: bool,
601 ) -> impl Iterator<Item = QuantifiedWhereClause> + use<'b, 'a> {
563 ) -> impl Iterator<Item = QuantifiedWhereClause> + use<'b, 'db> {
602564 let mut assoc_bounds = None;
603565 let mut clause = None;
604566 match bound {
......@@ -794,7 +756,7 @@ impl<'a> TyLoweringContext<'a> {
794756 ImplTrait { bounds: crate::make_single_type_binders(predicates) }
795757 }
796758
797 pub fn lower_lifetime(&self, lifetime: LifetimeRefId) -> Lifetime {
759 pub(crate) fn lower_lifetime(&self, lifetime: LifetimeRefId) -> Lifetime {
798760 match self.resolver.resolve_lifetime(&self.store[lifetime]) {
799761 Some(resolution) => match resolution {
800762 LifetimeNs::Static => static_lifetime(),
src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs+16-204
......@@ -3,15 +3,15 @@
33use chalk_ir::{BoundVar, cast::Cast, fold::Shift};
44use either::Either;
55use hir_def::{
6 GenericDefId, GenericParamId, Lookup, TraitId,
6 GenericDefId, GenericParamId, TraitId,
77 expr_store::{
8 ExpressionStore, HygieneId,
8 ExpressionStore,
99 path::{GenericArg, GenericArgs, GenericArgsParentheses, Path, PathSegment, PathSegments},
1010 },
1111 hir::generics::{
1212 GenericParamDataRef, TypeOrConstParamData, TypeParamData, TypeParamProvenance,
1313 },
14 resolver::{ResolveValueResult, TypeNs, ValueNs},
14 resolver::TypeNs,
1515 signatures::TraitFlags,
1616 type_ref::{TypeRef, TypeRefId},
1717};
......@@ -21,36 +21,36 @@ use stdx::never;
2121use crate::{
2222 AliasEq, AliasTy, GenericArgsProhibitedReason, ImplTraitLoweringMode, IncorrectGenericsLenKind,
2323 Interner, ParamLoweringMode, PathGenericsSource, PathLoweringDiagnostic, ProjectionTy,
24 QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyDefId, TyKind,
25 TyLoweringContext, ValueTyDefId, WhereClause,
26 consteval::{unknown_const, unknown_const_as_generic},
24 QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyDefId, TyKind, WhereClause,
25 consteval_chalk::{unknown_const, unknown_const_as_generic},
2726 db::HirDatabase,
2827 error_lifetime,
2928 generics::{Generics, generics},
30 lower::{LifetimeElisionKind, named_associated_type_shorthand_candidates},
29 lower::{LifetimeElisionKind, TyLoweringContext, named_associated_type_shorthand_candidates},
3130 next_solver::{
3231 DbInterner,
3332 mapping::{ChalkToNextSolver, NextSolverToChalk},
3433 },
35 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
34 to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
3635 utils::associated_type_by_name_including_super_traits,
3736};
3837
39type CallbackData<'a> = Either<
38type CallbackData<'a, 'db> = Either<
4039 super::PathDiagnosticCallbackData,
41 crate::infer::diagnostics::PathDiagnosticCallbackData<'a>,
40 crate::infer::diagnostics::PathDiagnosticCallbackData<'a, 'db>,
4241>;
4342
4443// We cannot use `&mut dyn FnMut()` because of lifetime issues, and we don't want to use `Box<dyn FnMut()>`
4544// because of the allocation, so we create a lifetime-less callback, tailored for our needs.
46pub(crate) struct PathDiagnosticCallback<'a> {
47 pub(crate) data: CallbackData<'a>,
48 pub(crate) callback: fn(&CallbackData<'_>, &mut TyLoweringContext<'_>, PathLoweringDiagnostic),
45pub(crate) struct PathDiagnosticCallback<'a, 'db> {
46 pub(crate) data: CallbackData<'a, 'db>,
47 pub(crate) callback:
48 fn(&CallbackData<'_, 'db>, &mut TyLoweringContext<'_>, PathLoweringDiagnostic),
4949}
5050
5151pub(crate) struct PathLoweringContext<'a, 'b> {
5252 ctx: &'a mut TyLoweringContext<'b>,
53 on_diagnostic: PathDiagnosticCallback<'a>,
53 on_diagnostic: PathDiagnosticCallback<'a, 'b>,
5454 path: &'a Path,
5555 segments: PathSegments<'a>,
5656 current_segment_idx: usize,
......@@ -62,7 +62,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
6262 #[inline]
6363 pub(crate) fn new(
6464 ctx: &'a mut TyLoweringContext<'b>,
65 on_diagnostic: PathDiagnosticCallback<'a>,
65 on_diagnostic: PathDiagnosticCallback<'a, 'b>,
6666 path: &'a Path,
6767 ) -> Self {
6868 let segments = path.segments();
......@@ -109,20 +109,6 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
109109 self.segments.get(self.current_segment_idx).unwrap_or(self.current_or_prev_segment);
110110 }
111111
112 #[inline]
113 pub(crate) fn ignore_last_segment(&mut self) {
114 self.segments = self.segments.strip_last();
115 }
116
117 #[inline]
118 pub(crate) fn set_current_segment(&mut self, segment: usize) {
119 self.current_segment_idx = segment;
120 self.current_or_prev_segment = self
121 .segments
122 .get(segment)
123 .expect("invalid segment passed to PathLoweringContext::set_current_segment()");
124 }
125
126112 #[inline]
127113 fn with_lifetime_elision<T>(
128114 &mut self,
......@@ -390,103 +376,6 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
390376 Some((resolution, remaining_index))
391377 }
392378
393 pub(crate) fn resolve_path_in_value_ns(
394 &mut self,
395 hygiene_id: HygieneId,
396 ) -> Option<ResolveValueResult> {
397 let (res, prefix_info) = self.ctx.resolver.resolve_path_in_value_ns_with_prefix_info(
398 self.ctx.db,
399 self.path,
400 hygiene_id,
401 )?;
402
403 let segments = self.segments;
404 if segments.is_empty() || matches!(self.path, Path::LangItem(..)) {
405 // `segments.is_empty()` can occur with `self`.
406 return Some(res);
407 }
408
409 let (mod_segments, enum_segment, resolved_segment_idx) = match res {
410 ResolveValueResult::Partial(_, unresolved_segment, _) => {
411 (segments.take(unresolved_segment - 1), None, unresolved_segment - 1)
412 }
413 ResolveValueResult::ValueNs(ValueNs::EnumVariantId(_), _)
414 if prefix_info.enum_variant =>
415 {
416 (segments.strip_last_two(), segments.len().checked_sub(2), segments.len() - 1)
417 }
418 ResolveValueResult::ValueNs(..) => (segments.strip_last(), None, segments.len() - 1),
419 };
420
421 self.current_segment_idx = resolved_segment_idx;
422 self.current_or_prev_segment =
423 segments.get(resolved_segment_idx).expect("should have resolved segment");
424
425 for (i, mod_segment) in mod_segments.iter().enumerate() {
426 if mod_segment.args_and_bindings.is_some() {
427 self.on_diagnostic(PathLoweringDiagnostic::GenericArgsProhibited {
428 segment: i as u32,
429 reason: GenericArgsProhibitedReason::Module,
430 });
431 }
432 }
433
434 if let Some(enum_segment) = enum_segment
435 && segments.get(enum_segment).is_some_and(|it| it.args_and_bindings.is_some())
436 && segments.get(enum_segment + 1).is_some_and(|it| it.args_and_bindings.is_some())
437 {
438 self.on_diagnostic(PathLoweringDiagnostic::GenericArgsProhibited {
439 segment: (enum_segment + 1) as u32,
440 reason: GenericArgsProhibitedReason::EnumVariant,
441 });
442 }
443
444 match &res {
445 ResolveValueResult::ValueNs(resolution, _) => {
446 let resolved_segment_idx = self.current_segment_u32();
447 let resolved_segment = self.current_or_prev_segment;
448
449 let mut prohibit_generics_on_resolved = |reason| {
450 if resolved_segment.args_and_bindings.is_some() {
451 self.on_diagnostic(PathLoweringDiagnostic::GenericArgsProhibited {
452 segment: resolved_segment_idx,
453 reason,
454 });
455 }
456 };
457
458 match resolution {
459 ValueNs::ImplSelf(_) => {
460 prohibit_generics_on_resolved(GenericArgsProhibitedReason::SelfTy)
461 }
462 // FIXME: rustc generates E0107 (incorrect number of generic arguments) and not
463 // E0109 (generic arguments provided for a type that doesn't accept them) for
464 // consts and statics, presumably as a defense against future in which consts
465 // and statics can be generic, or just because it was easier for rustc implementors.
466 // That means we'll show the wrong error code. Because of us it's easier to do it
467 // this way :)
468 ValueNs::GenericParam(_) => {
469 prohibit_generics_on_resolved(GenericArgsProhibitedReason::Const)
470 }
471 ValueNs::StaticId(_) => {
472 prohibit_generics_on_resolved(GenericArgsProhibitedReason::Static)
473 }
474 ValueNs::LocalBinding(_) => {
475 prohibit_generics_on_resolved(GenericArgsProhibitedReason::LocalVariable)
476 }
477 ValueNs::FunctionId(_)
478 | ValueNs::StructId(_)
479 | ValueNs::EnumVariantId(_)
480 | ValueNs::ConstId(_) => {}
481 }
482 }
483 ResolveValueResult::Partial(resolution, _, _) => {
484 self.handle_type_ns_resolution(resolution);
485 }
486 };
487 Some(res)
488 }
489
490379 fn select_associated_type(&mut self, res: Option<TypeNs>, infer_args: bool) -> Ty {
491380 let Some(res) = res else {
492381 return TyKind::Error.intern(Interner);
......@@ -556,62 +445,6 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
556445 self.ctx.db.ty(typeable).instantiate(interner, args).to_chalk(interner)
557446 }
558447
559 /// Collect generic arguments from a path into a `Substs`. See also
560 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
561 pub(crate) fn substs_from_path(
562 &mut self,
563 // Note that we don't call `db.value_type(resolved)` here,
564 // `ValueTyDefId` is just a convenient way to pass generics and
565 // special-case enum variants
566 resolved: ValueTyDefId,
567 infer_args: bool,
568 lowering_assoc_type_generics: bool,
569 ) -> Substitution {
570 let prev_current_segment_idx = self.current_segment_idx;
571 let prev_current_segment = self.current_or_prev_segment;
572
573 let generic_def = match resolved {
574 ValueTyDefId::FunctionId(it) => it.into(),
575 ValueTyDefId::StructId(it) => it.into(),
576 ValueTyDefId::UnionId(it) => it.into(),
577 ValueTyDefId::ConstId(it) => it.into(),
578 ValueTyDefId::StaticId(_) => return Substitution::empty(Interner),
579 ValueTyDefId::EnumVariantId(var) => {
580 // the generic args for an enum variant may be either specified
581 // on the segment referring to the enum, or on the segment
582 // referring to the variant. So `Option::<T>::None` and
583 // `Option::None::<T>` are both allowed (though the former is
584 // FIXME: This isn't strictly correct, enum variants may be used not through the enum
585 // (via `use Enum::Variant`). The resolver returns whether they were, but we don't have its result
586 // available here. The worst that can happen is that we will show some confusing diagnostics to the user,
587 // if generics exist on the module and they don't match with the variant.
588 // preferred). See also `def_ids_for_path_segments` in rustc.
589 //
590 // `wrapping_sub(1)` will return a number which `get` will return None for if current_segment_idx<2.
591 // This simplifies the code a bit.
592 let penultimate_idx = self.current_segment_idx.wrapping_sub(1);
593 let penultimate = self.segments.get(penultimate_idx);
594 if let Some(penultimate) = penultimate
595 && self.current_or_prev_segment.args_and_bindings.is_none()
596 && penultimate.args_and_bindings.is_some()
597 {
598 self.current_segment_idx = penultimate_idx;
599 self.current_or_prev_segment = penultimate;
600 }
601 var.lookup(self.ctx.db).parent.into()
602 }
603 };
604 let result = self.substs_from_path_segment(
605 generic_def,
606 infer_args,
607 None,
608 lowering_assoc_type_generics,
609 );
610 self.current_segment_idx = prev_current_segment_idx;
611 self.current_or_prev_segment = prev_current_segment;
612 result
613 }
614
615448 pub(crate) fn substs_from_path_segment(
616449 &mut self,
617450 def: GenericDefId,
......@@ -816,14 +649,6 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
816649 });
817650 }
818651
819 fn report_elision_failure(&mut self, def: GenericDefId, expected_count: u32) {
820 self.ctx.on_diagnostic(PathLoweringDiagnostic::ElisionFailure {
821 generics_source: self.generics_source,
822 def,
823 expected_count,
824 });
825 }
826
827652 fn report_missing_lifetime(&mut self, def: GenericDefId, expected_count: u32) {
828653 self.ctx.on_diagnostic(PathLoweringDiagnostic::MissingLifetime {
829654 generics_source: self.generics_source,
......@@ -976,8 +801,6 @@ pub(crate) trait GenericArgsLowerer {
976801 hard_error: bool,
977802 );
978803
979 fn report_elision_failure(&mut self, def: GenericDefId, expected_count: u32);
980
981804 fn report_missing_lifetime(&mut self, def: GenericDefId, expected_count: u32);
982805
983806 fn report_len_mismatch(
......@@ -1050,13 +873,6 @@ fn check_generic_args_len(
1050873 ctx.report_missing_lifetime(def, lifetime_args_len as u32);
1051874 had_error = true
1052875 }
1053 LifetimeElisionKind::ElisionFailure => {
1054 ctx.report_elision_failure(def, lifetime_args_len as u32);
1055 had_error = true;
1056 }
1057 LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: _ } => {
1058 // FIXME: Check there are other lifetimes in scope, and error/lint.
1059 }
1060876 LifetimeElisionKind::Elided(_) => {
1061877 ctx.report_elided_lifetimes_in_path(def, lifetime_args_len as u32, false);
1062878 }
......@@ -1265,15 +1081,11 @@ pub(crate) fn substs_from_args_and_bindings(
12651081 // If there are fewer arguments than parameters, it means we're inferring the remaining arguments.
12661082 let param = if let GenericParamId::LifetimeParamId(_) = param_id {
12671083 match &lifetime_elision {
1268 LifetimeElisionKind::ElisionFailure
1269 | LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }
1084 LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }
12701085 | LifetimeElisionKind::AnonymousReportError => {
12711086 assert!(had_count_error);
12721087 ctx.inferred_kind(def, param_id, param, infer_args, &substs)
12731088 }
1274 LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: _ } => {
1275 static_lifetime().cast(Interner)
1276 }
12771089 LifetimeElisionKind::Elided(lifetime) => lifetime.clone().cast(Interner),
12781090 LifetimeElisionKind::AnonymousCreateParameter { report_in_path: false }
12791091 | LifetimeElisionKind::Infer => {
src/tools/rust-analyzer/crates/hir-ty/src/lower_nextsolver.rs+173-28
......@@ -17,6 +17,7 @@ use std::{
1717
1818use base_db::Crate;
1919use either::Either;
20use hir_def::hir::generics::GenericParamDataRef;
2021use hir_def::item_tree::FieldsShape;
2122use hir_def::{
2223 AdtId, AssocItemId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId,
......@@ -35,11 +36,11 @@ use hir_def::{
3536 TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId,
3637 },
3738};
38use hir_def::{ConstId, StaticId};
39use hir_def::{ConstId, LifetimeParamId, StaticId, TypeParamId};
3940use hir_expand::name::Name;
40use intern::sym;
41use intern::{Symbol, sym};
4142use la_arena::{Arena, ArenaMap, Idx};
42use path::{PathDiagnosticCallback, PathLoweringContext, builtin};
43use path::{PathDiagnosticCallback, PathLoweringContext};
4344use rustc_ast_ir::Mutability;
4445use rustc_hash::FxHashSet;
4546use rustc_pattern_analysis::Captures;
......@@ -50,16 +51,18 @@ use rustc_type_ir::{
5051 TypeVisitableExt,
5152 inherent::{GenericArg as _, GenericArgs as _, IntoKind as _, Region as _, SliceLike, Ty as _},
5253};
54use rustc_type_ir::{TypeFoldable, TypeFolder, Upcast};
5355use salsa::plumbing::AsId;
5456use smallvec::{SmallVec, smallvec};
5557use stdx::never;
5658use triomphe::Arc;
5759
5860use crate::ValueTyDefId;
61use crate::next_solver::ParamConst;
5962use crate::{
6063 FnAbi, ImplTraitId, Interner, ParamKind, TraitEnvironment, TyDefId, TyLoweringDiagnostic,
6164 TyLoweringDiagnosticKind,
62 consteval_nextsolver::{intern_const_ref, path_to_const, unknown_const_as_generic},
65 consteval::{intern_const_ref, path_to_const, unknown_const_as_generic},
6366 db::HirDatabase,
6467 generics::{Generics, generics, trait_self_param_idx},
6568 lower::{Diagnostics, PathDiagnosticCallbackData, create_diagnostics},
......@@ -79,11 +82,11 @@ pub struct ImplTraits<'db> {
7982}
8083
8184#[derive(PartialEq, Eq, Debug, Hash)]
82pub(crate) struct ImplTrait<'db> {
85pub struct ImplTrait<'db> {
8386 pub(crate) predicates: Vec<Clause<'db>>,
8487}
8588
86pub(crate) type ImplTraitIdx<'db> = Idx<ImplTrait<'db>>;
89pub type ImplTraitIdx<'db> = Idx<ImplTrait<'db>>;
8790
8891#[derive(Debug, Default)]
8992struct ImplTraitLoweringState<'db> {
......@@ -102,7 +105,7 @@ impl<'db> ImplTraitLoweringState<'db> {
102105}
103106
104107#[derive(Debug, Clone)]
105pub(crate) enum LifetimeElisionKind<'db> {
108pub enum LifetimeElisionKind<'db> {
106109 /// Create a new anonymous lifetime parameter and reference it.
107110 ///
108111 /// If `report_in_path`, report an error when encountering lifetime elision in a path:
......@@ -171,7 +174,7 @@ impl<'db> LifetimeElisionKind<'db> {
171174}
172175
173176#[derive(Debug)]
174pub(crate) struct TyLoweringContext<'db, 'a> {
177pub struct TyLoweringContext<'db, 'a> {
175178 pub db: &'db dyn HirDatabase,
176179 interner: DbInterner<'db>,
177180 resolver: &'a Resolver<'db>,
......@@ -184,10 +187,12 @@ pub(crate) struct TyLoweringContext<'db, 'a> {
184187 pub(crate) unsized_types: FxHashSet<Ty<'db>>,
185188 pub(crate) diagnostics: Vec<TyLoweringDiagnostic>,
186189 lifetime_elision: LifetimeElisionKind<'db>,
190 /// We disallow referencing generic parameters that have an index greater than or equal to this number.
191 disallow_params_after: u32,
187192}
188193
189194impl<'db, 'a> TyLoweringContext<'db, 'a> {
190 pub(crate) fn new(
195 pub fn new(
191196 db: &'db dyn HirDatabase,
192197 resolver: &'a Resolver<'db>,
193198 store: &'a ExpressionStore,
......@@ -208,6 +213,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
208213 unsized_types: FxHashSet::default(),
209214 diagnostics: Vec::new(),
210215 lifetime_elision,
216 disallow_params_after: u32::MAX,
211217 }
212218 }
213219
......@@ -243,6 +249,10 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
243249 self
244250 }
245251
252 pub(crate) fn disallow_params_after(&mut self, after: u32) {
253 self.disallow_params_after = after;
254 }
255
246256 pub(crate) fn push_diagnostic(&mut self, type_ref: TypeRefId, kind: TyLoweringDiagnosticKind) {
247257 self.diagnostics.push(TyLoweringDiagnostic { source: type_ref, kind });
248258 }
......@@ -261,11 +271,11 @@ pub(crate) enum ImplTraitLoweringMode {
261271}
262272
263273impl<'db, 'a> TyLoweringContext<'db, 'a> {
264 pub(crate) fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
274 pub fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
265275 self.lower_ty_ext(type_ref).0
266276 }
267277
268 pub(crate) fn lower_const(&mut self, const_ref: &ConstRef, const_type: Ty<'db>) -> Const<'db> {
278 pub(crate) fn lower_const(&mut self, const_ref: ConstRef, const_type: Ty<'db>) -> Const<'db> {
269279 let const_ref = &self.store[const_ref.expr];
270280 match const_ref {
271281 hir_def::hir::Expr::Path(path) => {
......@@ -323,8 +333,35 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
323333 self.generics.get_or_init(|| generics(self.db, self.def))
324334 }
325335
336 fn type_param(&mut self, id: TypeParamId, index: u32, name: Symbol) -> Ty<'db> {
337 if index >= self.disallow_params_after {
338 // FIXME: Report an error.
339 Ty::new_error(self.interner, ErrorGuaranteed)
340 } else {
341 Ty::new_param(self.interner, id, index, name)
342 }
343 }
344
345 fn const_param(&mut self, id: ConstParamId, index: u32) -> Const<'db> {
346 if index >= self.disallow_params_after {
347 // FIXME: Report an error.
348 Const::error(self.interner)
349 } else {
350 Const::new_param(self.interner, ParamConst { id, index })
351 }
352 }
353
354 fn region_param(&mut self, id: LifetimeParamId, index: u32) -> Region<'db> {
355 if index >= self.disallow_params_after {
356 // FIXME: Report an error.
357 Region::error(self.interner)
358 } else {
359 Region::new_early_param(self.interner, EarlyParamRegion { id, index })
360 }
361 }
362
326363 #[tracing::instrument(skip(self), ret)]
327 pub(crate) fn lower_ty_ext(&mut self, type_ref_id: TypeRefId) -> (Ty<'db>, Option<TypeNs>) {
364 pub fn lower_ty_ext(&mut self, type_ref_id: TypeRefId) -> (Ty<'db>, Option<TypeNs>) {
328365 let interner = self.interner;
329366 let mut res = None;
330367 let type_ref = &self.store[type_ref_id];
......@@ -351,8 +388,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
351388 TypeOrConstParamData::TypeParamData(ty) => ty,
352389 _ => unreachable!(),
353390 };
354 Ty::new_param(
355 self.interner,
391 self.type_param(
356392 type_param_id,
357393 idx as u32,
358394 type_data
......@@ -367,7 +403,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
367403 }
368404 TypeRef::Array(array) => {
369405 let inner_ty = self.lower_ty(array.ty);
370 let const_len = self.lower_const(&array.len, Ty::new_usize(interner));
406 let const_len = self.lower_const(array.len, Ty::new_usize(interner));
371407 Ty::new_array_with_const_len(interner, inner_ty, const_len)
372408 }
373409 &TypeRef::Slice(inner) => {
......@@ -491,7 +527,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
491527 }
492528
493529 #[inline]
494 fn on_path_diagnostic_callback(type_ref: TypeRefId) -> PathDiagnosticCallback<'static, 'db> {
530 fn on_path_diagnostic_callback<'b>(type_ref: TypeRefId) -> PathDiagnosticCallback<'b, 'db> {
495531 PathDiagnosticCallback {
496532 data: Either::Left(PathDiagnosticCallbackData(type_ref)),
497533 callback: |data, this, diag| {
......@@ -515,7 +551,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
515551 if let Some(type_ref) = path.type_anchor() {
516552 let (ty, res) = self.lower_ty_ext(type_ref);
517553 let mut ctx = self.at_path(path_id);
518 return ctx.lower_ty_relative_path(ty, res);
554 return ctx.lower_ty_relative_path(ty, res, false);
519555 }
520556
521557 let mut ctx = self.at_path(path_id);
......@@ -545,7 +581,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
545581 TypeNs::TraitId(tr) => tr,
546582 _ => return None,
547583 };
548 Some((ctx.lower_trait_ref_from_resolved_path(resolved, explicit_self_ty), ctx))
584 Some((ctx.lower_trait_ref_from_resolved_path(resolved, explicit_self_ty, false), ctx))
549585 }
550586
551587 fn lower_trait_ref(
......@@ -869,7 +905,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
869905 ImplTrait { predicates }
870906 }
871907
872 pub(crate) fn lower_lifetime(&self, lifetime: LifetimeRefId) -> Region<'db> {
908 pub(crate) fn lower_lifetime(&mut self, lifetime: LifetimeRefId) -> Region<'db> {
873909 match self.resolver.resolve_lifetime(&self.store[lifetime]) {
874910 Some(resolution) => match resolution {
875911 LifetimeNs::Static => Region::new_static(self.interner),
......@@ -878,10 +914,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
878914 None => return Region::error(self.interner),
879915 Some(idx) => idx,
880916 };
881 Region::new_early_param(
882 self.interner,
883 EarlyParamRegion { index: idx as u32, id },
884 )
917 self.region_param(id, idx as u32)
885918 }
886919 },
887920 None => Region::error(self.interner),
......@@ -980,10 +1013,10 @@ pub(crate) fn type_alias_impl_traits<'db>(
9801013pub(crate) fn ty_query<'db>(db: &'db dyn HirDatabase, def: TyDefId) -> EarlyBinder<'db, Ty<'db>> {
9811014 let interner = DbInterner::new_with(db, None, None);
9821015 match def {
983 TyDefId::BuiltinType(it) => EarlyBinder::bind(builtin(interner, it)),
1016 TyDefId::BuiltinType(it) => EarlyBinder::bind(Ty::from_builtin_type(interner, it)),
9841017 TyDefId::AdtId(it) => EarlyBinder::bind(Ty::new_adt(
9851018 interner,
986 AdtDef::new(it, interner),
1019 it,
9871020 GenericArgs::identity_for_item(interner, it.into()),
9881021 )),
9891022 TyDefId::TypeAliasId(it) => db.type_for_type_alias_with_diagnostics(it).0,
......@@ -1368,6 +1401,7 @@ pub(crate) fn generic_predicates_for_param_cycle_result(
13681401pub struct GenericPredicates<'db>(Option<Arc<[Clause<'db>]>>);
13691402
13701403impl<'db> GenericPredicates<'db> {
1404 #[inline]
13711405 pub fn instantiate(
13721406 &self,
13731407 interner: DbInterner<'db>,
......@@ -1377,6 +1411,11 @@ impl<'db> GenericPredicates<'db> {
13771411 .as_ref()
13781412 .map(|it| EarlyBinder::bind(it.iter().copied()).iter_instantiated(interner, args))
13791413 }
1414
1415 #[inline]
1416 pub fn instantiate_identity(&self) -> Option<impl Iterator<Item = Clause<'db>>> {
1417 self.0.as_ref().map(|it| it.iter().copied())
1418 }
13801419}
13811420
13821421impl<'db> ops::Deref for GenericPredicates<'db> {
......@@ -1425,8 +1464,7 @@ pub(crate) fn trait_environment_query<'db>(
14251464 for pred in maybe_parent_generics.where_predicates() {
14261465 for pred in ctx.lower_where_predicate(pred, false, &generics, PredicateFilter::All) {
14271466 if let rustc_type_ir::ClauseKind::Trait(tr) = pred.kind().skip_binder() {
1428 traits_in_scope
1429 .push((convert_ty_for_result(interner, tr.self_ty()), tr.def_id().0));
1467 traits_in_scope.push((tr.self_ty(), tr.def_id().0));
14301468 }
14311469 clauses.push(pred);
14321470 }
......@@ -1748,6 +1786,113 @@ pub(crate) fn lower_generic_arg<'a, 'db, T>(
17481786 }
17491787}
17501788
1789#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1790pub struct GenericDefaults<'db>(
1791 Option<Arc<[Option<EarlyBinder<'db, crate::next_solver::GenericArg<'db>>>]>>,
1792);
1793
1794impl<'db> GenericDefaults<'db> {
1795 #[inline]
1796 pub fn get(&self, idx: usize) -> Option<EarlyBinder<'db, crate::next_solver::GenericArg<'db>>> {
1797 self.0.as_ref()?[idx]
1798 }
1799}
1800
1801pub(crate) fn generic_defaults_query(
1802 db: &dyn HirDatabase,
1803 def: GenericDefId,
1804) -> GenericDefaults<'_> {
1805 db.generic_defaults_ns_with_diagnostics(def).0
1806}
1807
1808/// Resolve the default type params from generics.
1809///
1810/// Diagnostics are only returned for this `GenericDefId` (returned defaults include parents).
1811pub(crate) fn generic_defaults_with_diagnostics_query(
1812 db: &dyn HirDatabase,
1813 def: GenericDefId,
1814) -> (GenericDefaults<'_>, Diagnostics) {
1815 let generic_params = generics(db, def);
1816 if generic_params.is_empty() {
1817 return (GenericDefaults(None), None);
1818 }
1819 let resolver = def.resolver(db);
1820
1821 let mut ctx = TyLoweringContext::new(
1822 db,
1823 &resolver,
1824 generic_params.store(),
1825 def,
1826 LifetimeElisionKind::AnonymousReportError,
1827 )
1828 .with_impl_trait_mode(ImplTraitLoweringMode::Disallowed);
1829 let mut idx = 0;
1830 let mut has_any_default = false;
1831 let mut defaults = generic_params
1832 .iter_parents_with_store()
1833 .map(|((id, p), store)| {
1834 ctx.store = store;
1835 let (result, has_default) = handle_generic_param(&mut ctx, idx, id, p, &generic_params);
1836 has_any_default |= has_default;
1837 idx += 1;
1838 result
1839 })
1840 .collect::<Vec<_>>();
1841 ctx.diagnostics.clear(); // Don't include diagnostics from the parent.
1842 defaults.extend(generic_params.iter_self().map(|(id, p)| {
1843 let (result, has_default) = handle_generic_param(&mut ctx, idx, id, p, &generic_params);
1844 has_any_default |= has_default;
1845 idx += 1;
1846 result
1847 }));
1848 let diagnostics = create_diagnostics(mem::take(&mut ctx.diagnostics));
1849 let defaults = if has_any_default {
1850 GenericDefaults(Some(Arc::from_iter(defaults)))
1851 } else {
1852 GenericDefaults(None)
1853 };
1854 return (defaults, diagnostics);
1855
1856 fn handle_generic_param<'db>(
1857 ctx: &mut TyLoweringContext<'db, '_>,
1858 idx: usize,
1859 id: GenericParamId,
1860 p: GenericParamDataRef<'_>,
1861 generic_params: &Generics,
1862 ) -> (Option<EarlyBinder<'db, crate::next_solver::GenericArg<'db>>>, bool) {
1863 // Each default can only refer to previous parameters.
1864 // Type variable default referring to parameter coming
1865 // after it is forbidden.
1866 ctx.disallow_params_after(idx as u32);
1867 match p {
1868 GenericParamDataRef::TypeParamData(p) => {
1869 let ty = p.default.map(|ty| ctx.lower_ty(ty));
1870 (ty.map(|ty| EarlyBinder::bind(ty.into())), p.default.is_some())
1871 }
1872 GenericParamDataRef::ConstParamData(p) => {
1873 let GenericParamId::ConstParamId(id) = id else {
1874 unreachable!("Unexpected lifetime or type argument")
1875 };
1876
1877 let mut val = p.default.map(|c| {
1878 let param_ty = ctx.lower_ty(p.ty);
1879 let c = ctx.lower_const(c, param_ty);
1880 c.into()
1881 });
1882 (val.map(EarlyBinder::bind), p.default.is_some())
1883 }
1884 GenericParamDataRef::LifetimeParamData(_) => (None, false),
1885 }
1886 }
1887}
1888
1889pub(crate) fn generic_defaults_with_diagnostics_cycle_result(
1890 _db: &dyn HirDatabase,
1891 _def: GenericDefId,
1892) -> (GenericDefaults<'_>, Diagnostics) {
1893 (GenericDefaults(None), None)
1894}
1895
17511896/// Build the signature of a callable item (function, struct or enum variant).
17521897pub(crate) fn callable_item_signature_query<'db>(
17531898 db: &'db dyn HirDatabase,
......@@ -1804,7 +1949,7 @@ fn fn_sig_for_fn<'db>(
18041949fn type_for_adt<'db>(db: &'db dyn HirDatabase, adt: AdtId) -> EarlyBinder<'db, Ty<'db>> {
18051950 let interner = DbInterner::new_with(db, None, None);
18061951 let args = GenericArgs::identity_for_item(interner, adt.into());
1807 let ty = Ty::new_adt(interner, AdtDef::new(adt, interner), args);
1952 let ty = Ty::new_adt(interner, adt, args);
18081953 EarlyBinder::bind(ty)
18091954}
18101955
src/tools/rust-analyzer/crates/hir-ty/src/lower_nextsolver/path.rs+40-62
......@@ -30,7 +30,7 @@ use stdx::never;
3030use crate::{
3131 GenericArgsProhibitedReason, IncorrectGenericsLenKind, PathGenericsSource,
3232 PathLoweringDiagnostic, TyDefId, ValueTyDefId,
33 consteval_nextsolver::{unknown_const, unknown_const_as_generic},
33 consteval::{unknown_const, unknown_const_as_generic},
3434 db::HirDatabase,
3535 generics::{Generics, generics},
3636 lower::PathDiagnosticCallbackData,
......@@ -51,15 +51,17 @@ use super::{
5151 const_param_ty_query, ty_query,
5252};
5353
54type CallbackData<'a> =
55 Either<PathDiagnosticCallbackData, crate::infer::diagnostics::PathDiagnosticCallbackData<'a>>;
54type CallbackData<'a, 'db> = Either<
55 PathDiagnosticCallbackData,
56 crate::infer::diagnostics::PathDiagnosticCallbackData<'a, 'db>,
57>;
5658
5759// We cannot use `&mut dyn FnMut()` because of lifetime issues, and we don't want to use `Box<dyn FnMut()>`
5860// because of the allocation, so we create a lifetime-less callback, tailored for our needs.
5961pub(crate) struct PathDiagnosticCallback<'a, 'db> {
60 pub(crate) data: CallbackData<'a>,
62 pub(crate) data: CallbackData<'a, 'db>,
6163 pub(crate) callback:
62 fn(&CallbackData<'_>, &mut TyLoweringContext<'db, '_>, PathLoweringDiagnostic),
64 fn(&CallbackData<'_, 'db>, &mut TyLoweringContext<'db, '_>, PathLoweringDiagnostic),
6365}
6466
6567pub(crate) struct PathLoweringContext<'a, 'b, 'db> {
......@@ -155,13 +157,14 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
155157 ty: Ty<'db>,
156158 // We need the original resolution to lower `Self::AssocTy` correctly
157159 res: Option<TypeNs>,
160 infer_args: bool,
158161 ) -> (Ty<'db>, Option<TypeNs>) {
159162 let remaining_segments = self.segments.len() - self.current_segment_idx;
160163 match remaining_segments {
161164 0 => (ty, res),
162165 1 => {
163166 // resolve unselected assoc types
164 (self.select_associated_type(res), None)
167 (self.select_associated_type(res, infer_args), None)
165168 }
166169 _ => {
167170 // FIXME report error (ambiguous associated type)
......@@ -204,6 +207,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
204207 let trait_ref = self.lower_trait_ref_from_resolved_path(
205208 trait_,
206209 Ty::new_error(self.ctx.interner, ErrorGuaranteed),
210 false,
207211 );
208212 tracing::debug!(?trait_ref);
209213 self.skip_resolved_segment();
......@@ -276,8 +280,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
276280 GenericParamDataRef::TypeParamData(p) => p,
277281 _ => unreachable!(),
278282 };
279 Ty::new_param(
280 self.ctx.interner,
283 self.ctx.type_param(
281284 param_id,
282285 idx as u32,
283286 p.name
......@@ -293,7 +296,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
293296 self.ctx.interner,
294297 adt.into(),
295298 );
296 Ty::new_adt(self.ctx.interner, AdtDef::new(adt, self.ctx.interner), args)
299 Ty::new_adt(self.ctx.interner, adt, args)
297300 }
298301
299302 TypeNs::AdtId(it) => self.lower_path_inner(it.into(), infer_args),
......@@ -308,7 +311,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
308311 tracing::debug!(?ty);
309312
310313 self.skip_resolved_segment();
311 self.lower_ty_relative_path(ty, Some(resolution))
314 self.lower_ty_relative_path(ty, Some(resolution), infer_args)
312315 }
313316
314317 fn handle_type_ns_resolution(&mut self, resolution: &TypeNs) {
......@@ -480,14 +483,19 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
480483 // and statics can be generic, or just because it was easier for rustc implementors.
481484 // That means we'll show the wrong error code. Because of us it's easier to do it
482485 // this way :)
483 ValueNs::GenericParam(_) | ValueNs::ConstId(_) => {
486 ValueNs::GenericParam(_) => {
484487 prohibit_generics_on_resolved(GenericArgsProhibitedReason::Const)
485488 }
486489 ValueNs::StaticId(_) => {
487490 prohibit_generics_on_resolved(GenericArgsProhibitedReason::Static)
488491 }
489 ValueNs::FunctionId(_) | ValueNs::StructId(_) | ValueNs::EnumVariantId(_) => {}
490 ValueNs::LocalBinding(_) => {}
492 ValueNs::LocalBinding(_) => {
493 prohibit_generics_on_resolved(GenericArgsProhibitedReason::LocalVariable)
494 }
495 ValueNs::FunctionId(_)
496 | ValueNs::StructId(_)
497 | ValueNs::EnumVariantId(_)
498 | ValueNs::ConstId(_) => {}
491499 }
492500 }
493501 ResolveValueResult::Partial(resolution, _, _) => {
......@@ -498,7 +506,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
498506 }
499507
500508 #[tracing::instrument(skip(self), ret)]
501 fn select_associated_type(&mut self, res: Option<TypeNs>) -> Ty<'db> {
509 fn select_associated_type(&mut self, res: Option<TypeNs>, infer_args: bool) -> Ty<'db> {
502510 let interner = self.ctx.interner;
503511 let Some(res) = res else {
504512 return Ty::new_error(self.ctx.interner, ErrorGuaranteed);
......@@ -516,7 +524,8 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
516524 // generic params. It's inefficient to splice the `Substitution`s, so we may want
517525 // that method to optionally take parent `Substitution` as we already know them at
518526 // this point (`t.substitution`).
519 let substs = self.substs_from_path_segment(associated_ty.into(), false, None, true);
527 let substs =
528 self.substs_from_path_segment(associated_ty.into(), infer_args, None, true);
520529
521530 let substs = crate::next_solver::GenericArgs::new_from_iter(
522531 interner,
......@@ -541,7 +550,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
541550
542551 fn lower_path_inner(&mut self, typeable: TyDefId, infer_args: bool) -> Ty<'db> {
543552 let generic_def = match typeable {
544 TyDefId::BuiltinType(builtinty) => return builtin(self.ctx.interner, builtinty),
553 TyDefId::BuiltinType(builtinty) => {
554 return Ty::from_builtin_type(self.ctx.interner, builtinty);
555 }
545556 TyDefId::AdtId(it) => it.into(),
546557 TyDefId::TypeAliasId(it) => it.into(),
547558 };
......@@ -715,12 +726,12 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
715726 param: GenericParamDataRef<'_>,
716727 arg: &GenericArg,
717728 ) -> crate::next_solver::GenericArg<'db> {
718 match (param, arg) {
729 match (param, *arg) {
719730 (GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => {
720 self.ctx.ctx.lower_lifetime(*lifetime).into()
731 self.ctx.ctx.lower_lifetime(lifetime).into()
721732 }
722733 (GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => {
723 self.ctx.ctx.lower_ty(*type_ref).into()
734 self.ctx.ctx.lower_ty(type_ref).into()
724735 }
725736 (GenericParamDataRef::ConstParamData(_), GenericArg::Const(konst)) => {
726737 let GenericParamId::ConstParamId(const_id) = param_id else {
......@@ -859,8 +870,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
859870 &mut self,
860871 resolved: TraitId,
861872 explicit_self_ty: Ty<'db>,
873 infer_args: bool,
862874 ) -> TraitRef<'db> {
863 let args = self.trait_ref_substs_from_path(resolved, explicit_self_ty);
875 let args = self.trait_ref_substs_from_path(resolved, explicit_self_ty, infer_args);
864876 TraitRef::new_from_args(self.ctx.interner, resolved.into(), args)
865877 }
866878
......@@ -868,8 +880,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
868880 &mut self,
869881 resolved: TraitId,
870882 explicit_self_ty: Ty<'db>,
883 infer_args: bool,
871884 ) -> crate::next_solver::GenericArgs<'db> {
872 self.substs_from_path_segment(resolved.into(), false, Some(explicit_self_ty), false)
885 self.substs_from_path_segment(resolved.into(), infer_args, Some(explicit_self_ty), false)
873886 }
874887
875888 pub(super) fn assoc_type_bindings_from_type_bound<'c>(
......@@ -1039,8 +1052,12 @@ fn check_generic_args_len<'db>(
10391052 }
10401053
10411054 let lifetime_args_len = def_generics.len_lifetimes_self();
1042 if provided_lifetimes_count == 0 && lifetime_args_len > 0 && !lowering_assoc_type_generics {
1043 // In generic associated types, we never allow inferring the lifetimes.
1055 if provided_lifetimes_count == 0
1056 && lifetime_args_len > 0
1057 && (!lowering_assoc_type_generics || infer_args)
1058 {
1059 // In generic associated types, we never allow inferring the lifetimes, but only in type context, that is
1060 // when `infer_args == false`. In expression/pattern context we always allow inferring them, even for GATs.
10441061 match lifetime_elision {
10451062 &LifetimeElisionKind::AnonymousCreateParameter { report_in_path } => {
10461063 ctx.report_elided_lifetimes_in_path(def, lifetime_args_len as u32, report_in_path);
......@@ -1335,42 +1352,3 @@ fn unknown_subst<'db>(
13351352 }),
13361353 )
13371354}
1338
1339pub(crate) fn builtin<'db>(interner: DbInterner<'db>, builtin: BuiltinType) -> Ty<'db> {
1340 match builtin {
1341 BuiltinType::Char => Ty::new(interner, rustc_type_ir::TyKind::Char),
1342 BuiltinType::Bool => Ty::new_bool(interner),
1343 BuiltinType::Str => Ty::new(interner, rustc_type_ir::TyKind::Str),
1344 BuiltinType::Int(t) => {
1345 let int_ty = match primitive::int_ty_from_builtin(t) {
1346 chalk_ir::IntTy::Isize => rustc_type_ir::IntTy::Isize,
1347 chalk_ir::IntTy::I8 => rustc_type_ir::IntTy::I8,
1348 chalk_ir::IntTy::I16 => rustc_type_ir::IntTy::I16,
1349 chalk_ir::IntTy::I32 => rustc_type_ir::IntTy::I32,
1350 chalk_ir::IntTy::I64 => rustc_type_ir::IntTy::I64,
1351 chalk_ir::IntTy::I128 => rustc_type_ir::IntTy::I128,
1352 };
1353 Ty::new_int(interner, int_ty)
1354 }
1355 BuiltinType::Uint(t) => {
1356 let uint_ty = match primitive::uint_ty_from_builtin(t) {
1357 chalk_ir::UintTy::Usize => rustc_type_ir::UintTy::Usize,
1358 chalk_ir::UintTy::U8 => rustc_type_ir::UintTy::U8,
1359 chalk_ir::UintTy::U16 => rustc_type_ir::UintTy::U16,
1360 chalk_ir::UintTy::U32 => rustc_type_ir::UintTy::U32,
1361 chalk_ir::UintTy::U64 => rustc_type_ir::UintTy::U64,
1362 chalk_ir::UintTy::U128 => rustc_type_ir::UintTy::U128,
1363 };
1364 Ty::new_uint(interner, uint_ty)
1365 }
1366 BuiltinType::Float(t) => {
1367 let float_ty = match primitive::float_ty_from_builtin(t) {
1368 chalk_ir::FloatTy::F16 => rustc_type_ir::FloatTy::F16,
1369 chalk_ir::FloatTy::F32 => rustc_type_ir::FloatTy::F32,
1370 chalk_ir::FloatTy::F64 => rustc_type_ir::FloatTy::F64,
1371 chalk_ir::FloatTy::F128 => rustc_type_ir::FloatTy::F128,
1372 };
1373 Ty::new_float(interner, float_ty)
1374 }
1375 }
1376}
src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs+342-514
......@@ -4,43 +4,44 @@
44//! and the corresponding code mostly in rustc_hir_analysis/check/method/probe.rs.
55use std::ops::ControlFlow;
66
7use arrayvec::ArrayVec;
87use base_db::Crate;
9use chalk_ir::{UniverseIndex, WithKind, cast::Cast};
108use hir_def::{
11 AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup,
12 ModuleId, TraitId,
13 nameres::{DefMap, assoc::ImplItems, block_def_map, crate_def_map},
9 AdtId, AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup,
10 ModuleId, TraitId, TypeAliasId,
11 nameres::{DefMap, block_def_map, crate_def_map},
1412 signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags},
1513};
1614use hir_expand::name::Name;
1715use intern::sym;
16use rustc_ast_ir::Mutability;
1817use rustc_hash::{FxHashMap, FxHashSet};
19use rustc_type_ir::inherent::{IntoKind, SliceLike, Ty as _};
18use rustc_type_ir::{
19 FloatTy, IntTy, TypeVisitableExt, UintTy,
20 inherent::{
21 AdtDef, BoundExistentialPredicates, GenericArgs as _, IntoKind, SliceLike, Ty as _,
22 },
23};
2024use smallvec::{SmallVec, smallvec};
2125use stdx::never;
2226use triomphe::Arc;
2327
28use crate::next_solver::infer::InferCtxt;
29use crate::next_solver::infer::select::ImplSource;
2430use crate::{
25 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, GenericArgData,
26 Goal, InEnvironment, Interner, Mutability, Scalar, Substitution, TraitEnvironment, TraitRef,
27 TraitRefExt, Ty, TyBuilder, TyExt, TyKind, VariableKind, WhereClause,
31 TraitEnvironment, TyBuilder,
2832 autoderef::{self, AutoderefKind},
2933 db::HirDatabase,
30 from_chalk_trait_id, from_foreign_def_id,
3134 infer::{Adjust, Adjustment, OverloadedDeref, PointerCast, unify::InferenceTable},
3235 lang_items::is_box,
3336 next_solver::{
34 self, DbInterner, SolverDefId,
37 Canonical, DbInterner, ErrorGuaranteed, GenericArgs, Goal, Predicate, Region, SolverDefId,
38 TraitRef, Ty, TyKind, TypingMode,
3539 infer::{
36 DefineOpaqueTypes,
37 traits::{ObligationCause, PredicateObligation},
40 DbInternerInferExt, DefineOpaqueTypes,
41 traits::{Obligation, ObligationCause, PredicateObligation},
3842 },
39 mapping::{ChalkToNextSolver, NextSolverToChalk},
4043 obligation_ctxt::ObligationCtxt,
4144 },
42 primitive::{FloatTy, IntTy, UintTy},
43 to_chalk_trait_id,
4445 traits::next_trait_solve_canonical_in_ctxt,
4546 utils::all_super_traits,
4647};
......@@ -55,11 +56,15 @@ pub enum TyFingerprint {
5556 Never,
5657 Ref(Mutability),
5758 RawPtr(Mutability),
58 Scalar(Scalar),
59 Bool,
60 Char,
61 Int(IntTy),
62 Uint(UintTy),
63 Float(FloatTy),
5964 // These can have user-defined impls:
6065 Adt(hir_def::AdtId),
6166 Dyn(TraitId),
62 ForeignType(ForeignDefId),
67 ForeignType(TypeAliasId),
6368 // These only exist for trait impls
6469 Unit,
6570 Unnameable,
......@@ -71,140 +76,73 @@ impl TyFingerprint {
7176 /// types can have inherent impls: if we have some `struct S`, we can have
7277 /// an `impl S`, but not `impl &S`. Hence, this will return `None` for
7378 /// reference types and such.
74 pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> {
75 let fp = match ty.kind(Interner) {
79 pub fn for_inherent_impl<'db>(ty: Ty<'db>) -> Option<TyFingerprint> {
80 let fp = match ty.kind() {
7681 TyKind::Str => TyFingerprint::Str,
7782 TyKind::Never => TyFingerprint::Never,
7883 TyKind::Slice(..) => TyFingerprint::Slice,
7984 TyKind::Array(..) => TyFingerprint::Array,
80 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
81 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
82 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
83 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
84 TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?,
85 TyKind::Bool => TyFingerprint::Bool,
86 TyKind::Char => TyFingerprint::Char,
87 TyKind::Int(int) => TyFingerprint::Int(int),
88 TyKind::Uint(int) => TyFingerprint::Uint(int),
89 TyKind::Float(float) => TyFingerprint::Float(float),
90 TyKind::Adt(adt_def, _) => TyFingerprint::Adt(adt_def.def_id().0),
91 TyKind::RawPtr(_, mutability) => TyFingerprint::RawPtr(mutability),
92 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(alias_id.0),
93 TyKind::Dynamic(bounds, _) => {
94 bounds.principal_def_id().map(|trait_| TyFingerprint::Dyn(trait_.0))?
95 }
8596 _ => return None,
8697 };
8798 Some(fp)
8899 }
89100
90101 /// Creates a TyFingerprint for looking up a trait impl.
91 pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> {
92 let fp = match ty.kind(Interner) {
102 pub fn for_trait_impl<'db>(ty: Ty<'db>) -> Option<TyFingerprint> {
103 let fp = match ty.kind() {
93104 TyKind::Str => TyFingerprint::Str,
94105 TyKind::Never => TyFingerprint::Never,
95106 TyKind::Slice(..) => TyFingerprint::Slice,
96107 TyKind::Array(..) => TyFingerprint::Array,
97 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
98 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
99 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
100 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
101 TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?,
102 TyKind::Ref(mutability, _, _) => TyFingerprint::Ref(*mutability),
103 TyKind::Tuple(_, subst) => {
104 let first_ty = subst.interned().first().map(|arg| arg.assert_ty_ref(Interner));
108 TyKind::Bool => TyFingerprint::Bool,
109 TyKind::Char => TyFingerprint::Char,
110 TyKind::Int(int) => TyFingerprint::Int(int),
111 TyKind::Uint(int) => TyFingerprint::Uint(int),
112 TyKind::Float(float) => TyFingerprint::Float(float),
113 TyKind::Adt(adt_def, _) => TyFingerprint::Adt(adt_def.def_id().0),
114 TyKind::RawPtr(_, mutability) => TyFingerprint::RawPtr(mutability),
115 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(alias_id.0),
116 TyKind::Dynamic(bounds, _) => {
117 bounds.principal_def_id().map(|trait_| TyFingerprint::Dyn(trait_.0))?
118 }
119 TyKind::Ref(_, _, mutability) => TyFingerprint::Ref(mutability),
120 TyKind::Tuple(subst) => {
121 let first_ty = subst.as_slice().first();
105122 match first_ty {
106 Some(ty) => return TyFingerprint::for_trait_impl(ty),
123 Some(ty) => return TyFingerprint::for_trait_impl(*ty),
107124 None => TyFingerprint::Unit,
108125 }
109126 }
110 TyKind::AssociatedType(_, _)
111127 // FIXME(next-solver): Putting `Alias` here is *probably* incorrect, AFAIK it should return `None`. But this breaks
112128 // flyimport, which uses an incorrect but fast method resolution algorithm. Therefore we put it here,
113129 // because this function is only called by flyimport, and anyway we should get rid of `TyFingerprint`
114130 // and switch to `rustc_type_ir`'s `SimplifiedType`.
115 | TyKind::Alias(_)
116 | TyKind::OpaqueType(_, _)
131 TyKind::Alias(..)
117132 | TyKind::FnDef(_, _)
118133 | TyKind::Closure(_, _)
119134 | TyKind::Coroutine(..)
135 | TyKind::CoroutineClosure(..)
120136 | TyKind::CoroutineWitness(..) => TyFingerprint::Unnameable,
121 TyKind::Function(fn_ptr) => {
122 TyFingerprint::Function(fn_ptr.substitution.0.len(Interner) as u32)
123 }
124 TyKind::Placeholder(_)
125 | TyKind::BoundVar(_)
126 | TyKind::InferenceVar(_, _)
127 | TyKind::Error => return None,
128 };
129 Some(fp)
130 }
131
132 /// Creates a TyFingerprint for looking up a trait impl.
133 pub fn for_trait_impl_ns<'db>(ty: &next_solver::Ty<'db>) -> Option<TyFingerprint> {
134 use rustc_type_ir::TyKind;
135 let fp = match (*ty).kind() {
136 TyKind::Str => TyFingerprint::Str,
137 TyKind::Never => TyFingerprint::Never,
138 TyKind::Slice(..) => TyFingerprint::Slice,
139 TyKind::Array(..) => TyFingerprint::Array,
140 TyKind::Int(int) => TyFingerprint::Scalar(Scalar::Int(match int {
141 rustc_type_ir::IntTy::Isize => IntTy::Isize,
142 rustc_type_ir::IntTy::I8 => IntTy::I8,
143 rustc_type_ir::IntTy::I16 => IntTy::I16,
144 rustc_type_ir::IntTy::I32 => IntTy::I32,
145 rustc_type_ir::IntTy::I64 => IntTy::I64,
146 rustc_type_ir::IntTy::I128 => IntTy::I128,
147 })),
148 TyKind::Uint(uint) => TyFingerprint::Scalar(Scalar::Uint(match uint {
149 rustc_type_ir::UintTy::Usize => UintTy::Usize,
150 rustc_type_ir::UintTy::U8 => UintTy::U8,
151 rustc_type_ir::UintTy::U16 => UintTy::U16,
152 rustc_type_ir::UintTy::U32 => UintTy::U32,
153 rustc_type_ir::UintTy::U64 => UintTy::U64,
154 rustc_type_ir::UintTy::U128 => UintTy::U128,
155 })),
156 TyKind::Float(float) => TyFingerprint::Scalar(Scalar::Float(match float {
157 rustc_type_ir::FloatTy::F16 => FloatTy::F16,
158 rustc_type_ir::FloatTy::F32 => FloatTy::F32,
159 rustc_type_ir::FloatTy::F64 => FloatTy::F64,
160 rustc_type_ir::FloatTy::F128 => FloatTy::F128,
161 })),
162 TyKind::Bool => TyFingerprint::Scalar(Scalar::Bool),
163 TyKind::Char => TyFingerprint::Scalar(Scalar::Char),
164 TyKind::Adt(def, _) => TyFingerprint::Adt(def.inner().id),
165 TyKind::RawPtr(.., mutability) => match mutability {
166 rustc_ast_ir::Mutability::Mut => TyFingerprint::RawPtr(Mutability::Mut),
167 rustc_ast_ir::Mutability::Not => TyFingerprint::RawPtr(Mutability::Not),
168 },
169 TyKind::Foreign(def) => TyFingerprint::ForeignType(crate::to_foreign_def_id(def.0)),
170 TyKind::Dynamic(bounds, _) => {
171 let trait_ref = bounds
172 .as_slice()
173 .iter()
174 .map(|b| (*b).skip_binder())
175 .filter_map(|b| match b {
176 rustc_type_ir::ExistentialPredicate::Trait(t) => Some(t.def_id),
177 _ => None,
178 })
179 .next()?;
180 TyFingerprint::Dyn(trait_ref.0)
181 }
182 TyKind::Ref(_, _, mutability) => match mutability {
183 rustc_ast_ir::Mutability::Mut => TyFingerprint::Ref(Mutability::Mut),
184 rustc_ast_ir::Mutability::Not => TyFingerprint::Ref(Mutability::Not),
185 },
186 TyKind::Tuple(tys) => {
187 let first_ty = tys.as_slice().iter().next();
188 match first_ty {
189 Some(ty) => return TyFingerprint::for_trait_impl_ns(ty),
190 None => TyFingerprint::Unit,
191 }
192 }
193 TyKind::FnDef(_, _)
194 | TyKind::Closure(_, _)
195 | TyKind::Coroutine(..)
196 | TyKind::CoroutineWitness(..)
197 | TyKind::Pat(..)
198 | TyKind::CoroutineClosure(..) => TyFingerprint::Unnameable,
199137 TyKind::FnPtr(sig, _) => {
200 TyFingerprint::Function(sig.inputs().skip_binder().len() as u32)
138 TyFingerprint::Function(sig.skip_binder().inputs_and_output.inner().len() as u32)
201139 }
202 TyKind::Alias(..)
203 | TyKind::Placeholder(_)
140 TyKind::Param(_)
204141 | TyKind::Bound(..)
142 | TyKind::Placeholder(..)
205143 | TyKind::Infer(_)
206144 | TyKind::Error(_)
207 | TyKind::Param(..)
145 | TyKind::Pat(..)
208146 | TyKind::UnsafeBinder(..) => return None,
209147 };
210148 Some(fp)
......@@ -212,25 +150,25 @@ impl TyFingerprint {
212150}
213151
214152pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
215 TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
216 TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
217 TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
218 TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
219 TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
220 TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
221 TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
222 TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
223 TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
224 TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
225 TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
226 TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
153 TyFingerprint::Int(IntTy::I8),
154 TyFingerprint::Int(IntTy::I16),
155 TyFingerprint::Int(IntTy::I32),
156 TyFingerprint::Int(IntTy::I64),
157 TyFingerprint::Int(IntTy::I128),
158 TyFingerprint::Int(IntTy::Isize),
159 TyFingerprint::Uint(UintTy::U8),
160 TyFingerprint::Uint(UintTy::U16),
161 TyFingerprint::Uint(UintTy::U32),
162 TyFingerprint::Uint(UintTy::U64),
163 TyFingerprint::Uint(UintTy::U128),
164 TyFingerprint::Uint(UintTy::Usize),
227165];
228166
229167pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 4] = [
230 TyFingerprint::Scalar(Scalar::Float(FloatTy::F16)),
231 TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
232 TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
233 TyFingerprint::Scalar(Scalar::Float(FloatTy::F128)),
168 TyFingerprint::Float(FloatTy::F16),
169 TyFingerprint::Float(FloatTy::F32),
170 TyFingerprint::Float(FloatTy::F64),
171 TyFingerprint::Float(FloatTy::F128),
234172];
235173
236174type TraitFpMap = FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Box<[ImplId]>>>;
......@@ -300,9 +238,8 @@ impl TraitImpls {
300238 Some(tr) => tr.skip_binder().def_id.0,
301239 None => continue,
302240 };
303 let interner = DbInterner::new_with(db, None, None);
304 let self_ty = db.impl_self_ty(impl_id).instantiate_identity().to_chalk(interner);
305 let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty);
241 let self_ty = db.impl_self_ty(impl_id);
242 let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.instantiate_identity());
306243 map.entry(target_trait).or_default().entry(self_ty_fp).or_default().push(impl_id);
307244 }
308245
......@@ -415,8 +352,8 @@ impl InherentImpls {
415352 continue;
416353 }
417354
418 let interner = DbInterner::new_with(db, None, None);
419 let self_ty = &db.impl_self_ty(impl_id).instantiate_identity().to_chalk(interner);
355 let self_ty = db.impl_self_ty(impl_id);
356 let self_ty = self_ty.instantiate_identity();
420357
421358 match is_inherent_impl_coherent(db, def_map, impl_id, self_ty) {
422359 true => {
......@@ -440,7 +377,7 @@ impl InherentImpls {
440377 }
441378 }
442379
443 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {
380 pub fn for_self_ty<'db>(&self, self_ty: Ty<'db>) -> &[ImplId] {
444381 match TyFingerprint::for_inherent_impl(self_ty) {
445382 Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]),
446383 None => &[],
......@@ -476,9 +413,14 @@ pub(crate) fn incoherent_inherent_impl_crates(
476413 res
477414}
478415
479pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<SmallVec<[Crate; 2]>> {
480 match ty.kind(Interner) {
481 &TyKind::Adt(AdtId(def_id), _) => {
416pub fn def_crates<'db>(
417 db: &'db dyn HirDatabase,
418 ty: Ty<'db>,
419 cur_crate: Crate,
420) -> Option<SmallVec<[Crate; 2]>> {
421 match ty.kind() {
422 TyKind::Adt(adt_def, _) => {
423 let def_id = adt_def.def_id().0;
482424 let rustc_has_incoherent_inherent_impls = match def_id {
483425 hir_def::AdtId::StructId(id) => db
484426 .struct_signature(id)
......@@ -499,22 +441,22 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma
499441 smallvec![def_id.module(db).krate()]
500442 })
501443 }
502 &TyKind::Foreign(id) => {
503 let alias = from_foreign_def_id(id);
444 TyKind::Foreign(alias) => {
445 let alias = alias.0;
504446 Some(
505447 if db
506448 .type_alias_signature(alias)
507449 .flags
508450 .contains(TypeAliasFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPL)
509451 {
510 db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::ForeignType(id))
452 db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::ForeignType(alias))
511453 } else {
512454 smallvec![alias.module(db).krate()]
513455 },
514456 )
515457 }
516 TyKind::Dyn(_) => {
517 let trait_id = ty.dyn_trait()?;
458 TyKind::Dynamic(bounds, _) => {
459 let trait_id = bounds.principal_def_id()?.0;
518460 Some(
519461 if db
520462 .trait_signature(trait_id)
......@@ -530,11 +472,15 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma
530472 // for primitives, there may be impls in various places (core and alloc
531473 // mostly). We just check the whole crate graph for crates with impls
532474 // (cached behind a query).
533 TyKind::Scalar(_)
475 TyKind::Bool
476 | TyKind::Char
477 | TyKind::Int(_)
478 | TyKind::Uint(_)
479 | TyKind::Float(_)
534480 | TyKind::Str
535481 | TyKind::Slice(_)
536482 | TyKind::Array(..)
537 | TyKind::Raw(..) => Some(db.incoherent_inherent_impl_crates(
483 | TyKind::RawPtr(..) => Some(db.incoherent_inherent_impl_crates(
538484 cur_crate,
539485 TyFingerprint::for_inherent_impl(ty).expect("fingerprint for primitive"),
540486 )),
......@@ -545,7 +491,7 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma
545491/// Look up the method with the given name.
546492pub(crate) fn lookup_method<'db>(
547493 db: &'db dyn HirDatabase,
548 ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
494 ty: &Canonical<'db, Ty<'db>>,
549495 env: Arc<TraitEnvironment<'db>>,
550496 traits_in_scope: &FxHashSet<TraitId>,
551497 visible_from_module: VisibleFromModule,
......@@ -626,23 +572,23 @@ pub struct ReceiverAdjustments {
626572}
627573
628574impl ReceiverAdjustments {
629 pub(crate) fn apply(
575 pub(crate) fn apply<'db>(
630576 &self,
631 table: &mut InferenceTable<'_>,
632 mut ty: Ty,
633 ) -> (Ty, Vec<Adjustment>) {
577 table: &mut InferenceTable<'db>,
578 mut ty: Ty<'db>,
579 ) -> (Ty<'db>, Vec<Adjustment<'db>>) {
634580 let mut adjust = Vec::new();
635 let mut autoderef = table.autoderef(ty.to_nextsolver(table.interner));
581 let mut autoderef = table.autoderef(ty);
636582 autoderef.next();
637583 for _ in 0..self.autoderefs {
638584 match autoderef.next() {
639585 None => {
640586 never!("autoderef not possible for {:?}", ty);
641 ty = TyKind::Error.intern(Interner);
587 ty = Ty::new_error(table.interner(), ErrorGuaranteed);
642588 break;
643589 }
644590 Some((new_ty, _)) => {
645 ty = new_ty.to_chalk(autoderef.table.interner);
591 ty = new_ty;
646592 let mutbl = match self.autoref {
647593 Some(AutorefOrPtrAdjustment::Autoref(m)) => Some(m),
648594 Some(AutorefOrPtrAdjustment::ToConstPtr) => Some(Mutability::Not),
......@@ -654,26 +600,26 @@ impl ReceiverAdjustments {
654600 AutoderefKind::Overloaded => Some(OverloadedDeref(mutbl)),
655601 AutoderefKind::Builtin => None,
656602 }),
657 target: ty.clone(),
603 target: ty,
658604 });
659605 }
660606 }
661607 }
662608 if let Some(autoref) = &self.autoref {
663 let lt = table.new_lifetime_var();
609 let lt = table.next_region_var();
664610 match autoref {
665611 AutorefOrPtrAdjustment::Autoref(m) => {
666 let a = Adjustment::borrow(*m, ty, lt);
667 ty = a.target.clone();
612 let a = Adjustment::borrow(table.interner(), *m, ty, lt);
613 ty = a.target;
668614 adjust.push(a);
669615 }
670616 AutorefOrPtrAdjustment::ToConstPtr => {
671 if let TyKind::Raw(Mutability::Mut, pointee) = ty.kind(Interner) {
617 if let TyKind::RawPtr(pointee, Mutability::Mut) = ty.kind() {
672618 let a = Adjustment {
673619 kind: Adjust::Pointer(PointerCast::MutToConstPointer),
674 target: TyKind::Raw(Mutability::Not, pointee.clone()).intern(Interner),
620 target: Ty::new_ptr(table.interner(), pointee, Mutability::Not),
675621 };
676 ty = a.target.clone();
622 ty = a.target;
677623 adjust.push(a);
678624 } else {
679625 never!("`ToConstPtr` target is not a raw mutable pointer");
......@@ -683,23 +629,20 @@ impl ReceiverAdjustments {
683629 }
684630 if self.unsize_array {
685631 ty = 'it: {
686 if let TyKind::Ref(m, l, inner) = ty.kind(Interner)
687 && let TyKind::Array(inner, _) = inner.kind(Interner)
632 if let TyKind::Ref(l, inner, m) = ty.kind()
633 && let TyKind::Array(inner, _) = inner.kind()
688634 {
689 break 'it TyKind::Ref(
690 *m,
691 l.clone(),
692 TyKind::Slice(inner.clone()).intern(Interner),
693 )
694 .intern(Interner);
635 break 'it Ty::new_ref(
636 table.interner(),
637 l,
638 Ty::new_slice(table.interner(), inner),
639 m,
640 );
695641 }
696642 // FIXME: report diagnostic if array unsizing happens without indirection.
697643 ty
698644 };
699 adjust.push(Adjustment {
700 kind: Adjust::Pointer(PointerCast::Unsize),
701 target: ty.clone(),
702 });
645 adjust.push(Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target: ty });
703646 }
704647 (ty, adjust)
705648 }
......@@ -713,7 +656,7 @@ impl ReceiverAdjustments {
713656// lifetime problems, because we need to borrow temp `CrateImplDefs`.
714657// FIXME add a context type here?
715658pub(crate) fn iterate_method_candidates<'db, T>(
716 ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
659 ty: &Canonical<'db, Ty<'db>>,
717660 db: &'db dyn HirDatabase,
718661 env: Arc<TraitEnvironment<'db>>,
719662 traits_in_scope: &FxHashSet<TraitId>,
......@@ -744,17 +687,19 @@ pub(crate) fn iterate_method_candidates<'db, T>(
744687}
745688
746689pub fn lookup_impl_const<'db>(
747 db: &'db dyn HirDatabase,
690 infcx: &InferCtxt<'db>,
748691 env: Arc<TraitEnvironment<'db>>,
749692 const_id: ConstId,
750 subs: Substitution,
751) -> (ConstId, Substitution) {
693 subs: GenericArgs<'db>,
694) -> (ConstId, GenericArgs<'db>) {
695 let interner = infcx.interner;
696 let db = interner.db;
697
752698 let trait_id = match const_id.lookup(db).container {
753699 ItemContainerId::TraitId(id) => id,
754700 _ => return (const_id, subs),
755701 };
756 let substitution = Substitution::from_iter(Interner, subs.iter(Interner));
757 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution };
702 let trait_ref = TraitRef::new(interner, trait_id.into(), subs);
758703
759704 let const_signature = db.const_signature(const_id);
760705 let name = match const_signature.name.as_ref() {
......@@ -762,7 +707,7 @@ pub fn lookup_impl_const<'db>(
762707 None => return (const_id, subs),
763708 };
764709
765 lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name)
710 lookup_impl_assoc_item_for_trait_ref(infcx, trait_ref, env, name)
766711 .and_then(
767712 |assoc| if let (AssocItemId::ConstId(id), s) = assoc { Some((id, s)) } else { None },
768713 )
......@@ -772,37 +717,30 @@ pub fn lookup_impl_const<'db>(
772717/// Checks if the self parameter of `Trait` method is the `dyn Trait` and we should
773718/// call the method using the vtable.
774719pub fn is_dyn_method<'db>(
775 db: &'db dyn HirDatabase,
720 interner: DbInterner<'db>,
776721 _env: Arc<TraitEnvironment<'db>>,
777722 func: FunctionId,
778 fn_subst: Substitution,
723 fn_subst: GenericArgs<'db>,
779724) -> Option<usize> {
725 let db = interner.db;
726
780727 let ItemContainerId::TraitId(trait_id) = func.lookup(db).container else {
781728 return None;
782729 };
783730 let trait_params = db.generic_params(trait_id.into()).len();
784 let fn_params = fn_subst.len(Interner) - trait_params;
785 let trait_ref = TraitRef {
786 trait_id: to_chalk_trait_id(trait_id),
787 substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).take(trait_params)),
788 };
789 let self_ty = trait_ref.self_type_parameter(Interner);
790 if let TyKind::Dyn(d) = self_ty.kind(Interner) {
731 let fn_params = fn_subst.len() - trait_params;
732 let trait_ref = TraitRef::new(
733 interner,
734 trait_id.into(),
735 GenericArgs::new_from_iter(interner, fn_subst.iter().take(trait_params)),
736 );
737 let self_ty = trait_ref.self_ty();
738 if let TyKind::Dynamic(d, _) = self_ty.kind() {
739 // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
740 // what the generics are, we are sure that the method is come from the vtable.
791741 let is_my_trait_in_bounds = d
792 .bounds
793 .skip_binders()
794 .as_slice(Interner)
795 .iter()
796 .map(|it| it.skip_binders())
797 .flat_map(|it| match it {
798 WhereClause::Implemented(tr) => {
799 all_super_traits(db, from_chalk_trait_id(tr.trait_id))
800 }
801 _ => smallvec![],
802 })
803 // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
804 // what the generics are, we are sure that the method is come from the vtable.
805 .any(|x| x == trait_id);
742 .principal_def_id()
743 .is_some_and(|trait_| all_super_traits(db, trait_.0).contains(&trait_id));
806744 if is_my_trait_in_bounds {
807745 return Some(fn_params);
808746 }
......@@ -817,20 +755,24 @@ pub(crate) fn lookup_impl_method_query<'db>(
817755 db: &'db dyn HirDatabase,
818756 env: Arc<TraitEnvironment<'db>>,
819757 func: FunctionId,
820 fn_subst: Substitution,
821) -> (FunctionId, Substitution) {
758 fn_subst: GenericArgs<'db>,
759) -> (FunctionId, GenericArgs<'db>) {
760 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
761 let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
762
822763 let ItemContainerId::TraitId(trait_id) = func.lookup(db).container else {
823764 return (func, fn_subst);
824765 };
825766 let trait_params = db.generic_params(trait_id.into()).len();
826 let trait_ref = TraitRef {
827 trait_id: to_chalk_trait_id(trait_id),
828 substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).take(trait_params)),
829 };
767 let trait_ref = TraitRef::new(
768 interner,
769 trait_id.into(),
770 GenericArgs::new_from_iter(interner, fn_subst.iter().take(trait_params)),
771 );
830772
831773 let name = &db.function_signature(func).name;
832774 let Some((impl_fn, impl_subst)) =
833 lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name).and_then(|assoc| {
775 lookup_impl_assoc_item_for_trait_ref(&infcx, trait_ref, env, name).and_then(|assoc| {
834776 if let (AssocItemId::FunctionId(id), subst) = assoc { Some((id, subst)) } else { None }
835777 })
836778 else {
......@@ -839,133 +781,109 @@ pub(crate) fn lookup_impl_method_query<'db>(
839781
840782 (
841783 impl_fn,
842 Substitution::from_iter(
843 Interner,
844 impl_subst.iter(Interner).chain(fn_subst.iter(Interner).skip(trait_params)),
784 GenericArgs::new_from_iter(
785 interner,
786 impl_subst.iter().chain(fn_subst.iter().skip(trait_params)),
845787 ),
846788 )
847789}
848790
849791fn lookup_impl_assoc_item_for_trait_ref<'db>(
850 trait_ref: TraitRef,
851 db: &'db dyn HirDatabase,
792 infcx: &InferCtxt<'db>,
793 trait_ref: TraitRef<'db>,
852794 env: Arc<TraitEnvironment<'db>>,
853795 name: &Name,
854) -> Option<(AssocItemId, Substitution)> {
855 let hir_trait_id = trait_ref.hir_trait_id();
856 let self_ty = trait_ref.self_type_parameter(Interner);
857 let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?;
858 let impls = db.trait_impls_in_deps(env.krate);
859
860 let trait_module = hir_trait_id.module(db);
861 let type_module = match self_ty_fp {
862 TyFingerprint::Adt(adt_id) => Some(adt_id.module(db)),
863 TyFingerprint::ForeignType(type_id) => Some(from_foreign_def_id(type_id).module(db)),
864 TyFingerprint::Dyn(trait_id) => Some(trait_id.module(db)),
865 _ => None,
866 };
867
868 let def_blocks: ArrayVec<_, 2> =
869 [trait_module.containing_block(), type_module.and_then(|it| it.containing_block())]
870 .into_iter()
871 .flatten()
872 .filter_map(|block_id| db.trait_impls_in_block(block_id))
873 .collect();
874
875 let impls = impls
876 .iter()
877 .chain(&def_blocks)
878 .flat_map(|impls| impls.for_trait_and_self_ty(hir_trait_id, self_ty_fp));
879
880 let table = InferenceTable::new(db, env);
881
882 let (impl_data, impl_subst) = find_matching_impl(impls, table, trait_ref)?;
883 let item = impl_data.items.iter().find_map(|(n, it)| match *it {
884 AssocItemId::FunctionId(f) => (n == name).then_some(AssocItemId::FunctionId(f)),
885 AssocItemId::ConstId(c) => (n == name).then_some(AssocItemId::ConstId(c)),
886 AssocItemId::TypeAliasId(_) => None,
887 })?;
796) -> Option<(AssocItemId, GenericArgs<'db>)> {
797 let (impl_id, impl_subst) = find_matching_impl(infcx, &env, trait_ref)?;
798 let item =
799 impl_id.impl_items(infcx.interner.db).items.iter().find_map(|(n, it)| match *it {
800 AssocItemId::FunctionId(f) => (n == name).then_some(AssocItemId::FunctionId(f)),
801 AssocItemId::ConstId(c) => (n == name).then_some(AssocItemId::ConstId(c)),
802 AssocItemId::TypeAliasId(_) => None,
803 })?;
888804 Some((item, impl_subst))
889805}
890806
891fn find_matching_impl(
892 mut impls: impl Iterator<Item = ImplId>,
893 mut table: InferenceTable<'_>,
894 actual_trait_ref: TraitRef,
895) -> Option<(&ImplItems, Substitution)> {
896 let db = table.db;
897 impls.find_map(|impl_| {
898 table.run_in_snapshot(|table| {
899 let impl_substs =
900 TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build();
901 let args: crate::next_solver::GenericArgs<'_> =
902 impl_substs.to_nextsolver(table.interner);
903 let trait_ref = db
904 .impl_trait(impl_)
905 .expect("non-trait method in find_matching_impl")
906 .instantiate(table.interner, args)
907 .to_chalk(table.interner);
908
909 if !table.unify(&trait_ref, &actual_trait_ref) {
910 return None;
911 }
807pub(crate) fn find_matching_impl<'db>(
808 infcx: &InferCtxt<'db>,
809 env: &TraitEnvironment<'db>,
810 trait_ref: TraitRef<'db>,
811) -> Option<(ImplId, GenericArgs<'db>)> {
812 let trait_ref =
813 infcx.at(&ObligationCause::dummy(), env.env).deeply_normalize(trait_ref).ok()?;
912814
913 let wcs = crate::chalk_db::convert_where_clauses(db, impl_.into(), &impl_substs)
914 .into_iter()
915 .map(|b| -> Goal { b.cast(Interner) });
916 for goal in wcs {
917 let goal = goal.to_nextsolver(table.interner);
918 if table.try_obligation(goal).no_solution() {
919 return None;
920 }
921 table.register_obligation(goal);
922 }
923 Some((
924 impl_.impl_items(db),
925 table.resolve_completely::<_, crate::next_solver::GenericArgs<'_>>(impl_substs),
926 ))
927 })
928 })
815 let obligation = Obligation::new(infcx.interner, ObligationCause::dummy(), env.env, trait_ref);
816
817 let selection = infcx.select(&obligation).ok()??;
818
819 // Currently, we use a fulfillment context to completely resolve
820 // all nested obligations. This is because they can inform the
821 // inference of the impl's type parameters.
822 let mut ocx = ObligationCtxt::new(infcx);
823 let impl_source = selection.map(|obligation| ocx.register_obligation(obligation));
824
825 let errors = ocx.evaluate_obligations_error_on_ambiguity();
826 if !errors.is_empty() {
827 return None;
828 }
829
830 let impl_source = infcx.resolve_vars_if_possible(impl_source);
831 if impl_source.has_non_region_infer() {
832 return None;
833 }
834
835 match impl_source {
836 ImplSource::UserDefined(impl_source) => Some((impl_source.impl_def_id, impl_source.args)),
837 ImplSource::Param(_) | ImplSource::Builtin(..) => None,
838 }
929839}
930840
931fn is_inherent_impl_coherent(
932 db: &dyn HirDatabase,
841fn is_inherent_impl_coherent<'db>(
842 db: &'db dyn HirDatabase,
933843 def_map: &DefMap,
934844 impl_id: ImplId,
935 self_ty: &Ty,
845 self_ty: Ty<'db>,
936846) -> bool {
937 let self_ty = self_ty.kind(Interner);
847 let self_ty = self_ty.kind();
938848 let impl_allowed = match self_ty {
939 TyKind::Tuple(_, _)
849 TyKind::Tuple(_)
940850 | TyKind::FnDef(_, _)
941851 | TyKind::Array(_, _)
942852 | TyKind::Never
943 | TyKind::Raw(_, _)
853 | TyKind::RawPtr(_, _)
944854 | TyKind::Ref(_, _, _)
945855 | TyKind::Slice(_)
946856 | TyKind::Str
947 | TyKind::Scalar(_) => def_map.is_rustc_coherence_is_core(),
857 | TyKind::Bool
858 | TyKind::Char
859 | TyKind::Int(_)
860 | TyKind::Uint(_)
861 | TyKind::Float(_) => def_map.is_rustc_coherence_is_core(),
948862
949 &TyKind::Adt(AdtId(adt), _) => adt.module(db).krate() == def_map.krate(),
950 TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| {
951 from_chalk_trait_id(trait_id).module(db).krate() == def_map.krate()
952 }),
863 TyKind::Adt(adt_def, _) => adt_def.def_id().0.module(db).krate() == def_map.krate(),
864 TyKind::Dynamic(it, _) => it
865 .principal_def_id()
866 .is_some_and(|trait_id| trait_id.0.module(db).krate() == def_map.krate()),
953867
954868 _ => true,
955869 };
956870 impl_allowed || {
957871 let rustc_has_incoherent_inherent_impls = match self_ty {
958 TyKind::Tuple(_, _)
872 TyKind::Tuple(_)
959873 | TyKind::FnDef(_, _)
960874 | TyKind::Array(_, _)
961875 | TyKind::Never
962 | TyKind::Raw(_, _)
876 | TyKind::RawPtr(_, _)
963877 | TyKind::Ref(_, _, _)
964878 | TyKind::Slice(_)
965879 | TyKind::Str
966 | TyKind::Scalar(_) => true,
880 | TyKind::Bool
881 | TyKind::Char
882 | TyKind::Int(_)
883 | TyKind::Uint(_)
884 | TyKind::Float(_) => true,
967885
968 &TyKind::Adt(AdtId(adt), _) => match adt {
886 TyKind::Adt(adt_def, _) => match adt_def.def_id().0 {
969887 hir_def::AdtId::StructId(id) => db
970888 .struct_signature(id)
971889 .flags
......@@ -979,8 +897,8 @@ fn is_inherent_impl_coherent(
979897 .flags
980898 .contains(EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
981899 },
982 TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| {
983 db.trait_signature(from_chalk_trait_id(trait_id))
900 TyKind::Dynamic(it, _) => it.principal_def_id().is_some_and(|trait_id| {
901 db.trait_signature(trait_id.0)
984902 .flags
985903 .contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
986904 }),
......@@ -1012,8 +930,7 @@ fn is_inherent_impl_coherent(
1012930/// - All of
1013931/// - At least one of the types `T0..=Tn`` must be a local type. Let `Ti`` be the first such type.
1014932/// - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`)
1015pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
1016 let substs = TyBuilder::placeholder_subst(db, impl_);
933pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool {
1017934 let Some(impl_trait) = db.impl_trait(impl_) else {
1018935 // not a trait impl
1019936 return true;
......@@ -1022,24 +939,25 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
1022939 let local_crate = impl_.lookup(db).container.krate();
1023940 let is_local = |tgt_crate| tgt_crate == local_crate;
1024941
1025 let interner = DbInterner::new_with(db, None, None);
1026 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
1027 let trait_ref = impl_trait.instantiate(interner, args).to_chalk(interner);
1028 let trait_id = from_chalk_trait_id(trait_ref.trait_id);
942 let trait_ref = impl_trait.instantiate_identity();
943 let trait_id = trait_ref.def_id.0;
1029944 if is_local(trait_id.module(db).krate()) {
1030945 // trait to be implemented is local
1031946 return true;
1032947 }
1033948
1034 let unwrap_fundamental = |mut ty: Ty| {
949 let unwrap_fundamental = |mut ty: Ty<'db>| {
1035950 // Unwrap all layers of fundamental types with a loop.
1036951 loop {
1037 match ty.kind(Interner) {
1038 TyKind::Ref(_, _, referenced) => ty = referenced.clone(),
1039 &TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref subs) => {
952 match ty.kind() {
953 TyKind::Ref(_, referenced, _) => ty = referenced,
954 TyKind::Adt(adt_def, subs) => {
955 let AdtId::StructId(s) = adt_def.def_id().0 else {
956 break ty;
957 };
1040958 let struct_signature = db.struct_signature(s);
1041959 if struct_signature.flags.contains(StructFlags::FUNDAMENTAL) {
1042 let next = subs.type_parameters(Interner).next();
960 let next = subs.types().next();
1043961 match next {
1044962 Some(it) => ty = it,
1045963 None => break ty,
......@@ -1056,22 +974,20 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
1056974
1057975 // FIXME: param coverage
1058976 // - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`)
1059 let is_not_orphan = trait_ref.substitution.type_parameters(Interner).any(|ty| {
1060 match unwrap_fundamental(ty).kind(Interner) {
1061 &TyKind::Adt(AdtId(id), _) => is_local(id.module(db).krate()),
1062 TyKind::Error => true,
1063 TyKind::Dyn(it) => it
1064 .principal_id()
1065 .is_some_and(|trait_id| is_local(from_chalk_trait_id(trait_id).module(db).krate())),
1066 _ => false,
977 let is_not_orphan = trait_ref.args.types().any(|ty| match unwrap_fundamental(ty).kind() {
978 TyKind::Adt(adt_def, _) => is_local(adt_def.def_id().0.module(db).krate()),
979 TyKind::Error(_) => true,
980 TyKind::Dynamic(it, _) => {
981 it.principal_def_id().is_some_and(|trait_id| is_local(trait_id.0.module(db).krate()))
1067982 }
983 _ => false,
1068984 });
1069985 #[allow(clippy::let_and_return)]
1070986 is_not_orphan
1071987}
1072988
1073989pub fn iterate_path_candidates<'db>(
1074 ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
990 ty: &Canonical<'db, Ty<'db>>,
1075991 db: &'db dyn HirDatabase,
1076992 env: Arc<TraitEnvironment<'db>>,
1077993 traits_in_scope: &FxHashSet<TraitId>,
......@@ -1093,7 +1009,7 @@ pub fn iterate_path_candidates<'db>(
10931009}
10941010
10951011pub fn iterate_method_candidates_dyn<'db>(
1096 ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
1012 ty: &Canonical<'db, Ty<'db>>,
10971013 db: &'db dyn HirDatabase,
10981014 env: Arc<TraitEnvironment<'db>>,
10991015 traits_in_scope: &FxHashSet<TraitId>,
......@@ -1132,7 +1048,7 @@ pub fn iterate_method_candidates_dyn<'db>(
11321048 // types*.
11331049
11341050 let mut table = InferenceTable::new(db, env);
1135 let ty = table.instantiate_canonical_ns(*ty);
1051 let ty = table.instantiate_canonical(*ty);
11361052 let deref_chain = autoderef_method_receiver(&mut table, ty);
11371053
11381054 deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| {
......@@ -1165,14 +1081,14 @@ pub fn iterate_method_candidates_dyn<'db>(
11651081#[tracing::instrument(skip_all, fields(name = ?name))]
11661082fn iterate_method_candidates_with_autoref<'db>(
11671083 table: &mut InferenceTable<'db>,
1168 receiver_ty: next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
1084 receiver_ty: Canonical<'db, Ty<'db>>,
11691085 first_adjustment: ReceiverAdjustments,
11701086 traits_in_scope: &FxHashSet<TraitId>,
11711087 visible_from_module: VisibleFromModule,
11721088 name: Option<&Name>,
11731089 callback: &mut dyn MethodCandidateCallback,
11741090) -> ControlFlow<()> {
1175 let interner = table.interner;
1091 let interner = table.interner();
11761092
11771093 let mut iterate_method_candidates_by_receiver = move |receiver_ty, first_adjustment| {
11781094 iterate_method_candidates_by_receiver(
......@@ -1187,11 +1103,7 @@ fn iterate_method_candidates_with_autoref<'db>(
11871103 };
11881104
11891105 let mut maybe_reborrowed = first_adjustment.clone();
1190 if let rustc_type_ir::TyKind::Ref(_, _, m) = receiver_ty.value.kind() {
1191 let m = match m {
1192 rustc_ast_ir::Mutability::Mut => chalk_ir::Mutability::Mut,
1193 rustc_ast_ir::Mutability::Not => chalk_ir::Mutability::Not,
1194 };
1106 if let TyKind::Ref(_, _, m) = receiver_ty.value.kind() {
11951107 // Prefer reborrow of references to move
11961108 maybe_reborrowed.autoref = Some(AutorefOrPtrAdjustment::Autoref(m));
11971109 maybe_reborrowed.autoderefs += 1;
......@@ -1199,15 +1111,10 @@ fn iterate_method_candidates_with_autoref<'db>(
11991111
12001112 iterate_method_candidates_by_receiver(receiver_ty, maybe_reborrowed)?;
12011113
1202 let refed = next_solver::Canonical {
1114 let refed = Canonical {
12031115 max_universe: receiver_ty.max_universe,
12041116 variables: receiver_ty.variables,
1205 value: next_solver::Ty::new_ref(
1206 interner,
1207 next_solver::Region::error(interner),
1208 receiver_ty.value,
1209 rustc_ast_ir::Mutability::Not,
1210 ),
1117 value: Ty::new_ref(interner, Region::error(interner), receiver_ty.value, Mutability::Not),
12111118 };
12121119
12131120 iterate_method_candidates_by_receiver(
......@@ -1215,15 +1122,10 @@ fn iterate_method_candidates_with_autoref<'db>(
12151122 first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Not)),
12161123 )?;
12171124
1218 let ref_muted = next_solver::Canonical {
1125 let ref_muted = Canonical {
12191126 max_universe: receiver_ty.max_universe,
12201127 variables: receiver_ty.variables,
1221 value: next_solver::Ty::new_ref(
1222 interner,
1223 next_solver::Region::error(interner),
1224 receiver_ty.value,
1225 rustc_ast_ir::Mutability::Mut,
1226 ),
1128 value: Ty::new_ref(interner, Region::error(interner), receiver_ty.value, Mutability::Mut),
12271129 };
12281130
12291131 iterate_method_candidates_by_receiver(
......@@ -1231,12 +1133,10 @@ fn iterate_method_candidates_with_autoref<'db>(
12311133 first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Mut)),
12321134 )?;
12331135
1234 if let rustc_type_ir::TyKind::RawPtr(ty, rustc_ast_ir::Mutability::Mut) =
1235 receiver_ty.value.kind()
1236 {
1136 if let TyKind::RawPtr(ty, Mutability::Mut) = receiver_ty.value.kind() {
12371137 let const_ptr_ty = rustc_type_ir::Canonical {
12381138 max_universe: rustc_type_ir::UniverseIndex::ZERO,
1239 value: next_solver::Ty::new_ptr(interner, ty, rustc_ast_ir::Mutability::Not),
1139 value: Ty::new_ptr(interner, ty, Mutability::Not),
12401140 variables: receiver_ty.variables,
12411141 };
12421142 iterate_method_candidates_by_receiver(
......@@ -1290,30 +1190,27 @@ where
12901190#[tracing::instrument(skip_all, fields(name = ?name))]
12911191fn iterate_method_candidates_by_receiver<'db>(
12921192 table: &mut InferenceTable<'db>,
1293 receiver_ty: next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
1193 receiver_ty: Canonical<'db, Ty<'db>>,
12941194 receiver_adjustments: ReceiverAdjustments,
12951195 traits_in_scope: &FxHashSet<TraitId>,
12961196 visible_from_module: VisibleFromModule,
12971197 name: Option<&Name>,
12981198 callback: &mut dyn MethodCandidateCallback,
12991199) -> ControlFlow<()> {
1300 let interner = table.interner;
1301 let receiver_ty = table.instantiate_canonical_ns(receiver_ty);
1302 let receiver_ty: crate::Ty = receiver_ty.to_chalk(interner);
1200 let receiver_ty = table.instantiate_canonical(receiver_ty);
13031201 // We're looking for methods with *receiver* type receiver_ty. These could
13041202 // be found in any of the derefs of receiver_ty, so we have to go through
13051203 // that, including raw derefs.
13061204 table.run_in_snapshot(|table| {
1307 let mut autoderef =
1308 autoderef::Autoderef::new_no_tracking(table, receiver_ty.to_nextsolver(interner))
1309 .include_raw_pointers()
1310 .use_receiver_trait();
1205 let mut autoderef = autoderef::Autoderef::new_no_tracking(table, receiver_ty)
1206 .include_raw_pointers()
1207 .use_receiver_trait();
13111208 while let Some((self_ty, _)) = autoderef.next() {
13121209 iterate_inherent_methods(
1313 &self_ty.to_chalk(interner),
1210 self_ty,
13141211 autoderef.table,
13151212 name,
1316 Some(&receiver_ty),
1213 Some(receiver_ty),
13171214 Some(receiver_adjustments.clone()),
13181215 visible_from_module,
13191216 LookupMode::MethodCall,
......@@ -1325,23 +1222,21 @@ fn iterate_method_candidates_by_receiver<'db>(
13251222 ControlFlow::Continue(())
13261223 })?;
13271224 table.run_in_snapshot(|table| {
1328 let mut autoderef =
1329 autoderef::Autoderef::new_no_tracking(table, receiver_ty.to_nextsolver(interner))
1330 .include_raw_pointers()
1331 .use_receiver_trait();
1225 let mut autoderef = autoderef::Autoderef::new_no_tracking(table, receiver_ty)
1226 .include_raw_pointers()
1227 .use_receiver_trait();
13321228 while let Some((self_ty, _)) = autoderef.next() {
1333 if matches!(self_ty.kind(), crate::next_solver::TyKind::Infer(rustc_type_ir::TyVar(_)))
1334 {
1229 if matches!(self_ty.kind(), TyKind::Infer(rustc_type_ir::TyVar(_))) {
13351230 // don't try to resolve methods on unknown types
13361231 return ControlFlow::Continue(());
13371232 }
13381233
13391234 iterate_trait_method_candidates(
1340 &self_ty.to_chalk(interner),
1235 self_ty,
13411236 autoderef.table,
13421237 traits_in_scope,
13431238 name,
1344 Some(&receiver_ty),
1239 Some(receiver_ty),
13451240 Some(receiver_adjustments.clone()),
13461241 LookupMode::MethodCall,
13471242 &mut |adjustments, item, is_visible| {
......@@ -1355,7 +1250,7 @@ fn iterate_method_candidates_by_receiver<'db>(
13551250
13561251#[tracing::instrument(skip_all, fields(name = ?name))]
13571252fn iterate_method_candidates_for_self_ty<'db>(
1358 self_ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
1253 self_ty: &Canonical<'db, Ty<'db>>,
13591254 db: &'db dyn HirDatabase,
13601255 env: Arc<TraitEnvironment<'db>>,
13611256 traits_in_scope: &FxHashSet<TraitId>,
......@@ -1364,9 +1259,9 @@ fn iterate_method_candidates_for_self_ty<'db>(
13641259 callback: &mut dyn MethodCandidateCallback,
13651260) -> ControlFlow<()> {
13661261 let mut table = InferenceTable::new(db, env);
1367 let self_ty = table.instantiate_canonical_ns(*self_ty).to_chalk(table.interner);
1262 let self_ty = table.instantiate_canonical(*self_ty);
13681263 iterate_inherent_methods(
1369 &self_ty,
1264 self_ty,
13701265 &mut table,
13711266 name,
13721267 None,
......@@ -1378,7 +1273,7 @@ fn iterate_method_candidates_for_self_ty<'db>(
13781273 },
13791274 )?;
13801275 iterate_trait_method_candidates(
1381 &self_ty,
1276 self_ty,
13821277 &mut table,
13831278 traits_in_scope,
13841279 name,
......@@ -1392,19 +1287,19 @@ fn iterate_method_candidates_for_self_ty<'db>(
13921287}
13931288
13941289#[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]
1395fn iterate_trait_method_candidates(
1396 self_ty: &Ty,
1397 table: &mut InferenceTable<'_>,
1290fn iterate_trait_method_candidates<'db>(
1291 self_ty: Ty<'db>,
1292 table: &mut InferenceTable<'db>,
13981293 traits_in_scope: &FxHashSet<TraitId>,
13991294 name: Option<&Name>,
1400 receiver_ty: Option<&Ty>,
1295 receiver_ty: Option<Ty<'db>>,
14011296 receiver_adjustments: Option<ReceiverAdjustments>,
14021297 mode: LookupMode,
14031298 callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
14041299) -> ControlFlow<()> {
14051300 let db = table.db;
14061301
1407 let canonical_self_ty = table.canonicalize(self_ty.clone().to_nextsolver(table.interner));
1302 let canonical_self_ty = table.canonicalize(self_ty);
14081303 let krate = table.trait_env.krate;
14091304
14101305 'traits: for &t in traits_in_scope {
......@@ -1416,7 +1311,7 @@ fn iterate_trait_method_candidates(
14161311 // This is to make `[a].into_iter()` not break code with the new `IntoIterator` impl for
14171312 // arrays.
14181313 if data.flags.contains(TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH)
1419 && matches!(self_ty.kind(Interner), TyKind::Array(..))
1314 && matches!(self_ty.kind(), TyKind::Array(..))
14201315 {
14211316 // FIXME: this should really be using the edition of the method name's span, in case it
14221317 // comes from a macro
......@@ -1426,9 +1321,9 @@ fn iterate_trait_method_candidates(
14261321 }
14271322 if data.flags.contains(TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH)
14281323 && matches!(
1429 self_ty.kind(Interner), TyKind::Adt(AdtId(def), subst)
1430 if is_box(table.db, *def)
1431 && matches!(subst.at(Interner, 0).assert_ty_ref(Interner).kind(Interner), TyKind::Slice(..))
1324 self_ty.kind(), TyKind::Adt(adt_def, subst)
1325 if is_box(table.db, adt_def.def_id().0)
1326 && matches!(subst.type_at(0).kind(), TyKind::Slice(..))
14321327 )
14331328 {
14341329 // FIXME: this should really be using the edition of the method name's span, in case it
......@@ -1472,11 +1367,11 @@ fn iterate_trait_method_candidates(
14721367}
14731368
14741369#[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]
1475fn iterate_inherent_methods(
1476 self_ty: &Ty,
1477 table: &mut InferenceTable<'_>,
1370fn iterate_inherent_methods<'db>(
1371 self_ty: Ty<'db>,
1372 table: &mut InferenceTable<'db>,
14781373 name: Option<&Name>,
1479 receiver_ty: Option<&Ty>,
1374 receiver_ty: Option<Ty<'db>>,
14801375 receiver_adjustments: Option<ReceiverAdjustments>,
14811376 visible_from_module: VisibleFromModule,
14821377 mode: LookupMode,
......@@ -1489,12 +1384,11 @@ fn iterate_inherent_methods(
14891384 // its super traits are considered inherent methods. This matters because these methods have
14901385 // higher priority than the other traits' methods, which would be considered in
14911386 // `iterate_trait_method_candidates()` only after this function.
1492 match self_ty.kind(Interner) {
1493 TyKind::Placeholder(_) => {
1387 match self_ty.kind() {
1388 TyKind::Param(_) => {
14941389 let env = table.trait_env.clone();
1495 let traits = env
1496 .traits_in_scope_from_clauses(self_ty.clone())
1497 .flat_map(|t| all_super_traits(db, t));
1390 let traits =
1391 env.traits_in_scope_from_clauses(self_ty).flat_map(|t| all_super_traits(db, t));
14981392 iterate_inherent_trait_methods(
14991393 self_ty,
15001394 table,
......@@ -1506,9 +1400,9 @@ fn iterate_inherent_methods(
15061400 mode,
15071401 )?;
15081402 }
1509 TyKind::Dyn(_) => {
1510 if let Some(principal_trait) = self_ty.dyn_trait() {
1511 let traits = all_super_traits(db, principal_trait);
1403 TyKind::Dynamic(bounds, _) => {
1404 if let Some(principal_trait) = bounds.principal_def_id() {
1405 let traits = all_super_traits(db, principal_trait.0);
15121406 iterate_inherent_trait_methods(
15131407 self_ty,
15141408 table,
......@@ -1568,11 +1462,11 @@ fn iterate_inherent_methods(
15681462 return ControlFlow::Continue(());
15691463
15701464 #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]
1571 fn iterate_inherent_trait_methods(
1572 self_ty: &Ty,
1573 table: &mut InferenceTable<'_>,
1465 fn iterate_inherent_trait_methods<'db>(
1466 self_ty: Ty<'db>,
1467 table: &mut InferenceTable<'db>,
15741468 name: Option<&Name>,
1575 receiver_ty: Option<&Ty>,
1469 receiver_ty: Option<Ty<'db>>,
15761470 receiver_adjustments: Option<ReceiverAdjustments>,
15771471 callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
15781472 traits: impl Iterator<Item = TraitId>,
......@@ -1603,12 +1497,12 @@ fn iterate_inherent_methods(
16031497 }
16041498
16051499 #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))]
1606 fn impls_for_self_ty(
1500 fn impls_for_self_ty<'db>(
16071501 impls: &InherentImpls,
1608 self_ty: &Ty,
1609 table: &mut InferenceTable<'_>,
1502 self_ty: Ty<'db>,
1503 table: &mut InferenceTable<'db>,
16101504 name: Option<&Name>,
1611 receiver_ty: Option<&Ty>,
1505 receiver_ty: Option<Ty<'db>>,
16121506 receiver_adjustments: Option<ReceiverAdjustments>,
16131507 visible_from_module: Option<ModuleId>,
16141508 callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
......@@ -1639,10 +1533,10 @@ fn iterate_inherent_methods(
16391533/// Returns the receiver type for the index trait call.
16401534pub(crate) fn resolve_indexing_op<'db>(
16411535 table: &mut InferenceTable<'db>,
1642 ty: next_solver::Canonical<'db, next_solver::Ty<'db>>,
1536 ty: Canonical<'db, Ty<'db>>,
16431537 index_trait: TraitId,
16441538) -> Option<ReceiverAdjustments> {
1645 let ty = table.instantiate_canonical_ns(ty);
1539 let ty = table.instantiate_canonical(ty);
16461540 let deref_chain = autoderef_method_receiver(table, ty);
16471541 for (ty, adj) in deref_chain {
16481542 let goal = generic_implements_goal_ns(table, index_trait, ty);
......@@ -1670,10 +1564,10 @@ enum IsValidCandidate {
16701564}
16711565
16721566#[tracing::instrument(skip_all, fields(name))]
1673fn is_valid_impl_method_candidate(
1674 table: &mut InferenceTable<'_>,
1675 self_ty: &Ty,
1676 receiver_ty: Option<&Ty>,
1567fn is_valid_impl_method_candidate<'db>(
1568 table: &mut InferenceTable<'db>,
1569 self_ty: Ty<'db>,
1570 receiver_ty: Option<Ty<'db>>,
16771571 visible_from_module: Option<ModuleId>,
16781572 name: Option<&Name>,
16791573 impl_id: ImplId,
......@@ -1705,9 +1599,8 @@ fn is_valid_impl_method_candidate(
17051599 let self_ty_matches = table.run_in_snapshot(|table| {
17061600 let expected_self_ty = TyBuilder::impl_self_ty(db, impl_id)
17071601 .fill_with_inference_vars(table)
1708 .build(DbInterner::conjure())
1709 .to_chalk(DbInterner::conjure());
1710 table.unify(&expected_self_ty, self_ty)
1602 .build(table.interner());
1603 table.unify(expected_self_ty, self_ty)
17111604 });
17121605 if !self_ty_matches {
17131606 cov_mark::hit!(const_candidate_self_type_mismatch);
......@@ -1721,13 +1614,13 @@ fn is_valid_impl_method_candidate(
17211614
17221615/// Checks whether a given `AssocItemId` is applicable for `receiver_ty`.
17231616#[tracing::instrument(skip_all, fields(name))]
1724fn is_valid_trait_method_candidate(
1725 table: &mut InferenceTable<'_>,
1617fn is_valid_trait_method_candidate<'db>(
1618 table: &mut InferenceTable<'db>,
17261619 trait_id: TraitId,
17271620 name: Option<&Name>,
1728 receiver_ty: Option<&Ty>,
1621 receiver_ty: Option<Ty<'db>>,
17291622 item: AssocItemId,
1730 self_ty: &Ty,
1623 self_ty: Ty<'db>,
17311624 mode: LookupMode,
17321625) -> IsValidCandidate {
17331626 let db = table.db;
......@@ -1738,27 +1631,20 @@ fn is_valid_trait_method_candidate(
17381631 check_that!(name.is_none_or(|n| n == &data.name));
17391632
17401633 table.run_in_snapshot(|table| {
1741 let impl_subst = TyBuilder::subst_for_def(db, trait_id, None)
1742 .fill_with_inference_vars(table)
1743 .build();
1744 let expect_self_ty = impl_subst.at(Interner, 0).assert_ty_ref(Interner).clone();
1634 let impl_subst = table.fresh_args_for_item(trait_id.into());
1635 let expect_self_ty = impl_subst.type_at(0);
17451636
1746 check_that!(table.unify(&expect_self_ty, self_ty));
1637 check_that!(table.unify(expect_self_ty, self_ty));
17471638
17481639 if let Some(receiver_ty) = receiver_ty {
17491640 check_that!(data.has_self_param());
17501641
1751 let fn_subst = TyBuilder::subst_for_def(db, fn_id, Some(impl_subst))
1752 .fill_with_inference_vars(table)
1753 .build();
1642 let args = table.fill_rest_fresh_args(fn_id.into(), impl_subst);
17541643
1755 let args: crate::next_solver::GenericArgs<'_> =
1756 fn_subst.to_nextsolver(table.interner);
17571644 let sig = db.callable_item_signature(fn_id.into());
17581645 let expected_receiver = sig
17591646 .map_bound(|s| s.skip_binder().inputs_and_output.as_slice()[0])
1760 .instantiate(table.interner, args)
1761 .to_chalk(table.interner);
1647 .instantiate(table.interner(), args);
17621648
17631649 // FIXME: Clean up this mess with some context struct like rustc's `ProbeContext`
17641650 let variance = match mode {
......@@ -1767,16 +1653,8 @@ fn is_valid_trait_method_candidate(
17671653 };
17681654 let res = table
17691655 .infer_ctxt
1770 .at(
1771 &next_solver::infer::traits::ObligationCause::dummy(),
1772 table.trait_env.env,
1773 )
1774 .relate(
1775 DefineOpaqueTypes::No,
1776 expected_receiver.to_nextsolver(table.interner),
1777 variance,
1778 receiver_ty.to_nextsolver(table.interner),
1779 );
1656 .at(&ObligationCause::dummy(), table.trait_env.env)
1657 .relate(DefineOpaqueTypes::No, expected_receiver, variance, receiver_ty);
17801658 let Ok(infer_ok) = res else {
17811659 return IsValidCandidate::No;
17821660 };
......@@ -1788,7 +1666,7 @@ fn is_valid_trait_method_candidate(
17881666 check_that!(ctxt.try_evaluate_obligations().is_empty());
17891667 }
17901668
1791 check_that!(table.unify(receiver_ty, &expected_receiver));
1669 check_that!(table.unify(receiver_ty, expected_receiver));
17921670 }
17931671
17941672 IsValidCandidate::Yes
......@@ -1805,13 +1683,13 @@ fn is_valid_trait_method_candidate(
18051683}
18061684
18071685#[tracing::instrument(skip_all, fields(name))]
1808fn is_valid_impl_fn_candidate(
1809 table: &mut InferenceTable<'_>,
1686fn is_valid_impl_fn_candidate<'db>(
1687 table: &mut InferenceTable<'db>,
18101688 impl_id: ImplId,
18111689 fn_id: FunctionId,
18121690 name: Option<&Name>,
1813 receiver_ty: Option<&Ty>,
1814 self_ty: &Ty,
1691 receiver_ty: Option<Ty<'db>>,
1692 self_ty: Ty<'db>,
18151693 visible_from_module: Option<ModuleId>,
18161694 item_name: &Name,
18171695) -> IsValidCandidate {
......@@ -1829,34 +1707,28 @@ fn is_valid_impl_fn_candidate(
18291707 table.run_in_snapshot(|table| {
18301708 let _p = tracing::info_span!("subst_for_def").entered();
18311709 let impl_subst = table.infer_ctxt.fresh_args_for_item(impl_id.into());
1832 let expect_self_ty = db
1833 .impl_self_ty(impl_id)
1834 .instantiate(table.interner, &impl_subst)
1835 .to_chalk(table.interner);
1710 let expect_self_ty = db.impl_self_ty(impl_id).instantiate(table.interner(), &impl_subst);
18361711
1837 check_that!(table.unify(&expect_self_ty, self_ty));
1712 check_that!(table.unify(expect_self_ty, self_ty));
18381713
18391714 if let Some(receiver_ty) = receiver_ty {
18401715 let _p = tracing::info_span!("check_receiver_ty").entered();
18411716 check_that!(data.has_self_param());
18421717
1843 let fn_subst: crate::Substitution =
1844 table.infer_ctxt.fresh_args_for_item(fn_id.into()).to_chalk(table.interner);
1718 let args = table.infer_ctxt.fresh_args_for_item(fn_id.into());
18451719
1846 let args: crate::next_solver::GenericArgs<'_> = fn_subst.to_nextsolver(table.interner);
18471720 let sig = db.callable_item_signature(fn_id.into());
18481721 let expected_receiver = sig
18491722 .map_bound(|s| s.skip_binder().inputs_and_output.as_slice()[0])
1850 .instantiate(table.interner, args)
1851 .to_chalk(table.interner);
1723 .instantiate(table.interner(), args);
18521724
1853 check_that!(table.unify(receiver_ty, &expected_receiver));
1725 check_that!(table.unify(receiver_ty, expected_receiver));
18541726 }
18551727
18561728 // We need to consider the bounds on the impl to distinguish functions of the same name
18571729 // for a type.
18581730 let predicates = db.generic_predicates_ns(impl_id.into());
1859 let Some(predicates) = predicates.instantiate(table.interner, impl_subst) else {
1731 let Some(predicates) = predicates.instantiate(table.interner(), impl_subst) else {
18601732 return IsValidCandidate::Yes;
18611733 };
18621734
......@@ -1864,7 +1736,7 @@ fn is_valid_impl_fn_candidate(
18641736
18651737 ctxt.register_obligations(predicates.into_iter().map(|p| {
18661738 PredicateObligation::new(
1867 table.interner,
1739 table.interner(),
18681740 ObligationCause::new(),
18691741 table.trait_env.env,
18701742 p.0,
......@@ -1879,73 +1751,29 @@ fn is_valid_impl_fn_candidate(
18791751 })
18801752}
18811753
1882pub fn implements_trait_unique<'db>(
1883 ty: &Canonical<Ty>,
1884 db: &'db dyn HirDatabase,
1885 env: &TraitEnvironment<'db>,
1886 trait_: TraitId,
1887) -> bool {
1888 let goal = generic_implements_goal(db, env, trait_, ty);
1889 db.trait_solve(env.krate, env.block, goal.cast(Interner)).certain()
1890}
1891
1892/// This creates Substs for a trait with the given Self type and type variables
1893/// for all other parameters, to query next solver with it.
1894#[tracing::instrument(skip_all)]
1895fn generic_implements_goal<'db>(
1896 db: &'db dyn HirDatabase,
1897 env: &TraitEnvironment<'db>,
1898 trait_: TraitId,
1899 self_ty: &Canonical<Ty>,
1900) -> Canonical<InEnvironment<super::DomainGoal>> {
1901 let binders = self_ty.binders.interned();
1902 let trait_ref = TyBuilder::trait_ref(db, trait_)
1903 .push(self_ty.value.clone())
1904 .fill_with_bound_vars(DebruijnIndex::INNERMOST, binders.len())
1905 .build();
1906
1907 let kinds =
1908 binders.iter().cloned().chain(trait_ref.substitution.iter(Interner).skip(1).map(|it| {
1909 let vk = match it.data(Interner) {
1910 GenericArgData::Ty(_) => VariableKind::Ty(chalk_ir::TyVariableKind::General),
1911 GenericArgData::Lifetime(_) => VariableKind::Lifetime,
1912 GenericArgData::Const(c) => VariableKind::Const(c.data(Interner).ty.clone()),
1913 };
1914 WithKind::new(vk, UniverseIndex::ROOT)
1915 }));
1916 let binders = CanonicalVarKinds::from_iter(Interner, kinds);
1917
1918 let obligation = trait_ref.cast(Interner);
1919 let value = InEnvironment::new(
1920 &env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)),
1921 obligation,
1922 );
1923 Canonical { binders, value }
1924}
1925
19261754/// This creates Substs for a trait with the given Self type and type variables
19271755/// for all other parameters, to query the trait solver with it.
19281756#[tracing::instrument(skip_all)]
19291757fn generic_implements_goal_ns<'db>(
19301758 table: &mut InferenceTable<'db>,
19311759 trait_: TraitId,
1932 self_ty: next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
1933) -> next_solver::Canonical<'db, next_solver::Goal<'db, crate::next_solver::Predicate<'db>>> {
1760 self_ty: Canonical<'db, Ty<'db>>,
1761) -> Canonical<'db, Goal<'db, Predicate<'db>>> {
19341762 let args = table.infer_ctxt.fresh_args_for_item(SolverDefId::TraitId(trait_));
1935 let self_ty = table.instantiate_canonical_ns(self_ty);
1763 let self_ty = table.instantiate_canonical(self_ty);
19361764 let trait_ref =
19371765 rustc_type_ir::TraitRef::new_from_args(table.infer_ctxt.interner, trait_.into(), args)
19381766 .with_replaced_self_ty(table.infer_ctxt.interner, self_ty);
1939 let goal = next_solver::Goal::new(table.infer_ctxt.interner, table.trait_env.env, trait_ref);
1767 let goal = Goal::new(table.infer_ctxt.interner, table.trait_env.env, trait_ref);
19401768
19411769 table.canonicalize(goal)
19421770}
19431771
19441772fn autoderef_method_receiver<'db>(
19451773 table: &mut InferenceTable<'db>,
1946 ty: next_solver::Ty<'db>,
1947) -> Vec<(next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, ReceiverAdjustments)> {
1948 let interner = table.interner;
1774 ty: Ty<'db>,
1775) -> Vec<(Canonical<'db, Ty<'db>>, ReceiverAdjustments)> {
1776 let interner = table.interner();
19491777 let mut deref_chain = Vec::new();
19501778 let mut autoderef = autoderef::Autoderef::new_no_tracking(table, ty).use_receiver_trait();
19511779 while let Some((ty, derefs)) = autoderef.next() {
......@@ -1958,9 +1786,9 @@ fn autoderef_method_receiver<'db>(
19581786 if let Some((rustc_type_ir::Array(parameters, _), variables, max_universe, adj)) =
19591787 deref_chain.last().map(|d| (d.0.value.kind(), d.0.variables, d.0.max_universe, d.1.clone()))
19601788 {
1961 let unsized_ty = next_solver::Ty::new_slice(interner, parameters);
1789 let unsized_ty = Ty::new_slice(interner, parameters);
19621790 deref_chain.push((
1963 next_solver::Canonical { max_universe, value: unsized_ty, variables },
1791 Canonical { max_universe, value: unsized_ty, variables },
19641792 ReceiverAdjustments { unsize_array: true, ..adj.clone() },
19651793 ));
19661794 }
src/tools/rust-analyzer/crates/hir-ty/src/mir.rs+203-196
......@@ -2,18 +2,7 @@
22
33use std::{collections::hash_map::Entry, fmt::Display, iter};
44
5use crate::{
6 CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap,
7 Substitution, TraitEnvironment, Ty, TyExt, TyKind,
8 consteval::usize_const,
9 db::HirDatabase,
10 display::{DisplayTarget, HirDisplay},
11 infer::{PointerCast, normalize},
12 lang_items::is_box,
13 mapping::ToChalk,
14};
155use base_db::Crate;
16use chalk_ir::Mutability;
176use either::Either;
187use hir_def::{
198 DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId,
......@@ -21,6 +10,25 @@ use hir_def::{
2110 hir::{BindingAnnotation, BindingId, Expr, ExprId, Ordering, PatId},
2211};
2312use la_arena::{Arena, ArenaMap, Idx, RawIdx};
13use rustc_ast_ir::Mutability;
14use rustc_hash::FxHashMap;
15use rustc_type_ir::inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Ty as _};
16use smallvec::{SmallVec, smallvec};
17use stdx::{impl_from, never};
18
19use crate::{
20 CallableDefId, InferenceResult, MemoryMap,
21 consteval::usize_const,
22 db::{HirDatabase, InternedClosureId},
23 display::{DisplayTarget, HirDisplay},
24 infer::PointerCast,
25 lang_items::is_box,
26 next_solver::{
27 Const, DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, Ty, TyKind,
28 infer::{InferCtxt, traits::ObligationCause},
29 obligation_ctxt::ObligationCtxt,
30 },
31};
2432
2533mod borrowck;
2634mod eval;
......@@ -36,25 +44,22 @@ pub use lower::{MirLowerError, lower_to_mir, mir_body_for_closure_query, mir_bod
3644pub use monomorphization::{
3745 monomorphized_mir_body_for_closure_query, monomorphized_mir_body_query,
3846};
39use rustc_hash::FxHashMap;
40use smallvec::{SmallVec, smallvec};
41use stdx::{impl_from, never};
4247
4348pub(crate) use lower::mir_body_cycle_result;
4449pub(crate) use monomorphization::monomorphized_mir_body_cycle_result;
4550
46use super::consteval::{intern_const_scalar, try_const_usize};
51use super::consteval::try_const_usize;
4752
48pub type BasicBlockId = Idx<BasicBlock>;
49pub type LocalId = Idx<Local>;
53pub type BasicBlockId<'db> = Idx<BasicBlock<'db>>;
54pub type LocalId<'db> = Idx<Local<'db>>;
5055
51fn return_slot() -> LocalId {
56fn return_slot<'db>() -> LocalId<'db> {
5257 LocalId::from_raw(RawIdx::from(0))
5358}
5459
5560#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct Local {
57 pub ty: Ty,
61pub struct Local<'db> {
62 pub ty: Ty<'db>,
5863}
5964
6065/// An operand in MIR represents a "value" in Rust, the definition of which is undecided and part of
......@@ -76,19 +81,19 @@ pub struct Local {
7681/// currently implements it, but it seems like this may be something to check against in the
7782/// validator.
7883#[derive(Debug, PartialEq, Eq, Clone)]
79pub struct Operand {
80 kind: OperandKind,
84pub struct Operand<'db> {
85 kind: OperandKind<'db>,
8186 // FIXME : This should actually just be of type `MirSpan`.
8287 span: Option<MirSpan>,
8388}
8489
8590#[derive(Debug, PartialEq, Eq, Clone)]
86pub enum OperandKind {
91pub enum OperandKind<'db> {
8792 /// Creates a value by loading the given place.
8893 ///
8994 /// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there
9095 /// is no such requirement.
91 Copy(Place),
96 Copy(Place<'db>),
9297
9398 /// Creates a value by performing loading the place, just like the `Copy` operand.
9499 ///
......@@ -97,41 +102,41 @@ pub enum OperandKind {
97102 /// place without first re-initializing it.
98103 ///
99104 /// [UCG#188]: https://github.com/rust-lang/unsafe-code-guidelines/issues/188
100 Move(Place),
105 Move(Place<'db>),
101106 /// Constants are already semantically values, and remain unchanged.
102 Constant(Const),
107 Constant { konst: Const<'db>, ty: Ty<'db> },
103108 /// NON STANDARD: This kind of operand returns an immutable reference to that static memory. Rustc
104109 /// handles it with the `Constant` variant somehow.
105110 Static(StaticId),
106111}
107112
108impl Operand {
109 fn from_concrete_const(data: Box<[u8]>, memory_map: MemoryMap<'static>, ty: Ty) -> Self {
113impl<'db> Operand<'db> {
114 fn from_concrete_const(data: Box<[u8]>, memory_map: MemoryMap<'db>, ty: Ty<'db>) -> Self {
115 let interner = DbInterner::conjure();
110116 Operand {
111 kind: OperandKind::Constant(intern_const_scalar(
112 ConstScalar::Bytes(data, memory_map),
117 kind: OperandKind::Constant {
118 konst: Const::new_valtree(interner, ty, data, memory_map),
113119 ty,
114 )),
120 },
115121 span: None,
116122 }
117123 }
118124
119 fn from_bytes(data: Box<[u8]>, ty: Ty) -> Self {
125 fn from_bytes(data: Box<[u8]>, ty: Ty<'db>) -> Self {
120126 Operand::from_concrete_const(data, MemoryMap::default(), ty)
121127 }
122128
123 fn const_zst(ty: Ty) -> Operand {
129 fn const_zst(ty: Ty<'db>) -> Operand<'db> {
124130 Self::from_bytes(Box::default(), ty)
125131 }
126132
127133 fn from_fn(
128 db: &dyn HirDatabase,
134 db: &'db dyn HirDatabase,
129135 func_id: hir_def::FunctionId,
130 generic_args: Substitution,
131 ) -> Operand {
132 let ty =
133 chalk_ir::TyKind::FnDef(CallableDefId::FunctionId(func_id).to_chalk(db), generic_args)
134 .intern(Interner);
136 generic_args: GenericArgs<'db>,
137 ) -> Operand<'db> {
138 let interner = DbInterner::new_with(db, None, None);
139 let ty = Ty::new_fn_def(interner, CallableDefId::FunctionId(func_id).into(), generic_args);
135140 Operand::from_bytes(Box::default(), ty)
136141 }
137142}
......@@ -150,83 +155,81 @@ pub enum ProjectionElem<V, T> {
150155}
151156
152157impl<V, T> ProjectionElem<V, T> {
153 pub fn projected_ty(
158 pub fn projected_ty<'db>(
154159 &self,
155 mut base: Ty,
156 db: &dyn HirDatabase,
157 closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty,
160 infcx: &InferCtxt<'db>,
161 mut base: Ty<'db>,
162 closure_field: impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db>,
158163 krate: Crate,
159 ) -> Ty {
164 ) -> Ty<'db> {
165 let interner = infcx.interner;
166 let db = interner.db;
167
160168 // we only bail on mir building when there are type mismatches
161169 // but error types may pop up resulting in us still attempting to build the mir
162170 // so just propagate the error type
163 if base.is_unknown() {
164 return TyKind::Error.intern(Interner);
171 if base.is_ty_error() {
172 return Ty::new_error(interner, ErrorGuaranteed);
165173 }
166174
167 if matches!(base.kind(Interner), TyKind::Alias(_) | TyKind::AssociatedType(..)) {
168 base = normalize(
169 db,
170 // FIXME: we should get this from caller
171 TraitEnvironment::empty(krate),
172 base,
173 );
175 if matches!(base.kind(), TyKind::Alias(..)) {
176 let mut ocx = ObligationCtxt::new(infcx);
177 // FIXME: we should get this from caller
178 let env = ParamEnv::empty();
179 match ocx.structurally_normalize_ty(&ObligationCause::dummy(), env, base) {
180 Ok(it) => base = it,
181 Err(_) => return Ty::new_error(interner, ErrorGuaranteed),
182 }
174183 }
184
175185 match self {
176 ProjectionElem::Deref => match &base.kind(Interner) {
177 TyKind::Raw(_, inner) | TyKind::Ref(_, _, inner) => inner.clone(),
178 TyKind::Adt(adt, subst) if is_box(db, adt.0) => {
179 subst.at(Interner, 0).assert_ty_ref(Interner).clone()
180 }
186 ProjectionElem::Deref => match base.kind() {
187 TyKind::RawPtr(inner, _) | TyKind::Ref(_, inner, _) => inner,
188 TyKind::Adt(adt_def, subst) if is_box(db, adt_def.def_id().0) => subst.type_at(0),
181189 _ => {
182190 never!(
183191 "Overloaded deref on type {} is not a projection",
184192 base.display(db, DisplayTarget::from_crate(db, krate))
185193 );
186 TyKind::Error.intern(Interner)
194 Ty::new_error(interner, ErrorGuaranteed)
187195 }
188196 },
189 ProjectionElem::Field(Either::Left(f)) => match base.kind(Interner) {
197 ProjectionElem::Field(Either::Left(f)) => match base.kind() {
190198 TyKind::Adt(_, subst) => {
191 db.field_types(f.parent)[f.local_id].clone().substitute(Interner, subst)
199 db.field_types_ns(f.parent)[f.local_id].instantiate(interner, subst)
192200 }
193201 ty => {
194202 never!("Only adt has field, found {:?}", ty);
195 TyKind::Error.intern(Interner)
203 Ty::new_error(interner, ErrorGuaranteed)
196204 }
197205 },
198 ProjectionElem::Field(Either::Right(f)) => match &base.kind(Interner) {
199 TyKind::Tuple(_, subst) => subst
200 .as_slice(Interner)
201 .get(f.index as usize)
202 .map(|x| x.assert_ty_ref(Interner))
203 .cloned()
204 .unwrap_or_else(|| {
206 ProjectionElem::Field(Either::Right(f)) => match base.kind() {
207 TyKind::Tuple(subst) => {
208 subst.as_slice().get(f.index as usize).copied().unwrap_or_else(|| {
205209 never!("Out of bound tuple field");
206 TyKind::Error.intern(Interner)
207 }),
210 Ty::new_error(interner, ErrorGuaranteed)
211 })
212 }
208213 ty => {
209214 never!("Only tuple has tuple field: {:?}", ty);
210 TyKind::Error.intern(Interner)
215 Ty::new_error(interner, ErrorGuaranteed)
211216 }
212217 },
213 ProjectionElem::ClosureField(f) => match &base.kind(Interner) {
214 TyKind::Closure(id, subst) => closure_field(*id, subst, *f),
218 ProjectionElem::ClosureField(f) => match base.kind() {
219 TyKind::Closure(id, subst) => closure_field(id.0, subst, *f),
215220 _ => {
216221 never!("Only closure has closure field");
217 TyKind::Error.intern(Interner)
222 Ty::new_error(interner, ErrorGuaranteed)
218223 }
219224 },
220 ProjectionElem::ConstantIndex { .. } | ProjectionElem::Index(_) => {
221 match &base.kind(Interner) {
222 TyKind::Array(inner, _) | TyKind::Slice(inner) => inner.clone(),
223 _ => {
224 never!("Overloaded index is not a projection");
225 TyKind::Error.intern(Interner)
226 }
225 ProjectionElem::ConstantIndex { .. } | ProjectionElem::Index(_) => match base.kind() {
226 TyKind::Array(inner, _) | TyKind::Slice(inner) => inner,
227 _ => {
228 never!("Overloaded index is not a projection");
229 Ty::new_error(interner, ErrorGuaranteed)
227230 }
228 }
229 &ProjectionElem::Subslice { from, to } => match &base.kind(Interner) {
231 },
232 &ProjectionElem::Subslice { from, to } => match base.kind() {
230233 TyKind::Array(inner, c) => {
231234 let next_c = usize_const(
232235 db,
......@@ -236,34 +239,34 @@ impl<V, T> ProjectionElem<V, T> {
236239 },
237240 krate,
238241 );
239 TyKind::Array(inner.clone(), next_c).intern(Interner)
242 Ty::new_array_with_const_len(interner, inner, next_c)
240243 }
241 TyKind::Slice(_) => base.clone(),
244 TyKind::Slice(_) => base,
242245 _ => {
243246 never!("Subslice projection should only happen on slice and array");
244 TyKind::Error.intern(Interner)
247 Ty::new_error(interner, ErrorGuaranteed)
245248 }
246249 },
247250 ProjectionElem::OpaqueCast(_) => {
248251 never!("We don't emit these yet");
249 TyKind::Error.intern(Interner)
252 Ty::new_error(interner, ErrorGuaranteed)
250253 }
251254 }
252255 }
253256}
254257
255type PlaceElem = ProjectionElem<LocalId, Ty>;
258type PlaceElem<'db> = ProjectionElem<LocalId<'db>, Ty<'db>>;
256259
257260#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
258261pub struct ProjectionId(u32);
259262
260263#[derive(Debug, Clone, PartialEq, Eq)]
261pub struct ProjectionStore {
262 id_to_proj: FxHashMap<ProjectionId, Box<[PlaceElem]>>,
263 proj_to_id: FxHashMap<Box<[PlaceElem]>, ProjectionId>,
264pub struct ProjectionStore<'db> {
265 id_to_proj: FxHashMap<ProjectionId, Box<[PlaceElem<'db>]>>,
266 proj_to_id: FxHashMap<Box<[PlaceElem<'db>]>, ProjectionId>,
264267}
265268
266impl Default for ProjectionStore {
269impl Default for ProjectionStore<'_> {
267270 fn default() -> Self {
268271 let mut this = Self { id_to_proj: Default::default(), proj_to_id: Default::default() };
269272 // Ensure that [] will get the id 0 which is used in `ProjectionId::Empty`
......@@ -272,17 +275,17 @@ impl Default for ProjectionStore {
272275 }
273276}
274277
275impl ProjectionStore {
278impl<'db> ProjectionStore<'db> {
276279 pub fn shrink_to_fit(&mut self) {
277280 self.id_to_proj.shrink_to_fit();
278281 self.proj_to_id.shrink_to_fit();
279282 }
280283
281 pub fn intern_if_exist(&self, projection: &[PlaceElem]) -> Option<ProjectionId> {
284 pub fn intern_if_exist(&self, projection: &[PlaceElem<'db>]) -> Option<ProjectionId> {
282285 self.proj_to_id.get(projection).copied()
283286 }
284287
285 pub fn intern(&mut self, projection: Box<[PlaceElem]>) -> ProjectionId {
288 pub fn intern(&mut self, projection: Box<[PlaceElem<'db>]>) -> ProjectionId {
286289 let new_id = ProjectionId(self.proj_to_id.len() as u32);
287290 match self.proj_to_id.entry(projection) {
288291 Entry::Occupied(id) => *id.get(),
......@@ -303,11 +306,15 @@ impl ProjectionId {
303306 self == ProjectionId::EMPTY
304307 }
305308
306 pub fn lookup(self, store: &ProjectionStore) -> &[PlaceElem] {
309 pub fn lookup<'a, 'db>(self, store: &'a ProjectionStore<'db>) -> &'a [PlaceElem<'db>] {
307310 store.id_to_proj.get(&self).unwrap()
308311 }
309312
310 pub fn project(self, projection: PlaceElem, store: &mut ProjectionStore) -> ProjectionId {
313 pub fn project<'db>(
314 self,
315 projection: PlaceElem<'db>,
316 store: &mut ProjectionStore<'db>,
317 ) -> ProjectionId {
311318 let mut current = self.lookup(store).to_vec();
312319 current.push(projection);
313320 store.intern(current.into())
......@@ -315,13 +322,13 @@ impl ProjectionId {
315322}
316323
317324#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
318pub struct Place {
319 pub local: LocalId,
325pub struct Place<'db> {
326 pub local: LocalId<'db>,
320327 pub projection: ProjectionId,
321328}
322329
323impl Place {
324 fn is_parent(&self, child: &Place, store: &ProjectionStore) -> bool {
330impl<'db> Place<'db> {
331 fn is_parent(&self, child: &Place<'db>, store: &ProjectionStore<'db>) -> bool {
325332 self.local == child.local
326333 && child.projection.lookup(store).starts_with(self.projection.lookup(store))
327334 }
......@@ -329,39 +336,39 @@ impl Place {
329336 /// The place itself is not included
330337 fn iterate_over_parents<'a>(
331338 &'a self,
332 store: &'a ProjectionStore,
333 ) -> impl Iterator<Item = Place> + 'a {
339 store: &'a ProjectionStore<'db>,
340 ) -> impl Iterator<Item = Place<'db>> + 'a {
334341 let projection = self.projection.lookup(store);
335342 (0..projection.len()).map(|x| &projection[0..x]).filter_map(move |x| {
336343 Some(Place { local: self.local, projection: store.intern_if_exist(x)? })
337344 })
338345 }
339346
340 fn project(&self, projection: PlaceElem, store: &mut ProjectionStore) -> Place {
347 fn project(&self, projection: PlaceElem<'db>, store: &mut ProjectionStore<'db>) -> Place<'db> {
341348 Place { local: self.local, projection: self.projection.project(projection, store) }
342349 }
343350}
344351
345impl From<LocalId> for Place {
346 fn from(local: LocalId) -> Self {
352impl<'db> From<LocalId<'db>> for Place<'db> {
353 fn from(local: LocalId<'db>) -> Self {
347354 Self { local, projection: ProjectionId::EMPTY }
348355 }
349356}
350357
351358#[derive(Debug, PartialEq, Eq, Clone)]
352pub enum AggregateKind {
359pub enum AggregateKind<'db> {
353360 /// The type is of the element
354 Array(Ty),
361 Array(Ty<'db>),
355362 /// The type is of the tuple
356 Tuple(Ty),
357 Adt(VariantId, Substitution),
363 Tuple(Ty<'db>),
364 Adt(VariantId, GenericArgs<'db>),
358365 Union(UnionId, FieldId),
359 Closure(Ty),
366 Closure(Ty<'db>),
360367 //Coroutine(LocalDefId, SubstsRef, Movability),
361368}
362369
363370#[derive(Debug, Clone, Hash, PartialEq, Eq)]
364pub struct SwitchTargets {
371pub struct SwitchTargets<'db> {
365372 /// Possible values. The locations to branch to in each case
366373 /// are found in the corresponding indices from the `targets` vector.
367374 values: SmallVec<[u128; 1]>,
......@@ -378,17 +385,17 @@ pub struct SwitchTargets {
378385 //
379386 // However we’ve decided to keep this as-is until we figure a case
380387 // where some other approach seems to be strictly better than other.
381 targets: SmallVec<[BasicBlockId; 2]>,
388 targets: SmallVec<[BasicBlockId<'db>; 2]>,
382389}
383390
384impl SwitchTargets {
391impl<'db> SwitchTargets<'db> {
385392 /// Creates switch targets from an iterator of values and target blocks.
386393 ///
387394 /// The iterator may be empty, in which case the `SwitchInt` instruction is equivalent to
388395 /// `goto otherwise;`.
389396 pub fn new(
390 targets: impl Iterator<Item = (u128, BasicBlockId)>,
391 otherwise: BasicBlockId,
397 targets: impl Iterator<Item = (u128, BasicBlockId<'db>)>,
398 otherwise: BasicBlockId<'db>,
392399 ) -> Self {
393400 let (values, mut targets): (SmallVec<_>, SmallVec<_>) = targets.unzip();
394401 targets.push(otherwise);
......@@ -397,12 +404,12 @@ impl SwitchTargets {
397404
398405 /// Builds a switch targets definition that jumps to `then` if the tested value equals `value`,
399406 /// and to `else_` if not.
400 pub fn static_if(value: u128, then: BasicBlockId, else_: BasicBlockId) -> Self {
407 pub fn static_if(value: u128, then: BasicBlockId<'db>, else_: BasicBlockId<'db>) -> Self {
401408 Self { values: smallvec![value], targets: smallvec![then, else_] }
402409 }
403410
404411 /// Returns the fallback target that is jumped to when none of the values match the operand.
405 pub fn otherwise(&self) -> BasicBlockId {
412 pub fn otherwise(&self) -> BasicBlockId<'db> {
406413 *self.targets.last().unwrap()
407414 }
408415
......@@ -412,33 +419,33 @@ impl SwitchTargets {
412419 /// including the `otherwise` fallback target.
413420 ///
414421 /// Note that this may yield 0 elements. Only the `otherwise` branch is mandatory.
415 pub fn iter(&self) -> impl Iterator<Item = (u128, BasicBlockId)> + '_ {
422 pub fn iter(&self) -> impl Iterator<Item = (u128, BasicBlockId<'db>)> + '_ {
416423 iter::zip(&self.values, &self.targets).map(|(x, y)| (*x, *y))
417424 }
418425
419426 /// Returns a slice with all possible jump targets (including the fallback target).
420 pub fn all_targets(&self) -> &[BasicBlockId] {
427 pub fn all_targets(&self) -> &[BasicBlockId<'db>] {
421428 &self.targets
422429 }
423430
424431 /// Finds the `BasicBlock` to which this `SwitchInt` will branch given the
425432 /// specific value. This cannot fail, as it'll return the `otherwise`
426433 /// branch if there's not a specific match for the value.
427 pub fn target_for_value(&self, value: u128) -> BasicBlockId {
434 pub fn target_for_value(&self, value: u128) -> BasicBlockId<'db> {
428435 self.iter().find_map(|(v, t)| (v == value).then_some(t)).unwrap_or_else(|| self.otherwise())
429436 }
430437}
431438
432439#[derive(Debug, PartialEq, Eq, Clone)]
433pub struct Terminator {
440pub struct Terminator<'db> {
434441 pub span: MirSpan,
435 pub kind: TerminatorKind,
442 pub kind: TerminatorKind<'db>,
436443}
437444
438445#[derive(Debug, PartialEq, Eq, Clone)]
439pub enum TerminatorKind {
446pub enum TerminatorKind<'db> {
440447 /// Block has one successor; we continue execution there.
441 Goto { target: BasicBlockId },
448 Goto { target: BasicBlockId<'db> },
442449
443450 /// Switches based on the computed value.
444451 ///
......@@ -450,9 +457,9 @@ pub enum TerminatorKind {
450457 /// Target values may not appear more than once.
451458 SwitchInt {
452459 /// The discriminant value being tested.
453 discr: Operand,
460 discr: Operand<'db>,
454461
455 targets: SwitchTargets,
462 targets: SwitchTargets<'db>,
456463 },
457464
458465 /// Indicates that the landing pad is finished and that the process should continue unwinding.
......@@ -503,7 +510,7 @@ pub enum TerminatorKind {
503510 /// > The drop glue is executed if, among all statements executed within this `Body`, an assignment to
504511 /// > the place or one of its "parents" occurred more recently than a move out of it. This does not
505512 /// > consider indirect assignments.
506 Drop { place: Place, target: BasicBlockId, unwind: Option<BasicBlockId> },
513 Drop { place: Place<'db>, target: BasicBlockId<'db>, unwind: Option<BasicBlockId<'db>> },
507514
508515 /// Drops the place and assigns a new value to it.
509516 ///
......@@ -536,10 +543,10 @@ pub enum TerminatorKind {
536543 ///
537544 /// Disallowed after drop elaboration.
538545 DropAndReplace {
539 place: Place,
540 value: Operand,
541 target: BasicBlockId,
542 unwind: Option<BasicBlockId>,
546 place: Place<'db>,
547 value: Operand<'db>,
548 target: BasicBlockId<'db>,
549 unwind: Option<BasicBlockId<'db>>,
543550 },
544551
545552 /// Roughly speaking, evaluates the `func` operand and the arguments, and starts execution of
......@@ -554,18 +561,18 @@ pub enum TerminatorKind {
554561 /// [#71117]: https://github.com/rust-lang/rust/issues/71117
555562 Call {
556563 /// The function that’s being called.
557 func: Operand,
564 func: Operand<'db>,
558565 /// Arguments the function is called with.
559566 /// These are owned by the callee, which is free to modify them.
560567 /// This allows the memory occupied by "by-value" arguments to be
561568 /// reused across function calls without duplicating the contents.
562 args: Box<[Operand]>,
569 args: Box<[Operand<'db>]>,
563570 /// Where the returned value will be written
564 destination: Place,
571 destination: Place<'db>,
565572 /// Where to go after this call returns. If none, the call necessarily diverges.
566 target: Option<BasicBlockId>,
573 target: Option<BasicBlockId<'db>>,
567574 /// Cleanups to be done if the call unwinds.
568 cleanup: Option<BasicBlockId>,
575 cleanup: Option<BasicBlockId<'db>>,
569576 /// `true` if this is from a call in HIR rather than from an overloaded
570577 /// operator. True for overloaded function call.
571578 from_hir_call: bool,
......@@ -581,11 +588,11 @@ pub enum TerminatorKind {
581588 /// necessarily executed even in the case of a panic, for example in `-C panic=abort`. If the
582589 /// assertion does not fail, execution continues at the specified basic block.
583590 Assert {
584 cond: Operand,
591 cond: Operand<'db>,
585592 expected: bool,
586593 //msg: AssertMessage,
587 target: BasicBlockId,
588 cleanup: Option<BasicBlockId>,
594 target: BasicBlockId<'db>,
595 cleanup: Option<BasicBlockId<'db>>,
589596 },
590597
591598 /// Marks a suspend point.
......@@ -602,13 +609,13 @@ pub enum TerminatorKind {
602609 /// **Needs clarification**: What about the evaluation order of the `resume_arg` and `value`?
603610 Yield {
604611 /// The value to return.
605 value: Operand,
612 value: Operand<'db>,
606613 /// Where to resume to.
607 resume: BasicBlockId,
614 resume: BasicBlockId<'db>,
608615 /// The place to store the resume argument in.
609 resume_arg: Place,
616 resume_arg: Place<'db>,
610617 /// Cleanup to be done if the coroutine is dropped at this suspend point.
611 drop: Option<BasicBlockId>,
618 drop: Option<BasicBlockId<'db>>,
612619 },
613620
614621 /// Indicates the end of dropping a coroutine.
......@@ -631,10 +638,10 @@ pub enum TerminatorKind {
631638 /// Disallowed after drop elaboration.
632639 FalseEdge {
633640 /// The target normal control flow will take.
634 real_target: BasicBlockId,
641 real_target: BasicBlockId<'db>,
635642 /// A block control flow could conceptually jump to, but won't in
636643 /// practice.
637 imaginary_target: BasicBlockId,
644 imaginary_target: BasicBlockId<'db>,
638645 },
639646
640647 /// A terminator for blocks that only take one path in reality, but where we reserve the right
......@@ -646,14 +653,14 @@ pub enum TerminatorKind {
646653 /// Disallowed after drop elaboration.
647654 FalseUnwind {
648655 /// The target normal control flow will take.
649 real_target: BasicBlockId,
656 real_target: BasicBlockId<'db>,
650657 /// The imaginary cleanup block link. This particular path will never be taken
651658 /// in practice, but in order to avoid fragility we want to always
652659 /// consider it in borrowck. We don't want to accept programs which
653660 /// pass borrowck only when `panic=abort` or some assertions are disabled
654661 /// due to release vs. debug mode builds. This needs to be an `Option` because
655662 /// of the `remove_noop_landing_pads` and `abort_unwinding_calls` passes.
656 unwind: Option<BasicBlockId>,
663 unwind: Option<BasicBlockId<'db>>,
657664 },
658665}
659666
......@@ -708,10 +715,10 @@ impl BorrowKind {
708715 }
709716 }
710717
711 fn from_chalk(m: Mutability) -> Self {
718 fn from_rustc(m: rustc_ast_ir::Mutability) -> Self {
712719 match m {
713 Mutability::Not => BorrowKind::Shared,
714 Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
720 rustc_ast_ir::Mutability::Not => BorrowKind::Shared,
721 rustc_ast_ir::Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
715722 }
716723 }
717724}
......@@ -840,8 +847,8 @@ impl From<hir_def::hir::CmpOp> for BinOp {
840847 }
841848}
842849
843impl From<Operand> for Rvalue {
844 fn from(x: Operand) -> Self {
850impl<'db> From<Operand<'db>> for Rvalue<'db> {
851 fn from(x: Operand<'db>) -> Self {
845852 Self::Use(x)
846853 }
847854}
......@@ -870,14 +877,14 @@ pub enum CastKind {
870877}
871878
872879#[derive(Debug, PartialEq, Eq, Clone)]
873pub enum Rvalue {
880pub enum Rvalue<'db> {
874881 /// Yields the operand unchanged
875 Use(Operand),
882 Use(Operand<'db>),
876883
877884 /// Creates an array where each element is the value of the operand.
878885 ///
879886 /// Corresponds to source code like `[x; 32]`.
880 Repeat(Operand, Const),
887 Repeat(Operand<'db>, Const<'db>),
881888
882889 /// Creates a reference of the indicated kind to the place.
883890 ///
......@@ -886,7 +893,7 @@ pub enum Rvalue {
886893 /// exactly what the behavior of this operation should be.
887894 ///
888895 /// `Shallow` borrows are disallowed after drop lowering.
889 Ref(BorrowKind, Place),
896 Ref(BorrowKind, Place<'db>),
890897
891898 /// Creates a pointer/reference to the given thread local.
892899 ///
......@@ -917,7 +924,7 @@ pub enum Rvalue {
917924 /// If the type of the place is an array, this is the array length. For slices (`[T]`, not
918925 /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
919926 /// ill-formed for places of other types.
920 Len(Place),
927 Len(Place<'db>),
921928
922929 /// Performs essentially all of the casts that can be performed via `as`.
923930 ///
......@@ -925,7 +932,7 @@ pub enum Rvalue {
925932 ///
926933 /// **FIXME**: Document exactly which `CastKind`s allow which types of casts. Figure out why
927934 /// `ArrayToPointer` and `MutToConstPointer` are special.
928 Cast(CastKind, Operand, Ty),
935 Cast(CastKind, Operand<'db>, Ty<'db>),
929936
930937 // FIXME link to `pointer::offset` when it hits stable.
931938 /// * `Offset` has the same semantics as `pointer::offset`, except that the second
......@@ -957,7 +964,7 @@ pub enum Rvalue {
957964 /// when the value of right-hand side is negative.
958965 ///
959966 /// Other combinations of types and operators are unsupported.
960 CheckedBinaryOp(BinOp, Operand, Operand),
967 CheckedBinaryOp(BinOp, Operand<'db>, Operand<'db>),
961968
962969 /// Computes a value as described by the operation.
963970 //NullaryOp(NullOp, Ty),
......@@ -968,7 +975,7 @@ pub enum Rvalue {
968975 /// Also does two's-complement arithmetic. Negation requires a signed integer or a float;
969976 /// bitwise not requires a signed integer, unsigned integer, or bool. Both operation kinds
970977 /// return a value with the same type as their operand.
971 UnaryOp(UnOp, Operand),
978 UnaryOp(UnOp, Operand<'db>),
972979
973980 /// Computes the discriminant of the place, returning it as an integer of type
974981 /// [`discriminant_ty`]. Returns zero for types without discriminant.
......@@ -980,7 +987,7 @@ pub enum Rvalue {
980987 /// [`discriminant_ty`]: crate::ty::Ty::discriminant_ty
981988 /// [#91095]: https://github.com/rust-lang/rust/issues/91095
982989 /// [`discriminant_for_variant`]: crate::ty::Ty::discriminant_for_variant
983 Discriminant(Place),
990 Discriminant(Place<'db>),
984991
985992 /// Creates an aggregate value, like a tuple or struct.
986993 ///
......@@ -990,17 +997,17 @@ pub enum Rvalue {
990997 ///
991998 /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Coroutine`. After
992999 /// coroutine lowering, `Coroutine` aggregate kinds are disallowed too.
993 Aggregate(AggregateKind, Box<[Operand]>),
1000 Aggregate(AggregateKind<'db>, Box<[Operand<'db>]>),
9941001
9951002 /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
9961003 ///
9971004 /// This is different from a normal transmute because dataflow analysis will treat the box as
9981005 /// initialized but its content as uninitialized. Like other pointer casts, this in general
9991006 /// affects alias analysis.
1000 ShallowInitBox(Operand, Ty),
1007 ShallowInitBox(Operand<'db>, Ty<'db>),
10011008
10021009 /// NON STANDARD: allocates memory with the type's layout, and shallow init the box with the resulting pointer.
1003 ShallowInitBoxWithAlloc(Ty),
1010 ShallowInitBoxWithAlloc(Ty<'db>),
10041011
10051012 /// A CopyForDeref is equivalent to a read from a place at the
10061013 /// codegen level, but is treated specially by drop elaboration. When such a read happens, it
......@@ -1010,41 +1017,41 @@ pub enum Rvalue {
10101017 /// read never happened and just projects further. This allows simplifying various MIR
10111018 /// optimizations and codegen backends that previously had to handle deref operations anywhere
10121019 /// in a place.
1013 CopyForDeref(Place),
1020 CopyForDeref(Place<'db>),
10141021}
10151022
10161023#[derive(Debug, PartialEq, Eq, Clone)]
1017pub enum StatementKind {
1018 Assign(Place, Rvalue),
1019 FakeRead(Place),
1024pub enum StatementKind<'db> {
1025 Assign(Place<'db>, Rvalue<'db>),
1026 FakeRead(Place<'db>),
10201027 //SetDiscriminant {
10211028 // place: Box<Place>,
10221029 // variant_index: VariantIdx,
10231030 //},
1024 Deinit(Place),
1025 StorageLive(LocalId),
1026 StorageDead(LocalId),
1031 Deinit(Place<'db>),
1032 StorageLive(LocalId<'db>),
1033 StorageDead(LocalId<'db>),
10271034 //Retag(RetagKind, Box<Place>),
10281035 //AscribeUserType(Place, UserTypeProjection, Variance),
10291036 //Intrinsic(Box<NonDivergingIntrinsic>),
10301037 Nop,
10311038}
1032impl StatementKind {
1033 fn with_span(self, span: MirSpan) -> Statement {
1039impl<'db> StatementKind<'db> {
1040 fn with_span(self, span: MirSpan) -> Statement<'db> {
10341041 Statement { kind: self, span }
10351042 }
10361043}
10371044
10381045#[derive(Debug, PartialEq, Eq, Clone)]
1039pub struct Statement {
1040 pub kind: StatementKind,
1046pub struct Statement<'db> {
1047 pub kind: StatementKind<'db>,
10411048 pub span: MirSpan,
10421049}
10431050
10441051#[derive(Debug, Default, Clone, PartialEq, Eq)]
1045pub struct BasicBlock {
1052pub struct BasicBlock<'db> {
10461053 /// List of statements in this block.
1047 pub statements: Vec<Statement>,
1054 pub statements: Vec<Statement<'db>>,
10481055
10491056 /// Terminator for this block.
10501057 ///
......@@ -1054,7 +1061,7 @@ pub struct BasicBlock {
10541061 /// exception is that certain passes, such as `simplify_cfg`, swap
10551062 /// out the terminator temporarily with `None` while they continue
10561063 /// to recurse over the set of basic blocks.
1057 pub terminator: Option<Terminator>,
1064 pub terminator: Option<Terminator<'db>>,
10581065
10591066 /// If true, this block lies on an unwind path. This is used
10601067 /// during codegen where distinct kinds of basic blocks may be
......@@ -1064,35 +1071,35 @@ pub struct BasicBlock {
10641071}
10651072
10661073#[derive(Debug, Clone, PartialEq, Eq)]
1067pub struct MirBody {
1068 pub projection_store: ProjectionStore,
1069 pub basic_blocks: Arena<BasicBlock>,
1070 pub locals: Arena<Local>,
1071 pub start_block: BasicBlockId,
1074pub struct MirBody<'db> {
1075 pub projection_store: ProjectionStore<'db>,
1076 pub basic_blocks: Arena<BasicBlock<'db>>,
1077 pub locals: Arena<Local<'db>>,
1078 pub start_block: BasicBlockId<'db>,
10721079 pub owner: DefWithBodyId,
1073 pub binding_locals: ArenaMap<BindingId, LocalId>,
1074 pub param_locals: Vec<LocalId>,
1080 pub binding_locals: ArenaMap<BindingId, LocalId<'db>>,
1081 pub param_locals: Vec<LocalId<'db>>,
10751082 /// This field stores the closures directly owned by this body. It is used
10761083 /// in traversing every mir body.
1077 pub closures: Vec<ClosureId>,
1084 pub closures: Vec<InternedClosureId>,
10781085}
10791086
1080impl MirBody {
1081 pub fn local_to_binding_map(&self) -> ArenaMap<LocalId, BindingId> {
1087impl<'db> MirBody<'db> {
1088 pub fn local_to_binding_map(&self) -> ArenaMap<LocalId<'db>, BindingId> {
10821089 self.binding_locals.iter().map(|(it, y)| (*y, it)).collect()
10831090 }
10841091
1085 fn walk_places(&mut self, mut f: impl FnMut(&mut Place, &mut ProjectionStore)) {
1086 fn for_operand(
1087 op: &mut Operand,
1088 f: &mut impl FnMut(&mut Place, &mut ProjectionStore),
1089 store: &mut ProjectionStore,
1092 fn walk_places(&mut self, mut f: impl FnMut(&mut Place<'db>, &mut ProjectionStore<'db>)) {
1093 fn for_operand<'db>(
1094 op: &mut Operand<'db>,
1095 f: &mut impl FnMut(&mut Place<'db>, &mut ProjectionStore<'db>),
1096 store: &mut ProjectionStore<'db>,
10901097 ) {
10911098 match &mut op.kind {
10921099 OperandKind::Copy(p) | OperandKind::Move(p) => {
10931100 f(p, store);
10941101 }
1095 OperandKind::Constant(_) | OperandKind::Static(_) => (),
1102 OperandKind::Constant { .. } | OperandKind::Static(_) => (),
10961103 }
10971104 }
10981105 for (_, block) in self.basic_blocks.iter_mut() {
src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs+118-86
......@@ -12,11 +12,14 @@ use stdx::never;
1212use triomphe::Arc;
1313
1414use crate::{
15 ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags,
16 db::{HirDatabase, InternedClosure},
15 TraitEnvironment,
16 db::{HirDatabase, InternedClosure, InternedClosureId},
1717 display::DisplayTarget,
1818 mir::OperandKind,
19 utils::ClosureSubst,
19 next_solver::{
20 DbInterner, GenericArgs, SolverDefIds, Ty, TypingMode,
21 infer::{DbInternerInferExt, InferCtxt},
22 },
2023};
2124
2225use super::{
......@@ -33,45 +36,45 @@ pub enum MutabilityReason {
3336}
3437
3538#[derive(Debug, Clone, PartialEq, Eq)]
36pub struct MovedOutOfRef {
37 pub ty: Ty,
39pub struct MovedOutOfRef<'db> {
40 pub ty: Ty<'db>,
3841 pub span: MirSpan,
3942}
4043
4144#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct PartiallyMoved {
43 pub ty: Ty,
45pub struct PartiallyMoved<'db> {
46 pub ty: Ty<'db>,
4447 pub span: MirSpan,
45 pub local: LocalId,
48 pub local: LocalId<'db>,
4649}
4750
4851#[derive(Debug, Clone, PartialEq, Eq)]
49pub struct BorrowRegion {
50 pub local: LocalId,
52pub struct BorrowRegion<'db> {
53 pub local: LocalId<'db>,
5154 pub kind: BorrowKind,
5255 pub places: Vec<MirSpan>,
5356}
5457
5558#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct BorrowckResult {
57 pub mir_body: Arc<MirBody>,
58 pub mutability_of_locals: ArenaMap<LocalId, MutabilityReason>,
59 pub moved_out_of_ref: Vec<MovedOutOfRef>,
60 pub partially_moved: Vec<PartiallyMoved>,
61 pub borrow_regions: Vec<BorrowRegion>,
59pub struct BorrowckResult<'db> {
60 pub mir_body: Arc<MirBody<'db>>,
61 pub mutability_of_locals: ArenaMap<LocalId<'db>, MutabilityReason>,
62 pub moved_out_of_ref: Vec<MovedOutOfRef<'db>>,
63 pub partially_moved: Vec<PartiallyMoved<'db>>,
64 pub borrow_regions: Vec<BorrowRegion<'db>>,
6265}
6366
64fn all_mir_bodies(
65 db: &dyn HirDatabase,
67fn all_mir_bodies<'db>(
68 db: &'db dyn HirDatabase,
6669 def: DefWithBodyId,
67 mut cb: impl FnMut(Arc<MirBody>),
68) -> Result<(), MirLowerError> {
69 fn for_closure(
70 db: &dyn HirDatabase,
71 c: ClosureId,
72 cb: &mut impl FnMut(Arc<MirBody>),
73 ) -> Result<(), MirLowerError> {
74 match db.mir_body_for_closure(c.into()) {
70 mut cb: impl FnMut(Arc<MirBody<'db>>),
71) -> Result<(), MirLowerError<'db>> {
72 fn for_closure<'db>(
73 db: &'db dyn HirDatabase,
74 c: InternedClosureId,
75 cb: &mut impl FnMut(Arc<MirBody<'db>>),
76 ) -> Result<(), MirLowerError<'db>> {
77 match db.mir_body_for_closure(c) {
7578 Ok(body) => {
7679 cb(body.clone());
7780 body.closures.iter().try_for_each(|&it| for_closure(db, it, cb))
......@@ -88,17 +91,24 @@ fn all_mir_bodies(
8891 }
8992}
9093
91pub fn borrowck_query(
92 db: &dyn HirDatabase,
94pub fn borrowck_query<'db>(
95 db: &'db dyn HirDatabase,
9396 def: DefWithBodyId,
94) -> Result<Arc<[BorrowckResult]>, MirLowerError> {
97) -> Result<Arc<[BorrowckResult<'db>]>, MirLowerError<'db>> {
9598 let _p = tracing::info_span!("borrowck_query").entered();
99 let module = def.module(db);
100 let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
101 let env = db.trait_environment_for_body(def);
96102 let mut res = vec![];
97103 all_mir_bodies(db, def, |body| {
104 // FIXME(next-solver): Opaques.
105 let infcx = interner.infer_ctxt().build(TypingMode::Borrowck {
106 defining_opaque_types: SolverDefIds::new_from_iter(interner, []),
107 });
98108 res.push(BorrowckResult {
99 mutability_of_locals: mutability_of_locals(db, &body),
100 moved_out_of_ref: moved_out_of_ref(db, &body),
101 partially_moved: partially_moved(db, &body),
109 mutability_of_locals: mutability_of_locals(&infcx, &body),
110 moved_out_of_ref: moved_out_of_ref(&infcx, &env, &body),
111 partially_moved: partially_moved(&infcx, &env, &body),
102112 borrow_regions: borrow_regions(db, &body),
103113 mir_body: body,
104114 });
......@@ -106,48 +116,49 @@ pub fn borrowck_query(
106116 Ok(res.into())
107117}
108118
109fn make_fetch_closure_field(
110 db: &dyn HirDatabase,
111) -> impl FnOnce(ClosureId, &Substitution, usize) -> Ty + '_ {
112 |c: ClosureId, subst: &Substitution, f: usize| {
113 let InternedClosure(def, _) = db.lookup_intern_closure(c.into());
119fn make_fetch_closure_field<'db>(
120 db: &'db dyn HirDatabase,
121) -> impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db> + use<'db> {
122 |c: InternedClosureId, subst: GenericArgs<'db>, f: usize| {
123 let InternedClosure(def, _) = db.lookup_intern_closure(c);
114124 let infer = db.infer(def);
115 let (captures, _) = infer.closure_info(&c);
116 let parent_subst = ClosureSubst(subst).parent_subst(db);
117 captures
118 .get(f)
119 .expect("broken closure field")
120 .ty
121 .clone()
122 .substitute(Interner, &parent_subst)
125 let (captures, _) = infer.closure_info(c);
126 let parent_subst = subst.split_closure_args_untupled().parent_args;
127 let interner = DbInterner::new_with(db, None, None);
128 captures.get(f).expect("broken closure field").ty.instantiate(interner, parent_subst)
123129 }
124130}
125131
126fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef> {
132fn moved_out_of_ref<'db>(
133 infcx: &InferCtxt<'db>,
134 env: &TraitEnvironment<'db>,
135 body: &MirBody<'db>,
136) -> Vec<MovedOutOfRef<'db>> {
137 let db = infcx.interner.db;
127138 let mut result = vec![];
128 let mut for_operand = |op: &Operand, span: MirSpan| match op.kind {
139 let mut for_operand = |op: &Operand<'db>, span: MirSpan| match op.kind {
129140 OperandKind::Copy(p) | OperandKind::Move(p) => {
130 let mut ty: Ty = body.locals[p.local].ty.clone();
141 let mut ty: Ty<'db> = body.locals[p.local].ty;
131142 let mut is_dereference_of_ref = false;
132143 for proj in p.projection.lookup(&body.projection_store) {
133144 if *proj == ProjectionElem::Deref && ty.as_reference().is_some() {
134145 is_dereference_of_ref = true;
135146 }
136147 ty = proj.projected_ty(
148 infcx,
137149 ty,
138 db,
139150 make_fetch_closure_field(db),
140151 body.owner.module(db).krate(),
141152 );
142153 }
143154 if is_dereference_of_ref
144 && !ty.clone().is_copy(db, body.owner)
145 && !ty.data(Interner).flags.intersects(TypeFlags::HAS_ERROR)
155 && !infcx.type_is_copy_modulo_regions(env.env, ty)
156 && !ty.references_non_lt_error()
146157 {
147158 result.push(MovedOutOfRef { span: op.span.unwrap_or(span), ty });
148159 }
149160 }
150 OperandKind::Constant(_) | OperandKind::Static(_) => (),
161 OperandKind::Constant { .. } | OperandKind::Static(_) => (),
151162 };
152163 for (_, block) in body.basic_blocks.iter() {
153164 db.unwind_if_revision_cancelled();
......@@ -218,26 +229,29 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
218229 result
219230}
220231
221fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec<PartiallyMoved> {
232fn partially_moved<'db>(
233 infcx: &InferCtxt<'db>,
234 env: &TraitEnvironment<'db>,
235 body: &MirBody<'db>,
236) -> Vec<PartiallyMoved<'db>> {
237 let db = infcx.interner.db;
222238 let mut result = vec![];
223 let mut for_operand = |op: &Operand, span: MirSpan| match op.kind {
239 let mut for_operand = |op: &Operand<'db>, span: MirSpan| match op.kind {
224240 OperandKind::Copy(p) | OperandKind::Move(p) => {
225 let mut ty: Ty = body.locals[p.local].ty.clone();
241 let mut ty: Ty<'db> = body.locals[p.local].ty;
226242 for proj in p.projection.lookup(&body.projection_store) {
227243 ty = proj.projected_ty(
244 infcx,
228245 ty,
229 db,
230246 make_fetch_closure_field(db),
231247 body.owner.module(db).krate(),
232248 );
233249 }
234 if !ty.clone().is_copy(db, body.owner)
235 && !ty.data(Interner).flags.intersects(TypeFlags::HAS_ERROR)
236 {
250 if !infcx.type_is_copy_modulo_regions(env.env, ty) && !ty.references_non_lt_error() {
237251 result.push(PartiallyMoved { span, ty, local: p.local });
238252 }
239253 }
240 OperandKind::Constant(_) | OperandKind::Static(_) => (),
254 OperandKind::Constant { .. } | OperandKind::Static(_) => (),
241255 };
242256 for (_, block) in body.basic_blocks.iter() {
243257 db.unwind_if_revision_cancelled();
......@@ -308,7 +322,7 @@ fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec<PartiallyMoved>
308322 result
309323}
310324
311fn borrow_regions(db: &dyn HirDatabase, body: &MirBody) -> Vec<BorrowRegion> {
325fn borrow_regions<'db>(db: &'db dyn HirDatabase, body: &MirBody<'db>) -> Vec<BorrowRegion<'db>> {
312326 let mut borrows = FxHashMap::default();
313327 for (_, block) in body.basic_blocks.iter() {
314328 db.unwind_if_revision_cancelled();
......@@ -316,7 +330,7 @@ fn borrow_regions(db: &dyn HirDatabase, body: &MirBody) -> Vec<BorrowRegion> {
316330 if let StatementKind::Assign(_, Rvalue::Ref(kind, p)) = &statement.kind {
317331 borrows
318332 .entry(p.local)
319 .and_modify(|it: &mut BorrowRegion| {
333 .and_modify(|it: &mut BorrowRegion<'db>| {
320334 it.places.push(statement.span);
321335 })
322336 .or_insert_with(|| BorrowRegion {
......@@ -358,9 +372,14 @@ enum ProjectionCase {
358372 Indirect,
359373}
360374
361fn place_case(db: &dyn HirDatabase, body: &MirBody, lvalue: &Place) -> ProjectionCase {
375fn place_case<'db>(
376 infcx: &InferCtxt<'db>,
377 body: &MirBody<'db>,
378 lvalue: &Place<'db>,
379) -> ProjectionCase {
380 let db = infcx.interner.db;
362381 let mut is_part_of = false;
363 let mut ty = body.locals[lvalue.local].ty.clone();
382 let mut ty = body.locals[lvalue.local].ty;
364383 for proj in lvalue.projection.lookup(&body.projection_store).iter() {
365384 match proj {
366385 ProjectionElem::Deref if ty.as_adt().is_none() => return ProjectionCase::Indirect, // It's indirect in case of reference and raw
......@@ -374,7 +393,12 @@ fn place_case(db: &dyn HirDatabase, body: &MirBody, lvalue: &Place) -> Projectio
374393 }
375394 ProjectionElem::OpaqueCast(_) => (),
376395 }
377 ty = proj.projected_ty(ty, db, make_fetch_closure_field(db), body.owner.module(db).krate());
396 ty = proj.projected_ty(
397 infcx,
398 ty,
399 make_fetch_closure_field(db),
400 body.owner.module(db).krate(),
401 );
378402 }
379403 if is_part_of { ProjectionCase::DirectPart } else { ProjectionCase::Direct }
380404}
......@@ -382,18 +406,18 @@ fn place_case(db: &dyn HirDatabase, body: &MirBody, lvalue: &Place) -> Projectio
382406/// Returns a map from basic blocks to the set of locals that might be ever initialized before
383407/// the start of the block. Only `StorageDead` can remove something from this map, and we ignore
384408/// `Uninit` and `drop` and similar after initialization.
385fn ever_initialized_map(
386 db: &dyn HirDatabase,
387 body: &MirBody,
388) -> ArenaMap<BasicBlockId, ArenaMap<LocalId, bool>> {
389 let mut result: ArenaMap<BasicBlockId, ArenaMap<LocalId, bool>> =
409fn ever_initialized_map<'db>(
410 db: &'db dyn HirDatabase,
411 body: &MirBody<'db>,
412) -> ArenaMap<BasicBlockId<'db>, ArenaMap<LocalId<'db>, bool>> {
413 let mut result: ArenaMap<BasicBlockId<'db>, ArenaMap<LocalId<'db>, bool>> =
390414 body.basic_blocks.iter().map(|it| (it.0, ArenaMap::default())).collect();
391 fn dfs(
392 db: &dyn HirDatabase,
393 body: &MirBody,
394 l: LocalId,
395 stack: &mut Vec<BasicBlockId>,
396 result: &mut ArenaMap<BasicBlockId, ArenaMap<LocalId, bool>>,
415 fn dfs<'db>(
416 db: &'db dyn HirDatabase,
417 body: &MirBody<'db>,
418 l: LocalId<'db>,
419 stack: &mut Vec<BasicBlockId<'db>>,
420 result: &mut ArenaMap<BasicBlockId<'db>, ArenaMap<LocalId<'db>, bool>>,
397421 ) {
398422 while let Some(b) = stack.pop() {
399423 let mut is_ever_initialized = result[b][l]; // It must be filled, as we use it as mark for dfs
......@@ -481,7 +505,11 @@ fn ever_initialized_map(
481505 result
482506}
483507
484fn push_mut_span(local: LocalId, span: MirSpan, result: &mut ArenaMap<LocalId, MutabilityReason>) {
508fn push_mut_span<'db>(
509 local: LocalId<'db>,
510 span: MirSpan,
511 result: &mut ArenaMap<LocalId<'db>, MutabilityReason>,
512) {
485513 match &mut result[local] {
486514 MutabilityReason::Mut { spans } => spans.push(span),
487515 it @ (MutabilityReason::Not | MutabilityReason::Unused) => {
......@@ -490,23 +518,27 @@ fn push_mut_span(local: LocalId, span: MirSpan, result: &mut ArenaMap<LocalId, M
490518 };
491519}
492520
493fn record_usage(local: LocalId, result: &mut ArenaMap<LocalId, MutabilityReason>) {
521fn record_usage<'db>(local: LocalId<'db>, result: &mut ArenaMap<LocalId<'db>, MutabilityReason>) {
494522 if let it @ MutabilityReason::Unused = &mut result[local] {
495523 *it = MutabilityReason::Not;
496524 };
497525}
498526
499fn record_usage_for_operand(arg: &Operand, result: &mut ArenaMap<LocalId, MutabilityReason>) {
527fn record_usage_for_operand<'db>(
528 arg: &Operand<'db>,
529 result: &mut ArenaMap<LocalId<'db>, MutabilityReason>,
530) {
500531 if let OperandKind::Copy(p) | OperandKind::Move(p) = arg.kind {
501532 record_usage(p.local, result);
502533 }
503534}
504535
505fn mutability_of_locals(
506 db: &dyn HirDatabase,
507 body: &MirBody,
508) -> ArenaMap<LocalId, MutabilityReason> {
509 let mut result: ArenaMap<LocalId, MutabilityReason> =
536fn mutability_of_locals<'db>(
537 infcx: &InferCtxt<'db>,
538 body: &MirBody<'db>,
539) -> ArenaMap<LocalId<'db>, MutabilityReason> {
540 let db = infcx.interner.db;
541 let mut result: ArenaMap<LocalId<'db>, MutabilityReason> =
510542 body.locals.iter().map(|it| (it.0, MutabilityReason::Unused)).collect();
511543
512544 let ever_init_maps = ever_initialized_map(db, body);
......@@ -515,7 +547,7 @@ fn mutability_of_locals(
515547 for statement in &block.statements {
516548 match &statement.kind {
517549 StatementKind::Assign(place, value) => {
518 match place_case(db, body, place) {
550 match place_case(infcx, body, place) {
519551 ProjectionCase::Direct => {
520552 if ever_init_map.get(place.local).copied().unwrap_or_default() {
521553 push_mut_span(place.local, statement.span, &mut result);
......@@ -564,7 +596,7 @@ fn mutability_of_locals(
564596 },
565597 p,
566598 ) = value
567 && place_case(db, body, p) != ProjectionCase::Indirect
599 && place_case(infcx, body, p) != ProjectionCase::Indirect
568600 {
569601 push_mut_span(p.local, statement.span, &mut result);
570602 }
src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs+479-497
......@@ -2,14 +2,11 @@
22
33use std::{borrow::Cow, cell::RefCell, fmt::Write, iter, mem, ops::Range};
44
5use base_db::Crate;
6use base_db::target::TargetLoadError;
7use chalk_ir::{Mutability, cast::Cast};
5use base_db::{Crate, target::TargetLoadError};
86use either::Either;
97use hir_def::{
10 AdtId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, StaticId,
11 VariantId,
12 builtin_type::BuiltinType,
8 AdtId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, HasModule, ItemContainerId,
9 Lookup, StaticId, VariantId,
1310 expr_store::HygieneId,
1411 item_tree::FieldsShape,
1512 lang_item::LangItem,
......@@ -25,30 +22,33 @@ use rustc_apfloat::{
2522 Float,
2623 ieee::{Half as f16, Quad as f128},
2724};
25use rustc_ast_ir::Mutability;
2826use rustc_hash::{FxHashMap, FxHashSet};
29use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike};
27use rustc_type_ir::{
28 AliasTyKind,
29 inherent::{AdtDef, IntoKind, Region as _, SliceLike, Ty as _},
30};
3031use span::FileId;
3132use stdx::never;
3233use syntax::{SyntaxNodePtr, TextRange};
3334use triomphe::Arc;
3435
3536use crate::{
36 AliasTy, CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, Interner,
37 MemoryMap, Substitution, ToChalk, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
38 consteval::{ConstEvalError, intern_const_scalar, try_const_usize},
39 consteval_nextsolver,
40 db::{HirDatabase, InternedClosure},
37 CallableDefId, ComplexMemoryMap, MemoryMap, TraitEnvironment,
38 consteval::{self, ConstEvalError, try_const_usize},
39 db::{HirDatabase, InternedClosure, InternedClosureId},
4140 display::{ClosureStyle, DisplayTarget, HirDisplay},
4241 infer::PointerCast,
4342 layout::{Layout, LayoutError, RustcEnumVariantIdx},
4443 method_resolution::{is_dyn_method, lookup_impl_const},
4544 next_solver::{
46 DbInterner,
47 mapping::{ChalkToNextSolver, convert_args_for_result, convert_ty_for_result},
45 Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region,
46 SolverDefId, Ty, TyKind, TypingMode, UnevaluatedConst, ValueConst,
47 infer::{DbInternerInferExt, InferCtxt, traits::ObligationCause},
48 obligation_ctxt::ObligationCtxt,
4849 },
49 static_lifetime,
5050 traits::FnTrait,
51 utils::{ClosureSubst, detect_variant_from_bytes},
51 utils::detect_variant_from_bytes,
5252};
5353
5454use super::{
......@@ -85,14 +85,14 @@ macro_rules! not_supported {
8585
8686#[derive(Debug, Default, Clone, PartialEq, Eq)]
8787pub struct VTableMap<'db> {
88 ty_to_id: FxHashMap<crate::next_solver::Ty<'db>, usize>,
89 id_to_ty: Vec<crate::next_solver::Ty<'db>>,
88 ty_to_id: FxHashMap<Ty<'db>, usize>,
89 id_to_ty: Vec<Ty<'db>>,
9090}
9191
9292impl<'db> VTableMap<'db> {
9393 const OFFSET: usize = 1000; // We should add some offset to ids to make 0 (null) an invalid id.
9494
95 fn id(&mut self, ty: crate::next_solver::Ty<'db>) -> usize {
95 fn id(&mut self, ty: Ty<'db>) -> usize {
9696 if let Some(it) = self.ty_to_id.get(&ty) {
9797 return *it;
9898 }
......@@ -102,13 +102,13 @@ impl<'db> VTableMap<'db> {
102102 id
103103 }
104104
105 pub(crate) fn ty(&self, id: usize) -> Result<crate::next_solver::Ty<'db>> {
105 pub(crate) fn ty(&self, id: usize) -> Result<'db, Ty<'db>> {
106106 id.checked_sub(VTableMap::OFFSET)
107107 .and_then(|id| self.id_to_ty.get(id).copied())
108108 .ok_or(MirEvalError::InvalidVTableId(id))
109109 }
110110
111 fn ty_of_bytes(&self, bytes: &[u8]) -> Result<crate::next_solver::Ty<'db>> {
111 fn ty_of_bytes(&self, bytes: &[u8]) -> Result<'db, Ty<'db>> {
112112 let id = from_bytes!(usize, bytes);
113113 self.ty(id)
114114 }
......@@ -134,14 +134,14 @@ impl TlsData {
134134 self.keys.len() - 1
135135 }
136136
137 fn get_key(&mut self, key: usize) -> Result<u128> {
137 fn get_key(&mut self, key: usize) -> Result<'static, u128> {
138138 let r = self.keys.get(key).ok_or_else(|| {
139139 MirEvalError::UndefinedBehavior(format!("Getting invalid tls key {key}"))
140140 })?;
141141 Ok(*r)
142142 }
143143
144 fn set_key(&mut self, key: usize, value: u128) -> Result<()> {
144 fn set_key(&mut self, key: usize, value: u128) -> Result<'static, ()> {
145145 let r = self.keys.get_mut(key).ok_or_else(|| {
146146 MirEvalError::UndefinedBehavior(format!("Setting invalid tls key {key}"))
147147 })?;
......@@ -150,45 +150,45 @@ impl TlsData {
150150 }
151151}
152152
153struct StackFrame {
154 locals: Locals,
155 destination: Option<BasicBlockId>,
153struct StackFrame<'db> {
154 locals: Locals<'db>,
155 destination: Option<BasicBlockId<'db>>,
156156 prev_stack_ptr: usize,
157157 span: (MirSpan, DefWithBodyId),
158158}
159159
160160#[derive(Clone)]
161enum MirOrDynIndex {
162 Mir(Arc<MirBody>),
161enum MirOrDynIndex<'db> {
162 Mir(Arc<MirBody<'db>>),
163163 Dyn(usize),
164164}
165165
166pub struct Evaluator<'a> {
167 db: &'a dyn HirDatabase,
168 trait_env: Arc<TraitEnvironment<'a>>,
166pub struct Evaluator<'db> {
167 db: &'db dyn HirDatabase,
168 trait_env: Arc<TraitEnvironment<'db>>,
169169 target_data_layout: Arc<TargetDataLayout>,
170170 stack: Vec<u8>,
171171 heap: Vec<u8>,
172 code_stack: Vec<StackFrame>,
172 code_stack: Vec<StackFrame<'db>>,
173173 /// Stores the global location of the statics. We const evaluate every static first time we need it
174174 /// and see it's missing, then we add it to this to reuse.
175175 static_locations: FxHashMap<StaticId, Address>,
176176 /// We don't really have function pointers, i.e. pointers to some assembly instructions that we can run. Instead, we
177177 /// store the type as an interned id in place of function and vtable pointers, and we recover back the type at the
178178 /// time of use.
179 vtable_map: VTableMap<'a>,
179 vtable_map: VTableMap<'db>,
180180 thread_local_storage: TlsData,
181181 random_state: oorandom::Rand64,
182182 stdout: Vec<u8>,
183183 stderr: Vec<u8>,
184 layout_cache: RefCell<FxHashMap<crate::next_solver::Ty<'a>, Arc<Layout>>>,
185 projected_ty_cache: RefCell<FxHashMap<(Ty, PlaceElem), Ty>>,
184 layout_cache: RefCell<FxHashMap<Ty<'db>, Arc<Layout>>>,
185 projected_ty_cache: RefCell<FxHashMap<(Ty<'db>, PlaceElem<'db>), Ty<'db>>>,
186186 not_special_fn_cache: RefCell<FxHashSet<FunctionId>>,
187 mir_or_dyn_index_cache: RefCell<FxHashMap<(FunctionId, Substitution), MirOrDynIndex>>,
188 /// Constantly dropping and creating `Locals` is very costly. We store
187 mir_or_dyn_index_cache: RefCell<FxHashMap<(FunctionId, GenericArgs<'db>), MirOrDynIndex<'db>>>,
188 /// Constantly dropping and creating `Locals<'db>` is very costly. We store
189189 /// old locals that we normally want to drop here, to reuse their allocations
190190 /// later.
191 unused_locals_store: RefCell<FxHashMap<DefWithBodyId, Vec<Locals>>>,
191 unused_locals_store: RefCell<FxHashMap<DefWithBodyId, Vec<Locals<'db>>>>,
192192 cached_ptr_size: usize,
193193 cached_fn_trait_func: Option<FunctionId>,
194194 cached_fn_mut_trait_func: Option<FunctionId>,
......@@ -202,6 +202,7 @@ pub struct Evaluator<'a> {
202202 stack_depth_limit: usize,
203203 /// Maximum count of bytes that heap and stack can grow
204204 memory_limit: usize,
205 infcx: InferCtxt<'db>,
205206}
206207
207208#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
......@@ -220,9 +221,9 @@ struct Interval {
220221}
221222
222223#[derive(Debug, Clone)]
223struct IntervalAndTy {
224struct IntervalAndTy<'db> {
224225 interval: Interval,
225 ty: Ty,
226 ty: Ty<'db>,
226227}
227228
228229impl Interval {
......@@ -230,15 +231,19 @@ impl Interval {
230231 Self { addr, size }
231232 }
232233
233 fn get<'a, 'db>(&self, memory: &'a Evaluator<'db>) -> Result<&'a [u8]> {
234 fn get<'a, 'db>(&self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> {
234235 memory.read_memory(self.addr, self.size)
235236 }
236237
237 fn write_from_bytes(&self, memory: &mut Evaluator<'_>, bytes: &[u8]) -> Result<()> {
238 fn write_from_bytes<'db>(&self, memory: &mut Evaluator<'db>, bytes: &[u8]) -> Result<'db, ()> {
238239 memory.write_memory(self.addr, bytes)
239240 }
240241
241 fn write_from_interval(&self, memory: &mut Evaluator<'_>, interval: Interval) -> Result<()> {
242 fn write_from_interval<'db>(
243 &self,
244 memory: &mut Evaluator<'db>,
245 interval: Interval,
246 ) -> Result<'db, ()> {
242247 memory.copy_from_interval(self.addr, interval)
243248 }
244249
......@@ -247,18 +252,18 @@ impl Interval {
247252 }
248253}
249254
250impl IntervalAndTy {
251 fn get<'a, 'db>(&self, memory: &'a Evaluator<'db>) -> Result<&'a [u8]> {
255impl<'db> IntervalAndTy<'db> {
256 fn get<'a>(&self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> {
252257 memory.read_memory(self.interval.addr, self.interval.size)
253258 }
254259
255260 fn new(
256261 addr: Address,
257 ty: Ty,
258 evaluator: &Evaluator<'_>,
259 locals: &Locals,
260 ) -> Result<IntervalAndTy> {
261 let size = evaluator.size_of_sized(&ty, locals, "type of interval")?;
262 ty: Ty<'db>,
263 evaluator: &Evaluator<'db>,
264 locals: &Locals<'db>,
265 ) -> Result<'db, IntervalAndTy<'db>> {
266 let size = evaluator.size_of_sized(ty, locals, "type of interval")?;
262267 Ok(IntervalAndTy { interval: Interval { addr, size }, ty })
263268 }
264269}
......@@ -275,7 +280,7 @@ impl From<Interval> for IntervalOrOwned {
275280}
276281
277282impl IntervalOrOwned {
278 fn get<'a, 'db>(&'a self, memory: &'a Evaluator<'db>) -> Result<&'a [u8]> {
283 fn get<'a, 'db>(&'a self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> {
279284 Ok(match self {
280285 IntervalOrOwned::Owned(o) => o,
281286 IntervalOrOwned::Borrowed(b) => b.get(memory)?,
......@@ -295,7 +300,7 @@ const HEAP_OFFSET: usize = 1 << 29;
295300
296301impl Address {
297302 #[allow(clippy::double_parens)]
298 fn from_bytes(it: &[u8]) -> Result<Self> {
303 fn from_bytes<'db>(it: &[u8]) -> Result<'db, Self> {
299304 Ok(Address::from_usize(from_bytes!(usize, it)))
300305 }
301306
......@@ -335,32 +340,35 @@ impl Address {
335340}
336341
337342#[derive(Clone, PartialEq, Eq)]
338pub enum MirEvalError {
339 ConstEvalError(String, Box<ConstEvalError>),
340 LayoutError(LayoutError, Ty),
343pub enum MirEvalError<'db> {
344 ConstEvalError(String, Box<ConstEvalError<'db>>),
345 LayoutError(LayoutError, Ty<'db>),
341346 TargetDataLayoutNotAvailable(TargetLoadError),
342347 /// Means that code had undefined behavior. We don't try to actively detect UB, but if it was detected
343348 /// then use this type of error.
344349 UndefinedBehavior(String),
345350 Panic(String),
346351 // FIXME: This should be folded into ConstEvalError?
347 MirLowerError(FunctionId, MirLowerError),
348 MirLowerErrorForClosure(ClosureId, MirLowerError),
349 TypeIsUnsized(Ty, &'static str),
352 MirLowerError(FunctionId, MirLowerError<'db>),
353 MirLowerErrorForClosure(InternedClosureId, MirLowerError<'db>),
354 TypeIsUnsized(Ty<'db>, &'static str),
350355 NotSupported(String),
351 InvalidConst(Const),
352 InFunction(Box<MirEvalError>, Vec<(Either<FunctionId, ClosureId>, MirSpan, DefWithBodyId)>),
356 InvalidConst(Const<'db>),
357 InFunction(
358 Box<MirEvalError<'db>>,
359 Vec<(Either<FunctionId, InternedClosureId>, MirSpan, DefWithBodyId)>,
360 ),
353361 ExecutionLimitExceeded,
354362 StackOverflow,
355363 /// FIXME: Fold this into InternalError
356364 InvalidVTableId(usize),
357365 /// ?
358 CoerceUnsizedError(Ty),
366 CoerceUnsizedError(Ty<'db>),
359367 /// These should not occur, usually indicates a bug in mir lowering.
360368 InternalError(Box<str>),
361369}
362370
363impl MirEvalError {
371impl MirEvalError<'_> {
364372 pub fn pretty_print(
365373 &self,
366374 f: &mut String,
......@@ -431,13 +439,8 @@ impl MirEvalError {
431439 let function_name = db.function_signature(*func);
432440 let self_ = match func.lookup(db).container {
433441 ItemContainerId::ImplId(impl_id) => Some({
434 let generics = crate::generics::generics(db, impl_id.into());
435 let interner = DbInterner::new_with(db, None, None);
436 let substs = generics.placeholder_subst(db);
437 let args: crate::next_solver::GenericArgs<'_> =
438 substs.to_nextsolver(interner);
439442 db.impl_self_ty(impl_id)
440 .instantiate(interner, args)
443 .instantiate_identity()
441444 .display(db, display_target)
442445 .to_string()
443446 }),
......@@ -492,7 +495,7 @@ impl MirEvalError {
492495 }
493496}
494497
495impl std::fmt::Debug for MirEvalError {
498impl std::fmt::Debug for MirEvalError<'_> {
496499 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
497500 match self {
498501 Self::ConstEvalError(arg0, arg1) => {
......@@ -523,10 +526,7 @@ impl std::fmt::Debug for MirEvalError {
523526 Self::InternalError(arg0) => f.debug_tuple("InternalError").field(arg0).finish(),
524527 Self::InvalidVTableId(arg0) => f.debug_tuple("InvalidVTableId").field(arg0).finish(),
525528 Self::NotSupported(arg0) => f.debug_tuple("NotSupported").field(arg0).finish(),
526 Self::InvalidConst(arg0) => {
527 let data = &arg0.data(Interner);
528 f.debug_struct("InvalidConst").field("ty", &data.ty).field("value", &arg0).finish()
529 }
529 Self::InvalidConst(arg0) => f.debug_tuple("InvalidConst").field(&arg0).finish(),
530530 Self::InFunction(e, stack) => {
531531 f.debug_struct("WithStack").field("error", e).field("stack", &stack).finish()
532532 }
......@@ -534,15 +534,15 @@ impl std::fmt::Debug for MirEvalError {
534534 }
535535}
536536
537type Result<T> = std::result::Result<T, MirEvalError>;
537type Result<'db, T> = std::result::Result<T, MirEvalError<'db>>;
538538
539539#[derive(Debug, Default)]
540struct DropFlags {
541 need_drop: FxHashSet<Place>,
540struct DropFlags<'db> {
541 need_drop: FxHashSet<Place<'db>>,
542542}
543543
544impl DropFlags {
545 fn add_place(&mut self, p: Place, store: &ProjectionStore) {
544impl<'db> DropFlags<'db> {
545 fn add_place(&mut self, p: Place<'db>, store: &ProjectionStore<'db>) {
546546 if p.iterate_over_parents(store).any(|it| self.need_drop.contains(&it)) {
547547 return;
548548 }
......@@ -550,7 +550,7 @@ impl DropFlags {
550550 self.need_drop.insert(p);
551551 }
552552
553 fn remove_place(&mut self, p: &Place, store: &ProjectionStore) -> bool {
553 fn remove_place(&mut self, p: &Place<'db>, store: &ProjectionStore<'db>) -> bool {
554554 // FIXME: replace parents with parts
555555 if let Some(parent) = p.iterate_over_parents(store).find(|it| self.need_drop.contains(it)) {
556556 self.need_drop.remove(&parent);
......@@ -565,10 +565,10 @@ impl DropFlags {
565565}
566566
567567#[derive(Debug)]
568struct Locals {
569 ptr: ArenaMap<LocalId, Interval>,
570 body: Arc<MirBody>,
571 drop_flags: DropFlags,
568struct Locals<'db> {
569 ptr: ArenaMap<LocalId<'db>, Interval>,
570 body: Arc<MirBody<'db>>,
571 drop_flags: DropFlags<'db>,
572572}
573573
574574pub struct MirOutput {
......@@ -587,7 +587,7 @@ impl MirOutput {
587587
588588pub fn interpret_mir<'db>(
589589 db: &'db dyn HirDatabase,
590 body: Arc<MirBody>,
590 body: Arc<MirBody<'db>>,
591591 // FIXME: This is workaround. Ideally, const generics should have a separate body (issue #7434), but now
592592 // they share their body with their parent, so in MIR lowering we have locals of the parent body, which
593593 // might have placeholders. With this argument, we (wrongly) assume that every placeholder type has
......@@ -595,10 +595,10 @@ pub fn interpret_mir<'db>(
595595 // (and probably should) do better here, for example by excluding bindings outside of the target expression.
596596 assert_placeholder_ty_is_unused: bool,
597597 trait_env: Option<Arc<TraitEnvironment<'db>>>,
598) -> Result<(Result<Const>, MirOutput)> {
599 let ty = body.locals[return_slot()].ty.clone();
598) -> Result<'db, (Result<'db, Const<'db>>, MirOutput)> {
599 let ty = body.locals[return_slot()].ty;
600600 let mut evaluator = Evaluator::new(db, body.owner, assert_placeholder_ty_is_unused, trait_env)?;
601 let it: Result<Const> = (|| {
601 let it: Result<'db, Const<'db>> = (|| {
602602 if evaluator.ptr_size() != size_of::<usize>() {
603603 not_supported!("targets with different pointer size from host");
604604 }
......@@ -606,7 +606,7 @@ pub fn interpret_mir<'db>(
606606 let bytes = interval.get(&evaluator)?;
607607 let mut memory_map = evaluator.create_memory_map(
608608 bytes,
609 &ty,
609 ty,
610610 &Locals { ptr: ArenaMap::new(), body, drop_flags: DropFlags::default() },
611611 )?;
612612 let bytes = bytes.into();
......@@ -617,13 +617,7 @@ pub fn interpret_mir<'db>(
617617 memory_map.vtable.shrink_to_fit();
618618 MemoryMap::Complex(Box::new(memory_map))
619619 };
620 // SAFETY: will never use this without a db
621 Ok(intern_const_scalar(
622 ConstScalar::Bytes(bytes, unsafe {
623 std::mem::transmute::<MemoryMap<'_>, MemoryMap<'static>>(memory_map)
624 }),
625 ty,
626 ))
620 Ok(Const::new_valtree(evaluator.interner(), ty, bytes, memory_map))
627621 })();
628622 Ok((it, MirOutput { stdout: evaluator.stdout, stderr: evaluator.stderr }))
629623}
......@@ -639,13 +633,16 @@ impl<'db> Evaluator<'db> {
639633 owner: DefWithBodyId,
640634 assert_placeholder_ty_is_unused: bool,
641635 trait_env: Option<Arc<TraitEnvironment<'db>>>,
642 ) -> Result<Evaluator<'db>> {
643 let crate_id = owner.module(db).krate();
636 ) -> Result<'db, Evaluator<'db>> {
637 let module = owner.module(db);
638 let crate_id = module.krate();
644639 let target_data_layout = match db.target_data_layout(crate_id) {
645640 Ok(target_data_layout) => target_data_layout,
646641 Err(e) => return Err(MirEvalError::TargetDataLayoutNotAvailable(e)),
647642 };
648643 let cached_ptr_size = target_data_layout.pointer_size().bytes_usize();
644 let interner = DbInterner::new_with(db, Some(crate_id), module.containing_block());
645 let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
649646 Ok(Evaluator {
650647 target_data_layout,
651648 stack: vec![0],
......@@ -679,19 +676,25 @@ impl<'db> Evaluator<'db> {
679676 cached_fn_once_trait_func: LangItem::FnOnce.resolve_trait(db, crate_id).and_then(|x| {
680677 x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call_once))
681678 }),
679 infcx,
682680 })
683681 }
684682
685 fn place_addr(&self, p: &Place, locals: &Locals) -> Result<Address> {
683 #[inline]
684 fn interner(&self) -> DbInterner<'db> {
685 self.infcx.interner
686 }
687
688 fn place_addr(&self, p: &Place<'db>, locals: &Locals<'db>) -> Result<'db, Address> {
686689 Ok(self.place_addr_and_ty_and_metadata(p, locals)?.0)
687690 }
688691
689 fn place_interval(&self, p: &Place, locals: &Locals) -> Result<Interval> {
692 fn place_interval(&self, p: &Place<'db>, locals: &Locals<'db>) -> Result<'db, Interval> {
690693 let place_addr_and_ty = self.place_addr_and_ty_and_metadata(p, locals)?;
691694 Ok(Interval {
692695 addr: place_addr_and_ty.0,
693696 size: self.size_of_sized(
694 &place_addr_and_ty.1,
697 place_addr_and_ty.1,
695698 locals,
696699 "Type of place that we need its interval",
697700 )?,
......@@ -702,48 +705,46 @@ impl<'db> Evaluator<'db> {
702705 self.cached_ptr_size
703706 }
704707
705 fn projected_ty(&self, ty: Ty, proj: PlaceElem) -> Ty {
708 fn projected_ty(&self, ty: Ty<'db>, proj: PlaceElem<'db>) -> Ty<'db> {
706709 let pair = (ty, proj);
707710 if let Some(r) = self.projected_ty_cache.borrow().get(&pair) {
708 return r.clone();
711 return *r;
709712 }
710713 let (ty, proj) = pair;
711714 let r = proj.projected_ty(
712 ty.clone(),
713 self.db,
715 &self.infcx,
716 ty,
714717 |c, subst, f| {
715 let InternedClosure(def, _) = self.db.lookup_intern_closure(c.into());
718 let InternedClosure(def, _) = self.db.lookup_intern_closure(c);
716719 let infer = self.db.infer(def);
717 let (captures, _) = infer.closure_info(&c);
718 let parent_subst = ClosureSubst(subst).parent_subst(self.db);
720 let (captures, _) = infer.closure_info(c);
721 let parent_subst = subst.split_closure_args_untupled().parent_args;
719722 captures
720723 .get(f)
721724 .expect("broken closure field")
722725 .ty
723 .clone()
724 .substitute(Interner, &parent_subst)
726 .instantiate(self.interner(), parent_subst)
725727 },
726728 self.crate_id,
727729 );
728 self.projected_ty_cache.borrow_mut().insert((ty, proj), r.clone());
730 self.projected_ty_cache.borrow_mut().insert((ty, proj), r);
729731 r
730732 }
731733
732734 fn place_addr_and_ty_and_metadata<'a>(
733735 &'a self,
734 p: &Place,
735 locals: &'a Locals,
736 ) -> Result<(Address, Ty, Option<IntervalOrOwned>)> {
737 let interner = DbInterner::new_with(self.db, None, None);
736 p: &Place<'db>,
737 locals: &'a Locals<'db>,
738 ) -> Result<'db, (Address, Ty<'db>, Option<IntervalOrOwned>)> {
738739 let mut addr = locals.ptr[p.local].addr;
739 let mut ty: Ty = locals.body.locals[p.local].ty.clone();
740 let mut ty: Ty<'db> = locals.body.locals[p.local].ty;
740741 let mut metadata: Option<IntervalOrOwned> = None; // locals are always sized
741742 for proj in p.projection.lookup(&locals.body.projection_store) {
742 let prev_ty = ty.clone();
743 let prev_ty = ty;
743744 ty = self.projected_ty(ty, proj.clone());
744745 match proj {
745746 ProjectionElem::Deref => {
746 metadata = if self.size_align_of(&ty, locals)?.is_none() {
747 metadata = if self.size_align_of(ty, locals)?.is_none() {
747748 Some(
748749 Interval { addr: addr.offset(self.ptr_size()), size: self.ptr_size() }
749750 .into(),
......@@ -761,12 +762,12 @@ impl<'db> Evaluator<'db> {
761762 );
762763 metadata = None; // Result of index is always sized
763764 let ty_size =
764 self.size_of_sized(&ty, locals, "array inner type should be sized")?;
765 self.size_of_sized(ty, locals, "array inner type should be sized")?;
765766 addr = addr.offset(ty_size * offset);
766767 }
767768 &ProjectionElem::ConstantIndex { from_end, offset } => {
768769 let offset = if from_end {
769 let len = match prev_ty.kind(Interner) {
770 let len = match prev_ty.kind() {
770771 TyKind::Array(_, c) => match try_const_usize(self.db, c) {
771772 Some(it) => it as u64,
772773 None => {
......@@ -785,13 +786,13 @@ impl<'db> Evaluator<'db> {
785786 };
786787 metadata = None; // Result of index is always sized
787788 let ty_size =
788 self.size_of_sized(&ty, locals, "array inner type should be sized")?;
789 self.size_of_sized(ty, locals, "array inner type should be sized")?;
789790 addr = addr.offset(ty_size * offset);
790791 }
791792 &ProjectionElem::Subslice { from, to } => {
792 let inner_ty = match &ty.kind(Interner) {
793 TyKind::Array(inner, _) | TyKind::Slice(inner) => inner.clone(),
794 _ => TyKind::Error.intern(Interner),
793 let inner_ty = match ty.kind() {
794 TyKind::Array(inner, _) | TyKind::Slice(inner) => inner,
795 _ => Ty::new_error(self.interner(), ErrorGuaranteed),
795796 };
796797 metadata = match metadata {
797798 Some(it) => {
......@@ -803,23 +804,23 @@ impl<'db> Evaluator<'db> {
803804 None => None,
804805 };
805806 let ty_size =
806 self.size_of_sized(&inner_ty, locals, "array inner type should be sized")?;
807 self.size_of_sized(inner_ty, locals, "array inner type should be sized")?;
807808 addr = addr.offset(ty_size * (from as usize));
808809 }
809810 &ProjectionElem::ClosureField(f) => {
810 let layout = self.layout(prev_ty.to_nextsolver(interner))?;
811 let layout = self.layout(prev_ty)?;
811812 let offset = layout.fields.offset(f).bytes_usize();
812813 addr = addr.offset(offset);
813814 metadata = None;
814815 }
815816 ProjectionElem::Field(Either::Right(f)) => {
816 let layout = self.layout(prev_ty.to_nextsolver(interner))?;
817 let layout = self.layout(prev_ty)?;
817818 let offset = layout.fields.offset(f.index as usize).bytes_usize();
818819 addr = addr.offset(offset);
819820 metadata = None; // tuple field is always sized FIXME: This is wrong, the tail can be unsized
820821 }
821822 ProjectionElem::Field(Either::Left(f)) => {
822 let layout = self.layout(prev_ty.to_nextsolver(interner))?;
823 let layout = self.layout(prev_ty)?;
823824 let variant_layout = match &layout.variants {
824825 Variants::Single { .. } | Variants::Empty => &layout,
825826 Variants::Multiple { variants, .. } => {
......@@ -841,7 +842,7 @@ impl<'db> Evaluator<'db> {
841842 .bytes_usize();
842843 addr = addr.offset(offset);
843844 // Unsized field metadata is equal to the metadata of the struct
844 if self.size_align_of(&ty, locals)?.is_some() {
845 if self.size_align_of(ty, locals)?.is_some() {
845846 metadata = None;
846847 }
847848 }
......@@ -851,46 +852,47 @@ impl<'db> Evaluator<'db> {
851852 Ok((addr, ty, metadata))
852853 }
853854
854 fn layout(&self, ty: crate::next_solver::Ty<'db>) -> Result<Arc<Layout>> {
855 fn layout(&self, ty: Ty<'db>) -> Result<'db, Arc<Layout>> {
855856 if let Some(x) = self.layout_cache.borrow().get(&ty) {
856857 return Ok(x.clone());
857858 }
858 let interner = DbInterner::new_with(self.db, None, None);
859859 let r = self
860860 .db
861861 .layout_of_ty(ty, self.trait_env.clone())
862 .map_err(|e| MirEvalError::LayoutError(e, convert_ty_for_result(interner, ty)))?;
862 .map_err(|e| MirEvalError::LayoutError(e, ty))?;
863863 self.layout_cache.borrow_mut().insert(ty, r.clone());
864864 Ok(r)
865865 }
866866
867 fn layout_adt(&self, adt: AdtId, subst: Substitution) -> Result<Arc<Layout>> {
868 let interner = DbInterner::new_with(self.db, None, None);
869 self.layout(crate::next_solver::Ty::new(
870 interner,
871 rustc_type_ir::TyKind::Adt(
872 crate::next_solver::AdtDef::new(adt, interner),
873 subst.to_nextsolver(interner),
874 ),
875 ))
867 fn layout_adt(&self, adt: AdtId, subst: GenericArgs<'db>) -> Result<'db, Arc<Layout>> {
868 self.layout(Ty::new_adt(self.interner(), adt, subst))
876869 }
877870
878 fn place_ty<'a>(&'a self, p: &Place, locals: &'a Locals) -> Result<Ty> {
871 fn place_ty<'a>(&'a self, p: &Place<'db>, locals: &'a Locals<'db>) -> Result<'db, Ty<'db>> {
879872 Ok(self.place_addr_and_ty_and_metadata(p, locals)?.1)
880873 }
881874
882 fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<Ty> {
875 fn operand_ty(&self, o: &Operand<'db>, locals: &Locals<'db>) -> Result<'db, Ty<'db>> {
883876 Ok(match &o.kind {
884877 OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?,
885 OperandKind::Constant(c) => c.data(Interner).ty.clone(),
878 OperandKind::Constant { konst: _, ty } => *ty,
886879 &OperandKind::Static(s) => {
887 let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr].clone();
888 TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner)
880 let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr];
881 Ty::new_ref(
882 self.interner(),
883 Region::new_static(self.interner()),
884 ty,
885 Mutability::Not,
886 )
889887 }
890888 })
891889 }
892890
893 fn operand_ty_and_eval(&mut self, o: &Operand, locals: &mut Locals) -> Result<IntervalAndTy> {
891 fn operand_ty_and_eval(
892 &mut self,
893 o: &Operand<'db>,
894 locals: &mut Locals<'db>,
895 ) -> Result<'db, IntervalAndTy<'db>> {
894896 Ok(IntervalAndTy {
895897 interval: self.eval_operand(o, locals)?,
896898 ty: self.operand_ty(o, locals)?,
......@@ -899,9 +901,9 @@ impl<'db> Evaluator<'db> {
899901
900902 fn interpret_mir(
901903 &mut self,
902 body: Arc<MirBody>,
904 body: Arc<MirBody<'db>>,
903905 args: impl Iterator<Item = IntervalOrOwned>,
904 ) -> Result<Interval> {
906 ) -> Result<'db, Interval> {
905907 if let Some(it) = self.stack_depth_limit.checked_sub(1) {
906908 self.stack_depth_limit = it;
907909 } else {
......@@ -962,9 +964,9 @@ impl<'db> Evaluator<'db> {
962964 let args = args
963965 .iter()
964966 .map(|it| self.operand_ty_and_eval(it, locals))
965 .collect::<Result<Vec<_>>>()?;
966 let stack_frame = match &fn_ty.kind(Interner) {
967 TyKind::Function(_) => {
967 .collect::<Result<'db, Vec<_>>>()?;
968 let stack_frame = match fn_ty.kind() {
969 TyKind::FnPtr(..) => {
968970 let bytes = self.eval_operand(func, locals)?;
969971 self.exec_fn_pointer(
970972 bytes,
......@@ -976,7 +978,7 @@ impl<'db> Evaluator<'db> {
976978 )?
977979 }
978980 TyKind::FnDef(def, generic_args) => self.exec_fn_def(
979 CallableDefId::from_chalk(self.db, *def),
981 def.0,
980982 generic_args,
981983 destination_interval,
982984 &args,
......@@ -1063,10 +1065,10 @@ impl<'db> Evaluator<'db> {
10631065
10641066 fn fill_locals_for_body(
10651067 &mut self,
1066 body: &MirBody,
1067 locals: &mut Locals,
1068 body: &MirBody<'db>,
1069 locals: &mut Locals<'db>,
10681070 args: impl Iterator<Item = IntervalOrOwned>,
1069 ) -> Result<()> {
1071 ) -> Result<'db, ()> {
10701072 let mut remain_args = body.param_locals.len();
10711073 for ((l, interval), value) in locals.ptr.iter().skip(1).zip(args) {
10721074 locals.drop_flags.add_place(l.into(), &locals.body.projection_store);
......@@ -1087,9 +1089,9 @@ impl<'db> Evaluator<'db> {
10871089
10881090 fn create_locals_for_body(
10891091 &mut self,
1090 body: &Arc<MirBody>,
1092 body: &Arc<MirBody<'db>>,
10911093 destination: Option<Interval>,
1092 ) -> Result<(Locals, usize)> {
1094 ) -> Result<'db, (Locals<'db>, usize)> {
10931095 let mut locals =
10941096 match self.unused_locals_store.borrow_mut().entry(body.owner).or_default().pop() {
10951097 None => Locals {
......@@ -1113,7 +1115,7 @@ impl<'db> Evaluator<'db> {
11131115 continue;
11141116 }
11151117 let (size, align) = self.size_align_of_sized(
1116 &it.ty,
1118 it.ty,
11171119 &locals,
11181120 "no unsized local in extending stack",
11191121 )?;
......@@ -1136,8 +1138,11 @@ impl<'db> Evaluator<'db> {
11361138 Ok((locals, prev_stack_pointer))
11371139 }
11381140
1139 fn eval_rvalue(&mut self, r: &Rvalue, locals: &mut Locals) -> Result<IntervalOrOwned> {
1140 let interner = DbInterner::new_with(self.db, None, None);
1141 fn eval_rvalue(
1142 &mut self,
1143 r: &Rvalue<'db>,
1144 locals: &mut Locals<'db>,
1145 ) -> Result<'db, IntervalOrOwned> {
11411146 use IntervalOrOwned::*;
11421147 Ok(match r {
11431148 Rvalue::Use(it) => Borrowed(self.eval_operand(it, locals)?),
......@@ -1163,33 +1168,33 @@ impl<'db> Evaluator<'db> {
11631168 Rvalue::UnaryOp(op, val) => {
11641169 let mut c = self.eval_operand(val, locals)?.get(self)?;
11651170 let mut ty = self.operand_ty(val, locals)?;
1166 while let TyKind::Ref(_, _, z) = ty.kind(Interner) {
1167 ty = z.clone();
1168 let size = self.size_of_sized(&ty, locals, "operand of unary op")?;
1171 while let TyKind::Ref(_, z, _) = ty.kind() {
1172 ty = z;
1173 let size = self.size_of_sized(ty, locals, "operand of unary op")?;
11691174 c = self.read_memory(Address::from_bytes(c)?, size)?;
11701175 }
1171 if let TyKind::Scalar(chalk_ir::Scalar::Float(f)) = ty.kind(Interner) {
1176 if let TyKind::Float(f) = ty.kind() {
11721177 match f {
1173 chalk_ir::FloatTy::F16 => {
1178 rustc_type_ir::FloatTy::F16 => {
11741179 let c = -from_bytes!(f16, u16, c);
11751180 Owned(u16::try_from(c.to_bits()).unwrap().to_le_bytes().into())
11761181 }
1177 chalk_ir::FloatTy::F32 => {
1182 rustc_type_ir::FloatTy::F32 => {
11781183 let c = -from_bytes!(f32, c);
11791184 Owned(c.to_le_bytes().into())
11801185 }
1181 chalk_ir::FloatTy::F64 => {
1186 rustc_type_ir::FloatTy::F64 => {
11821187 let c = -from_bytes!(f64, c);
11831188 Owned(c.to_le_bytes().into())
11841189 }
1185 chalk_ir::FloatTy::F128 => {
1190 rustc_type_ir::FloatTy::F128 => {
11861191 let c = -from_bytes!(f128, u128, c);
11871192 Owned(c.to_bits().to_le_bytes().into())
11881193 }
11891194 }
11901195 } else {
11911196 let mut c = c.to_vec();
1192 if ty.as_builtin() == Some(BuiltinType::Bool) {
1197 if matches!(ty.kind(), TyKind::Bool) {
11931198 c[0] = 1 - c[0];
11941199 } else {
11951200 match op {
......@@ -1215,8 +1220,8 @@ impl<'db> Evaluator<'db> {
12151220 let mut lc = lc.get(self)?;
12161221 let mut rc = rc.get(self)?;
12171222 let mut ty = self.operand_ty(lhs, locals)?;
1218 while let TyKind::Ref(_, _, z) = ty.kind(Interner) {
1219 ty = z.clone();
1223 while let TyKind::Ref(_, z, _) = ty.kind() {
1224 ty = z;
12201225 let size = if ty.is_str() {
12211226 if *op != BinOp::Eq {
12221227 never!("Only eq is builtin for `str`");
......@@ -1232,14 +1237,14 @@ impl<'db> Evaluator<'db> {
12321237 rc = self.read_memory(Address::from_bytes(rc)?, ls)?;
12331238 break 'binary_op Owned(vec![u8::from(lc == rc)]);
12341239 } else {
1235 self.size_of_sized(&ty, locals, "operand of binary op")?
1240 self.size_of_sized(ty, locals, "operand of binary op")?
12361241 };
12371242 lc = self.read_memory(Address::from_bytes(lc)?, size)?;
12381243 rc = self.read_memory(Address::from_bytes(rc)?, size)?;
12391244 }
1240 if let TyKind::Scalar(chalk_ir::Scalar::Float(f)) = ty.kind(Interner) {
1245 if let TyKind::Float(f) = ty.kind() {
12411246 match f {
1242 chalk_ir::FloatTy::F16 => {
1247 rustc_type_ir::FloatTy::F16 => {
12431248 let l = from_bytes!(f16, u16, lc);
12441249 let r = from_bytes!(f16, u16, rc);
12451250 match op {
......@@ -1272,7 +1277,7 @@ impl<'db> Evaluator<'db> {
12721277 ),
12731278 }
12741279 }
1275 chalk_ir::FloatTy::F32 => {
1280 rustc_type_ir::FloatTy::F32 => {
12761281 let l = from_bytes!(f32, lc);
12771282 let r = from_bytes!(f32, rc);
12781283 match op {
......@@ -1300,7 +1305,7 @@ impl<'db> Evaluator<'db> {
13001305 ),
13011306 }
13021307 }
1303 chalk_ir::FloatTy::F64 => {
1308 rustc_type_ir::FloatTy::F64 => {
13041309 let l = from_bytes!(f64, lc);
13051310 let r = from_bytes!(f64, rc);
13061311 match op {
......@@ -1328,7 +1333,7 @@ impl<'db> Evaluator<'db> {
13281333 ),
13291334 }
13301335 }
1331 chalk_ir::FloatTy::F128 => {
1336 rustc_type_ir::FloatTy::F128 => {
13321337 let l = from_bytes!(f128, u128, lc);
13331338 let r = from_bytes!(f128, u128, rc);
13341339 match op {
......@@ -1358,7 +1363,7 @@ impl<'db> Evaluator<'db> {
13581363 }
13591364 }
13601365 } else {
1361 let is_signed = matches!(ty.as_builtin(), Some(BuiltinType::Int(_)));
1366 let is_signed = matches!(ty.kind(), TyKind::Int(_));
13621367 let l128 = IntValue::from_bytes(lc, is_signed);
13631368 let r128 = IntValue::from_bytes(rc, is_signed);
13641369 match op {
......@@ -1429,7 +1434,7 @@ impl<'db> Evaluator<'db> {
14291434 Owned(result.to_le_bytes().to_vec())
14301435 }
14311436 Rvalue::Repeat(it, len) => {
1432 let len = match try_const_usize(self.db, len) {
1437 let len = match try_const_usize(self.db, *len) {
14331438 Some(it) => it as usize,
14341439 None => not_supported!("non evaluatable array len in repeat Rvalue"),
14351440 };
......@@ -1439,7 +1444,7 @@ impl<'db> Evaluator<'db> {
14391444 }
14401445 Rvalue::ShallowInitBox(_, _) => not_supported!("shallow init box"),
14411446 Rvalue::ShallowInitBoxWithAlloc(ty) => {
1442 let Some((size, align)) = self.size_align_of(ty, locals)? else {
1447 let Some((size, align)) = self.size_align_of(*ty, locals)? else {
14431448 not_supported!("unsized box initialization");
14441449 };
14451450 let addr = self.heap_allocate(size, align)?;
......@@ -1450,7 +1455,7 @@ impl<'db> Evaluator<'db> {
14501455 let values = values
14511456 .iter()
14521457 .map(|it| self.eval_operand(it, locals))
1453 .collect::<Result<Vec<_>>>()?;
1458 .collect::<Result<'db, Vec<_>>>()?;
14541459 match kind {
14551460 AggregateKind::Array(_) => {
14561461 let mut r = vec![];
......@@ -1461,7 +1466,7 @@ impl<'db> Evaluator<'db> {
14611466 Owned(r)
14621467 }
14631468 AggregateKind::Tuple(ty) => {
1464 let layout = self.layout(ty.to_nextsolver(interner))?;
1469 let layout = self.layout(*ty)?;
14651470 Owned(self.construct_with_layout(
14661471 layout.size.bytes_usize(),
14671472 &layout,
......@@ -1470,8 +1475,10 @@ impl<'db> Evaluator<'db> {
14701475 )?)
14711476 }
14721477 AggregateKind::Union(it, f) => {
1473 let layout =
1474 self.layout_adt((*it).into(), Substitution::empty(Interner))?;
1478 let layout = self.layout_adt(
1479 (*it).into(),
1480 GenericArgs::new_from_iter(self.interner(), []),
1481 )?;
14751482 let offset = layout
14761483 .fields
14771484 .offset(u32::from(f.local_id.into_raw()) as usize)
......@@ -1483,7 +1490,7 @@ impl<'db> Evaluator<'db> {
14831490 }
14841491 AggregateKind::Adt(it, subst) => {
14851492 let (size, variant_layout, tag) =
1486 self.layout_of_variant(*it, subst.clone(), locals)?;
1493 self.layout_of_variant(*it, *subst, locals)?;
14871494 Owned(self.construct_with_layout(
14881495 size,
14891496 &variant_layout,
......@@ -1492,7 +1499,7 @@ impl<'db> Evaluator<'db> {
14921499 )?)
14931500 }
14941501 AggregateKind::Closure(ty) => {
1495 let layout = self.layout(ty.to_nextsolver(interner))?;
1502 let layout = self.layout(*ty)?;
14961503 Owned(self.construct_with_layout(
14971504 layout.size.bytes_usize(),
14981505 &layout,
......@@ -1506,11 +1513,7 @@ impl<'db> Evaluator<'db> {
15061513 CastKind::PointerCoercion(cast) => match cast {
15071514 PointerCast::ReifyFnPointer | PointerCast::ClosureFnPointer(_) => {
15081515 let current_ty = self.operand_ty(operand, locals)?;
1509 if let TyKind::FnDef(_, _) | TyKind::Closure(_, _) =
1510 &current_ty.kind(Interner)
1511 {
1512 let interner = DbInterner::new_with(self.db, None, None);
1513 let current_ty = current_ty.to_nextsolver(interner);
1516 if let TyKind::FnDef(_, _) | TyKind::Closure(_, _) = current_ty.kind() {
15141517 let id = self.vtable_map.id(current_ty);
15151518 let ptr_size = self.ptr_size();
15161519 Owned(id.to_le_bytes()[0..ptr_size].to_vec())
......@@ -1523,7 +1526,7 @@ impl<'db> Evaluator<'db> {
15231526 PointerCast::Unsize => {
15241527 let current_ty = self.operand_ty(operand, locals)?;
15251528 let addr = self.eval_operand(operand, locals)?;
1526 self.coerce_unsized(addr, &current_ty, target_ty)?
1529 self.coerce_unsized(addr, current_ty, *target_ty)?
15271530 }
15281531 PointerCast::MutToConstPointer | PointerCast::UnsafeFnPointer => {
15291532 // This is no-op
......@@ -1540,40 +1543,34 @@ impl<'db> Evaluator<'db> {
15401543 | CastKind::PointerExposeAddress
15411544 | CastKind::PointerFromExposedAddress => {
15421545 let current_ty = self.operand_ty(operand, locals)?;
1543 let is_signed = matches!(
1544 current_ty.kind(Interner),
1545 TyKind::Scalar(chalk_ir::Scalar::Int(_))
1546 );
1546 let is_signed = matches!(current_ty.kind(), TyKind::Int(_));
15471547 let current = pad16(self.eval_operand(operand, locals)?.get(self)?, is_signed);
15481548 let dest_size =
1549 self.size_of_sized(target_ty, locals, "destination of int to int cast")?;
1549 self.size_of_sized(*target_ty, locals, "destination of int to int cast")?;
15501550 Owned(current[0..dest_size].to_vec())
15511551 }
15521552 CastKind::FloatToInt => {
15531553 let ty = self.operand_ty(operand, locals)?;
1554 let TyKind::Scalar(chalk_ir::Scalar::Float(ty)) = ty.kind(Interner) else {
1554 let TyKind::Float(ty) = ty.kind() else {
15551555 not_supported!("invalid float to int cast");
15561556 };
15571557 let value = self.eval_operand(operand, locals)?.get(self)?;
15581558 let value = match ty {
1559 chalk_ir::FloatTy::F32 => {
1559 rustc_type_ir::FloatTy::F32 => {
15601560 let value = value.try_into().unwrap();
15611561 f32::from_le_bytes(value) as f64
15621562 }
1563 chalk_ir::FloatTy::F64 => {
1563 rustc_type_ir::FloatTy::F64 => {
15641564 let value = value.try_into().unwrap();
15651565 f64::from_le_bytes(value)
15661566 }
1567 chalk_ir::FloatTy::F16 | chalk_ir::FloatTy::F128 => {
1567 rustc_type_ir::FloatTy::F16 | rustc_type_ir::FloatTy::F128 => {
15681568 not_supported!("unstable floating point type f16 and f128");
15691569 }
15701570 };
1571 let is_signed = matches!(
1572 target_ty.kind(Interner),
1573 TyKind::Scalar(chalk_ir::Scalar::Int(_))
1574 );
1571 let is_signed = matches!(target_ty.kind(), TyKind::Int(_));
15751572 let dest_size =
1576 self.size_of_sized(target_ty, locals, "destination of float to int cast")?;
1573 self.size_of_sized(*target_ty, locals, "destination of float to int cast")?;
15771574 let dest_bits = dest_size * 8;
15781575 let (max, min) = if dest_bits == 128 {
15791576 (i128::MAX, i128::MIN)
......@@ -1589,53 +1586,46 @@ impl<'db> Evaluator<'db> {
15891586 }
15901587 CastKind::FloatToFloat => {
15911588 let ty = self.operand_ty(operand, locals)?;
1592 let TyKind::Scalar(chalk_ir::Scalar::Float(ty)) = ty.kind(Interner) else {
1589 let TyKind::Float(ty) = ty.kind() else {
15931590 not_supported!("invalid float to int cast");
15941591 };
15951592 let value = self.eval_operand(operand, locals)?.get(self)?;
15961593 let value = match ty {
1597 chalk_ir::FloatTy::F32 => {
1594 rustc_type_ir::FloatTy::F32 => {
15981595 let value = value.try_into().unwrap();
15991596 f32::from_le_bytes(value) as f64
16001597 }
1601 chalk_ir::FloatTy::F64 => {
1598 rustc_type_ir::FloatTy::F64 => {
16021599 let value = value.try_into().unwrap();
16031600 f64::from_le_bytes(value)
16041601 }
1605 chalk_ir::FloatTy::F16 | chalk_ir::FloatTy::F128 => {
1602 rustc_type_ir::FloatTy::F16 | rustc_type_ir::FloatTy::F128 => {
16061603 not_supported!("unstable floating point type f16 and f128");
16071604 }
16081605 };
1609 let TyKind::Scalar(chalk_ir::Scalar::Float(target_ty)) =
1610 target_ty.kind(Interner)
1611 else {
1606 let TyKind::Float(target_ty) = target_ty.kind() else {
16121607 not_supported!("invalid float to float cast");
16131608 };
16141609 match target_ty {
1615 chalk_ir::FloatTy::F32 => Owned((value as f32).to_le_bytes().to_vec()),
1616 chalk_ir::FloatTy::F64 => Owned((value as f64).to_le_bytes().to_vec()),
1617 chalk_ir::FloatTy::F16 | chalk_ir::FloatTy::F128 => {
1610 rustc_type_ir::FloatTy::F32 => Owned((value as f32).to_le_bytes().to_vec()),
1611 rustc_type_ir::FloatTy::F64 => Owned((value as f64).to_le_bytes().to_vec()),
1612 rustc_type_ir::FloatTy::F16 | rustc_type_ir::FloatTy::F128 => {
16181613 not_supported!("unstable floating point type f16 and f128");
16191614 }
16201615 }
16211616 }
16221617 CastKind::IntToFloat => {
16231618 let current_ty = self.operand_ty(operand, locals)?;
1624 let is_signed = matches!(
1625 current_ty.kind(Interner),
1626 TyKind::Scalar(chalk_ir::Scalar::Int(_))
1627 );
1619 let is_signed = matches!(current_ty.kind(), TyKind::Int(_));
16281620 let value = pad16(self.eval_operand(operand, locals)?.get(self)?, is_signed);
16291621 let value = i128::from_le_bytes(value);
1630 let TyKind::Scalar(chalk_ir::Scalar::Float(target_ty)) =
1631 target_ty.kind(Interner)
1632 else {
1622 let TyKind::Float(target_ty) = target_ty.kind() else {
16331623 not_supported!("invalid int to float cast");
16341624 };
16351625 match target_ty {
1636 chalk_ir::FloatTy::F32 => Owned((value as f32).to_le_bytes().to_vec()),
1637 chalk_ir::FloatTy::F64 => Owned((value as f64).to_le_bytes().to_vec()),
1638 chalk_ir::FloatTy::F16 | chalk_ir::FloatTy::F128 => {
1626 rustc_type_ir::FloatTy::F32 => Owned((value as f32).to_le_bytes().to_vec()),
1627 rustc_type_ir::FloatTy::F64 => Owned((value as f64).to_le_bytes().to_vec()),
1628 rustc_type_ir::FloatTy::F16 | rustc_type_ir::FloatTy::F128 => {
16391629 not_supported!("unstable floating point type f16 and f128");
16401630 }
16411631 }
......@@ -1649,10 +1639,12 @@ impl<'db> Evaluator<'db> {
16491639 })
16501640 }
16511641
1652 fn compute_discriminant(&self, ty: Ty, bytes: &[u8]) -> Result<i128> {
1653 let interner = DbInterner::new_with(self.db, None, None);
1654 let layout = self.layout(ty.to_nextsolver(interner))?;
1655 let &TyKind::Adt(chalk_ir::AdtId(AdtId::EnumId(e)), _) = ty.kind(Interner) else {
1642 fn compute_discriminant(&self, ty: Ty<'db>, bytes: &[u8]) -> Result<'db, i128> {
1643 let layout = self.layout(ty)?;
1644 let TyKind::Adt(adt_def, _) = ty.kind() else {
1645 return Ok(0);
1646 };
1647 let AdtId::EnumId(e) = adt_def.def_id().0 else {
16561648 return Ok(0);
16571649 };
16581650 match &layout.variants {
......@@ -1694,35 +1686,35 @@ impl<'db> Evaluator<'db> {
16941686
16951687 fn coerce_unsized_look_through_fields<T>(
16961688 &self,
1697 ty: &Ty,
1698 goal: impl Fn(&TyKind) -> Option<T>,
1699 ) -> Result<T> {
1700 let kind = ty.kind(Interner);
1689 ty: Ty<'db>,
1690 goal: impl Fn(TyKind<'db>) -> Option<T>,
1691 ) -> Result<'db, T> {
1692 let kind = ty.kind();
17011693 if let Some(it) = goal(kind) {
17021694 return Ok(it);
17031695 }
1704 if let TyKind::Adt(id, subst) = kind
1705 && let AdtId::StructId(struct_id) = id.0
1696 if let TyKind::Adt(adt_ef, subst) = kind
1697 && let AdtId::StructId(struct_id) = adt_ef.def_id().0
17061698 {
1707 let field_types = self.db.field_types(struct_id.into());
1699 let field_types = self.db.field_types_ns(struct_id.into());
17081700 if let Some(ty) =
1709 field_types.iter().last().map(|it| it.1.clone().substitute(Interner, subst))
1701 field_types.iter().last().map(|it| it.1.instantiate(self.interner(), subst))
17101702 {
1711 return self.coerce_unsized_look_through_fields(&ty, goal);
1703 return self.coerce_unsized_look_through_fields(ty, goal);
17121704 }
17131705 }
1714 Err(MirEvalError::CoerceUnsizedError(ty.clone()))
1706 Err(MirEvalError::CoerceUnsizedError(ty))
17151707 }
17161708
17171709 fn coerce_unsized(
17181710 &mut self,
17191711 addr: Interval,
1720 current_ty: &Ty,
1721 target_ty: &Ty,
1722 ) -> Result<IntervalOrOwned> {
1723 fn for_ptr(it: &TyKind) -> Option<Ty> {
1712 current_ty: Ty<'db>,
1713 target_ty: Ty<'db>,
1714 ) -> Result<'db, IntervalOrOwned> {
1715 fn for_ptr<'db>(it: TyKind<'db>) -> Option<Ty<'db>> {
17241716 match it {
1725 TyKind::Raw(_, ty) | TyKind::Ref(_, _, ty) => Some(ty.clone()),
1717 TyKind::RawPtr(ty, _) | TyKind::Ref(_, ty, _) => Some(ty),
17261718 _ => None,
17271719 }
17281720 }
......@@ -1735,15 +1727,15 @@ impl<'db> Evaluator<'db> {
17351727 /// Adds metadata to the address and create the fat pointer result of the unsizing operation.
17361728 fn unsizing_ptr_from_addr(
17371729 &mut self,
1738 target_ty: Ty,
1739 current_ty: Ty,
1730 target_ty: Ty<'db>,
1731 current_ty: Ty<'db>,
17401732 addr: Interval,
1741 ) -> Result<IntervalOrOwned> {
1733 ) -> Result<'db, IntervalOrOwned> {
17421734 use IntervalOrOwned::*;
1743 Ok(match &target_ty.kind(Interner) {
1744 TyKind::Slice(_) => match &current_ty.kind(Interner) {
1735 Ok(match &target_ty.kind() {
1736 TyKind::Slice(_) => match &current_ty.kind() {
17451737 TyKind::Array(_, size) => {
1746 let len = match try_const_usize(self.db, size) {
1738 let len = match try_const_usize(self.db, *size) {
17471739 None => {
17481740 not_supported!("unevaluatble len of array in coerce unsized")
17491741 }
......@@ -1759,9 +1751,7 @@ impl<'db> Evaluator<'db> {
17591751 not_supported!("slice unsizing from non array type {t:?}")
17601752 }
17611753 },
1762 TyKind::Dyn(_) => {
1763 let interner = DbInterner::new_with(self.db, None, None);
1764 let current_ty = current_ty.to_nextsolver(interner);
1754 TyKind::Dynamic(..) => {
17651755 let vtable = self.vtable_map.id(current_ty);
17661756 let mut r = Vec::with_capacity(16);
17671757 let addr = addr.get(self)?;
......@@ -1769,12 +1759,14 @@ impl<'db> Evaluator<'db> {
17691759 r.extend(vtable.to_le_bytes());
17701760 Owned(r)
17711761 }
1772 TyKind::Adt(id, target_subst) => match &current_ty.kind(Interner) {
1773 TyKind::Adt(current_id, current_subst) => {
1762 TyKind::Adt(adt_def, target_subst) => match &current_ty.kind() {
1763 TyKind::Adt(current_adt_def, current_subst) => {
1764 let id = adt_def.def_id().0;
1765 let current_id = current_adt_def.def_id().0;
17741766 if id != current_id {
17751767 not_supported!("unsizing struct with different type");
17761768 }
1777 let id = match id.0 {
1769 let id = match id {
17781770 AdtId::StructId(s) => s,
17791771 AdtId::UnionId(_) => not_supported!("unsizing unions"),
17801772 AdtId::EnumId(_) => not_supported!("unsizing enums"),
......@@ -1783,12 +1775,10 @@ impl<'db> Evaluator<'db> {
17831775 else {
17841776 not_supported!("unsizing struct without field");
17851777 };
1786 let target_last_field = self.db.field_types(id.into())[last_field]
1787 .clone()
1788 .substitute(Interner, target_subst);
1789 let current_last_field = self.db.field_types(id.into())[last_field]
1790 .clone()
1791 .substitute(Interner, current_subst);
1778 let target_last_field = self.db.field_types_ns(id.into())[last_field]
1779 .instantiate(self.interner(), target_subst);
1780 let current_last_field = self.db.field_types_ns(id.into())[last_field]
1781 .instantiate(self.interner(), current_subst);
17921782 return self.unsizing_ptr_from_addr(
17931783 target_last_field,
17941784 current_last_field,
......@@ -1804,10 +1794,9 @@ impl<'db> Evaluator<'db> {
18041794 fn layout_of_variant(
18051795 &mut self,
18061796 it: VariantId,
1807 subst: Substitution,
1808 locals: &Locals,
1809 ) -> Result<(usize, Arc<Layout>, Option<(usize, usize, i128)>)> {
1810 let interner = DbInterner::new_with(self.db, None, None);
1797 subst: GenericArgs<'db>,
1798 locals: &Locals<'db>,
1799 ) -> Result<'db, (usize, Arc<Layout>, Option<(usize, usize, i128)>)> {
18111800 let adt = it.adt_id(self.db);
18121801 if let DefWithBodyId::VariantId(f) = locals.body.owner
18131802 && let VariantId::EnumVariantId(it) = it
......@@ -1817,11 +1806,7 @@ impl<'db> Evaluator<'db> {
18171806 // Computing the exact size of enums require resolving the enum discriminants. In order to prevent loops (and
18181807 // infinite sized type errors) we use a dummy layout
18191808 let i = self.const_eval_discriminant(it)?;
1820 return Ok((
1821 16,
1822 self.layout(crate::next_solver::Ty::new_empty_tuple(interner))?,
1823 Some((0, 16, i)),
1824 ));
1809 return Ok((16, self.layout(Ty::new_empty_tuple(self.interner()))?, Some((0, 16, i))));
18251810 }
18261811 let layout = self.layout_adt(adt, subst)?;
18271812 Ok(match &layout.variants {
......@@ -1874,7 +1859,7 @@ impl<'db> Evaluator<'db> {
18741859 variant_layout: &Layout,
18751860 tag: Option<(usize, usize, i128)>,
18761861 values: impl Iterator<Item = IntervalOrOwned>,
1877 ) -> Result<Vec<u8>> {
1862 ) -> Result<'db, Vec<u8>> {
18781863 let mut result = vec![0; size];
18791864 if let Some((offset, size, value)) = tag {
18801865 match result.get_mut(offset..offset + size) {
......@@ -1904,7 +1889,11 @@ impl<'db> Evaluator<'db> {
19041889 Ok(result)
19051890 }
19061891
1907 fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<Interval> {
1892 fn eval_operand(
1893 &mut self,
1894 it: &Operand<'db>,
1895 locals: &mut Locals<'db>,
1896 ) -> Result<'db, Interval> {
19081897 Ok(match &it.kind {
19091898 OperandKind::Copy(p) | OperandKind::Move(p) => {
19101899 locals.drop_flags.remove_place(p, &locals.body.projection_store);
......@@ -1914,25 +1903,28 @@ impl<'db> Evaluator<'db> {
19141903 let addr = self.eval_static(*st, locals)?;
19151904 Interval::new(addr, self.ptr_size())
19161905 }
1917 OperandKind::Constant(konst) => self.allocate_const_in_heap(locals, konst)?,
1906 OperandKind::Constant { konst, .. } => self.allocate_const_in_heap(locals, *konst)?,
19181907 })
19191908 }
19201909
19211910 #[allow(clippy::double_parens)]
1922 fn allocate_const_in_heap(&mut self, locals: &Locals, konst: &Const) -> Result<Interval> {
1923 let interner = DbInterner::new_with(self.db, None, None);
1924 let ConstData { ty, value: chalk_ir::ConstValue::Concrete(c) } = &konst.data(Interner)
1925 else {
1926 not_supported!("evaluating non concrete constant");
1927 };
1911 fn allocate_const_in_heap(
1912 &mut self,
1913 locals: &Locals<'db>,
1914 konst: Const<'db>,
1915 ) -> Result<'db, Interval> {
19281916 let result_owner;
1929 let (v, memory_map) = match &c.interned {
1930 ConstScalar::Bytes(v, mm) => (v, mm),
1931 ConstScalar::UnevaluatedConst(const_id, subst) => 'b: {
1932 let mut const_id = *const_id;
1933 let mut subst = subst.clone();
1917 let value = match konst.kind() {
1918 ConstKind::Value(value) => value,
1919 ConstKind::Unevaluated(UnevaluatedConst { def: const_id, args: subst }) => 'b: {
1920 let mut const_id = match const_id {
1921 SolverDefId::ConstId(it) => GeneralConstId::from(it),
1922 SolverDefId::StaticId(it) => it.into(),
1923 _ => unreachable!("unevaluated consts should be consts or statics"),
1924 };
1925 let mut subst = subst;
19341926 if let hir_def::GeneralConstId::ConstId(c) = const_id {
1935 let (c, s) = lookup_impl_const(self.db, self.trait_env.clone(), c, subst);
1927 let (c, s) = lookup_impl_const(&self.infcx, self.trait_env.clone(), c, subst);
19361928 const_id = hir_def::GeneralConstId::ConstId(c);
19371929 subst = s;
19381930 }
......@@ -1943,15 +1935,15 @@ impl<'db> Evaluator<'db> {
19431935 let name = const_id.name(self.db);
19441936 MirEvalError::ConstEvalError(name, Box::new(e))
19451937 })?;
1946 if let chalk_ir::ConstValue::Concrete(c) = &result_owner.data(Interner).value
1947 && let ConstScalar::Bytes(v, mm) = &c.interned
1948 {
1949 break 'b (v, mm);
1938 if let ConstKind::Value(value) = result_owner.kind() {
1939 break 'b value;
19501940 }
19511941 not_supported!("unevaluatable constant");
19521942 }
1953 ConstScalar::Unknown => not_supported!("evaluating unknown const"),
1943 _ => not_supported!("evaluating unknown const"),
19541944 };
1945 let ValueConst { ty, value } = value;
1946 let ConstBytes { memory: v, memory_map } = value.inner();
19551947 let patch_map = memory_map.transform_addresses(|b, align| {
19561948 let addr = self.heap_allocate(b.len(), align)?;
19571949 self.write_memory(addr, b)?;
......@@ -1965,7 +1957,7 @@ impl<'db> Evaluator<'db> {
19651957 } else if size < 16 && v.len() == 16 {
19661958 Cow::Borrowed(&v[0..size])
19671959 } else {
1968 return Err(MirEvalError::InvalidConst(konst.clone()));
1960 return Err(MirEvalError::InvalidConst(konst));
19691961 }
19701962 } else {
19711963 Cow::Borrowed(v)
......@@ -1981,21 +1973,21 @@ impl<'db> Evaluator<'db> {
19811973 MemoryMap::Complex(cm) => cm.vtable.ty_of_bytes(bytes),
19821974 },
19831975 addr,
1984 ty.to_nextsolver(interner),
1976 ty,
19851977 locals,
19861978 )?;
19871979 Ok(Interval::new(addr, size))
19881980 }
19891981
1990 fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<Interval> {
1982 fn eval_place(&mut self, p: &Place<'db>, locals: &Locals<'db>) -> Result<'db, Interval> {
19911983 let addr = self.place_addr(p, locals)?;
19921984 Ok(Interval::new(
19931985 addr,
1994 self.size_of_sized(&self.place_ty(p, locals)?, locals, "type of this place")?,
1986 self.size_of_sized(self.place_ty(p, locals)?, locals, "type of this place")?,
19951987 ))
19961988 }
19971989
1998 fn read_memory(&self, addr: Address, size: usize) -> Result<&[u8]> {
1990 fn read_memory(&self, addr: Address, size: usize) -> Result<'db, &[u8]> {
19991991 if size == 0 {
20001992 return Ok(&[]);
20011993 }
......@@ -2012,7 +2004,7 @@ impl<'db> Evaluator<'db> {
20122004 .ok_or_else(|| MirEvalError::UndefinedBehavior("out of bound memory read".to_owned()))
20132005 }
20142006
2015 fn write_memory_using_ref(&mut self, addr: Address, size: usize) -> Result<&mut [u8]> {
2007 fn write_memory_using_ref(&mut self, addr: Address, size: usize) -> Result<'db, &mut [u8]> {
20162008 let (mem, pos) = match addr {
20172009 Stack(it) => (&mut self.stack, it),
20182010 Heap(it) => (&mut self.heap, it),
......@@ -2026,7 +2018,7 @@ impl<'db> Evaluator<'db> {
20262018 .ok_or_else(|| MirEvalError::UndefinedBehavior("out of bound memory write".to_owned()))
20272019 }
20282020
2029 fn write_memory(&mut self, addr: Address, r: &[u8]) -> Result<()> {
2021 fn write_memory(&mut self, addr: Address, r: &[u8]) -> Result<'db, ()> {
20302022 if r.is_empty() {
20312023 return Ok(());
20322024 }
......@@ -2034,14 +2026,18 @@ impl<'db> Evaluator<'db> {
20342026 Ok(())
20352027 }
20362028
2037 fn copy_from_interval_or_owned(&mut self, addr: Address, r: IntervalOrOwned) -> Result<()> {
2029 fn copy_from_interval_or_owned(
2030 &mut self,
2031 addr: Address,
2032 r: IntervalOrOwned,
2033 ) -> Result<'db, ()> {
20382034 match r {
20392035 IntervalOrOwned::Borrowed(r) => self.copy_from_interval(addr, r),
20402036 IntervalOrOwned::Owned(r) => self.write_memory(addr, &r),
20412037 }
20422038 }
20432039
2044 fn copy_from_interval(&mut self, addr: Address, r: Interval) -> Result<()> {
2040 fn copy_from_interval(&mut self, addr: Address, r: Interval) -> Result<'db, ()> {
20452041 if r.size == 0 {
20462042 return Ok(());
20472043 }
......@@ -2083,9 +2079,12 @@ impl<'db> Evaluator<'db> {
20832079 Ok(())
20842080 }
20852081
2086 fn size_align_of(&self, ty: &Ty, locals: &Locals) -> Result<Option<(usize, usize)>> {
2087 let interner = DbInterner::new_with(self.db, None, None);
2088 if let Some(layout) = self.layout_cache.borrow().get(&ty.to_nextsolver(interner)) {
2082 fn size_align_of(
2083 &self,
2084 ty: Ty<'db>,
2085 locals: &Locals<'db>,
2086 ) -> Result<'db, Option<(usize, usize)>> {
2087 if let Some(layout) = self.layout_cache.borrow().get(&ty) {
20892088 return Ok(layout
20902089 .is_sized()
20912090 .then(|| (layout.size.bytes_usize(), layout.align.bytes() as usize)));
......@@ -2098,24 +2097,27 @@ impl<'db> Evaluator<'db> {
20982097 // infinite sized type errors) we use a dummy size
20992098 return Ok(Some((16, 16)));
21002099 }
2101 let layout = self.layout(ty.to_nextsolver(interner));
2100 let layout = self.layout(ty);
21022101 if self.assert_placeholder_ty_is_unused
21032102 && matches!(layout, Err(MirEvalError::LayoutError(LayoutError::HasPlaceholder, _)))
21042103 {
21052104 return Ok(Some((0, 1)));
21062105 }
21072106 let layout = layout?;
2108 Ok(layout
2109 .is_sized()
2110 .then(|| (layout.size.bytes_usize(), layout.align.bytes() as usize)))
2107 Ok(layout.is_sized().then(|| (layout.size.bytes_usize(), layout.align.bytes() as usize)))
21112108 }
21122109
21132110 /// A version of `self.size_of` which returns error if the type is unsized. `what` argument should
21142111 /// be something that complete this: `error: type {ty} was unsized. {what} should be sized`
2115 fn size_of_sized(&self, ty: &Ty, locals: &Locals, what: &'static str) -> Result<usize> {
2112 fn size_of_sized(
2113 &self,
2114 ty: Ty<'db>,
2115 locals: &Locals<'db>,
2116 what: &'static str,
2117 ) -> Result<'db, usize> {
21162118 match self.size_align_of(ty, locals)? {
21172119 Some(it) => Ok(it.0),
2118 None => Err(MirEvalError::TypeIsUnsized(ty.clone(), what)),
2120 None => Err(MirEvalError::TypeIsUnsized(ty, what)),
21192121 }
21202122 }
21212123
......@@ -2123,17 +2125,17 @@ impl<'db> Evaluator<'db> {
21232125 /// be something that complete this: `error: type {ty} was unsized. {what} should be sized`
21242126 fn size_align_of_sized(
21252127 &self,
2126 ty: &Ty,
2127 locals: &Locals,
2128 ty: Ty<'db>,
2129 locals: &Locals<'db>,
21282130 what: &'static str,
2129 ) -> Result<(usize, usize)> {
2131 ) -> Result<'db, (usize, usize)> {
21302132 match self.size_align_of(ty, locals)? {
21312133 Some(it) => Ok(it),
2132 None => Err(MirEvalError::TypeIsUnsized(ty.clone(), what)),
2134 None => Err(MirEvalError::TypeIsUnsized(ty, what)),
21332135 }
21342136 }
21352137
2136 fn heap_allocate(&mut self, size: usize, align: usize) -> Result<Address> {
2138 fn heap_allocate(&mut self, size: usize, align: usize) -> Result<'db, Address> {
21372139 if !align.is_power_of_two() || align > 10000 {
21382140 return Err(MirEvalError::UndefinedBehavior(format!("Alignment {align} is invalid")));
21392141 }
......@@ -2164,23 +2166,22 @@ impl<'db> Evaluator<'db> {
21642166 fn create_memory_map(
21652167 &self,
21662168 bytes: &[u8],
2167 ty: &Ty,
2168 locals: &Locals,
2169 ) -> Result<ComplexMemoryMap<'db>> {
2169 ty: Ty<'db>,
2170 locals: &Locals<'db>,
2171 ) -> Result<'db, ComplexMemoryMap<'db>> {
21702172 fn rec<'db>(
21712173 this: &Evaluator<'db>,
21722174 bytes: &[u8],
2173 ty: &Ty,
2174 locals: &Locals,
2175 ty: Ty<'db>,
2176 locals: &Locals<'db>,
21752177 mm: &mut ComplexMemoryMap<'db>,
21762178 stack_depth_limit: usize,
2177 ) -> Result<()> {
2178 let interner = DbInterner::new_with(this.db, None, None);
2179 ) -> Result<'db, ()> {
21792180 if stack_depth_limit.checked_sub(1).is_none() {
21802181 return Err(MirEvalError::StackOverflow);
21812182 }
2182 match ty.kind(Interner) {
2183 TyKind::Ref(_, _, t) => {
2183 match ty.kind() {
2184 TyKind::Ref(_, t, _) => {
21842185 let size = this.size_align_of(t, locals)?;
21852186 match size {
21862187 Some((size, _)) => {
......@@ -2193,29 +2194,28 @@ impl<'db> Evaluator<'db> {
21932194 None => {
21942195 let mut check_inner = None;
21952196 let (addr, meta) = bytes.split_at(bytes.len() / 2);
2196 let element_size = match t.kind(Interner) {
2197 let element_size = match t.kind() {
21972198 TyKind::Str => 1,
21982199 TyKind::Slice(t) => {
2199 check_inner = Some(t.clone());
2200 check_inner = Some(t);
22002201 this.size_of_sized(t, locals, "slice inner type")?
22012202 }
2202 TyKind::Dyn(_) => {
2203 TyKind::Dynamic(..) => {
22032204 let t = this.vtable_map.ty_of_bytes(meta)?;
2204 let t = convert_ty_for_result(interner, t);
2205 check_inner = Some(t.clone());
2206 this.size_of_sized(&t, locals, "dyn concrete type")?
2205 check_inner = Some(t);
2206 this.size_of_sized(t, locals, "dyn concrete type")?
22072207 }
22082208 _ => return Ok(()),
22092209 };
2210 let count = match t.kind(Interner) {
2211 TyKind::Dyn(_) => 1,
2210 let count = match t.kind() {
2211 TyKind::Dynamic(..) => 1,
22122212 _ => from_bytes!(usize, meta),
22132213 };
22142214 let size = element_size * count;
22152215 let addr = Address::from_bytes(addr)?;
22162216 let b = this.read_memory(addr, size)?;
22172217 mm.insert(addr.to_usize(), b.into());
2218 if let Some(ty) = &check_inner {
2218 if let Some(ty) = check_inner {
22192219 for i in 0..count {
22202220 let offset = element_size * i;
22212221 rec(
......@@ -2249,12 +2249,11 @@ impl<'db> Evaluator<'db> {
22492249 )?;
22502250 }
22512251 }
2252 TyKind::Tuple(_, subst) => {
2253 let layout = this.layout(ty.to_nextsolver(interner))?;
2254 for (id, ty) in subst.iter(Interner).enumerate() {
2255 let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
2252 TyKind::Tuple(subst) => {
2253 let layout = this.layout(ty)?;
2254 for (id, ty) in subst.iter().enumerate() {
22562255 let offset = layout.fields.offset(id).bytes_usize();
2257 let size = this.layout(ty.to_nextsolver(interner))?.size.bytes_usize();
2256 let size = this.layout(ty)?.size.bytes_usize();
22582257 rec(
22592258 this,
22602259 &bytes[offset..offset + size],
......@@ -2265,18 +2264,18 @@ impl<'db> Evaluator<'db> {
22652264 )?;
22662265 }
22672266 }
2268 TyKind::Adt(adt, subst) => match adt.0 {
2267 TyKind::Adt(adt, subst) => match adt.def_id().0 {
22692268 AdtId::StructId(s) => {
22702269 let data = s.fields(this.db);
2271 let layout = this.layout(ty.to_nextsolver(interner))?;
2272 let field_types = this.db.field_types(s.into());
2270 let layout = this.layout(ty)?;
2271 let field_types = this.db.field_types_ns(s.into());
22732272 for (f, _) in data.fields().iter() {
22742273 let offset = layout
22752274 .fields
22762275 .offset(u32::from(f.into_raw()) as usize)
22772276 .bytes_usize();
2278 let ty = &field_types[f].clone().substitute(Interner, subst);
2279 let size = this.layout(ty.to_nextsolver(interner))?.size.bytes_usize();
2277 let ty = field_types[f].instantiate(this.interner(), subst);
2278 let size = this.layout(ty)?.size.bytes_usize();
22802279 rec(
22812280 this,
22822281 &bytes[offset..offset + size],
......@@ -2288,7 +2287,7 @@ impl<'db> Evaluator<'db> {
22882287 }
22892288 }
22902289 AdtId::EnumId(e) => {
2291 let layout = this.layout(ty.to_nextsolver(interner))?;
2290 let layout = this.layout(ty)?;
22922291 if let Some((v, l)) = detect_variant_from_bytes(
22932292 &layout,
22942293 this.db,
......@@ -2297,13 +2296,12 @@ impl<'db> Evaluator<'db> {
22972296 e,
22982297 ) {
22992298 let data = v.fields(this.db);
2300 let field_types = this.db.field_types(v.into());
2299 let field_types = this.db.field_types_ns(v.into());
23012300 for (f, _) in data.fields().iter() {
23022301 let offset =
23032302 l.fields.offset(u32::from(f.into_raw()) as usize).bytes_usize();
2304 let ty = &field_types[f].clone().substitute(Interner, subst);
2305 let size =
2306 this.layout(ty.to_nextsolver(interner))?.size.bytes_usize();
2303 let ty = field_types[f].instantiate(this.interner(), subst);
2304 let size = this.layout(ty)?.size.bytes_usize();
23072305 rec(
23082306 this,
23092307 &bytes[offset..offset + size],
......@@ -2317,9 +2315,17 @@ impl<'db> Evaluator<'db> {
23172315 }
23182316 AdtId::UnionId(_) => (),
23192317 },
2320 TyKind::Alias(AliasTy::Projection(proj)) => {
2321 let ty = this.db.normalize_projection(proj.clone(), this.trait_env.clone());
2322 rec(this, bytes, &ty, locals, mm, stack_depth_limit - 1)?;
2318 TyKind::Alias(AliasTyKind::Projection, _) => {
2319 let mut ocx = ObligationCtxt::new(&this.infcx);
2320 let ty = ocx
2321 .structurally_normalize_ty(
2322 &ObligationCause::dummy(),
2323 this.trait_env.env,
2324 ty,
2325 )
2326 .map_err(|_| MirEvalError::NotSupported("couldn't normalize".to_owned()))?;
2327
2328 rec(this, bytes, ty, locals, mm, stack_depth_limit - 1)?;
23232329 }
23242330 _ => (),
23252331 }
......@@ -2333,23 +2339,18 @@ impl<'db> Evaluator<'db> {
23332339 fn patch_addresses(
23342340 &mut self,
23352341 patch_map: &FxHashMap<usize, usize>,
2336 ty_of_bytes: impl Fn(&[u8]) -> Result<crate::next_solver::Ty<'db>> + Copy,
2342 ty_of_bytes: impl Fn(&[u8]) -> Result<'db, Ty<'db>> + Copy,
23372343 addr: Address,
2338 ty: crate::next_solver::Ty<'db>,
2339 locals: &Locals,
2340 ) -> Result<()> {
2341 let interner = DbInterner::new_with(self.db, None, None);
2344 ty: Ty<'db>,
2345 locals: &Locals<'db>,
2346 ) -> Result<'db, ()> {
23422347 // FIXME: support indirect references
23432348 let layout = self.layout(ty)?;
2344 let my_size = self.size_of_sized(
2345 &convert_ty_for_result(interner, ty),
2346 locals,
2347 "value to patch address",
2348 )?;
2349 let my_size = self.size_of_sized(ty, locals, "value to patch address")?;
23492350 use rustc_type_ir::TyKind;
23502351 match ty.kind() {
23512352 TyKind::Ref(_, t, _) => {
2352 let size = self.size_align_of(&convert_ty_for_result(interner, t), locals)?;
2353 let size = self.size_align_of(t, locals)?;
23532354 match size {
23542355 Some(_) => {
23552356 let current = from_bytes!(usize, self.read_memory(addr, my_size)?);
......@@ -2374,7 +2375,7 @@ impl<'db> Evaluator<'db> {
23742375 AdtId::StructId(s) => {
23752376 for (i, (_, ty)) in self.db.field_types_ns(s.into()).iter().enumerate() {
23762377 let offset = layout.fields.offset(i).bytes_usize();
2377 let ty = ty.instantiate(interner, args);
2378 let ty = ty.instantiate(self.interner(), args);
23782379 self.patch_addresses(
23792380 patch_map,
23802381 ty_of_bytes,
......@@ -2395,7 +2396,7 @@ impl<'db> Evaluator<'db> {
23952396 ) {
23962397 for (i, (_, ty)) in self.db.field_types_ns(ev.into()).iter().enumerate() {
23972398 let offset = layout.fields.offset(i).bytes_usize();
2398 let ty = ty.instantiate(interner, args);
2399 let ty = ty.instantiate(self.interner(), args);
23992400 self.patch_addresses(
24002401 patch_map,
24012402 ty_of_bytes,
......@@ -2414,15 +2415,11 @@ impl<'db> Evaluator<'db> {
24142415 }
24152416 }
24162417 TyKind::Array(inner, len) => {
2417 let len = match consteval_nextsolver::try_const_usize(self.db, len) {
2418 let len = match consteval::try_const_usize(self.db, len) {
24182419 Some(it) => it as usize,
24192420 None => not_supported!("non evaluatable array len in patching addresses"),
24202421 };
2421 let size = self.size_of_sized(
2422 &convert_ty_for_result(interner, inner),
2423 locals,
2424 "inner of array",
2425 )?;
2422 let size = self.size_of_sized(inner, locals, "inner of array")?;
24262423 for i in 0..len {
24272424 self.patch_addresses(
24282425 patch_map,
......@@ -2465,29 +2462,22 @@ impl<'db> Evaluator<'db> {
24652462 &mut self,
24662463 bytes: Interval,
24672464 destination: Interval,
2468 args: &[IntervalAndTy],
2469 locals: &Locals,
2470 target_bb: Option<BasicBlockId>,
2465 args: &[IntervalAndTy<'db>],
2466 locals: &Locals<'db>,
2467 target_bb: Option<BasicBlockId<'db>>,
24712468 span: MirSpan,
2472 ) -> Result<Option<StackFrame>> {
2469 ) -> Result<'db, Option<StackFrame<'db>>> {
24732470 let id = from_bytes!(usize, bytes.get(self)?);
24742471 let next_ty = self.vtable_map.ty(id)?;
2475 let interner = DbInterner::new_with(self.db, None, None);
24762472 use rustc_type_ir::TyKind;
24772473 match next_ty.kind() {
2478 TyKind::FnDef(def, generic_args) => self.exec_fn_def(
2479 def.0,
2480 &convert_args_for_result(interner, generic_args.as_slice()),
2481 destination,
2482 args,
2483 locals,
2484 target_bb,
2485 span,
2486 ),
2474 TyKind::FnDef(def, generic_args) => {
2475 self.exec_fn_def(def.0, generic_args, destination, args, locals, target_bb, span)
2476 }
24872477 TyKind::Closure(id, generic_args) => self.exec_closure(
2488 id.0.into(),
2478 id.0,
24892479 bytes.slice(0..0),
2490 &convert_args_for_result(interner, generic_args.as_slice()),
2480 generic_args,
24912481 destination,
24922482 args,
24932483 locals,
......@@ -2499,21 +2489,17 @@ impl<'db> Evaluator<'db> {
24992489
25002490 fn exec_closure(
25012491 &mut self,
2502 closure: ClosureId,
2492 closure: InternedClosureId,
25032493 closure_data: Interval,
2504 generic_args: &Substitution,
2494 generic_args: GenericArgs<'db>,
25052495 destination: Interval,
2506 args: &[IntervalAndTy],
2507 locals: &Locals,
2496 args: &[IntervalAndTy<'db>],
2497 locals: &Locals<'db>,
25082498 span: MirSpan,
2509 ) -> Result<Option<StackFrame>> {
2499 ) -> Result<'db, Option<StackFrame<'db>>> {
25102500 let mir_body = self
25112501 .db
2512 .monomorphized_mir_body_for_closure(
2513 closure.into(),
2514 generic_args.clone(),
2515 self.trait_env.clone(),
2516 )
2502 .monomorphized_mir_body_for_closure(closure, generic_args, self.trait_env.clone())
25172503 .map_err(|it| MirEvalError::MirLowerErrorForClosure(closure, it))?;
25182504 let closure_data = if mir_body.locals[mir_body.param_locals[0]].ty.as_reference().is_some()
25192505 {
......@@ -2523,7 +2509,7 @@ impl<'db> Evaluator<'db> {
25232509 };
25242510 let arg_bytes = iter::once(Ok(closure_data))
25252511 .chain(args.iter().map(|it| Ok(it.get(self)?.to_owned())))
2526 .collect::<Result<Vec<_>>>()?;
2512 .collect::<Result<'db, Vec<_>>>()?;
25272513 let interval = self
25282514 .interpret_mir(mir_body, arg_bytes.into_iter().map(IntervalOrOwned::Owned))
25292515 .map_err(|e| {
......@@ -2539,14 +2525,13 @@ impl<'db> Evaluator<'db> {
25392525 fn exec_fn_def(
25402526 &mut self,
25412527 def: CallableDefId,
2542 generic_args: &Substitution,
2528 generic_args: GenericArgs<'db>,
25432529 destination: Interval,
2544 args: &[IntervalAndTy],
2545 locals: &Locals,
2546 target_bb: Option<BasicBlockId>,
2530 args: &[IntervalAndTy<'db>],
2531 locals: &Locals<'db>,
2532 target_bb: Option<BasicBlockId<'db>>,
25472533 span: MirSpan,
2548 ) -> Result<Option<StackFrame>> {
2549 let generic_args = generic_args.clone();
2534 ) -> Result<'db, Option<StackFrame<'db>>> {
25502535 match def {
25512536 CallableDefId::FunctionId(def) => {
25522537 if self.detect_fn_trait(def).is_some() {
......@@ -2600,22 +2585,22 @@ impl<'db> Evaluator<'db> {
26002585 fn get_mir_or_dyn_index(
26012586 &self,
26022587 def: FunctionId,
2603 generic_args: Substitution,
2604 locals: &Locals,
2588 generic_args: GenericArgs<'db>,
2589 locals: &Locals<'db>,
26052590 span: MirSpan,
2606 ) -> Result<MirOrDynIndex> {
2591 ) -> Result<'db, MirOrDynIndex<'db>> {
26072592 let pair = (def, generic_args);
26082593 if let Some(r) = self.mir_or_dyn_index_cache.borrow().get(&pair) {
26092594 return Ok(r.clone());
26102595 }
26112596 let (def, generic_args) = pair;
26122597 let r = if let Some(self_ty_idx) =
2613 is_dyn_method(self.db, self.trait_env.clone(), def, generic_args.clone())
2598 is_dyn_method(self.interner(), self.trait_env.clone(), def, generic_args)
26142599 {
26152600 MirOrDynIndex::Dyn(self_ty_idx)
26162601 } else {
26172602 let (imp, generic_args) =
2618 self.db.lookup_impl_method(self.trait_env.clone(), def, generic_args.clone());
2603 self.db.lookup_impl_method(self.trait_env.clone(), def, generic_args);
26192604
26202605 let mir_body = self
26212606 .db
......@@ -2635,18 +2620,17 @@ impl<'db> Evaluator<'db> {
26352620 fn exec_fn_with_args(
26362621 &mut self,
26372622 mut def: FunctionId,
2638 args: &[IntervalAndTy],
2639 generic_args: Substitution,
2640 locals: &Locals,
2623 args: &[IntervalAndTy<'db>],
2624 generic_args: GenericArgs<'db>,
2625 locals: &Locals<'db>,
26412626 destination: Interval,
2642 target_bb: Option<BasicBlockId>,
2627 target_bb: Option<BasicBlockId<'db>>,
26432628 span: MirSpan,
2644 ) -> Result<Option<StackFrame>> {
2645 let interner = DbInterner::new_with(self.db, None, None);
2629 ) -> Result<'db, Option<StackFrame<'db>>> {
26462630 if self.detect_and_exec_special_function(
26472631 def,
26482632 args,
2649 &generic_args,
2633 generic_args,
26502634 locals,
26512635 destination,
26522636 span,
......@@ -2657,7 +2641,7 @@ impl<'db> Evaluator<'db> {
26572641 def = redirect_def;
26582642 }
26592643 let arg_bytes = args.iter().map(|it| IntervalOrOwned::Borrowed(it.interval));
2660 match self.get_mir_or_dyn_index(def, generic_args.clone(), locals, span)? {
2644 match self.get_mir_or_dyn_index(def, generic_args, locals, span)? {
26612645 MirOrDynIndex::Dyn(self_ty_idx) => {
26622646 // In the layout of current possible receiver, which at the moment of writing this code is one of
26632647 // `&T`, `&mut T`, `Box<T>`, `Rc<T>`, `Arc<T>`, and `Pin<P>` where `P` is one of possible receivers,
......@@ -2669,18 +2653,16 @@ impl<'db> Evaluator<'db> {
26692653 .vtable_map
26702654 .ty_of_bytes(&first_arg[self.ptr_size()..self.ptr_size() * 2])?;
26712655 let mut args_for_target = args.to_vec();
2672 let ty = convert_ty_for_result(interner, ty);
26732656 args_for_target[0] = IntervalAndTy {
26742657 interval: args_for_target[0].interval.slice(0..self.ptr_size()),
2675 ty: ty.clone(),
2658 ty,
26762659 };
2677 let ty = ty.clone().cast(Interner);
2678 let generics_for_target = Substitution::from_iter(
2679 Interner,
2660 let generics_for_target = GenericArgs::new_from_iter(
2661 self.interner(),
26802662 generic_args
2681 .iter(Interner)
2663 .iter()
26822664 .enumerate()
2683 .map(|(i, it)| if i == self_ty_idx { &ty } else { it }),
2665 .map(|(i, it)| if i == self_ty_idx { ty.into() } else { it }),
26842666 );
26852667 self.exec_fn_with_args(
26862668 def,
......@@ -2706,14 +2688,14 @@ impl<'db> Evaluator<'db> {
27062688
27072689 fn exec_looked_up_function(
27082690 &mut self,
2709 mir_body: Arc<MirBody>,
2710 locals: &Locals,
2691 mir_body: Arc<MirBody<'db>>,
2692 locals: &Locals<'db>,
27112693 def: FunctionId,
27122694 arg_bytes: impl Iterator<Item = IntervalOrOwned>,
27132695 span: MirSpan,
27142696 destination: Interval,
2715 target_bb: Option<BasicBlockId>,
2716 ) -> Result<Option<StackFrame>> {
2697 target_bb: Option<BasicBlockId<'db>>,
2698 ) -> Result<'db, Option<StackFrame<'db>>> {
27172699 Ok(if let Some(target_bb) = target_bb {
27182700 let (mut locals, prev_stack_ptr) =
27192701 self.create_locals_for_body(&mir_body, Some(destination))?;
......@@ -2735,47 +2717,40 @@ impl<'db> Evaluator<'db> {
27352717 fn exec_fn_trait(
27362718 &mut self,
27372719 def: FunctionId,
2738 args: &[IntervalAndTy],
2739 generic_args: Substitution,
2740 locals: &Locals,
2720 args: &[IntervalAndTy<'db>],
2721 generic_args: GenericArgs<'db>,
2722 locals: &Locals<'db>,
27412723 destination: Interval,
2742 target_bb: Option<BasicBlockId>,
2724 target_bb: Option<BasicBlockId<'db>>,
27432725 span: MirSpan,
2744 ) -> Result<Option<StackFrame>> {
2745 let interner = DbInterner::new_with(self.db, None, None);
2726 ) -> Result<'db, Option<StackFrame<'db>>> {
27462727 let func = args
27472728 .first()
27482729 .ok_or_else(|| MirEvalError::InternalError("fn trait with no arg".into()))?;
2749 let mut func_ty = func.ty.clone();
2730 let mut func_ty = func.ty;
27502731 let mut func_data = func.interval;
2751 while let TyKind::Ref(_, _, z) = func_ty.kind(Interner) {
2752 func_ty = z.clone();
2753 if matches!(func_ty.kind(Interner), TyKind::Dyn(_)) {
2732 while let TyKind::Ref(_, z, _) = func_ty.kind() {
2733 func_ty = z;
2734 if matches!(func_ty.kind(), TyKind::Dynamic(..)) {
27542735 let id =
27552736 from_bytes!(usize, &func_data.get(self)?[self.ptr_size()..self.ptr_size() * 2]);
27562737 func_data = func_data.slice(0..self.ptr_size());
2757 func_ty = convert_ty_for_result(interner, self.vtable_map.ty(id)?);
2738 func_ty = self.vtable_map.ty(id)?;
27582739 }
2759 let size = self.size_of_sized(&func_ty, locals, "self type of fn trait")?;
2740 let size = self.size_of_sized(func_ty, locals, "self type of fn trait")?;
27602741 func_data = Interval { addr: Address::from_bytes(func_data.get(self)?)?, size };
27612742 }
2762 match &func_ty.kind(Interner) {
2763 TyKind::FnDef(def, subst) => self.exec_fn_def(
2764 CallableDefId::from_chalk(self.db, *def),
2765 subst,
2766 destination,
2767 &args[1..],
2768 locals,
2769 target_bb,
2770 span,
2771 ),
2772 TyKind::Function(_) => {
2743 match func_ty.kind() {
2744 TyKind::FnDef(def, subst) => {
2745 self.exec_fn_def(def.0, subst, destination, &args[1..], locals, target_bb, span)
2746 }
2747 TyKind::FnPtr(..) => {
27732748 self.exec_fn_pointer(func_data, destination, &args[1..], locals, target_bb, span)
27742749 }
27752750 TyKind::Closure(closure, subst) => self.exec_closure(
2776 *closure,
2751 closure.0,
27772752 func_data,
2778 &ClosureSubst(subst).parent_subst(self.db),
2753 subst.split_closure_args_untupled().parent_args,
27792754 destination,
27802755 &args[1..],
27812756 locals,
......@@ -2786,12 +2761,8 @@ impl<'db> Evaluator<'db> {
27862761 let arg0 = func;
27872762 let args = &args[1..];
27882763 let arg1 = {
2789 let ty = TyKind::Tuple(
2790 args.len(),
2791 Substitution::from_iter(Interner, args.iter().map(|it| it.ty.clone())),
2792 )
2793 .intern(Interner);
2794 let layout = self.layout(ty.to_nextsolver(interner))?;
2764 let ty = Ty::new_tup_from_iter(self.interner(), args.iter().map(|it| it.ty));
2765 let layout = self.layout(ty)?;
27952766 let result = self.construct_with_layout(
27962767 layout.size.bytes_usize(),
27972768 &layout,
......@@ -2817,7 +2788,7 @@ impl<'db> Evaluator<'db> {
28172788 }
28182789 }
28192790
2820 fn eval_static(&mut self, st: StaticId, locals: &Locals) -> Result<Address> {
2791 fn eval_static(&mut self, st: StaticId, locals: &Locals<'db>) -> Result<'db, Address> {
28212792 if let Some(o) = self.static_locations.get(&st) {
28222793 return Ok(*o);
28232794 };
......@@ -2826,9 +2797,9 @@ impl<'db> Evaluator<'db> {
28262797 let konst = self.db.const_eval_static(st).map_err(|e| {
28272798 MirEvalError::ConstEvalError(static_data.name.as_str().to_owned(), Box::new(e))
28282799 })?;
2829 self.allocate_const_in_heap(locals, &konst)?
2800 self.allocate_const_in_heap(locals, konst)?
28302801 } else {
2831 let ty = &self.db.infer(st.into())[self.db.body(st.into()).body_expr];
2802 let ty = self.db.infer(st.into())[self.db.body(st.into()).body_expr];
28322803 let Some((size, align)) = self.size_align_of(ty, locals)? else {
28332804 not_supported!("unsized extern static");
28342805 };
......@@ -2841,7 +2812,7 @@ impl<'db> Evaluator<'db> {
28412812 Ok(addr)
28422813 }
28432814
2844 fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<i128> {
2815 fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<'db, i128> {
28452816 let r = self.db.const_eval_discriminant(variant);
28462817 match r {
28472818 Ok(r) => Ok(r),
......@@ -2863,7 +2834,12 @@ impl<'db> Evaluator<'db> {
28632834 }
28642835 }
28652836
2866 fn drop_place(&mut self, place: &Place, locals: &mut Locals, span: MirSpan) -> Result<()> {
2837 fn drop_place(
2838 &mut self,
2839 place: &Place<'db>,
2840 locals: &mut Locals<'db>,
2841 span: MirSpan,
2842 ) -> Result<'db, ()> {
28672843 let (addr, ty, metadata) = self.place_addr_and_ty_and_metadata(place, locals)?;
28682844 if !locals.drop_flags.remove_place(place, &locals.body.projection_store) {
28692845 return Ok(());
......@@ -2877,12 +2853,12 @@ impl<'db> Evaluator<'db> {
28772853
28782854 fn run_drop_glue_deep(
28792855 &mut self,
2880 ty: Ty,
2881 locals: &Locals,
2856 ty: Ty<'db>,
2857 locals: &Locals<'db>,
28822858 addr: Address,
28832859 _metadata: &[u8],
28842860 span: MirSpan,
2885 ) -> Result<()> {
2861 ) -> Result<'db, ()> {
28862862 let Some(drop_fn) = (|| {
28872863 let drop_trait = LangItem::Drop.resolve_trait(self.db, self.crate_id)?;
28882864 drop_trait.trait_items(self.db).method_by_name(&Name::new_symbol_root(sym::drop))
......@@ -2892,7 +2868,7 @@ impl<'db> Evaluator<'db> {
28922868 return Ok(());
28932869 };
28942870
2895 let generic_args = Substitution::from1(Interner, ty.clone());
2871 let generic_args = GenericArgs::new_from_iter(self.interner(), [ty.into()]);
28962872 if let Ok(MirOrDynIndex::Mir(body)) =
28972873 self.get_mir_or_dyn_index(drop_fn, generic_args, locals, span)
28982874 {
......@@ -2906,26 +2882,27 @@ impl<'db> Evaluator<'db> {
29062882 None,
29072883 )?;
29082884 }
2909 match ty.kind(Interner) {
2910 TyKind::Adt(id, subst) => {
2911 match id.0 {
2885 match ty.kind() {
2886 TyKind::Adt(adt_def, subst) => {
2887 let id = adt_def.def_id().0;
2888 match id {
29122889 AdtId::StructId(s) => {
29132890 let data = self.db.struct_signature(s);
29142891 if data.flags.contains(StructFlags::IS_MANUALLY_DROP) {
29152892 return Ok(());
29162893 }
2917 let layout = self.layout_adt(id.0, subst.clone())?;
2894 let layout = self.layout_adt(id, subst)?;
29182895 let variant_fields = s.fields(self.db);
29192896 match variant_fields.shape {
29202897 FieldsShape::Record | FieldsShape::Tuple => {
2921 let field_types = self.db.field_types(s.into());
2898 let field_types = self.db.field_types_ns(s.into());
29222899 for (field, _) in variant_fields.fields().iter() {
29232900 let offset = layout
29242901 .fields
29252902 .offset(u32::from(field.into_raw()) as usize)
29262903 .bytes_usize();
29272904 let addr = addr.offset(offset);
2928 let ty = field_types[field].clone().substitute(Interner, subst);
2905 let ty = field_types[field].instantiate(self.interner(), subst);
29292906 self.run_drop_glue_deep(ty, locals, addr, &[], span)?;
29302907 }
29312908 }
......@@ -2936,49 +2913,55 @@ impl<'db> Evaluator<'db> {
29362913 AdtId::EnumId(_) => (),
29372914 }
29382915 }
2939 TyKind::AssociatedType(_, _)
2940 | TyKind::Scalar(_)
2941 | TyKind::Tuple(_, _)
2916 TyKind::Bool
2917 | TyKind::Char
2918 | TyKind::Int(_)
2919 | TyKind::Uint(_)
2920 | TyKind::Float(_)
2921 | TyKind::Tuple(_)
29422922 | TyKind::Array(_, _)
29432923 | TyKind::Slice(_)
2944 | TyKind::Raw(_, _)
2924 | TyKind::RawPtr(_, _)
29452925 | TyKind::Ref(_, _, _)
2946 | TyKind::OpaqueType(_, _)
2926 | TyKind::Alias(..)
29472927 | TyKind::FnDef(_, _)
29482928 | TyKind::Str
29492929 | TyKind::Never
29502930 | TyKind::Closure(_, _)
29512931 | TyKind::Coroutine(_, _)
2932 | TyKind::CoroutineClosure(..)
29522933 | TyKind::CoroutineWitness(_, _)
29532934 | TyKind::Foreign(_)
2954 | TyKind::Error
2935 | TyKind::Error(_)
2936 | TyKind::Param(_)
29552937 | TyKind::Placeholder(_)
2956 | TyKind::Dyn(_)
2957 | TyKind::Alias(_)
2958 | TyKind::Function(_)
2959 | TyKind::BoundVar(_)
2960 | TyKind::InferenceVar(_, _) => (),
2938 | TyKind::Dynamic(..)
2939 | TyKind::FnPtr(..)
2940 | TyKind::Bound(..)
2941 | TyKind::Infer(..)
2942 | TyKind::Pat(..)
2943 | TyKind::UnsafeBinder(..) => (),
29612944 };
29622945 Ok(())
29632946 }
29642947
2965 fn write_to_stdout(&mut self, interval: Interval) -> Result<()> {
2948 fn write_to_stdout(&mut self, interval: Interval) -> Result<'db, ()> {
29662949 self.stdout.extend(interval.get(self)?.to_vec());
29672950 Ok(())
29682951 }
29692952
2970 fn write_to_stderr(&mut self, interval: Interval) -> Result<()> {
2953 fn write_to_stderr(&mut self, interval: Interval) -> Result<'db, ()> {
29712954 self.stderr.extend(interval.get(self)?.to_vec());
29722955 Ok(())
29732956 }
29742957}
29752958
2976pub fn render_const_using_debug_impl(
2977 db: &dyn HirDatabase,
2959pub fn render_const_using_debug_impl<'db>(
2960 db: &'db dyn HirDatabase,
29782961 owner: DefWithBodyId,
2979 c: &Const,
2980) -> Result<String> {
2981 let interner = DbInterner::new_with(db, None, None);
2962 c: Const<'db>,
2963 ty: Ty<'db>,
2964) -> Result<'db, String> {
29822965 let mut evaluator = Evaluator::new(db, owner, false, None)?;
29832966 let locals = &Locals {
29842967 ptr: ArenaMap::new(),
......@@ -3007,12 +2990,11 @@ pub fn render_const_using_debug_impl(
30072990 // and its ABI doesn't break yet, we put it in memory manually.
30082991 let a2 = evaluator.heap_allocate(evaluator.ptr_size() * 2, evaluator.ptr_size())?;
30092992 evaluator.write_memory(a2, &data.addr.to_bytes())?;
3010 let debug_fmt_fn_ptr = evaluator.vtable_map.id(TyKind::FnDef(
3011 CallableDefId::FunctionId(debug_fmt_fn).to_chalk(db),
3012 Substitution::from1(Interner, c.data(Interner).ty.clone()),
3013 )
3014 .intern(Interner)
3015 .to_nextsolver(interner));
2993 let debug_fmt_fn_ptr = evaluator.vtable_map.id(Ty::new_fn_def(
2994 evaluator.interner(),
2995 CallableDefId::FunctionId(debug_fmt_fn).into(),
2996 GenericArgs::new_from_iter(evaluator.interner(), [ty.into()]),
2997 ));
30162998 evaluator.write_memory(a2.offset(evaluator.ptr_size()), &debug_fmt_fn_ptr.to_le_bytes())?;
30172999 // a3 = ::core::fmt::Arguments::new_v1(a1, a2)
30183000 // FIXME: similarly, we should call function here, not directly working with memory.
src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs+138-184
......@@ -3,32 +3,21 @@
33//!
44use std::cmp::{self, Ordering};
55
6use chalk_ir::TyKind;
7use hir_def::signatures::FunctionSignature;
8use hir_def::{
9 CrateRootModuleId,
10 builtin_type::{BuiltinInt, BuiltinUint},
11 resolver::HasResolver,
12};
6use hir_def::{CrateRootModuleId, resolver::HasResolver, signatures::FunctionSignature};
137use hir_expand::name::Name;
148use intern::{Symbol, sym};
9use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike, Ty as _};
1510use stdx::never;
1611
17use crate::next_solver::mapping::NextSolverToChalk;
1812use crate::{
19 DropGlue,
2013 display::DisplayTarget,
21 error_lifetime,
14 drop::{DropGlue, has_drop_glue},
2215 mir::eval::{
23 Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay,
24 InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId,
25 LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution,
26 Ty, TyBuilder, TyExt, pad16,
27 },
28 next_solver::{
29 DbInterner,
30 mapping::{ChalkToNextSolver, convert_ty_for_result},
16 Address, AdtId, Arc, Evaluator, FunctionId, GenericArgs, HasModule, HirDisplay,
17 InternedClosure, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, LangItem,
18 Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Ty, TyKind, pad16,
3119 },
20 next_solver::Region,
3221};
3322
3423mod simd;
......@@ -49,16 +38,16 @@ macro_rules! not_supported {
4938 };
5039}
5140
52impl Evaluator<'_> {
41impl<'db> Evaluator<'db> {
5342 pub(super) fn detect_and_exec_special_function(
5443 &mut self,
5544 def: FunctionId,
56 args: &[IntervalAndTy],
57 generic_args: &Substitution,
58 locals: &Locals,
45 args: &[IntervalAndTy<'db>],
46 generic_args: GenericArgs<'db>,
47 locals: &Locals<'db>,
5948 destination: Interval,
6049 span: MirSpan,
61 ) -> Result<bool> {
50 ) -> Result<'db, bool> {
6251 if self.not_special_fn_cache.borrow().contains(&def) {
6352 return Ok(false);
6453 }
......@@ -118,18 +107,16 @@ impl Evaluator<'_> {
118107 if let ItemContainerId::TraitId(t) = def.lookup(self.db).container
119108 && self.db.lang_attr(t.into()) == Some(LangItem::Clone)
120109 {
121 let [self_ty] = generic_args.as_slice(Interner) else {
110 let [self_ty] = generic_args.as_slice() else {
122111 not_supported!("wrong generic arg count for clone");
123112 };
124 let Some(self_ty) = self_ty.ty(Interner) else {
113 let Some(self_ty) = self_ty.ty() else {
125114 not_supported!("wrong generic arg kind for clone");
126115 };
127116 // Clone has special impls for tuples and function pointers
128 if matches!(
129 self_ty.kind(Interner),
130 TyKind::Function(_) | TyKind::Tuple(..) | TyKind::Closure(..)
131 ) {
132 self.exec_clone(def, args, self_ty.clone(), locals, destination, span)?;
117 if matches!(self_ty.kind(), TyKind::FnPtr(..) | TyKind::Tuple(..) | TyKind::Closure(..))
118 {
119 self.exec_clone(def, args, self_ty, locals, destination, span)?;
133120 return Ok(true);
134121 }
135122 // Return early to prevent caching clone as non special fn.
......@@ -142,7 +129,7 @@ impl Evaluator<'_> {
142129 pub(super) fn detect_and_redirect_special_function(
143130 &mut self,
144131 def: FunctionId,
145 ) -> Result<Option<FunctionId>> {
132 ) -> Result<'db, Option<FunctionId>> {
146133 // `PanicFmt` is redirected to `ConstPanicFmt`
147134 if let Some(LangItem::PanicFmt) = self.db.lang_attr(def.into()) {
148135 let resolver = CrateRootModuleId::from(self.crate_id).resolver(self.db);
......@@ -161,15 +148,14 @@ impl Evaluator<'_> {
161148 fn exec_clone(
162149 &mut self,
163150 def: FunctionId,
164 args: &[IntervalAndTy],
165 self_ty: Ty,
166 locals: &Locals,
151 args: &[IntervalAndTy<'db>],
152 self_ty: Ty<'db>,
153 locals: &Locals<'db>,
167154 destination: Interval,
168155 span: MirSpan,
169 ) -> Result<()> {
170 let interner = DbInterner::new_with(self.db, None, None);
171 match self_ty.kind(Interner) {
172 TyKind::Function(_) => {
156 ) -> Result<'db, ()> {
157 match self_ty.kind() {
158 TyKind::FnPtr(..) => {
173159 let [arg] = args else {
174160 not_supported!("wrong arg count for clone");
175161 };
......@@ -182,27 +168,35 @@ impl Evaluator<'_> {
182168 not_supported!("wrong arg count for clone");
183169 };
184170 let addr = Address::from_bytes(arg.get(self)?)?;
185 let InternedClosure(closure_owner, _) = self.db.lookup_intern_closure((*id).into());
171 let InternedClosure(closure_owner, _) = self.db.lookup_intern_closure(id.0);
186172 let infer = self.db.infer(closure_owner);
187 let (captures, _) = infer.closure_info(id);
188 let layout = self.layout(self_ty.to_nextsolver(interner))?;
189 let ty_iter = captures.iter().map(|c| c.ty(self.db, subst));
173 let (captures, _) = infer.closure_info(id.0);
174 let layout = self.layout(self_ty)?;
175 let db = self.db;
176 let ty_iter = captures.iter().map(|c| c.ty(db, subst));
190177 self.exec_clone_for_fields(ty_iter, layout, addr, def, locals, destination, span)?;
191178 }
192 TyKind::Tuple(_, subst) => {
179 TyKind::Tuple(subst) => {
193180 let [arg] = args else {
194181 not_supported!("wrong arg count for clone");
195182 };
196183 let addr = Address::from_bytes(arg.get(self)?)?;
197 let layout = self.layout(self_ty.to_nextsolver(interner))?;
198 let ty_iter = subst.iter(Interner).map(|ga| ga.assert_ty_ref(Interner).clone());
199 self.exec_clone_for_fields(ty_iter, layout, addr, def, locals, destination, span)?;
184 let layout = self.layout(self_ty)?;
185 self.exec_clone_for_fields(
186 subst.iter(),
187 layout,
188 addr,
189 def,
190 locals,
191 destination,
192 span,
193 )?;
200194 }
201195 _ => {
202196 self.exec_fn_with_args(
203197 def,
204198 args,
205 Substitution::from1(Interner, self_ty),
199 GenericArgs::new_from_iter(self.interner(), [self_ty.into()]),
206200 locals,
207201 destination,
208202 None,
......@@ -215,21 +209,25 @@ impl Evaluator<'_> {
215209
216210 fn exec_clone_for_fields(
217211 &mut self,
218 ty_iter: impl Iterator<Item = Ty>,
212 ty_iter: impl Iterator<Item = Ty<'db>>,
219213 layout: Arc<Layout>,
220214 addr: Address,
221215 def: FunctionId,
222 locals: &Locals,
216 locals: &Locals<'db>,
223217 destination: Interval,
224218 span: MirSpan,
225 ) -> Result<()> {
226 let interner = DbInterner::new_with(self.db, None, None);
219 ) -> Result<'db, ()> {
227220 for (i, ty) in ty_iter.enumerate() {
228 let size = self.layout(ty.to_nextsolver(interner))?.size.bytes_usize();
221 let size = self.layout(ty)?.size.bytes_usize();
229222 let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?;
230223 let arg = IntervalAndTy {
231224 interval: Interval { addr: tmp, size: self.ptr_size() },
232 ty: TyKind::Ref(Mutability::Not, error_lifetime(), ty.clone()).intern(Interner),
225 ty: Ty::new_ref(
226 self.interner(),
227 Region::error(self.interner()),
228 ty,
229 Mutability::Not,
230 ),
233231 };
234232 let offset = layout.fields.offset(i).bytes_usize();
235233 self.write_memory(tmp, &addr.offset(offset).to_bytes())?;
......@@ -248,9 +246,9 @@ impl Evaluator<'_> {
248246 fn exec_alloc_fn(
249247 &mut self,
250248 alloc_fn: &Symbol,
251 args: &[IntervalAndTy],
249 args: &[IntervalAndTy<'db>],
252250 destination: Interval,
253 ) -> Result<()> {
251 ) -> Result<'db, ()> {
254252 match alloc_fn {
255253 _ if *alloc_fn == sym::rustc_allocator_zeroed || *alloc_fn == sym::rustc_allocator => {
256254 let [size, align] = args else {
......@@ -310,11 +308,11 @@ impl Evaluator<'_> {
310308 fn exec_lang_item(
311309 &mut self,
312310 it: LangItem,
313 generic_args: &Substitution,
314 args: &[IntervalAndTy],
315 locals: &Locals,
311 generic_args: GenericArgs<'db>,
312 args: &[IntervalAndTy<'db>],
313 locals: &Locals<'db>,
316314 span: MirSpan,
317 ) -> Result<Vec<u8>> {
315 ) -> Result<'db, Vec<u8>> {
318316 use LangItem::*;
319317 let mut args = args.iter();
320318 match it {
......@@ -325,7 +323,7 @@ impl Evaluator<'_> {
325323 "argument of BeginPanic is not provided".into(),
326324 ))?
327325 .clone();
328 while let TyKind::Ref(_, _, ty) = arg.ty.kind(Interner) {
326 while let TyKind::Ref(_, ty, _) = arg.ty.kind() {
329327 if ty.is_str() {
330328 let (pointee, metadata) = arg.interval.get(self)?.split_at(self.ptr_size());
331329 let len = from_bytes!(usize, metadata);
......@@ -344,13 +342,10 @@ impl Evaluator<'_> {
344342 let pointee = arg.interval.get(self)?;
345343 arg = IntervalAndTy {
346344 interval: Interval::new(Address::from_bytes(pointee)?, size),
347 ty: ty.clone(),
345 ty,
348346 };
349347 }
350 Err(MirEvalError::Panic(format!(
351 "unknown-panic-payload: {:?}",
352 arg.ty.kind(Interner)
353 )))
348 Err(MirEvalError::Panic(format!("unknown-panic-payload: {:?}", arg.ty.kind())))
354349 }
355350 SliceLen => {
356351 let arg = args.next().ok_or(MirEvalError::InternalError(
......@@ -361,18 +356,17 @@ impl Evaluator<'_> {
361356 Ok(arg[ptr_size..].into())
362357 }
363358 DropInPlace => {
364 let ty =
365 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner)).ok_or(
366 MirEvalError::InternalError(
367 "generic argument of drop_in_place is not provided".into(),
368 ),
369 )?;
359 let ty = generic_args.as_slice().first().and_then(|it| it.ty()).ok_or(
360 MirEvalError::InternalError(
361 "generic argument of drop_in_place is not provided".into(),
362 ),
363 )?;
370364 let arg = args.next().ok_or(MirEvalError::InternalError(
371365 "argument of drop_in_place is not provided".into(),
372366 ))?;
373367 let arg = arg.interval.get(self)?.to_owned();
374368 self.run_drop_glue_deep(
375 ty.clone(),
369 ty,
376370 locals,
377371 Address::from_bytes(&arg[0..self.ptr_size()])?,
378372 &arg[self.ptr_size()..],
......@@ -387,11 +381,11 @@ impl Evaluator<'_> {
387381 fn exec_syscall(
388382 &mut self,
389383 id: i64,
390 args: &[IntervalAndTy],
384 args: &[IntervalAndTy<'db>],
391385 destination: Interval,
392 _locals: &Locals,
386 _locals: &Locals<'db>,
393387 _span: MirSpan,
394 ) -> Result<()> {
388 ) -> Result<'db, ()> {
395389 match id {
396390 318 => {
397391 // SYS_getrandom
......@@ -417,12 +411,12 @@ impl Evaluator<'_> {
417411 fn exec_extern_c(
418412 &mut self,
419413 as_str: &str,
420 args: &[IntervalAndTy],
421 _generic_args: &Substitution,
414 args: &[IntervalAndTy<'db>],
415 _generic_args: GenericArgs<'db>,
422416 destination: Interval,
423 locals: &Locals,
417 locals: &Locals<'db>,
424418 span: MirSpan,
425 ) -> Result<()> {
419 ) -> Result<'db, ()> {
426420 match as_str {
427421 "memcmp" => {
428422 let [ptr1, ptr2, size] = args else {
......@@ -583,14 +577,13 @@ impl Evaluator<'_> {
583577 fn exec_intrinsic(
584578 &mut self,
585579 name: &str,
586 args: &[IntervalAndTy],
587 generic_args: &Substitution,
580 args: &[IntervalAndTy<'db>],
581 generic_args: GenericArgs<'db>,
588582 destination: Interval,
589 locals: &Locals,
583 locals: &Locals<'db>,
590584 span: MirSpan,
591585 needs_override: bool,
592 ) -> Result<bool> {
593 let interner = DbInterner::new_with(self.db, None, None);
586 ) -> Result<'db, bool> {
594587 if let Some(name) = name.strip_prefix("atomic_") {
595588 return self
596589 .exec_atomic_intrinsic(name, args, generic_args, destination, locals, span)
......@@ -748,9 +741,7 @@ impl Evaluator<'_> {
748741 }
749742 match name {
750743 "size_of" => {
751 let Some(ty) =
752 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
753 else {
744 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
754745 return Err(MirEvalError::InternalError(
755746 "size_of generic arg is not provided".into(),
756747 ));
......@@ -761,20 +752,16 @@ impl Evaluator<'_> {
761752 // FIXME: `min_align_of` was renamed to `align_of` in Rust 1.89
762753 // (https://github.com/rust-lang/rust/pull/142410)
763754 "min_align_of" | "align_of" => {
764 let Some(ty) =
765 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
766 else {
755 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
767756 return Err(MirEvalError::InternalError(
768757 "align_of generic arg is not provided".into(),
769758 ));
770759 };
771 let align = self.layout(ty.to_nextsolver(interner))?.align.bytes();
760 let align = self.layout(ty)?.align.bytes();
772761 destination.write_from_bytes(self, &align.to_le_bytes()[0..destination.size])
773762 }
774763 "size_of_val" => {
775 let Some(ty) =
776 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
777 else {
764 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
778765 return Err(MirEvalError::InternalError(
779766 "size_of_val generic arg is not provided".into(),
780767 ));
......@@ -795,9 +782,7 @@ impl Evaluator<'_> {
795782 // FIXME: `min_align_of_val` was renamed to `align_of_val` in Rust 1.89
796783 // (https://github.com/rust-lang/rust/pull/142410)
797784 "min_align_of_val" | "align_of_val" => {
798 let Some(ty) =
799 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
800 else {
785 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
801786 return Err(MirEvalError::InternalError(
802787 "align_of_val generic arg is not provided".into(),
803788 ));
......@@ -816,9 +801,7 @@ impl Evaluator<'_> {
816801 }
817802 }
818803 "type_name" => {
819 let Some(ty) =
820 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
821 else {
804 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
822805 return Err(MirEvalError::InternalError(
823806 "type_name generic arg is not provided".into(),
824807 ));
......@@ -845,14 +828,12 @@ impl Evaluator<'_> {
845828 .write_from_bytes(self, &len.to_le_bytes())
846829 }
847830 "needs_drop" => {
848 let Some(ty) =
849 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
850 else {
831 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
851832 return Err(MirEvalError::InternalError(
852833 "size_of generic arg is not provided".into(),
853834 ));
854835 };
855 let result = match self.db.has_drop_glue(ty.clone(), self.trait_env.clone()) {
836 let result = match has_drop_glue(&self.infcx, ty, self.trait_env.clone()) {
856837 DropGlue::HasDropGlue => true,
857838 DropGlue::None => false,
858839 DropGlue::DependOnParams => {
......@@ -915,9 +896,7 @@ impl Evaluator<'_> {
915896 let lhs = i128::from_le_bytes(pad16(lhs.get(self)?, false));
916897 let rhs = i128::from_le_bytes(pad16(rhs.get(self)?, false));
917898 let ans = lhs.wrapping_sub(rhs);
918 let Some(ty) =
919 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
920 else {
899 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
921900 return Err(MirEvalError::InternalError(
922901 "ptr_offset_from generic arg is not provided".into(),
923902 ));
......@@ -1006,13 +985,11 @@ impl Evaluator<'_> {
1006985 "const_eval_select args are not provided".into(),
1007986 ));
1008987 };
1009 let result_ty = TyKind::Tuple(
1010 2,
1011 Substitution::from_iter(Interner, [lhs.ty.clone(), TyBuilder::bool()]),
1012 )
1013 .intern(Interner);
1014 let op_size =
1015 self.size_of_sized(&lhs.ty, locals, "operand of add_with_overflow")?;
988 let result_ty = Ty::new_tup_from_iter(
989 self.interner(),
990 [lhs.ty, Ty::new_bool(self.interner())].into_iter(),
991 );
992 let op_size = self.size_of_sized(lhs.ty, locals, "operand of add_with_overflow")?;
1016993 let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
1017994 let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
1018995 let (ans, u128overflow) = match name {
......@@ -1024,7 +1001,7 @@ impl Evaluator<'_> {
10241001 let is_overflow = u128overflow
10251002 || ans.to_le_bytes()[op_size..].iter().any(|&it| it != 0 && it != 255);
10261003 let is_overflow = vec![u8::from(is_overflow)];
1027 let layout = self.layout(result_ty.to_nextsolver(interner))?;
1004 let layout = self.layout(result_ty)?;
10281005 let result = self.construct_with_layout(
10291006 layout.size.bytes_usize(),
10301007 &layout,
......@@ -1041,9 +1018,7 @@ impl Evaluator<'_> {
10411018 "copy_nonoverlapping args are not provided".into(),
10421019 ));
10431020 };
1044 let Some(ty) =
1045 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
1046 else {
1021 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
10471022 return Err(MirEvalError::InternalError(
10481023 "copy_nonoverlapping generic arg is not provided".into(),
10491024 ));
......@@ -1062,43 +1037,35 @@ impl Evaluator<'_> {
10621037 return Err(MirEvalError::InternalError("offset args are not provided".into()));
10631038 };
10641039 let ty = if name == "offset" {
1065 let Some(ty0) =
1066 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
1067 else {
1040 let Some(ty0) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
10681041 return Err(MirEvalError::InternalError(
10691042 "offset generic arg is not provided".into(),
10701043 ));
10711044 };
1072 let Some(ty1) =
1073 generic_args.as_slice(Interner).get(1).and_then(|it| it.ty(Interner))
1074 else {
1045 let Some(ty1) = generic_args.as_slice().get(1).and_then(|it| it.ty()) else {
10751046 return Err(MirEvalError::InternalError(
10761047 "offset generic arg is not provided".into(),
10771048 ));
10781049 };
10791050 if !matches!(
1080 ty1.as_builtin(),
1081 Some(
1082 BuiltinType::Int(BuiltinInt::Isize)
1083 | BuiltinType::Uint(BuiltinUint::Usize)
1084 )
1051 ty1.kind(),
1052 TyKind::Int(rustc_type_ir::IntTy::Isize)
1053 | TyKind::Uint(rustc_type_ir::UintTy::Usize)
10851054 ) {
10861055 return Err(MirEvalError::InternalError(
10871056 "offset generic arg is not usize or isize".into(),
10881057 ));
10891058 }
1090 match ty0.as_raw_ptr() {
1091 Some((ty, _)) => ty,
1092 None => {
1059 match ty0.kind() {
1060 TyKind::RawPtr(ty, _) => ty,
1061 _ => {
10931062 return Err(MirEvalError::InternalError(
10941063 "offset generic arg is not a raw pointer".into(),
10951064 ));
10961065 }
10971066 }
10981067 } else {
1099 let Some(ty) =
1100 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
1101 else {
1068 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
11021069 return Err(MirEvalError::InternalError(
11031070 "arith_offset generic arg is not provided".into(),
11041071 ));
......@@ -1223,9 +1190,7 @@ impl Evaluator<'_> {
12231190 "discriminant_value arg is not provided".into(),
12241191 ));
12251192 };
1226 let Some(ty) =
1227 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
1228 else {
1193 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
12291194 return Err(MirEvalError::InternalError(
12301195 "discriminant_value generic arg is not provided".into(),
12311196 ));
......@@ -1233,7 +1198,7 @@ impl Evaluator<'_> {
12331198 let addr = Address::from_bytes(arg.get(self)?)?;
12341199 let size = self.size_of_sized(ty, locals, "discriminant_value ptr type")?;
12351200 let interval = Interval { addr, size };
1236 let r = self.compute_discriminant(ty.clone(), interval.get(self)?)?;
1201 let r = self.compute_discriminant(ty, interval.get(self)?)?;
12371202 destination.write_from_bytes(self, &r.to_le_bytes()[0..destination.size])
12381203 }
12391204 "const_eval_select" => {
......@@ -1243,14 +1208,13 @@ impl Evaluator<'_> {
12431208 ));
12441209 };
12451210 let mut args = vec![const_fn.clone()];
1246 let TyKind::Tuple(_, fields) = tuple.ty.kind(Interner) else {
1211 let TyKind::Tuple(fields) = tuple.ty.kind() else {
12471212 return Err(MirEvalError::InternalError(
12481213 "const_eval_select arg[0] is not a tuple".into(),
12491214 ));
12501215 };
1251 let layout = self.layout(tuple.ty.to_nextsolver(interner))?;
1252 for (i, field) in fields.iter(Interner).enumerate() {
1253 let field = field.assert_ty_ref(Interner).clone();
1216 let layout = self.layout(tuple.ty)?;
1217 for (i, field) in fields.iter().enumerate() {
12541218 let offset = layout.fields.offset(i).bytes_usize();
12551219 let addr = tuple.interval.addr.offset(offset);
12561220 args.push(IntervalAndTy::new(addr, field, self, locals)?);
......@@ -1264,7 +1228,7 @@ impl Evaluator<'_> {
12641228 def,
12651229 &args,
12661230 // FIXME: wrong for manual impls of `FnOnce`
1267 Substitution::empty(Interner),
1231 GenericArgs::new_from_iter(self.interner(), []),
12681232 locals,
12691233 destination,
12701234 None,
......@@ -1290,9 +1254,7 @@ impl Evaluator<'_> {
12901254 ));
12911255 };
12921256 let dst = Address::from_bytes(ptr.get(self)?)?;
1293 let Some(ty) =
1294 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
1295 else {
1257 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
12961258 return Err(MirEvalError::InternalError(
12971259 "write_via_copy generic arg is not provided".into(),
12981260 ));
......@@ -1309,9 +1271,7 @@ impl Evaluator<'_> {
13091271 };
13101272 let count = from_bytes!(usize, count.get(self)?);
13111273 let val = from_bytes!(u8, val.get(self)?);
1312 let Some(ty) =
1313 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
1314 else {
1274 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
13151275 return Err(MirEvalError::InternalError(
13161276 "write_bytes generic arg is not provided".into(),
13171277 ));
......@@ -1339,16 +1299,14 @@ impl Evaluator<'_> {
13391299 "three_way_compare args are not provided".into(),
13401300 ));
13411301 };
1342 let Some(ty) =
1343 generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
1344 else {
1302 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
13451303 return Err(MirEvalError::InternalError(
13461304 "three_way_compare generic arg is not provided".into(),
13471305 ));
13481306 };
1349 let signed = match ty.as_builtin().unwrap() {
1350 BuiltinType::Int(_) => true,
1351 BuiltinType::Uint(_) => false,
1307 let signed = match ty.kind() {
1308 TyKind::Int(_) => true,
1309 TyKind::Uint(_) => false,
13521310 _ => {
13531311 return Err(MirEvalError::InternalError(
13541312 "three_way_compare expects an integral type".into(),
......@@ -1372,8 +1330,8 @@ impl Evaluator<'_> {
13721330 result = (l as i8).cmp(&(r as i8));
13731331 }
13741332 if let Some(e) = LangItem::Ordering.resolve_enum(self.db, self.crate_id) {
1375 let ty = self.db.ty(e.into()).skip_binder().to_chalk(interner);
1376 let r = self.compute_discriminant(ty.clone(), &[result as i8 as u8])?;
1333 let ty = self.db.ty(e.into()).skip_binder();
1334 let r = self.compute_discriminant(ty, &[result as i8 as u8])?;
13771335 destination.write_from_bytes(self, &r.to_le_bytes()[0..destination.size])?;
13781336 Ok(())
13791337 } else {
......@@ -1402,38 +1360,37 @@ impl Evaluator<'_> {
14021360
14031361 fn size_align_of_unsized(
14041362 &mut self,
1405 ty: &Ty,
1363 ty: Ty<'db>,
14061364 metadata: Interval,
1407 locals: &Locals,
1408 ) -> Result<(usize, usize)> {
1409 let interner = DbInterner::new_with(self.db, None, None);
1410 Ok(match ty.kind(Interner) {
1365 locals: &Locals<'db>,
1366 ) -> Result<'db, (usize, usize)> {
1367 Ok(match ty.kind() {
14111368 TyKind::Str => (from_bytes!(usize, metadata.get(self)?), 1),
14121369 TyKind::Slice(inner) => {
14131370 let len = from_bytes!(usize, metadata.get(self)?);
14141371 let (size, align) = self.size_align_of_sized(inner, locals, "slice inner type")?;
14151372 (size * len, align)
14161373 }
1417 TyKind::Dyn(_) => self.size_align_of_sized(
1418 &convert_ty_for_result(interner, self.vtable_map.ty_of_bytes(metadata.get(self)?)?),
1374 TyKind::Dynamic(..) => self.size_align_of_sized(
1375 self.vtable_map.ty_of_bytes(metadata.get(self)?)?,
14191376 locals,
14201377 "dyn concrete type",
14211378 )?,
1422 TyKind::Adt(id, subst) => {
1423 let id = id.0;
1424 let layout = self.layout_adt(id, subst.clone())?;
1379 TyKind::Adt(adt_def, subst) => {
1380 let id = adt_def.def_id().0;
1381 let layout = self.layout_adt(id, subst)?;
14251382 let id = match id {
14261383 AdtId::StructId(s) => s,
14271384 _ => not_supported!("unsized enum or union"),
14281385 };
1429 let field_types = &self.db.field_types(id.into());
1386 let field_types = self.db.field_types_ns(id.into());
14301387 let last_field_ty =
1431 field_types.iter().next_back().unwrap().1.clone().substitute(Interner, subst);
1388 field_types.iter().next_back().unwrap().1.instantiate(self.interner(), subst);
14321389 let sized_part_size =
14331390 layout.fields.offset(field_types.iter().count() - 1).bytes_usize();
14341391 let sized_part_align = layout.align.bytes() as usize;
14351392 let (unsized_part_size, unsized_part_align) =
1436 self.size_align_of_unsized(&last_field_ty, metadata, locals)?;
1393 self.size_align_of_unsized(last_field_ty, metadata, locals)?;
14371394 let align = sized_part_align.max(unsized_part_align) as isize;
14381395 let size = (sized_part_size + unsized_part_size) as isize;
14391396 // Must add any necessary padding to `size`
......@@ -1456,13 +1413,12 @@ impl Evaluator<'_> {
14561413 fn exec_atomic_intrinsic(
14571414 &mut self,
14581415 name: &str,
1459 args: &[IntervalAndTy],
1460 generic_args: &Substitution,
1416 args: &[IntervalAndTy<'db>],
1417 generic_args: GenericArgs<'db>,
14611418 destination: Interval,
1462 locals: &Locals,
1419 locals: &Locals<'db>,
14631420 _span: MirSpan,
1464 ) -> Result<()> {
1465 let interner = DbInterner::new_with(self.db, None, None);
1421 ) -> Result<'db, ()> {
14661422 // We are a single threaded runtime with no UB checking and no optimization, so
14671423 // we can implement atomic intrinsics as normal functions.
14681424
......@@ -1472,8 +1428,7 @@ impl Evaluator<'_> {
14721428
14731429 // The rest of atomic intrinsics have exactly one generic arg
14741430
1475 let Some(ty) = generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
1476 else {
1431 let Some(ty) = generic_args.as_slice().first().and_then(|it| it.ty()) else {
14771432 return Err(MirEvalError::InternalError(
14781433 "atomic intrinsic generic arg is not provided".into(),
14791434 ));
......@@ -1555,12 +1510,11 @@ impl Evaluator<'_> {
15551510 } else {
15561511 (arg0_interval, false)
15571512 };
1558 let result_ty = TyKind::Tuple(
1559 2,
1560 Substitution::from_iter(Interner, [ty.clone(), TyBuilder::bool()]),
1561 )
1562 .intern(Interner);
1563 let layout = self.layout(result_ty.to_nextsolver(interner))?;
1513 let result_ty = Ty::new_tup_from_iter(
1514 self.interner(),
1515 [ty, Ty::new_bool(self.interner())].into_iter(),
1516 );
1517 let layout = self.layout(result_ty)?;
15641518 let result = self.construct_with_layout(
15651519 layout.size.bytes_usize(),
15661520 &layout,
src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs+19-24
......@@ -2,7 +2,6 @@
22
33use std::cmp::Ordering;
44
5use crate::TyKind;
65use crate::consteval::try_const_usize;
76
87use super::*;
......@@ -22,23 +21,21 @@ macro_rules! not_supported {
2221 };
2322}
2423
25impl Evaluator<'_> {
26 fn detect_simd_ty(&self, ty: &Ty) -> Result<(usize, Ty)> {
27 match ty.kind(Interner) {
28 TyKind::Adt(id, subst) => {
29 let len = match subst.as_slice(Interner).get(1).and_then(|it| it.constant(Interner))
30 {
24impl<'db> Evaluator<'db> {
25 fn detect_simd_ty(&self, ty: Ty<'db>) -> Result<'db, (usize, Ty<'db>)> {
26 match ty.kind() {
27 TyKind::Adt(adt_def, subst) => {
28 let len = match subst.as_slice().get(1).and_then(|it| it.konst()) {
3129 Some(len) => len,
3230 _ => {
33 if let AdtId::StructId(id) = id.0 {
31 if let AdtId::StructId(id) = adt_def.def_id().0 {
3432 let struct_data = id.fields(self.db);
3533 let fields = struct_data.fields();
3634 let Some((first_field, _)) = fields.iter().next() else {
3735 not_supported!("simd type with no field");
3836 };
39 let field_ty = self.db.field_types(id.into())[first_field]
40 .clone()
41 .substitute(Interner, subst);
37 let field_ty = self.db.field_types_ns(id.into())[first_field]
38 .instantiate(self.interner(), subst);
4239 return Ok((fields.len(), field_ty));
4340 }
4441 return Err(MirEvalError::InternalError(
......@@ -48,14 +45,12 @@ impl Evaluator<'_> {
4845 };
4946 match try_const_usize(self.db, len) {
5047 Some(len) => {
51 let Some(ty) =
52 subst.as_slice(Interner).first().and_then(|it| it.ty(Interner))
53 else {
48 let Some(ty) = subst.as_slice().first().and_then(|it| it.ty()) else {
5449 return Err(MirEvalError::InternalError(
5550 "simd type with no ty param".into(),
5651 ));
5752 };
58 Ok((len as usize, ty.clone()))
53 Ok((len as usize, ty))
5954 }
6055 None => Err(MirEvalError::InternalError(
6156 "simd type with unevaluatable len param".into(),
......@@ -69,12 +64,12 @@ impl Evaluator<'_> {
6964 pub(super) fn exec_simd_intrinsic(
7065 &mut self,
7166 name: &str,
72 args: &[IntervalAndTy],
73 _generic_args: &Substitution,
67 args: &[IntervalAndTy<'db>],
68 _generic_args: GenericArgs<'db>,
7469 destination: Interval,
75 _locals: &Locals,
70 _locals: &Locals<'db>,
7671 _span: MirSpan,
77 ) -> Result<()> {
72 ) -> Result<'db, ()> {
7873 match name {
7974 "and" | "or" | "xor" => {
8075 let [left, right] = args else {
......@@ -99,8 +94,8 @@ impl Evaluator<'_> {
9994 let [left, right] = args else {
10095 return Err(MirEvalError::InternalError("simd args are not provided".into()));
10196 };
102 let (len, ty) = self.detect_simd_ty(&left.ty)?;
103 let is_signed = matches!(ty.as_builtin(), Some(BuiltinType::Int(_)));
97 let (len, ty) = self.detect_simd_ty(left.ty)?;
98 let is_signed = matches!(ty.kind(), TyKind::Int(_));
10499 let size = left.interval.size / len;
105100 let dest_size = destination.size / len;
106101 let mut destination_bytes = vec![];
......@@ -137,7 +132,7 @@ impl Evaluator<'_> {
137132 "simd_bitmask args are not provided".into(),
138133 ));
139134 };
140 let (op_len, _) = self.detect_simd_ty(&op.ty)?;
135 let (op_len, _) = self.detect_simd_ty(op.ty)?;
141136 let op_count = op.interval.size / op_len;
142137 let mut result: u64 = 0;
143138 for (i, val) in op.get(self)?.chunks(op_count).enumerate() {
......@@ -153,7 +148,7 @@ impl Evaluator<'_> {
153148 "simd_shuffle args are not provided".into(),
154149 ));
155150 };
156 let TyKind::Array(_, index_len) = index.ty.kind(Interner) else {
151 let TyKind::Array(_, index_len) = index.ty.kind() else {
157152 return Err(MirEvalError::InternalError(
158153 "simd_shuffle index argument has non-array type".into(),
159154 ));
......@@ -166,7 +161,7 @@ impl Evaluator<'_> {
166161 ));
167162 }
168163 };
169 let (left_len, _) = self.detect_simd_ty(&left.ty)?;
164 let (left_len, _) = self.detect_simd_ty(left.ty)?;
170165 let left_size = left.interval.size / left_len;
171166 let vector =
172167 left.get(self)?.chunks(left_size).chain(right.get(self)?.chunks(left_size));
src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs+21-12
......@@ -4,15 +4,20 @@ use span::Edition;
44use syntax::{TextRange, TextSize};
55use test_fixture::WithFixture;
66
7use crate::display::DisplayTarget;
87use crate::{
9 Interner, Substitution, db::HirDatabase, mir::MirLowerError, setup_tracing, test_db::TestDB,
8 db::HirDatabase,
9 display::DisplayTarget,
10 mir::MirLowerError,
11 next_solver::{DbInterner, GenericArgs},
12 setup_tracing,
13 test_db::TestDB,
1014};
1115
1216use super::{MirEvalError, interpret_mir};
1317
14fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), MirEvalError> {
15 salsa::attach(db, || {
18fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), MirEvalError<'_>> {
19 crate::attach_db(db, || {
20 let interner = DbInterner::new_with(db, None, None);
1621 let module_id = db.module_for_file(file_id.file_id(db));
1722 let def_map = module_id.def_map(db);
1823 let scope = &def_map[module_id.local_id].scope;
......@@ -34,7 +39,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String),
3439 let body = db
3540 .monomorphized_mir_body(
3641 func_id.into(),
37 Substitution::empty(Interner),
42 GenericArgs::new_from_iter(interner, []),
3843 db.trait_environment(func_id.into()),
3944 )
4045 .map_err(|e| MirEvalError::MirLowerError(func_id, e))?;
......@@ -56,7 +61,7 @@ fn check_pass_and_stdio(
5661) {
5762 let _tracing = setup_tracing();
5863 let (db, file_ids) = TestDB::with_many_files(ra_fixture);
59 salsa::attach(&db, || {
64 crate::attach_db(&db, || {
6065 let file_id = *file_ids.last().unwrap();
6166 let x = eval_main(&db, file_id);
6267 match x {
......@@ -102,7 +107,7 @@ fn check_pass_and_stdio(
102107
103108fn check_panic(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected_panic: &str) {
104109 let (db, file_ids) = TestDB::with_many_files(ra_fixture);
105 salsa::attach(&db, || {
110 crate::attach_db(&db, || {
106111 let file_id = *file_ids.last().unwrap();
107112 let e = eval_main(&db, file_id).unwrap_err();
108113 assert_eq!(
......@@ -114,10 +119,10 @@ fn check_panic(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected_panic:
114119
115120fn check_error_with(
116121 #[rust_analyzer::rust_fixture] ra_fixture: &str,
117 expect_err: impl FnOnce(MirEvalError) -> bool,
122 expect_err: impl FnOnce(MirEvalError<'_>) -> bool,
118123) {
119124 let (db, file_ids) = TestDB::with_many_files(ra_fixture);
120 salsa::attach(&db, || {
125 crate::attach_db(&db, || {
121126 let file_id = *file_ids.last().unwrap();
122127 let e = eval_main(&db, file_id).unwrap_err();
123128 assert!(expect_err(e));
......@@ -631,11 +636,16 @@ fn main() {
631636 );
632637}
633638
639#[ignore = "
640FIXME(next-solver):
641This does not work currently because I replaced homemade selection with selection by the trait solver;
642This will work once we implement `Interner::impl_specializes()` properly.
643"]
634644#[test]
635645fn specialization_array_clone() {
636646 check_pass(
637647 r#"
638//- minicore: copy, derive, slice, index, coerce_unsized
648//- minicore: copy, derive, slice, index, coerce_unsized, panic
639649impl<T: Clone, const N: usize> Clone for [T; N] {
640650 #[inline]
641651 fn clone(&self) -> Self {
......@@ -650,8 +660,7 @@ trait SpecArrayClone: Clone {
650660impl<T: Clone> SpecArrayClone for T {
651661 #[inline]
652662 default fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
653 // FIXME: panic here when we actually implement specialization.
654 from_slice(array)
663 panic!("should go to the specialized impl")
655664 }
656665}
657666
src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs+319-272
......@@ -3,10 +3,9 @@
33use std::{fmt::Write, iter, mem};
44
55use base_db::Crate;
6use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind};
76use hir_def::{
8 AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId,
9 Lookup, TraitId, TupleId, TypeOrConstParamId,
7 AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, GenericParamId, HasModule,
8 ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId,
109 expr_store::{Body, ExpressionStore, HygieneId, path::Path},
1110 hir::{
1211 ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal, MatchArm,
......@@ -20,36 +19,33 @@ use hir_expand::name::Name;
2019use la_arena::ArenaMap;
2120use rustc_apfloat::Float;
2221use rustc_hash::FxHashMap;
22use rustc_type_ir::inherent::{Const as _, IntoKind, SliceLike, Ty as _};
2323use span::{Edition, FileId};
2424use syntax::TextRange;
2525use triomphe::Arc;
2626
2727use crate::{
28 Adjust, Adjustment, AutoBorrow, CallableDefId, TraitEnvironment, TyBuilder, TyExt,
28 Adjust, Adjustment, AutoBorrow, CallableDefId, TraitEnvironment,
2929 consteval::ConstEvalError,
3030 db::{HirDatabase, InternedClosure, InternedClosureId},
3131 display::{DisplayTarget, HirDisplay, hir_display_with_store},
32 error_lifetime,
3332 generics::generics,
3433 infer::{CaptureKind, CapturedItem, TypeMismatch, cast::CastTy},
3534 inhabitedness::is_ty_uninhabited_from,
3635 layout::LayoutError,
37 mapping::ToChalk,
3836 mir::{
39 AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, BorrowKind, CastKind, ConstScalar,
40 Either, Expr, FieldId, Idx, InferenceResult, Interner, Local, LocalId, MemoryMap, MirBody,
41 MirSpan, Mutability, Operand, Place, PlaceElem, PointerCast, ProjectionElem,
42 ProjectionStore, RawIdx, Rvalue, Statement, StatementKind, Substitution, SwitchTargets,
43 Terminator, TerminatorKind, TupleFieldId, Ty, UnOp, VariantId, intern_const_scalar,
44 return_slot,
37 AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, BorrowKind, CastKind, Either, Expr,
38 FieldId, GenericArgs, Idx, InferenceResult, Local, LocalId, MemoryMap, MirBody, MirSpan,
39 Mutability, Operand, Place, PlaceElem, PointerCast, ProjectionElem, ProjectionStore,
40 RawIdx, Rvalue, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind,
41 TupleFieldId, Ty, UnOp, VariantId, return_slot,
4542 },
4643 next_solver::{
47 DbInterner,
48 mapping::{ChalkToNextSolver, NextSolverToChalk},
44 Const, DbInterner, ParamConst, Region, TyKind, TypingMode, UnevaluatedConst,
45 infer::{DbInternerInferExt, InferCtxt},
46 mapping::NextSolverToChalk,
4947 },
50 static_lifetime,
5148 traits::FnTrait,
52 utils::ClosureSubst,
5349};
5450
5551use super::OperandKind;
......@@ -60,38 +56,39 @@ mod pattern_matching;
6056mod tests;
6157
6258#[derive(Debug, Clone)]
63struct LoopBlocks {
64 begin: BasicBlockId,
59struct LoopBlocks<'db> {
60 begin: BasicBlockId<'db>,
6561 /// `None` for loops that are not terminating
66 end: Option<BasicBlockId>,
67 place: Place,
62 end: Option<BasicBlockId<'db>>,
63 place: Place<'db>,
6864 drop_scope_index: usize,
6965}
7066
7167#[derive(Debug, Clone, Default)]
72struct DropScope {
68struct DropScope<'db> {
7369 /// locals, in order of definition (so we should run drop glues in reverse order)
74 locals: Vec<LocalId>,
70 locals: Vec<LocalId<'db>>,
7571}
7672
77struct MirLowerCtx<'db> {
78 result: MirBody,
73struct MirLowerCtx<'a, 'db> {
74 result: MirBody<'db>,
7975 owner: DefWithBodyId,
80 current_loop_blocks: Option<LoopBlocks>,
81 labeled_loop_blocks: FxHashMap<LabelId, LoopBlocks>,
82 discr_temp: Option<Place>,
76 current_loop_blocks: Option<LoopBlocks<'db>>,
77 labeled_loop_blocks: FxHashMap<LabelId, LoopBlocks<'db>>,
78 discr_temp: Option<Place<'db>>,
8379 db: &'db dyn HirDatabase,
84 body: &'db Body,
85 infer: &'db InferenceResult,
80 body: &'a Body,
81 infer: &'a InferenceResult<'db>,
8682 resolver: Resolver<'db>,
87 drop_scopes: Vec<DropScope>,
83 drop_scopes: Vec<DropScope<'db>>,
8884 env: Arc<TraitEnvironment<'db>>,
85 infcx: InferCtxt<'db>,
8986}
9087
9188// FIXME: Make this smaller, its stored in database queries
9289#[derive(Debug, Clone, PartialEq, Eq)]
93pub enum MirLowerError {
94 ConstEvalError(Box<str>, Box<ConstEvalError>),
90pub enum MirLowerError<'db> {
91 ConstEvalError(Box<str>, Box<ConstEvalError<'db>>),
9592 LayoutError(LayoutError),
9693 IncompleteExpr,
9794 IncompletePattern,
......@@ -101,9 +98,9 @@ pub enum MirLowerError {
10198 RecordLiteralWithoutPath,
10299 UnresolvedMethod(String),
103100 UnresolvedField,
104 UnsizedTemporary(Ty),
101 UnsizedTemporary(Ty<'db>),
105102 MissingFunctionDefinition(DefWithBodyId, ExprId),
106 TypeMismatch(TypeMismatch),
103 TypeMismatch(TypeMismatch<'db>),
107104 HasErrors,
108105 /// This should never happen. Type mismatch should catch everything.
109106 TypeError(&'static str),
......@@ -116,22 +113,22 @@ pub enum MirLowerError {
116113 LangItemNotFound(LangItem),
117114 MutatingRvalue,
118115 UnresolvedLabel,
119 UnresolvedUpvar(Place),
116 UnresolvedUpvar(Place<'db>),
120117 InaccessibleLocal,
121118
122119 // monomorphization errors:
123 GenericArgNotProvided(TypeOrConstParamId, Substitution),
120 GenericArgNotProvided(GenericParamId, GenericArgs<'db>),
124121}
125122
126123/// A token to ensuring that each drop scope is popped at most once, thanks to the compiler that checks moves.
127124struct DropScopeToken;
128125impl DropScopeToken {
129 fn pop_and_drop(
126 fn pop_and_drop<'db>(
130127 self,
131 ctx: &mut MirLowerCtx<'_>,
132 current: BasicBlockId,
128 ctx: &mut MirLowerCtx<'_, 'db>,
129 current: BasicBlockId<'db>,
133130 span: MirSpan,
134 ) -> BasicBlockId {
131 ) -> BasicBlockId<'db> {
135132 std::mem::forget(self);
136133 ctx.pop_drop_scope_internal(current, span)
137134 }
......@@ -140,7 +137,7 @@ impl DropScopeToken {
140137 /// code. Either when the control flow is diverging (so drop code doesn't reached) or when drop is handled
141138 /// for us (for example a block that ended with a return statement. Return will drop everything, so the block shouldn't
142139 /// do anything)
143 fn pop_assume_dropped(self, ctx: &mut MirLowerCtx<'_>) {
140 fn pop_assume_dropped(self, ctx: &mut MirLowerCtx<'_, '_>) {
144141 std::mem::forget(self);
145142 ctx.pop_drop_scope_assume_dropped_internal();
146143 }
......@@ -161,7 +158,7 @@ impl Drop for DropScopeToken {
161158// }
162159// }
163160
164impl MirLowerError {
161impl MirLowerError<'_> {
165162 pub fn pretty_print(
166163 &self,
167164 f: &mut String,
......@@ -197,15 +194,24 @@ impl MirLowerError {
197194 e.actual.display(db, display_target),
198195 )?,
199196 MirLowerError::GenericArgNotProvided(id, subst) => {
200 let parent = id.parent;
201 let param = &db.generic_params(parent)[id.local_id];
197 let param_name = match *id {
198 GenericParamId::TypeParamId(id) => {
199 db.generic_params(id.parent())[id.local_id()].name().cloned()
200 }
201 GenericParamId::ConstParamId(id) => {
202 db.generic_params(id.parent())[id.local_id()].name().cloned()
203 }
204 GenericParamId::LifetimeParamId(id) => {
205 Some(db.generic_params(id.parent)[id.local_id].name.clone())
206 }
207 };
202208 writeln!(
203209 f,
204210 "Generic arg not provided for {}",
205 param.name().unwrap_or(&Name::missing()).display(db, display_target.edition)
211 param_name.unwrap_or(Name::missing()).display(db, display_target.edition)
206212 )?;
207213 writeln!(f, "Provided args: [")?;
208 for g in subst.iter(Interner) {
214 for g in subst.iter() {
209215 write!(f, " {},", g.display(db, display_target))?;
210216 }
211217 writeln!(f, "]")?;
......@@ -248,13 +254,13 @@ macro_rules! implementation_error {
248254 }};
249255}
250256
251impl From<LayoutError> for MirLowerError {
257impl From<LayoutError> for MirLowerError<'_> {
252258 fn from(value: LayoutError) -> Self {
253259 MirLowerError::LayoutError(value)
254260 }
255261}
256262
257impl MirLowerError {
263impl MirLowerError<'_> {
258264 fn unresolved_path(
259265 db: &dyn HirDatabase,
260266 p: &Path,
......@@ -267,14 +273,14 @@ impl MirLowerError {
267273 }
268274}
269275
270type Result<T> = std::result::Result<T, MirLowerError>;
276type Result<'db, T> = std::result::Result<T, MirLowerError<'db>>;
271277
272impl<'ctx> MirLowerCtx<'ctx> {
278impl<'a, 'db> MirLowerCtx<'a, 'db> {
273279 fn new(
274 db: &'ctx dyn HirDatabase,
280 db: &'db dyn HirDatabase,
275281 owner: DefWithBodyId,
276 body: &'ctx Body,
277 infer: &'ctx InferenceResult,
282 body: &'a Body,
283 infer: &'a InferenceResult<'db>,
278284 ) -> Self {
279285 let mut basic_blocks = Arena::new();
280286 let start_block = basic_blocks.alloc(BasicBlock {
......@@ -283,7 +289,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
283289 is_cleanup: false,
284290 });
285291 let locals = Arena::new();
286 let binding_locals: ArenaMap<BindingId, LocalId> = ArenaMap::new();
292 let binding_locals: ArenaMap<BindingId, LocalId<'db>> = ArenaMap::new();
287293 let mir = MirBody {
288294 projection_store: ProjectionStore::default(),
289295 basic_blocks,
......@@ -296,6 +302,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
296302 };
297303 let resolver = owner.resolver(db);
298304 let env = db.trait_environment_for_body(owner);
305 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
306 let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
299307
300308 MirLowerCtx {
301309 result: mir,
......@@ -309,11 +317,22 @@ impl<'ctx> MirLowerCtx<'ctx> {
309317 discr_temp: None,
310318 drop_scopes: vec![DropScope::default()],
311319 env,
320 infcx,
312321 }
313322 }
314323
315 fn temp(&mut self, ty: Ty, current: BasicBlockId, span: MirSpan) -> Result<LocalId> {
316 if matches!(ty.kind(Interner), TyKind::Slice(_) | TyKind::Dyn(_)) {
324 #[inline]
325 fn interner(&self) -> DbInterner<'db> {
326 self.infcx.interner
327 }
328
329 fn temp(
330 &mut self,
331 ty: Ty<'db>,
332 current: BasicBlockId<'db>,
333 span: MirSpan,
334 ) -> Result<'db, LocalId<'db>> {
335 if matches!(ty.kind(), TyKind::Slice(_) | TyKind::Dynamic(..)) {
317336 return Err(MirLowerError::UnsizedTemporary(ty));
318337 }
319338 let l = self.result.locals.alloc(Local { ty });
......@@ -324,8 +343,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
324343 fn lower_expr_to_some_operand(
325344 &mut self,
326345 expr_id: ExprId,
327 current: BasicBlockId,
328 ) -> Result<Option<(Operand, BasicBlockId)>> {
346 current: BasicBlockId<'db>,
347 ) -> Result<'db, Option<(Operand<'db>, BasicBlockId<'db>)>> {
329348 if !self.has_adjustments(expr_id)
330349 && let Expr::Literal(l) = &self.body[expr_id]
331350 {
......@@ -341,15 +360,18 @@ impl<'ctx> MirLowerCtx<'ctx> {
341360 fn lower_expr_to_place_with_adjust(
342361 &mut self,
343362 expr_id: ExprId,
344 place: Place,
345 current: BasicBlockId,
346 adjustments: &[Adjustment],
347 ) -> Result<Option<BasicBlockId>> {
363 place: Place<'db>,
364 current: BasicBlockId<'db>,
365 adjustments: &[Adjustment<'db>],
366 ) -> Result<'db, Option<BasicBlockId<'db>>> {
348367 match adjustments.split_last() {
349368 Some((last, rest)) => match &last.kind {
350369 Adjust::NeverToAny => {
351 let temp =
352 self.temp(TyKind::Never.intern(Interner), current, MirSpan::Unknown)?;
370 let temp = self.temp(
371 Ty::new(self.interner(), TyKind::Never),
372 current,
373 MirSpan::Unknown,
374 )?;
353375 self.lower_expr_to_place_with_adjust(expr_id, temp.into(), current, rest)
354376 }
355377 Adjust::Deref(_) => {
......@@ -372,7 +394,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
372394 else {
373395 return Ok(None);
374396 };
375 let bk = BorrowKind::from_chalk(*m);
397 let bk = BorrowKind::from_rustc(*m);
376398 self.push_assignment(current, place, Rvalue::Ref(bk, p), expr_id.into());
377399 Ok(Some(current))
378400 }
......@@ -388,7 +410,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
388410 Rvalue::Cast(
389411 CastKind::PointerCoercion(*cast),
390412 Operand { kind: OperandKind::Copy(p), span: None },
391 last.target.clone(),
413 last.target,
392414 ),
393415 expr_id.into(),
394416 );
......@@ -402,9 +424,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
402424 fn lower_expr_to_place(
403425 &mut self,
404426 expr_id: ExprId,
405 place: Place,
406 prev_block: BasicBlockId,
407 ) -> Result<Option<BasicBlockId>> {
427 place: Place<'db>,
428 prev_block: BasicBlockId<'db>,
429 ) -> Result<'db, Option<BasicBlockId<'db>>> {
408430 if let Some(adjustments) = self.infer.expr_adjustments.get(&expr_id) {
409431 return self.lower_expr_to_place_with_adjust(expr_id, place, prev_block, adjustments);
410432 }
......@@ -414,9 +436,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
414436 fn lower_expr_to_place_without_adjust(
415437 &mut self,
416438 expr_id: ExprId,
417 place: Place,
418 mut current: BasicBlockId,
419 ) -> Result<Option<BasicBlockId>> {
439 place: Place<'db>,
440 mut current: BasicBlockId<'db>,
441 ) -> Result<'db, Option<BasicBlockId<'db>>> {
420442 match &self.body[expr_id] {
421443 Expr::OffsetOf(_) => {
422444 not_supported!("builtin#offset_of")
......@@ -439,14 +461,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
439461 if let Some((assoc, subst)) = self.infer.assoc_resolutions_for_expr(expr_id) {
440462 match assoc {
441463 hir_def::AssocItemId::ConstId(c) => {
442 self.lower_const(
443 c.into(),
444 current,
445 place,
446 subst,
447 expr_id.into(),
448 self.expr_ty_without_adjust(expr_id),
449 )?;
464 self.lower_const(c.into(), current, place, subst, expr_id.into())?;
450465 return Ok(Some(current));
451466 }
452467 hir_def::AssocItemId::FunctionId(_) => {
......@@ -502,16 +517,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
502517 const_id.into(),
503518 current,
504519 place,
505 Substitution::empty(Interner),
520 GenericArgs::new_from_iter(self.interner(), []),
506521 expr_id.into(),
507 self.expr_ty_without_adjust(expr_id),
508522 )?;
509523 Ok(Some(current))
510524 }
511525 ValueNs::EnumVariantId(variant_id) => {
512526 let variant_fields = variant_id.fields(self.db);
513527 if variant_fields.shape == FieldsShape::Unit {
514 let ty = self.infer.type_of_expr[expr_id].clone();
528 let ty = self.infer.type_of_expr[expr_id];
515529 current = self.lower_enum_variant(
516530 variant_id,
517531 current,
......@@ -529,25 +543,21 @@ impl<'ctx> MirLowerCtx<'ctx> {
529543 not_supported!("owner without generic def id");
530544 };
531545 let generics = generics(self.db, def);
532 let ty = self.expr_ty_without_adjust(expr_id);
546 let index = generics
547 .type_or_const_param_idx(p.into())
548 .ok_or(MirLowerError::TypeError("fail to lower const generic param"))?
549 as u32;
533550 self.push_assignment(
534551 current,
535552 place,
536553 Rvalue::from(Operand {
537 kind: OperandKind::Constant(
538 ConstData {
539 ty,
540 value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
541 DebruijnIndex::INNERMOST,
542 generics.type_or_const_param_idx(p.into()).ok_or(
543 MirLowerError::TypeError(
544 "fail to lower const generic param",
545 ),
546 )?,
547 )),
548 }
549 .intern(Interner),
550 ),
554 kind: OperandKind::Constant {
555 konst: Const::new_param(
556 self.interner(),
557 ParamConst { id: p, index },
558 ),
559 ty: self.db.const_param_ty_ns(p),
560 },
551561 span: None,
552562 }),
553563 expr_id.into(),
......@@ -599,7 +609,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
599609 then_target,
600610 place,
601611 Box::new([1]),
602 TyBuilder::bool(),
612 Ty::new_bool(self.interner()),
603613 MirSpan::Unknown,
604614 )?;
605615 if let Some(else_target) = else_target {
......@@ -607,7 +617,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
607617 else_target,
608618 place,
609619 Box::new([0]),
610 TyBuilder::bool(),
620 Ty::new_bool(self.interner()),
611621 MirSpan::Unknown,
612622 )?;
613623 }
......@@ -649,11 +659,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
649659 }
650660 Expr::Call { callee, args, .. } => {
651661 if let Some((func_id, generic_args)) = self.infer.method_resolution(expr_id) {
652 let ty = chalk_ir::TyKind::FnDef(
653 CallableDefId::FunctionId(func_id).to_chalk(self.db),
662 let ty = Ty::new_fn_def(
663 self.interner(),
664 CallableDefId::FunctionId(func_id).into(),
654665 generic_args,
655 )
656 .intern(Interner);
666 );
657667 let func = Operand::from_bytes(Box::default(), ty);
658668 return self.lower_call_and_args(
659669 func,
......@@ -665,9 +675,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
665675 );
666676 }
667677 let callee_ty = self.expr_ty_after_adjustments(*callee);
668 match &callee_ty.kind(Interner) {
669 chalk_ir::TyKind::FnDef(..) => {
670 let func = Operand::from_bytes(Box::default(), callee_ty.clone());
678 match callee_ty.kind() {
679 TyKind::FnDef(..) => {
680 let func = Operand::from_bytes(Box::default(), callee_ty);
671681 self.lower_call_and_args(
672682 func,
673683 args.iter().copied(),
......@@ -677,7 +687,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
677687 expr_id.into(),
678688 )
679689 }
680 chalk_ir::TyKind::Function(_) => {
690 TyKind::FnPtr(..) => {
681691 let Some((func, current)) =
682692 self.lower_expr_to_some_operand(*callee, current)?
683693 else {
......@@ -697,7 +707,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
697707 "method resolution not emitted for closure (Are Fn traits available?)"
698708 );
699709 }
700 TyKind::Error => {
710 TyKind::Error(_) => {
701711 Err(MirLowerError::MissingFunctionDefinition(self.owner, expr_id))
702712 }
703713 _ => Err(MirLowerError::TypeError("function call on bad type")),
......@@ -858,8 +868,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
858868 ),
859869 None => MirLowerError::RecordLiteralWithoutPath,
860870 })?;
861 let subst = match self.expr_ty_without_adjust(expr_id).kind(Interner) {
862 TyKind::Adt(_, s) => s.clone(),
871 let subst = match self.expr_ty_without_adjust(expr_id).kind() {
872 TyKind::Adt(_, s) => s,
863873 _ => not_supported!("Non ADT record literal"),
864874 };
865875 let variant_fields = variant_id.fields(self.db);
......@@ -948,12 +958,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
948958 let rvalue = if self.infer.coercion_casts.contains(expr) {
949959 Rvalue::Use(it)
950960 } else {
951 let source_ty = self.infer[*expr].clone();
952 let target_ty = self.infer[expr_id].clone();
961 let source_ty = self.infer[*expr];
962 let target_ty = self.infer[expr_id];
953963 let cast_kind = if source_ty.as_reference().is_some() {
954964 CastKind::PointerCoercion(PointerCast::ArrayToPointer)
955965 } else {
956 cast_kind(self.db, &source_ty, &target_ty)?
966 cast_kind(self.db, source_ty, target_ty)?
957967 };
958968
959969 Rvalue::Cast(cast_kind, it, target_ty)
......@@ -1030,8 +1040,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
10301040 let lhs_ty = self.expr_ty_without_adjust(*lhs);
10311041 let rhs_ty = self.expr_ty_without_adjust(*rhs);
10321042 if matches!(op, BinaryOp::CmpOp(syntax::ast::CmpOp::Eq { .. }))
1033 && lhs_ty.as_raw_ptr().is_some()
1034 && rhs_ty.as_raw_ptr().is_some()
1043 && matches!(lhs_ty.kind(), TyKind::RawPtr(..))
1044 && matches!(rhs_ty.kind(), TyKind::RawPtr(..))
10351045 {
10361046 break 'b true;
10371047 }
......@@ -1040,9 +1050,21 @@ impl<'ctx> MirLowerCtx<'ctx> {
10401050 BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr)
10411051 | BinaryOp::Assignment { op: Some(ArithOp::Shl | ArithOp::Shr) }
10421052 );
1043 lhs_ty.is_scalar()
1044 && rhs_ty.is_scalar()
1045 && (lhs_ty == rhs_ty || builtin_inequal_impls)
1053 matches!(
1054 lhs_ty.kind(),
1055 TyKind::Bool
1056 | TyKind::Char
1057 | TyKind::Int(_)
1058 | TyKind::Uint(_)
1059 | TyKind::Float(_)
1060 ) && matches!(
1061 rhs_ty.kind(),
1062 TyKind::Bool
1063 | TyKind::Char
1064 | TyKind::Int(_)
1065 | TyKind::Uint(_)
1066 | TyKind::Float(_)
1067 ) && (lhs_ty == rhs_ty || builtin_inequal_impls)
10461068 };
10471069 if !is_builtin
10481070 && let Some((func_id, generic_args)) = self.infer.method_resolution(expr_id)
......@@ -1180,7 +1202,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
11801202 current,
11811203 place,
11821204 Rvalue::Aggregate(
1183 AggregateKind::Adt(st.into(), subst.clone()),
1205 AggregateKind::Adt(st.into(), subst),
11841206 st.fields(self.db)
11851207 .fields()
11861208 .iter()
......@@ -1188,14 +1210,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
11881210 let o = match it.1.name.as_str() {
11891211 "start" => lp.take(),
11901212 "end" => rp.take(),
1191 "exhausted" => {
1192 Some(Operand::from_bytes(Box::new([0]), TyBuilder::bool()))
1193 }
1213 "exhausted" => Some(Operand::from_bytes(
1214 Box::new([0]),
1215 Ty::new_bool(self.interner()),
1216 )),
11941217 _ => None,
11951218 };
11961219 o.ok_or(MirLowerError::UnresolvedField)
11971220 })
1198 .collect::<Result<_>>()?,
1221 .collect::<Result<'_, _>>()?,
11991222 ),
12001223 expr_id.into(),
12011224 );
......@@ -1203,11 +1226,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
12031226 }
12041227 Expr::Closure { .. } => {
12051228 let ty = self.expr_ty_without_adjust(expr_id);
1206 let TyKind::Closure(id, _) = ty.kind(Interner) else {
1229 let TyKind::Closure(id, _) = ty.kind() else {
12071230 not_supported!("closure with non closure type");
12081231 };
1209 self.result.closures.push(*id);
1210 let (captures, _) = self.infer.closure_info(id);
1232 self.result.closures.push(id.0);
1233 let (captures, _) = self.infer.closure_info(id.0);
12111234 let mut operands = vec![];
12121235 for capture in captures.iter() {
12131236 let p = Place {
......@@ -1241,12 +1264,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
12411264 };
12421265 match &capture.kind {
12431266 CaptureKind::ByRef(bk) => {
1244 let placeholder_subst = self.placeholder_subst();
1245 let tmp_ty =
1246 capture.ty.clone().substitute(Interner, &placeholder_subst);
1267 let tmp_ty = capture.ty.instantiate_identity();
12471268 // FIXME: Handle more than one span.
12481269 let capture_spans = capture.spans();
1249 let tmp: Place = self.temp(tmp_ty, current, capture_spans[0])?.into();
1270 let tmp: Place<'db> =
1271 self.temp(tmp_ty, current, capture_spans[0])?.into();
12501272 self.push_assignment(
12511273 current,
12521274 tmp,
......@@ -1278,7 +1300,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
12781300 current = c;
12791301 Ok(Some(o))
12801302 })
1281 .collect::<Result<Option<_>>>()?
1303 .collect::<Result<'_, Option<_>>>()?
12821304 else {
12831305 return Ok(None);
12841306 };
......@@ -1291,8 +1313,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
12911313 }
12921314 Expr::Array(l) => match l {
12931315 Array::ElementList { elements, .. } => {
1294 let elem_ty = match &self.expr_ty_without_adjust(expr_id).kind(Interner) {
1295 TyKind::Array(ty, _) => ty.clone(),
1316 let elem_ty = match self.expr_ty_without_adjust(expr_id).kind() {
1317 TyKind::Array(ty, _) => ty,
12961318 _ => {
12971319 return Err(MirLowerError::TypeError(
12981320 "Array expression with non array type",
......@@ -1309,7 +1331,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
13091331 current = c;
13101332 Ok(Some(o))
13111333 })
1312 .collect::<Result<Option<_>>>()?
1334 .collect::<Result<'_, Option<_>>>()?
13131335 else {
13141336 return Ok(None);
13151337 };
......@@ -1323,8 +1345,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
13231345 else {
13241346 return Ok(None);
13251347 };
1326 let len = match &self.expr_ty_without_adjust(expr_id).kind(Interner) {
1327 TyKind::Array(_, len) => len.clone(),
1348 let len = match self.expr_ty_without_adjust(expr_id).kind() {
1349 TyKind::Array(_, len) => len,
13281350 _ => {
13291351 return Err(MirLowerError::TypeError(
13301352 "Array repeat expression with non array type",
......@@ -1346,16 +1368,13 @@ impl<'ctx> MirLowerCtx<'ctx> {
13461368 }
13471369 }
13481370
1349 fn placeholder_subst(&mut self) -> Substitution {
1350 match self.owner.as_generic_def_id(self.db) {
1351 Some(it) => TyBuilder::placeholder_subst(self.db, it),
1352 None => Substitution::empty(Interner),
1353 }
1354 }
1355
1356 fn push_field_projection(&mut self, place: &mut Place, expr_id: ExprId) -> Result<()> {
1371 fn push_field_projection(
1372 &mut self,
1373 place: &mut Place<'db>,
1374 expr_id: ExprId,
1375 ) -> Result<'db, ()> {
13571376 if let Expr::Field { expr, name } = &self.body[expr_id] {
1358 if let TyKind::Tuple(..) = self.expr_ty_after_adjustments(*expr).kind(Interner) {
1377 if let TyKind::Tuple(..) = self.expr_ty_after_adjustments(*expr).kind() {
13591378 let index =
13601379 name.as_tuple_index().ok_or(MirLowerError::TypeError("named field on tuple"))?
13611380 as u32;
......@@ -1378,7 +1397,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
13781397 Ok(())
13791398 }
13801399
1381 fn lower_literal_or_const_to_operand(&mut self, ty: Ty, loc: &ExprId) -> Result<Operand> {
1400 fn lower_literal_or_const_to_operand(
1401 &mut self,
1402 ty: Ty<'db>,
1403 loc: &ExprId,
1404 ) -> Result<'db, Operand<'db>> {
13821405 match &self.body[*loc] {
13831406 Expr::Literal(l) => self.lower_literal_to_operand(ty, l),
13841407 Expr::Path(c) => {
......@@ -1399,7 +1422,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
13991422 match pr {
14001423 ResolveValueResult::ValueNs(v, _) => {
14011424 if let ValueNs::ConstId(c) = v {
1402 self.lower_const_to_operand(Substitution::empty(Interner), c.into(), ty)
1425 self.lower_const_to_operand(
1426 GenericArgs::new_from_iter(self.interner(), []),
1427 c.into(),
1428 )
14031429 } else {
14041430 not_supported!("bad path in range pattern");
14051431 }
......@@ -1415,13 +1441,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
14151441 }
14161442 }
14171443
1418 fn lower_literal_to_operand(&mut self, ty: Ty, l: &Literal) -> Result<Operand> {
1419 let interner = DbInterner::new_with(self.db, None, None);
1420 let size = || {
1421 self.db
1422 .layout_of_ty(ty.to_nextsolver(interner), self.env.clone())
1423 .map(|it| it.size.bytes_usize())
1424 };
1444 fn lower_literal_to_operand(&mut self, ty: Ty<'db>, l: &Literal) -> Result<'db, Operand<'db>> {
1445 let size = || self.db.layout_of_ty(ty, self.env.clone()).map(|it| it.size.bytes_usize());
14251446 const USIZE_SIZE: usize = size_of::<usize>();
14261447 let bytes: Box<[_]> = match l {
14271448 hir_def::hir::Literal::String(b) => {
......@@ -1467,50 +1488,59 @@ impl<'ctx> MirLowerCtx<'ctx> {
14671488 Ok(Operand::from_concrete_const(bytes, MemoryMap::default(), ty))
14681489 }
14691490
1470 fn new_basic_block(&mut self) -> BasicBlockId {
1491 fn new_basic_block(&mut self) -> BasicBlockId<'db> {
14711492 self.result.basic_blocks.alloc(BasicBlock::default())
14721493 }
14731494
14741495 fn lower_const(
14751496 &mut self,
14761497 const_id: GeneralConstId,
1477 prev_block: BasicBlockId,
1478 place: Place,
1479 subst: Substitution,
1498 prev_block: BasicBlockId<'db>,
1499 place: Place<'db>,
1500 subst: GenericArgs<'db>,
14801501 span: MirSpan,
1481 ty: Ty,
1482 ) -> Result<()> {
1483 let c = self.lower_const_to_operand(subst, const_id, ty)?;
1502 ) -> Result<'db, ()> {
1503 let c = self.lower_const_to_operand(subst, const_id)?;
14841504 self.push_assignment(prev_block, place, c.into(), span);
14851505 Ok(())
14861506 }
14871507
14881508 fn lower_const_to_operand(
14891509 &mut self,
1490 subst: Substitution,
1510 subst: GenericArgs<'db>,
14911511 const_id: GeneralConstId,
1492 ty: Ty,
1493 ) -> Result<Operand> {
1494 let c = if subst.len(Interner) != 0 {
1512 ) -> Result<'db, Operand<'db>> {
1513 let konst = if subst.len() != 0 {
14951514 // We can't evaluate constant with substitution now, as generics are not monomorphized in lowering.
1496 intern_const_scalar(ConstScalar::UnevaluatedConst(const_id, subst), ty)
1515 Const::new_unevaluated(
1516 self.interner(),
1517 UnevaluatedConst { def: const_id.into(), args: subst },
1518 )
14971519 } else {
14981520 let name = const_id.name(self.db);
14991521 self.db
15001522 .const_eval(const_id, subst, None)
15011523 .map_err(|e| MirLowerError::ConstEvalError(name.into(), Box::new(e)))?
15021524 };
1503 Ok(Operand { kind: OperandKind::Constant(c), span: None })
1525 let ty = self
1526 .db
1527 .value_ty(match const_id {
1528 GeneralConstId::ConstId(id) => id.into(),
1529 GeneralConstId::StaticId(id) => id.into(),
1530 })
1531 .unwrap()
1532 .instantiate(self.interner(), subst);
1533 Ok(Operand { kind: OperandKind::Constant { konst, ty }, span: None })
15041534 }
15051535
15061536 fn write_bytes_to_place(
15071537 &mut self,
1508 prev_block: BasicBlockId,
1509 place: Place,
1538 prev_block: BasicBlockId<'db>,
1539 place: Place<'db>,
15101540 cv: Box<[u8]>,
1511 ty: Ty,
1541 ty: Ty<'db>,
15121542 span: MirSpan,
1513 ) -> Result<()> {
1543 ) -> Result<'db, ()> {
15141544 self.push_assignment(prev_block, place, Operand::from_bytes(cv, ty).into(), span);
15151545 Ok(())
15161546 }
......@@ -1518,14 +1548,14 @@ impl<'ctx> MirLowerCtx<'ctx> {
15181548 fn lower_enum_variant(
15191549 &mut self,
15201550 variant_id: EnumVariantId,
1521 prev_block: BasicBlockId,
1522 place: Place,
1523 ty: Ty,
1524 fields: Box<[Operand]>,
1551 prev_block: BasicBlockId<'db>,
1552 place: Place<'db>,
1553 ty: Ty<'db>,
1554 fields: Box<[Operand<'db>]>,
15251555 span: MirSpan,
1526 ) -> Result<BasicBlockId> {
1527 let subst = match ty.kind(Interner) {
1528 TyKind::Adt(_, subst) => subst.clone(),
1556 ) -> Result<'db, BasicBlockId<'db>> {
1557 let subst = match ty.kind() {
1558 TyKind::Adt(_, subst) => subst,
15291559 _ => implementation_error!("Non ADT enum"),
15301560 };
15311561 self.push_assignment(
......@@ -1539,13 +1569,13 @@ impl<'ctx> MirLowerCtx<'ctx> {
15391569
15401570 fn lower_call_and_args(
15411571 &mut self,
1542 func: Operand,
1572 func: Operand<'db>,
15431573 args: impl Iterator<Item = ExprId>,
1544 place: Place,
1545 mut current: BasicBlockId,
1574 place: Place<'db>,
1575 mut current: BasicBlockId<'db>,
15461576 is_uninhabited: bool,
15471577 span: MirSpan,
1548 ) -> Result<Option<BasicBlockId>> {
1578 ) -> Result<'db, Option<BasicBlockId<'db>>> {
15491579 let Some(args) = args
15501580 .map(|arg| {
15511581 if let Some((temp, c)) = self.lower_expr_to_some_operand(arg, current)? {
......@@ -1555,7 +1585,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
15551585 Ok(None)
15561586 }
15571587 })
1558 .collect::<Result<Option<Vec<_>>>>()?
1588 .collect::<Result<'_, Option<Vec<_>>>>()?
15591589 else {
15601590 return Ok(None);
15611591 };
......@@ -1564,13 +1594,13 @@ impl<'ctx> MirLowerCtx<'ctx> {
15641594
15651595 fn lower_call(
15661596 &mut self,
1567 func: Operand,
1568 args: Box<[Operand]>,
1569 place: Place,
1570 current: BasicBlockId,
1597 func: Operand<'db>,
1598 args: Box<[Operand<'db>]>,
1599 place: Place<'db>,
1600 current: BasicBlockId<'db>,
15711601 is_uninhabited: bool,
15721602 span: MirSpan,
1573 ) -> Result<Option<BasicBlockId>> {
1603 ) -> Result<'db, Option<BasicBlockId<'db>>> {
15741604 let b = if is_uninhabited { None } else { Some(self.new_basic_block()) };
15751605 self.set_terminator(
15761606 current,
......@@ -1587,56 +1617,63 @@ impl<'ctx> MirLowerCtx<'ctx> {
15871617 Ok(b)
15881618 }
15891619
1590 fn is_unterminated(&mut self, source: BasicBlockId) -> bool {
1620 fn is_unterminated(&mut self, source: BasicBlockId<'db>) -> bool {
15911621 self.result.basic_blocks[source].terminator.is_none()
15921622 }
15931623
1594 fn set_terminator(&mut self, source: BasicBlockId, terminator: TerminatorKind, span: MirSpan) {
1624 fn set_terminator(
1625 &mut self,
1626 source: BasicBlockId<'db>,
1627 terminator: TerminatorKind<'db>,
1628 span: MirSpan,
1629 ) {
15951630 self.result.basic_blocks[source].terminator = Some(Terminator { span, kind: terminator });
15961631 }
15971632
1598 fn set_goto(&mut self, source: BasicBlockId, target: BasicBlockId, span: MirSpan) {
1633 fn set_goto(&mut self, source: BasicBlockId<'db>, target: BasicBlockId<'db>, span: MirSpan) {
15991634 self.set_terminator(source, TerminatorKind::Goto { target }, span);
16001635 }
16011636
1602 fn expr_ty_without_adjust(&self, e: ExprId) -> Ty {
1603 self.infer[e].clone()
1637 fn expr_ty_without_adjust(&self, e: ExprId) -> Ty<'db> {
1638 self.infer[e]
16041639 }
16051640
1606 fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty {
1641 fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db> {
16071642 let mut ty = None;
16081643 if let Some(it) = self.infer.expr_adjustments.get(&e)
16091644 && let Some(it) = it.last()
16101645 {
1611 ty = Some(it.target.clone());
1646 ty = Some(it.target);
16121647 }
16131648 ty.unwrap_or_else(|| self.expr_ty_without_adjust(e))
16141649 }
16151650
1616 fn push_statement(&mut self, block: BasicBlockId, statement: Statement) {
1651 fn push_statement(&mut self, block: BasicBlockId<'db>, statement: Statement<'db>) {
16171652 self.result.basic_blocks[block].statements.push(statement);
16181653 }
16191654
1620 fn push_fake_read(&mut self, block: BasicBlockId, p: Place, span: MirSpan) {
1655 fn push_fake_read(&mut self, block: BasicBlockId<'db>, p: Place<'db>, span: MirSpan) {
16211656 self.push_statement(block, StatementKind::FakeRead(p).with_span(span));
16221657 }
16231658
16241659 fn push_assignment(
16251660 &mut self,
1626 block: BasicBlockId,
1627 place: Place,
1628 rvalue: Rvalue,
1661 block: BasicBlockId<'db>,
1662 place: Place<'db>,
1663 rvalue: Rvalue<'db>,
16291664 span: MirSpan,
16301665 ) {
16311666 self.push_statement(block, StatementKind::Assign(place, rvalue).with_span(span));
16321667 }
16331668
1634 fn discr_temp_place(&mut self, current: BasicBlockId) -> Place {
1669 fn discr_temp_place(&mut self, current: BasicBlockId<'db>) -> Place<'db> {
16351670 match &self.discr_temp {
16361671 Some(it) => *it,
16371672 None => {
1638 let tmp: Place = self
1639 .temp(TyBuilder::discr_ty(), current, MirSpan::Unknown)
1673 // FIXME: rustc's ty is dependent on the adt type, maybe we need to do that as well
1674 let discr_ty = Ty::new_int(self.interner(), rustc_type_ir::IntTy::I128);
1675 let tmp: Place<'db> = self
1676 .temp(discr_ty, current, MirSpan::Unknown)
16401677 .expect("discr_ty is never unsized")
16411678 .into();
16421679 self.discr_temp = Some(tmp);
......@@ -1647,12 +1684,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
16471684
16481685 fn lower_loop(
16491686 &mut self,
1650 prev_block: BasicBlockId,
1651 place: Place,
1687 prev_block: BasicBlockId<'db>,
1688 place: Place<'db>,
16521689 label: Option<LabelId>,
16531690 span: MirSpan,
1654 f: impl FnOnce(&mut MirLowerCtx<'_>, BasicBlockId) -> Result<()>,
1655 ) -> Result<Option<BasicBlockId>> {
1691 f: impl FnOnce(&mut MirLowerCtx<'_, 'db>, BasicBlockId<'db>) -> Result<'db, ()>,
1692 ) -> Result<'db, Option<BasicBlockId<'db>>> {
16561693 let begin = self.new_basic_block();
16571694 let prev = self.current_loop_blocks.replace(LoopBlocks {
16581695 begin,
......@@ -1687,10 +1724,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
16871724
16881725 fn merge_blocks(
16891726 &mut self,
1690 b1: Option<BasicBlockId>,
1691 b2: Option<BasicBlockId>,
1727 b1: Option<BasicBlockId<'db>>,
1728 b2: Option<BasicBlockId<'db>>,
16921729 span: MirSpan,
1693 ) -> Option<BasicBlockId> {
1730 ) -> Option<BasicBlockId<'db>> {
16941731 match (b1, b2) {
16951732 (None, None) => None,
16961733 (None, Some(b)) | (Some(b), None) => Some(b),
......@@ -1703,7 +1740,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
17031740 }
17041741 }
17051742
1706 fn current_loop_end(&mut self) -> Result<BasicBlockId> {
1743 fn current_loop_end(&mut self) -> Result<'db, BasicBlockId<'db>> {
17071744 let r = match self
17081745 .current_loop_blocks
17091746 .as_mut()
......@@ -1730,7 +1767,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
17301767 fn is_uninhabited(&self, expr_id: ExprId) -> bool {
17311768 is_ty_uninhabited_from(
17321769 self.db,
1733 &self.infer[expr_id],
1770 &self.infer[expr_id].to_chalk(self.interner()),
17341771 self.owner.module(self.db),
17351772 self.env.clone(),
17361773 )
......@@ -1738,23 +1775,23 @@ impl<'ctx> MirLowerCtx<'ctx> {
17381775
17391776 /// This function push `StorageLive` statement for the binding, and applies changes to add `StorageDead` and
17401777 /// `Drop` in the appropriated places.
1741 fn push_storage_live(&mut self, b: BindingId, current: BasicBlockId) -> Result<()> {
1778 fn push_storage_live(&mut self, b: BindingId, current: BasicBlockId<'db>) -> Result<'db, ()> {
17421779 let l = self.binding_local(b)?;
17431780 self.push_storage_live_for_local(l, current, MirSpan::BindingId(b))
17441781 }
17451782
17461783 fn push_storage_live_for_local(
17471784 &mut self,
1748 l: LocalId,
1749 current: BasicBlockId,
1785 l: LocalId<'db>,
1786 current: BasicBlockId<'db>,
17501787 span: MirSpan,
1751 ) -> Result<()> {
1788 ) -> Result<'db, ()> {
17521789 self.drop_scopes.last_mut().unwrap().locals.push(l);
17531790 self.push_statement(current, StatementKind::StorageLive(l).with_span(span));
17541791 Ok(())
17551792 }
17561793
1757 fn resolve_lang_item(&self, item: LangItem) -> Result<LangItemTarget> {
1794 fn resolve_lang_item(&self, item: LangItem) -> Result<'db, LangItemTarget> {
17581795 let crate_id = self.owner.module(self.db).krate();
17591796 lang_item(self.db, crate_id, item).ok_or(MirLowerError::LangItemNotFound(item))
17601797 }
......@@ -1762,11 +1799,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
17621799 fn lower_block_to_place(
17631800 &mut self,
17641801 statements: &[hir_def::hir::Statement],
1765 mut current: BasicBlockId,
1802 mut current: BasicBlockId<'db>,
17661803 tail: Option<ExprId>,
1767 place: Place,
1804 place: Place<'db>,
17681805 span: MirSpan,
1769 ) -> Result<Option<Idx<BasicBlock>>> {
1806 ) -> Result<'db, Option<Idx<BasicBlock<'db>>>> {
17701807 let scope = self.push_drop_scope();
17711808 for statement in statements.iter() {
17721809 match statement {
......@@ -1839,10 +1876,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
18391876
18401877 fn lower_params_and_bindings(
18411878 &mut self,
1842 params: impl Iterator<Item = (PatId, Ty)> + Clone,
1843 self_binding: Option<(BindingId, Ty)>,
1879 params: impl Iterator<Item = (PatId, Ty<'db>)> + Clone,
1880 self_binding: Option<(BindingId, Ty<'db>)>,
18441881 pick_binding: impl Fn(BindingId) -> bool,
1845 ) -> Result<BasicBlockId> {
1882 ) -> Result<'db, BasicBlockId<'db>> {
18461883 let base_param_count = self.result.param_locals.len();
18471884 let self_binding = match self_binding {
18481885 Some((self_binding, ty)) => {
......@@ -1875,7 +1912,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
18751912 if !self.result.binding_locals.contains_idx(id) {
18761913 self.result
18771914 .binding_locals
1878 .insert(id, self.result.locals.alloc(Local { ty: self.infer[id].clone() }));
1915 .insert(id, self.result.locals.alloc(Local { ty: self.infer[id] }));
18791916 }
18801917 }
18811918 let mut current = self.result.start_block;
......@@ -1910,7 +1947,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
19101947 Ok(current)
19111948 }
19121949
1913 fn binding_local(&self, b: BindingId) -> Result<LocalId> {
1950 fn binding_local(&self, b: BindingId) -> Result<'db, LocalId<'db>> {
19141951 match self.result.binding_locals.get(b) {
19151952 Some(it) => Ok(*it),
19161953 None => {
......@@ -1922,7 +1959,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
19221959 }
19231960 }
19241961
1925 fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<i128> {
1962 fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<'db, i128> {
19261963 let r = self.db.const_eval_discriminant(variant);
19271964 match r {
19281965 Ok(r) => Ok(r),
......@@ -1959,9 +1996,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
19591996 fn drop_until_scope(
19601997 &mut self,
19611998 scope_index: usize,
1962 mut current: BasicBlockId,
1999 mut current: BasicBlockId<'db>,
19632000 span: MirSpan,
1964 ) -> BasicBlockId {
2001 ) -> BasicBlockId<'db> {
19652002 for scope in self.drop_scopes[scope_index..].to_vec().iter().rev() {
19662003 self.emit_drop_and_storage_dead_for_scope(scope, &mut current, span);
19672004 }
......@@ -1981,9 +2018,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
19812018 /// Don't call directly
19822019 fn pop_drop_scope_internal(
19832020 &mut self,
1984 mut current: BasicBlockId,
2021 mut current: BasicBlockId<'db>,
19852022 span: MirSpan,
1986 ) -> BasicBlockId {
2023 ) -> BasicBlockId<'db> {
19872024 let scope = self.drop_scopes.pop().unwrap();
19882025 self.emit_drop_and_storage_dead_for_scope(&scope, &mut current, span);
19892026 current
......@@ -1991,9 +2028,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
19912028
19922029 fn pop_drop_scope_assert_finished(
19932030 &mut self,
1994 mut current: BasicBlockId,
2031 mut current: BasicBlockId<'db>,
19952032 span: MirSpan,
1996 ) -> Result<BasicBlockId> {
2033 ) -> Result<'db, BasicBlockId<'db>> {
19972034 current = self.pop_drop_scope_internal(current, span);
19982035 if !self.drop_scopes.is_empty() {
19992036 implementation_error!("Mismatched count between drop scope push and pops");
......@@ -2003,12 +2040,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
20032040
20042041 fn emit_drop_and_storage_dead_for_scope(
20052042 &mut self,
2006 scope: &DropScope,
2007 current: &mut Idx<BasicBlock>,
2043 scope: &DropScope<'db>,
2044 current: &mut Idx<BasicBlock<'db>>,
20082045 span: MirSpan,
20092046 ) {
20102047 for &l in scope.locals.iter().rev() {
2011 if !self.result.locals[l].ty.clone().is_copy(self.db, self.owner) {
2048 if !self.infcx.type_is_copy_modulo_regions(self.env.env, self.result.locals[l].ty) {
20122049 let prev = std::mem::replace(current, self.new_basic_block());
20132050 self.set_terminator(
20142051 prev,
......@@ -2021,7 +2058,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
20212058 }
20222059}
20232060
2024fn cast_kind(db: &dyn HirDatabase, source_ty: &Ty, target_ty: &Ty) -> Result<CastKind> {
2061fn cast_kind<'db>(
2062 db: &'db dyn HirDatabase,
2063 source_ty: Ty<'db>,
2064 target_ty: Ty<'db>,
2065) -> Result<'db, CastKind> {
20252066 let from = CastTy::from_ty(db, source_ty);
20262067 let cast = CastTy::from_ty(db, target_ty);
20272068 Ok(match (from, cast) {
......@@ -2039,41 +2080,49 @@ fn cast_kind(db: &dyn HirDatabase, source_ty: &Ty, target_ty: &Ty) -> Result<Cas
20392080 })
20402081}
20412082
2042pub fn mir_body_for_closure_query(
2043 db: &dyn HirDatabase,
2083pub fn mir_body_for_closure_query<'db>(
2084 db: &'db dyn HirDatabase,
20442085 closure: InternedClosureId,
2045) -> Result<Arc<MirBody>> {
2086) -> Result<'db, Arc<MirBody<'db>>> {
20462087 let InternedClosure(owner, expr) = db.lookup_intern_closure(closure);
20472088 let body = db.body(owner);
20482089 let infer = db.infer(owner);
20492090 let Expr::Closure { args, body: root, .. } = &body[expr] else {
20502091 implementation_error!("closure expression is not closure");
20512092 };
2052 let TyKind::Closure(_, substs) = &infer[expr].kind(Interner) else {
2093 let crate::next_solver::TyKind::Closure(_, substs) = infer[expr].kind() else {
20532094 implementation_error!("closure expression is not closure");
20542095 };
2055 let (captures, kind) = infer.closure_info(&closure.into());
2096 let (captures, kind) = infer.closure_info(closure);
20562097 let mut ctx = MirLowerCtx::new(db, owner, &body, &infer);
20572098 // 0 is return local
2058 ctx.result.locals.alloc(Local { ty: infer[*root].clone() });
2099 ctx.result.locals.alloc(Local { ty: infer[*root] });
20592100 let closure_local = ctx.result.locals.alloc(Local {
20602101 ty: match kind {
2061 FnTrait::FnOnce | FnTrait::AsyncFnOnce => infer[expr].clone(),
2062 FnTrait::FnMut | FnTrait::AsyncFnMut => {
2063 TyKind::Ref(Mutability::Mut, error_lifetime(), infer[expr].clone()).intern(Interner)
2064 }
2065 FnTrait::Fn | FnTrait::AsyncFn => {
2066 TyKind::Ref(Mutability::Not, error_lifetime(), infer[expr].clone()).intern(Interner)
2067 }
2102 FnTrait::FnOnce | FnTrait::AsyncFnOnce => infer[expr],
2103 FnTrait::FnMut | FnTrait::AsyncFnMut => Ty::new_ref(
2104 ctx.interner(),
2105 Region::error(ctx.interner()),
2106 infer[expr],
2107 Mutability::Mut,
2108 ),
2109 FnTrait::Fn | FnTrait::AsyncFn => Ty::new_ref(
2110 ctx.interner(),
2111 Region::error(ctx.interner()),
2112 infer[expr],
2113 Mutability::Not,
2114 ),
20682115 },
20692116 });
20702117 ctx.result.param_locals.push(closure_local);
2071 let Some(sig) = ClosureSubst(substs).sig_ty(db).callable_sig(db) else {
2118 let Some(sig) =
2119 substs.split_closure_args_untupled().closure_sig_as_fn_ptr_ty.callable_sig(ctx.interner())
2120 else {
20722121 implementation_error!("closure has not callable sig");
20732122 };
20742123 let resolver_guard = ctx.resolver.update_to_inner_scope(db, owner, expr);
20752124 let current = ctx.lower_params_and_bindings(
2076 args.iter().zip(sig.params().iter()).map(|(it, y)| (*it, y.clone())),
2125 args.iter().zip(sig.skip_binder().inputs().iter()).map(|(it, y)| (*it, y)),
20772126 None,
20782127 |_| true,
20792128 )?;
......@@ -2082,7 +2131,8 @@ pub fn mir_body_for_closure_query(
20822131 let current = ctx.pop_drop_scope_assert_finished(current, root.into())?;
20832132 ctx.set_terminator(current, TerminatorKind::Return, (*root).into());
20842133 }
2085 let mut upvar_map: FxHashMap<LocalId, Vec<(&CapturedItem, usize)>> = FxHashMap::default();
2134 let mut upvar_map: FxHashMap<LocalId<'db>, Vec<(&CapturedItem<'_>, usize)>> =
2135 FxHashMap::default();
20862136 for (i, capture) in captures.iter().enumerate() {
20872137 let local = ctx.binding_local(capture.place.local)?;
20882138 upvar_map.entry(local).or_default().push((capture, i));
......@@ -2144,7 +2194,10 @@ pub fn mir_body_for_closure_query(
21442194 Ok(Arc::new(ctx.result))
21452195}
21462196
2147pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<MirBody>> {
2197pub fn mir_body_query<'db>(
2198 db: &'db dyn HirDatabase,
2199 def: DefWithBodyId,
2200) -> Result<'db, Arc<MirBody<'db>>> {
21482201 let krate = def.krate(db);
21492202 let edition = krate.data(db).edition;
21502203 let detail = match def {
......@@ -2177,22 +2230,22 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi
21772230 Ok(Arc::new(result))
21782231}
21792232
2180pub(crate) fn mir_body_cycle_result(
2181 _db: &dyn HirDatabase,
2233pub(crate) fn mir_body_cycle_result<'db>(
2234 _db: &'db dyn HirDatabase,
21822235 _def: DefWithBodyId,
2183) -> Result<Arc<MirBody>> {
2236) -> Result<'db, Arc<MirBody<'db>>> {
21842237 Err(MirLowerError::Loop)
21852238}
21862239
2187pub fn lower_to_mir(
2188 db: &dyn HirDatabase,
2240pub fn lower_to_mir<'db>(
2241 db: &'db dyn HirDatabase,
21892242 owner: DefWithBodyId,
21902243 body: &Body,
2191 infer: &InferenceResult,
2244 infer: &InferenceResult<'db>,
21922245 // FIXME: root_expr should always be the body.body_expr, but since `X` in `[(); X]` doesn't have its own specific body yet, we
21932246 // need to take this input explicitly.
21942247 root_expr: ExprId,
2195) -> Result<MirBody> {
2248) -> Result<'db, MirBody<'db>> {
21962249 if infer.type_mismatches().next().is_some() || infer.is_erroneous() {
21972250 return Err(MirLowerError::HasErrors);
21982251 }
......@@ -2209,18 +2262,12 @@ pub fn lower_to_mir(
22092262 if body.body_expr == root_expr {
22102263 // otherwise it's an inline const, and has no parameter
22112264 if let DefWithBodyId::FunctionId(fid) = owner {
2212 let substs = TyBuilder::placeholder_subst(db, fid);
2213 let interner = DbInterner::new_with(db, None, None);
2214 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2215 let callable_sig = db
2216 .callable_item_signature(fid.into())
2217 .instantiate(interner, args)
2218 .skip_binder()
2219 .to_chalk(interner);
2220 let mut params = callable_sig.params().iter();
2221 let self_param = body.self_param.and_then(|id| Some((id, params.next()?.clone())));
2265 let callable_sig =
2266 db.callable_item_signature(fid.into()).instantiate_identity().skip_binder();
2267 let mut params = callable_sig.inputs().iter();
2268 let self_param = body.self_param.and_then(|id| Some((id, params.next()?)));
22222269 break 'b ctx.lower_params_and_bindings(
2223 body.params.iter().zip(params).map(|(it, y)| (*it, y.clone())),
2270 body.params.iter().zip(params).map(|(it, y)| (*it, y)),
22242271 self_param,
22252272 binding_picker,
22262273 )?;
src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs+68-59
......@@ -1,10 +1,14 @@
11//! MIR lowering for places
22
3use crate::mir::{MutBorrowKind, Operand, OperandKind};
4
5use super::*;
63use hir_def::FunctionId;
74use intern::sym;
5use rustc_type_ir::inherent::{AdtDef, Region as _, Ty as _};
6
7use super::*;
8use crate::{
9 mir::{MutBorrowKind, Operand, OperandKind},
10 next_solver::Region,
11};
812
913macro_rules! not_supported {
1014 ($it: expr) => {
......@@ -12,12 +16,12 @@ macro_rules! not_supported {
1216 };
1317}
1418
15impl MirLowerCtx<'_> {
19impl<'db> MirLowerCtx<'_, 'db> {
1620 fn lower_expr_to_some_place_without_adjust(
1721 &mut self,
1822 expr_id: ExprId,
19 prev_block: BasicBlockId,
20 ) -> Result<Option<(Place, BasicBlockId)>> {
23 prev_block: BasicBlockId<'db>,
24 ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> {
2125 let ty = self.expr_ty_without_adjust(expr_id);
2226 let place = self.temp(ty, prev_block, expr_id.into())?;
2327 let Some(current) =
......@@ -31,12 +35,12 @@ impl MirLowerCtx<'_> {
3135 fn lower_expr_to_some_place_with_adjust(
3236 &mut self,
3337 expr_id: ExprId,
34 prev_block: BasicBlockId,
35 adjustments: &[Adjustment],
36 ) -> Result<Option<(Place, BasicBlockId)>> {
38 prev_block: BasicBlockId<'db>,
39 adjustments: &[Adjustment<'db>],
40 ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> {
3741 let ty = adjustments
3842 .last()
39 .map(|it| it.target.clone())
43 .map(|it| it.target)
4044 .unwrap_or_else(|| self.expr_ty_without_adjust(expr_id));
4145 let place = self.temp(ty, prev_block, expr_id.into())?;
4246 let Some(current) =
......@@ -49,12 +53,12 @@ impl MirLowerCtx<'_> {
4953
5054 pub(super) fn lower_expr_as_place_with_adjust(
5155 &mut self,
52 current: BasicBlockId,
56 current: BasicBlockId<'db>,
5357 expr_id: ExprId,
5458 upgrade_rvalue: bool,
55 adjustments: &[Adjustment],
56 ) -> Result<Option<(Place, BasicBlockId)>> {
57 let try_rvalue = |this: &mut MirLowerCtx<'_>| {
59 adjustments: &[Adjustment<'db>],
60 ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> {
61 let try_rvalue = |this: &mut MirLowerCtx<'_, 'db>| {
5862 if !upgrade_rvalue {
5963 return Err(MirLowerError::MutatingRvalue);
6064 }
......@@ -89,9 +93,9 @@ impl MirLowerCtx<'_> {
8993 current,
9094 r,
9195 rest.last()
92 .map(|it| it.target.clone())
96 .map(|it| it.target)
9397 .unwrap_or_else(|| self.expr_ty_without_adjust(expr_id)),
94 last.target.clone(),
98 last.target,
9599 expr_id.into(),
96100 match od.0 {
97101 Some(Mutability::Mut) => true,
......@@ -111,10 +115,10 @@ impl MirLowerCtx<'_> {
111115
112116 pub(super) fn lower_expr_as_place(
113117 &mut self,
114 current: BasicBlockId,
118 current: BasicBlockId<'db>,
115119 expr_id: ExprId,
116120 upgrade_rvalue: bool,
117 ) -> Result<Option<(Place, BasicBlockId)>> {
121 ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> {
118122 match self.infer.expr_adjustments.get(&expr_id) {
119123 Some(a) => self.lower_expr_as_place_with_adjust(current, expr_id, upgrade_rvalue, a),
120124 None => self.lower_expr_as_place_without_adjust(current, expr_id, upgrade_rvalue),
......@@ -123,11 +127,11 @@ impl MirLowerCtx<'_> {
123127
124128 pub(super) fn lower_expr_as_place_without_adjust(
125129 &mut self,
126 current: BasicBlockId,
130 current: BasicBlockId<'db>,
127131 expr_id: ExprId,
128132 upgrade_rvalue: bool,
129 ) -> Result<Option<(Place, BasicBlockId)>> {
130 let try_rvalue = |this: &mut MirLowerCtx<'_>| {
133 ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> {
134 let try_rvalue = |this: &mut MirLowerCtx<'_, 'db>| {
131135 if !upgrade_rvalue {
132136 return Err(MirLowerError::MutatingRvalue);
133137 }
......@@ -149,9 +153,13 @@ impl MirLowerCtx<'_> {
149153 }
150154 ValueNs::StaticId(s) => {
151155 let ty = self.expr_ty_without_adjust(expr_id);
152 let ref_ty =
153 TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner);
154 let temp: Place = self.temp(ref_ty, current, expr_id.into())?.into();
156 let ref_ty = Ty::new_ref(
157 self.interner(),
158 Region::new_static(self.interner()),
159 ty,
160 Mutability::Not,
161 );
162 let temp: Place<'db> = self.temp(ref_ty, current, expr_id.into())?.into();
155163 self.push_assignment(
156164 current,
157165 temp,
......@@ -167,10 +175,10 @@ impl MirLowerCtx<'_> {
167175 }
168176 }
169177 Expr::UnaryOp { expr, op: hir_def::hir::UnaryOp::Deref } => {
170 let is_builtin = match self.expr_ty_without_adjust(*expr).kind(Interner) {
171 TyKind::Ref(..) | TyKind::Raw(..) => true,
178 let is_builtin = match self.expr_ty_without_adjust(*expr).kind() {
179 TyKind::Ref(..) | TyKind::RawPtr(..) => true,
172180 TyKind::Adt(id, _) => {
173 if let Some(lang_item) = self.db.lang_attr(id.0.into()) {
181 if let Some(lang_item) = self.db.lang_attr(id.def_id().0.into()) {
174182 lang_item == LangItem::OwnedBox
175183 } else {
176184 false
......@@ -219,9 +227,9 @@ impl MirLowerCtx<'_> {
219227 Expr::Index { base, index } => {
220228 let base_ty = self.expr_ty_after_adjustments(*base);
221229 let index_ty = self.expr_ty_after_adjustments(*index);
222 if index_ty != TyBuilder::usize()
230 if !matches!(index_ty.kind(), TyKind::Uint(rustc_ast_ir::UintTy::Usize))
223231 || !matches!(
224 base_ty.strip_reference().kind(Interner),
232 base_ty.strip_reference().kind(),
225233 TyKind::Array(..) | TyKind::Slice(..)
226234 )
227235 {
......@@ -278,24 +286,26 @@ impl MirLowerCtx<'_> {
278286
279287 fn lower_overloaded_index(
280288 &mut self,
281 current: BasicBlockId,
282 place: Place,
283 base_ty: Ty,
284 result_ty: Ty,
285 index_operand: Operand,
289 current: BasicBlockId<'db>,
290 place: Place<'db>,
291 base_ty: Ty<'db>,
292 result_ty: Ty<'db>,
293 index_operand: Operand<'db>,
286294 span: MirSpan,
287 index_fn: (FunctionId, Substitution),
288 ) -> Result<Option<(Place, BasicBlockId)>> {
295 index_fn: (FunctionId, GenericArgs<'db>),
296 ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> {
289297 let mutability = match base_ty.as_reference() {
290298 Some((_, _, mutability)) => mutability,
291299 None => Mutability::Not,
292300 };
293 let result_ref = TyKind::Ref(mutability, error_lifetime(), result_ty).intern(Interner);
294 let mut result: Place = self.temp(result_ref, current, span)?.into();
295 let index_fn_op = Operand::const_zst(
296 TyKind::FnDef(CallableDefId::FunctionId(index_fn.0).to_chalk(self.db), index_fn.1)
297 .intern(Interner),
298 );
301 let result_ref =
302 Ty::new_ref(self.interner(), Region::error(self.interner()), result_ty, mutability);
303 let mut result: Place<'db> = self.temp(result_ref, current, span)?.into();
304 let index_fn_op = Operand::const_zst(Ty::new_fn_def(
305 self.interner(),
306 CallableDefId::FunctionId(index_fn.0).into(),
307 index_fn.1,
308 ));
299309 let Some(current) = self.lower_call(
300310 index_fn_op,
301311 Box::new([Operand { kind: OperandKind::Copy(place), span: None }, index_operand]),
......@@ -313,14 +323,14 @@ impl MirLowerCtx<'_> {
313323
314324 fn lower_overloaded_deref(
315325 &mut self,
316 current: BasicBlockId,
317 place: Place,
318 source_ty: Ty,
319 target_ty: Ty,
326 current: BasicBlockId<'db>,
327 place: Place<'db>,
328 source_ty: Ty<'db>,
329 target_ty: Ty<'db>,
320330 span: MirSpan,
321331 mutability: bool,
322 ) -> Result<Option<(Place, BasicBlockId)>> {
323 let (chalk_mut, trait_lang_item, trait_method_name, borrow_kind) = if !mutability {
332 ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> {
333 let (mutability, trait_lang_item, trait_method_name, borrow_kind) = if !mutability {
324334 (
325335 Mutability::Not,
326336 LangItem::Deref,
......@@ -335,9 +345,10 @@ impl MirLowerCtx<'_> {
335345 BorrowKind::Mut { kind: MutBorrowKind::Default },
336346 )
337347 };
338 let ty_ref = TyKind::Ref(chalk_mut, error_lifetime(), source_ty.clone()).intern(Interner);
339 let target_ty_ref = TyKind::Ref(chalk_mut, error_lifetime(), target_ty).intern(Interner);
340 let ref_place: Place = self.temp(ty_ref, current, span)?.into();
348 let error_region = Region::error(self.interner());
349 let ty_ref = Ty::new_ref(self.interner(), error_region, source_ty, mutability);
350 let target_ty_ref = Ty::new_ref(self.interner(), error_region, target_ty, mutability);
351 let ref_place: Place<'db> = self.temp(ty_ref, current, span)?.into();
341352 self.push_assignment(current, ref_place, Rvalue::Ref(borrow_kind, place), span);
342353 let deref_trait = self
343354 .resolve_lang_item(trait_lang_item)?
......@@ -347,14 +358,12 @@ impl MirLowerCtx<'_> {
347358 .trait_items(self.db)
348359 .method_by_name(&trait_method_name)
349360 .ok_or(MirLowerError::LangItemNotFound(trait_lang_item))?;
350 let deref_fn_op = Operand::const_zst(
351 TyKind::FnDef(
352 CallableDefId::FunctionId(deref_fn).to_chalk(self.db),
353 Substitution::from1(Interner, source_ty),
354 )
355 .intern(Interner),
356 );
357 let mut result: Place = self.temp(target_ty_ref, current, span)?.into();
361 let deref_fn_op = Operand::const_zst(Ty::new_fn_def(
362 self.interner(),
363 CallableDefId::FunctionId(deref_fn).into(),
364 GenericArgs::new_from_iter(self.interner(), [source_ty.into()]),
365 ));
366 let mut result: Place<'db> = self.temp(target_ty_ref, current, span)?.into();
358367 let Some(current) = self.lower_call(
359368 deref_fn_op,
360369 Box::new([Operand { kind: OperandKind::Copy(ref_place), span: None }]),
src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs+80-81
......@@ -1,17 +1,18 @@
11//! MIR lowering for patterns
22
33use hir_def::{AssocItemId, hir::ExprId, signatures::VariantFields};
4use rustc_type_ir::inherent::{IntoKind, SliceLike, Ty as _};
45
6use crate::next_solver::GenericArgs;
57use crate::{
68 BindingMode,
79 mir::{
810 LocalId, MutBorrowKind, Operand, OperandKind,
911 lower::{
10 BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner,
11 MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Pat, PatId, Place,
12 PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue,
13 Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind,
14 ValueNs, VariantId,
12 BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, MemoryMap,
13 MirLowerCtx, MirLowerError, MirSpan, Pat, PatId, Place, PlaceElem, ProjectionElem,
14 RecordFieldPat, ResolveValueResult, Result, Rvalue, SwitchTargets, TerminatorKind,
15 TupleFieldId, TupleId, Ty, TyKind, ValueNs, VariantId,
1516 },
1617 },
1718};
......@@ -50,7 +51,7 @@ enum MatchingMode {
5051 Assign,
5152}
5253
53impl MirLowerCtx<'_> {
54impl<'db> MirLowerCtx<'_, 'db> {
5455 /// It gets a `current` unterminated block, appends some statements and possibly a terminator to it to check if
5556 /// the pattern matches and write bindings, and returns two unterminated blocks, one for the matched path (which
5657 /// can be the `current` block) and one for the mismatched path. If the input pattern is irrefutable, the
......@@ -62,11 +63,11 @@ impl MirLowerCtx<'_> {
6263 /// so it should be an empty block.
6364 pub(super) fn pattern_match(
6465 &mut self,
65 current: BasicBlockId,
66 current_else: Option<BasicBlockId>,
67 cond_place: Place,
66 current: BasicBlockId<'db>,
67 current_else: Option<BasicBlockId<'db>>,
68 cond_place: Place<'db>,
6869 pattern: PatId,
69 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
70 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
7071 let (current, current_else) = self.pattern_match_inner(
7172 current,
7273 current_else,
......@@ -86,10 +87,10 @@ impl MirLowerCtx<'_> {
8687
8788 pub(super) fn pattern_match_assignment(
8889 &mut self,
89 current: BasicBlockId,
90 value: Place,
90 current: BasicBlockId<'db>,
91 value: Place<'db>,
9192 pattern: PatId,
92 ) -> Result<BasicBlockId> {
93 ) -> Result<'db, BasicBlockId<'db>> {
9394 let (current, _) =
9495 self.pattern_match_inner(current, None, value, pattern, MatchingMode::Assign)?;
9596 Ok(current)
......@@ -98,9 +99,9 @@ impl MirLowerCtx<'_> {
9899 pub(super) fn match_self_param(
99100 &mut self,
100101 id: BindingId,
101 current: BasicBlockId,
102 local: LocalId,
103 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
102 current: BasicBlockId<'db>,
103 local: LocalId<'db>,
104 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
104105 self.pattern_match_binding(
105106 id,
106107 BindingMode::Move,
......@@ -113,12 +114,12 @@ impl MirLowerCtx<'_> {
113114
114115 fn pattern_match_inner(
115116 &mut self,
116 mut current: BasicBlockId,
117 mut current_else: Option<BasicBlockId>,
118 mut cond_place: Place,
117 mut current: BasicBlockId<'db>,
118 mut current_else: Option<BasicBlockId<'db>>,
119 mut cond_place: Place<'db>,
119120 pattern: PatId,
120121 mode: MatchingMode,
121 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
122 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
122123 let cnt = self.infer.pat_adjustments.get(&pattern).map(|x| x.len()).unwrap_or_default();
123124 cond_place.projection = self.result.projection_store.intern(
124125 cond_place
......@@ -134,8 +135,8 @@ impl MirLowerCtx<'_> {
134135 Pat::Missing => return Err(MirLowerError::IncompletePattern),
135136 Pat::Wild => (current, current_else),
136137 Pat::Tuple { args, ellipsis } => {
137 let subst = match self.infer[pattern].kind(Interner) {
138 TyKind::Tuple(_, s) => s,
138 let subst = match self.infer[pattern].kind() {
139 TyKind::Tuple(s) => s,
139140 _ => {
140141 return Err(MirLowerError::TypeError(
141142 "non tuple type matched with tuple pattern",
......@@ -147,7 +148,7 @@ impl MirLowerCtx<'_> {
147148 current_else,
148149 args,
149150 *ellipsis,
150 (0..subst.len(Interner)).map(|i| {
151 (0..subst.len()).map(|i| {
151152 PlaceElem::Field(Either::Right(TupleFieldId {
152153 tuple: TupleId(!0), // Dummy as it is unused
153154 index: i as u32,
......@@ -207,13 +208,12 @@ impl MirLowerCtx<'_> {
207208 )?
208209 }
209210 Pat::Range { start, end } => {
210 let mut add_check = |l: &ExprId, binop| -> Result<()> {
211 let lv =
212 self.lower_literal_or_const_to_operand(self.infer[pattern].clone(), l)?;
211 let mut add_check = |l: &ExprId, binop| -> Result<'db, ()> {
212 let lv = self.lower_literal_or_const_to_operand(self.infer[pattern], l)?;
213213 let else_target = *current_else.get_or_insert_with(|| self.new_basic_block());
214214 let next = self.new_basic_block();
215 let discr: Place =
216 self.temp(TyBuilder::bool(), current, pattern.into())?.into();
215 let discr: Place<'db> =
216 self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into();
217217 self.push_assignment(
218218 current,
219219 discr,
......@@ -249,10 +249,11 @@ impl MirLowerCtx<'_> {
249249 Pat::Slice { prefix, slice, suffix } => {
250250 if mode == MatchingMode::Check {
251251 // emit runtime length check for slice
252 if let TyKind::Slice(_) = self.infer[pattern].kind(Interner) {
252 if let TyKind::Slice(_) = self.infer[pattern].kind() {
253253 let pattern_len = prefix.len() + suffix.len();
254 let place_len: Place =
255 self.temp(TyBuilder::usize(), current, pattern.into())?.into();
254 let place_len: Place<'db> = self
255 .temp(Ty::new_usize(self.interner()), current, pattern.into())?
256 .into();
256257 self.push_assignment(
257258 current,
258259 place_len,
......@@ -282,10 +283,11 @@ impl MirLowerCtx<'_> {
282283 let c = Operand::from_concrete_const(
283284 pattern_len.to_le_bytes().into(),
284285 MemoryMap::default(),
285 TyBuilder::usize(),
286 Ty::new_usize(self.interner()),
286287 );
287 let discr: Place =
288 self.temp(TyBuilder::bool(), current, pattern.into())?.into();
288 let discr: Place<'db> = self
289 .temp(Ty::new_bool(self.interner()), current, pattern.into())?
290 .into();
289291 self.push_assignment(
290292 current,
291293 discr,
......@@ -396,22 +398,16 @@ impl MirLowerCtx<'_> {
396398 break 'b (c, x.1);
397399 }
398400 if let ResolveValueResult::ValueNs(ValueNs::ConstId(c), _) = pr {
399 break 'b (c, Substitution::empty(Interner));
401 break 'b (c, GenericArgs::new_from_iter(self.interner(), []));
400402 }
401403 not_supported!("path in pattern position that is not const or variant")
402404 };
403 let tmp: Place =
404 self.temp(self.infer[pattern].clone(), current, pattern.into())?.into();
405 let tmp: Place<'db> =
406 self.temp(self.infer[pattern], current, pattern.into())?.into();
405407 let span = pattern.into();
406 self.lower_const(
407 c.into(),
408 current,
409 tmp,
410 subst,
411 span,
412 self.infer[pattern].clone(),
413 )?;
414 let tmp2: Place = self.temp(TyBuilder::bool(), current, pattern.into())?.into();
408 self.lower_const(c.into(), current, tmp, subst, span)?;
409 let tmp2: Place<'db> =
410 self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into();
415411 self.push_assignment(
416412 current,
417413 tmp2,
......@@ -438,7 +434,7 @@ impl MirLowerCtx<'_> {
438434 Pat::Lit(l) => match &self.body[*l] {
439435 Expr::Literal(l) => {
440436 if mode == MatchingMode::Check {
441 let c = self.lower_literal_to_operand(self.infer[pattern].clone(), l)?;
437 let c = self.lower_literal_to_operand(self.infer[pattern], l)?;
442438 self.pattern_match_const(current_else, current, c, cond_place, pattern)?
443439 } else {
444440 (current, current_else)
......@@ -510,11 +506,11 @@ impl MirLowerCtx<'_> {
510506 &mut self,
511507 id: BindingId,
512508 mode: BindingMode,
513 cond_place: Place,
509 cond_place: Place<'db>,
514510 span: MirSpan,
515 current: BasicBlockId,
516 current_else: Option<BasicBlockId>,
517 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
511 current: BasicBlockId<'db>,
512 current_else: Option<BasicBlockId<'db>>,
513 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
518514 let target_place = self.binding_local(id)?;
519515 self.push_storage_live(id, current)?;
520516 self.push_match_assignment(current, target_place, mode, cond_place, span);
......@@ -523,10 +519,10 @@ impl MirLowerCtx<'_> {
523519
524520 fn push_match_assignment(
525521 &mut self,
526 current: BasicBlockId,
527 target_place: LocalId,
522 current: BasicBlockId<'db>,
523 target_place: LocalId<'db>,
528524 mode: BindingMode,
529 cond_place: Place,
525 cond_place: Place<'db>,
530526 span: MirSpan,
531527 ) {
532528 self.push_assignment(
......@@ -536,8 +532,10 @@ impl MirLowerCtx<'_> {
536532 BindingMode::Move => {
537533 Operand { kind: OperandKind::Copy(cond_place), span: None }.into()
538534 }
539 BindingMode::Ref(Mutability::Not) => Rvalue::Ref(BorrowKind::Shared, cond_place),
540 BindingMode::Ref(Mutability::Mut) => {
535 BindingMode::Ref(rustc_ast_ir::Mutability::Not) => {
536 Rvalue::Ref(BorrowKind::Shared, cond_place)
537 }
538 BindingMode::Ref(rustc_ast_ir::Mutability::Mut) => {
541539 Rvalue::Ref(BorrowKind::Mut { kind: MutBorrowKind::Default }, cond_place)
542540 }
543541 },
......@@ -547,15 +545,16 @@ impl MirLowerCtx<'_> {
547545
548546 fn pattern_match_const(
549547 &mut self,
550 current_else: Option<BasicBlockId>,
551 current: BasicBlockId,
552 c: Operand,
553 cond_place: Place,
548 current_else: Option<BasicBlockId<'db>>,
549 current: BasicBlockId<'db>,
550 c: Operand<'db>,
551 cond_place: Place<'db>,
554552 pattern: Idx<Pat>,
555 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
553 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
556554 let then_target = self.new_basic_block();
557555 let else_target = current_else.unwrap_or_else(|| self.new_basic_block());
558 let discr: Place = self.temp(TyBuilder::bool(), current, pattern.into())?.into();
556 let discr: Place<'db> =
557 self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into();
559558 self.push_assignment(
560559 current,
561560 discr,
......@@ -580,14 +579,14 @@ impl MirLowerCtx<'_> {
580579
581580 fn pattern_matching_variant(
582581 &mut self,
583 cond_place: Place,
582 cond_place: Place<'db>,
584583 variant: VariantId,
585 mut current: BasicBlockId,
584 mut current: BasicBlockId<'db>,
586585 span: MirSpan,
587 mut current_else: Option<BasicBlockId>,
586 mut current_else: Option<BasicBlockId<'db>>,
588587 shape: AdtPatternShape<'_>,
589588 mode: MatchingMode,
590 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
589 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
591590 Ok(match variant {
592591 VariantId::EnumVariantId(v) => {
593592 if mode == MatchingMode::Check {
......@@ -636,11 +635,11 @@ impl MirLowerCtx<'_> {
636635 shape: AdtPatternShape<'_>,
637636 variant_data: &VariantFields,
638637 v: VariantId,
639 current: BasicBlockId,
640 current_else: Option<BasicBlockId>,
641 cond_place: &Place,
638 current: BasicBlockId<'db>,
639 current_else: Option<BasicBlockId<'db>>,
640 cond_place: &Place<'db>,
642641 mode: MatchingMode,
643 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
642 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
644643 Ok(match shape {
645644 AdtPatternShape::Record { args } => {
646645 let it = args
......@@ -656,7 +655,7 @@ impl MirLowerCtx<'_> {
656655 x.pat,
657656 ))
658657 })
659 .collect::<Result<Vec<_>>>()?;
658 .collect::<Result<'db, Vec<_>>>()?;
660659 self.pattern_match_adt(current, current_else, it.into_iter(), cond_place, mode)?
661660 }
662661 AdtPatternShape::Tuple { args, ellipsis } => {
......@@ -679,12 +678,12 @@ impl MirLowerCtx<'_> {
679678
680679 fn pattern_match_adt(
681680 &mut self,
682 mut current: BasicBlockId,
683 mut current_else: Option<BasicBlockId>,
684 args: impl Iterator<Item = (PlaceElem, PatId)>,
685 cond_place: &Place,
681 mut current: BasicBlockId<'db>,
682 mut current_else: Option<BasicBlockId<'db>>,
683 args: impl Iterator<Item = (PlaceElem<'db>, PatId)>,
684 cond_place: &Place<'db>,
686685 mode: MatchingMode,
687 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
686 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
688687 for (proj, arg) in args {
689688 let cond_place = cond_place.project(proj, &mut self.result.projection_store);
690689 (current, current_else) =
......@@ -695,14 +694,14 @@ impl MirLowerCtx<'_> {
695694
696695 fn pattern_match_tuple_like(
697696 &mut self,
698 current: BasicBlockId,
699 current_else: Option<BasicBlockId>,
697 current: BasicBlockId<'db>,
698 current_else: Option<BasicBlockId<'db>>,
700699 args: &[PatId],
701700 ellipsis: Option<u32>,
702 fields: impl DoubleEndedIterator<Item = PlaceElem> + Clone,
703 cond_place: &Place,
701 fields: impl DoubleEndedIterator<Item = PlaceElem<'db>> + Clone,
702 cond_place: &Place<'db>,
704703 mode: MatchingMode,
705 ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
704 ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> {
706705 let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
707706 let it = al
708707 .iter()
src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs+15-28
......@@ -1,36 +1,23 @@
1use hir_def::db::DefDatabase;
2use rustc_hash::FxHashMap;
3use span::Edition;
41use test_fixture::WithFixture;
5use triomphe::Arc;
62
7use crate::{
8 db::HirDatabase,
9 mir::{MirBody, MirLowerError},
10 setup_tracing,
11 test_db::TestDB,
12};
3use crate::{db::HirDatabase, setup_tracing, test_db::TestDB};
134
14fn lower_mir(
15 #[rust_analyzer::rust_fixture] ra_fixture: &str,
16) -> FxHashMap<String, Result<Arc<MirBody>, MirLowerError>> {
5fn lower_mir(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
176 let _tracing = setup_tracing();
187 let (db, file_ids) = TestDB::with_many_files(ra_fixture);
19 let file_id = *file_ids.last().unwrap();
20 let module_id = db.module_for_file(file_id.file_id(&db));
21 let def_map = module_id.def_map(&db);
22 let scope = &def_map[module_id.local_id].scope;
23 let funcs = scope.declarations().filter_map(|x| match x {
24 hir_def::ModuleDefId::FunctionId(it) => Some(it),
25 _ => None,
26 });
27 funcs
28 .map(|func| {
29 let name = db.function_signature(func).name.display(&db, Edition::CURRENT).to_string();
30 let mir = db.mir_body(func.into());
31 (name, mir)
32 })
33 .collect()
8 crate::attach_db(&db, || {
9 let file_id = *file_ids.last().unwrap();
10 let module_id = db.module_for_file(file_id.file_id(&db));
11 let def_map = module_id.def_map(&db);
12 let scope = &def_map[module_id.local_id].scope;
13 let funcs = scope.declarations().filter_map(|x| match x {
14 hir_def::ModuleDefId::FunctionId(it) => Some(it),
15 _ => None,
16 });
17 for func in funcs {
18 _ = db.mir_body(func.into());
19 }
20 })
3421}
3522
3623#[test]
src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs+98-196
......@@ -7,224 +7,129 @@
77//!
88//! So the monomorphization should be called even if the substitution is empty.
99
10use std::mem;
11
12use chalk_ir::{
13 ConstData, DebruijnIndex,
14 fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable},
15};
1610use hir_def::DefWithBodyId;
11use rustc_type_ir::inherent::{IntoKind, SliceLike};
12use rustc_type_ir::{
13 FallibleTypeFolder, TypeFlags, TypeFoldable, TypeSuperFoldable, TypeVisitableExt,
14};
1715use triomphe::Arc;
1816
17use crate::next_solver::{Const, ConstKind, Region, RegionKind};
1918use crate::{
20 Const, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, TyKind,
21 consteval::{intern_const_scalar, unknown_const},
22 db::{HirDatabase, InternedClosure, InternedClosureId},
23 from_placeholder_idx,
24 generics::{Generics, generics},
25 infer::normalize,
19 TraitEnvironment,
20 db::{HirDatabase, InternedClosureId},
21 next_solver::{
22 DbInterner, GenericArgs, Ty, TyKind, TypingMode,
23 infer::{DbInternerInferExt, InferCtxt, traits::ObligationCause},
24 obligation_ctxt::ObligationCtxt,
25 references_non_lt_error,
26 },
2627};
2728
2829use super::{MirBody, MirLowerError, Operand, OperandKind, Rvalue, StatementKind, TerminatorKind};
2930
30macro_rules! not_supported {
31 ($it: expr) => {
32 return Err(MirLowerError::NotSupported(format!($it)))
33 };
31struct Filler<'db> {
32 infcx: InferCtxt<'db>,
33 trait_env: Arc<TraitEnvironment<'db>>,
34 subst: GenericArgs<'db>,
3435}
3536
36struct Filler<'a> {
37 db: &'a dyn HirDatabase,
38 trait_env: Arc<TraitEnvironment<'a>>,
39 subst: &'a Substitution,
40 generics: Option<Generics>,
41}
42impl FallibleTypeFolder<Interner> for Filler<'_> {
43 type Error = MirLowerError;
37impl<'db> FallibleTypeFolder<DbInterner<'db>> for Filler<'db> {
38 type Error = MirLowerError<'db>;
4439
45 fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<Interner, Error = Self::Error> {
46 self
40 fn cx(&self) -> DbInterner<'db> {
41 self.infcx.interner
4742 }
4843
49 fn interner(&self) -> Interner {
50 Interner
51 }
44 fn try_fold_ty(&mut self, ty: Ty<'db>) -> Result<Ty<'db>, Self::Error> {
45 if !ty.has_type_flags(TypeFlags::HAS_ALIAS | TypeFlags::HAS_PARAM) {
46 return Ok(ty);
47 }
5248
53 fn try_fold_ty(
54 &mut self,
55 ty: Ty,
56 outer_binder: DebruijnIndex,
57 ) -> std::result::Result<Ty, Self::Error> {
58 match ty.kind(Interner) {
59 TyKind::AssociatedType(id, subst) => {
60 // I don't know exactly if and why this is needed, but it looks like `normalize_ty` likes
61 // this kind of associated types.
62 Ok(TyKind::Alias(chalk_ir::AliasTy::Projection(ProjectionTy {
63 associated_ty_id: *id,
64 substitution: subst.clone().try_fold_with(self, outer_binder)?,
65 }))
66 .intern(Interner))
67 }
68 TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
69 opaque_ty_id: id,
70 substitution: subst,
71 }))
72 | TyKind::OpaqueType(id, subst) => {
73 let impl_trait_id = self.db.lookup_intern_impl_trait_id((*id).into());
74 let subst = subst.clone().try_fold_with(self.as_dyn(), outer_binder)?;
75 match impl_trait_id {
76 crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
77 let infer = self.db.infer(func.into());
78 let filler = &mut Filler {
79 db: self.db,
80 trait_env: self.trait_env.clone(),
81 subst: &subst,
82 generics: Some(generics(self.db, func.into())),
83 };
84 filler.try_fold_ty(infer.type_of_rpit[idx].clone(), outer_binder)
85 }
86 crate::ImplTraitId::TypeAliasImplTrait(..) => {
87 not_supported!("type alias impl trait");
88 }
89 crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => {
90 not_supported!("async block impl trait");
91 }
92 }
49 match ty.kind() {
50 TyKind::Alias(..) => {
51 // First instantiate params.
52 let ty = ty.try_super_fold_with(self)?;
53
54 let mut ocx = ObligationCtxt::new(&self.infcx);
55 let ty = ocx
56 .structurally_normalize_ty(&ObligationCause::dummy(), self.trait_env.env, ty)
57 .map_err(|_| MirLowerError::NotSupported("can't normalize alias".to_owned()))?;
58 ty.try_super_fold_with(self)
9359 }
94 _ => ty.try_super_fold_with(self.as_dyn(), outer_binder),
60 TyKind::Param(param) => Ok(self
61 .subst
62 .as_slice()
63 .get(param.index as usize)
64 .and_then(|arg| arg.ty())
65 .ok_or_else(|| {
66 MirLowerError::GenericArgNotProvided(param.id.into(), self.subst)
67 })?),
68 _ => ty.try_super_fold_with(self),
9569 }
9670 }
9771
98 fn try_fold_free_placeholder_const(
99 &mut self,
100 _ty: chalk_ir::Ty<Interner>,
101 idx: chalk_ir::PlaceholderIndex,
102 _outer_binder: DebruijnIndex,
103 ) -> std::result::Result<chalk_ir::Const<Interner>, Self::Error> {
104 let it = from_placeholder_idx(self.db, idx).0;
105 let Some(idx) = self.generics.as_ref().and_then(|g| g.type_or_const_param_idx(it)) else {
106 not_supported!("missing idx in generics");
72 fn try_fold_const(&mut self, ct: Const<'db>) -> Result<Const<'db>, Self::Error> {
73 let ConstKind::Param(param) = ct.kind() else {
74 return ct.try_super_fold_with(self);
10775 };
108 Ok(self
109 .subst
110 .as_slice(Interner)
111 .get(idx)
112 .and_then(|it| it.constant(Interner))
113 .ok_or_else(|| MirLowerError::GenericArgNotProvided(it, self.subst.clone()))?
114 .clone())
76 self.subst
77 .as_slice()
78 .get(param.index as usize)
79 .and_then(|arg| arg.konst())
80 .ok_or_else(|| MirLowerError::GenericArgNotProvided(param.id.into(), self.subst))
11581 }
11682
117 fn try_fold_free_placeholder_ty(
118 &mut self,
119 idx: chalk_ir::PlaceholderIndex,
120 _outer_binder: DebruijnIndex,
121 ) -> std::result::Result<Ty, Self::Error> {
122 let it = from_placeholder_idx(self.db, idx).0;
123 let Some(idx) = self.generics.as_ref().and_then(|g| g.type_or_const_param_idx(it)) else {
124 not_supported!("missing idx in generics");
83 fn try_fold_region(&mut self, region: Region<'db>) -> Result<Region<'db>, Self::Error> {
84 let RegionKind::ReEarlyParam(param) = region.kind() else {
85 return Ok(region);
12586 };
126 Ok(self
127 .subst
128 .as_slice(Interner)
129 .get(idx)
130 .and_then(|it| it.ty(Interner))
131 .ok_or_else(|| MirLowerError::GenericArgNotProvided(it, self.subst.clone()))?
132 .clone())
133 }
134
135 fn try_fold_const(
136 &mut self,
137 constant: chalk_ir::Const<Interner>,
138 outer_binder: DebruijnIndex,
139 ) -> Result<chalk_ir::Const<Interner>, Self::Error> {
140 let next_ty = normalize(
141 self.db,
142 self.trait_env.clone(),
143 constant.data(Interner).ty.clone().try_fold_with(self, outer_binder)?,
144 );
145 ConstData { ty: next_ty, value: constant.data(Interner).value.clone() }
146 .intern(Interner)
147 .try_super_fold_with(self, outer_binder)
87 self.subst
88 .as_slice()
89 .get(param.index as usize)
90 .and_then(|arg| arg.region())
91 .ok_or_else(|| MirLowerError::GenericArgNotProvided(param.id.into(), self.subst))
14892 }
14993}
15094
151impl Filler<'_> {
152 fn fill_ty(&mut self, ty: &mut Ty) -> Result<(), MirLowerError> {
153 let tmp = mem::replace(ty, TyKind::Error.intern(Interner));
154 *ty = normalize(
155 self.db,
156 self.trait_env.clone(),
157 tmp.try_fold_with(self, DebruijnIndex::INNERMOST)?,
158 );
159 Ok(())
160 }
161
162 fn fill_const(&mut self, c: &mut Const) -> Result<(), MirLowerError> {
163 let tmp = mem::replace(c, unknown_const(c.data(Interner).ty.clone()));
164 *c = tmp.try_fold_with(self, DebruijnIndex::INNERMOST)?;
165 Ok(())
95impl<'db> Filler<'db> {
96 fn new(
97 db: &'db dyn HirDatabase,
98 env: Arc<TraitEnvironment<'db>>,
99 subst: GenericArgs<'db>,
100 ) -> Self {
101 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
102 let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
103 Self { infcx, trait_env: env, subst }
166104 }
167105
168 fn fill_subst(&mut self, ty: &mut Substitution) -> Result<(), MirLowerError> {
169 let tmp = mem::replace(ty, Substitution::empty(Interner));
170 *ty = tmp.try_fold_with(self, DebruijnIndex::INNERMOST)?;
171 Ok(())
106 fn fill<T: TypeFoldable<DbInterner<'db>> + Copy>(
107 &mut self,
108 t: &mut T,
109 ) -> Result<(), MirLowerError<'db>> {
110 // Can't deep normalized as that'll try to normalize consts and fail.
111 *t = t.try_fold_with(self)?;
112 if references_non_lt_error(t) {
113 Err(MirLowerError::NotSupported("monomorphization resulted in errors".to_owned()))
114 } else {
115 Ok(())
116 }
172117 }
173118
174 fn fill_operand(&mut self, op: &mut Operand) -> Result<(), MirLowerError> {
119 fn fill_operand(&mut self, op: &mut Operand<'db>) -> Result<(), MirLowerError<'db>> {
175120 match &mut op.kind {
176 OperandKind::Constant(c) => {
177 match &c.data(Interner).value {
178 chalk_ir::ConstValue::BoundVar(b) => {
179 let resolved = self
180 .subst
181 .as_slice(Interner)
182 .get(b.index)
183 .ok_or_else(|| {
184 MirLowerError::GenericArgNotProvided(
185 self.generics
186 .as_ref()
187 .and_then(|it| it.iter().nth(b.index))
188 .and_then(|(id, _)| match id {
189 hir_def::GenericParamId::ConstParamId(id) => {
190 Some(hir_def::TypeOrConstParamId::from(id))
191 }
192 hir_def::GenericParamId::TypeParamId(id) => {
193 Some(hir_def::TypeOrConstParamId::from(id))
194 }
195 _ => None,
196 })
197 .unwrap(),
198 self.subst.clone(),
199 )
200 })?
201 .assert_const_ref(Interner);
202 *c = resolved.clone();
203 }
204 chalk_ir::ConstValue::InferenceVar(_)
205 | chalk_ir::ConstValue::Placeholder(_) => {}
206 chalk_ir::ConstValue::Concrete(cc) => match &cc.interned {
207 crate::ConstScalar::UnevaluatedConst(const_id, subst) => {
208 let mut subst = subst.clone();
209 self.fill_subst(&mut subst)?;
210 *c = intern_const_scalar(
211 crate::ConstScalar::UnevaluatedConst(*const_id, subst),
212 c.data(Interner).ty.clone(),
213 );
214 }
215 crate::ConstScalar::Bytes(_, _) | crate::ConstScalar::Unknown => (),
216 },
217 }
218 self.fill_const(c)?;
121 OperandKind::Constant { konst, ty } => {
122 self.fill(konst)?;
123 self.fill(ty)?;
219124 }
220125 OperandKind::Copy(_) | OperandKind::Move(_) | OperandKind::Static(_) => (),
221126 }
222127 Ok(())
223128 }
224129
225 fn fill_body(&mut self, body: &mut MirBody) -> Result<(), MirLowerError> {
130 fn fill_body(&mut self, body: &mut MirBody<'db>) -> Result<(), MirLowerError<'db>> {
226131 for (_, l) in body.locals.iter_mut() {
227 self.fill_ty(&mut l.ty)?;
132 self.fill(&mut l.ty)?;
228133 }
229134 for (_, bb) in body.basic_blocks.iter_mut() {
230135 for statement in &mut bb.statements {
......@@ -237,20 +142,20 @@ impl Filler<'_> {
237142 match ak {
238143 super::AggregateKind::Array(ty)
239144 | super::AggregateKind::Tuple(ty)
240 | super::AggregateKind::Closure(ty) => self.fill_ty(ty)?,
241 super::AggregateKind::Adt(_, subst) => self.fill_subst(subst)?,
145 | super::AggregateKind::Closure(ty) => self.fill(ty)?,
146 super::AggregateKind::Adt(_, subst) => self.fill(subst)?,
242147 super::AggregateKind::Union(_, _) => (),
243148 }
244149 }
245150 Rvalue::ShallowInitBox(_, ty) | Rvalue::ShallowInitBoxWithAlloc(ty) => {
246 self.fill_ty(ty)?;
151 self.fill(ty)?;
247152 }
248153 Rvalue::Use(op) => {
249154 self.fill_operand(op)?;
250155 }
251156 Rvalue::Repeat(op, len) => {
252157 self.fill_operand(op)?;
253 self.fill_const(len)?;
158 self.fill(len)?;
254159 }
255160 Rvalue::Ref(_, _)
256161 | Rvalue::Len(_)
......@@ -304,11 +209,10 @@ impl Filler<'_> {
304209pub fn monomorphized_mir_body_query<'db>(
305210 db: &'db dyn HirDatabase,
306211 owner: DefWithBodyId,
307 subst: Substitution,
212 subst: GenericArgs<'db>,
308213 trait_env: Arc<crate::TraitEnvironment<'db>>,
309) -> Result<Arc<MirBody>, MirLowerError> {
310 let generics = owner.as_generic_def_id(db).map(|g_def| generics(db, g_def));
311 let filler = &mut Filler { db, subst: &subst, trait_env, generics };
214) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>> {
215 let mut filler = Filler::new(db, trait_env, subst);
312216 let body = db.mir_body(owner)?;
313217 let mut body = (*body).clone();
314218 filler.fill_body(&mut body)?;
......@@ -318,21 +222,19 @@ pub fn monomorphized_mir_body_query<'db>(
318222pub(crate) fn monomorphized_mir_body_cycle_result<'db>(
319223 _db: &'db dyn HirDatabase,
320224 _: DefWithBodyId,
321 _: Substitution,
225 _: GenericArgs<'db>,
322226 _: Arc<crate::TraitEnvironment<'db>>,
323) -> Result<Arc<MirBody>, MirLowerError> {
227) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>> {
324228 Err(MirLowerError::Loop)
325229}
326230
327231pub fn monomorphized_mir_body_for_closure_query<'db>(
328232 db: &'db dyn HirDatabase,
329233 closure: InternedClosureId,
330 subst: Substitution,
234 subst: GenericArgs<'db>,
331235 trait_env: Arc<crate::TraitEnvironment<'db>>,
332) -> Result<Arc<MirBody>, MirLowerError> {
333 let InternedClosure(owner, _) = db.lookup_intern_closure(closure);
334 let generics = owner.as_generic_def_id(db).map(|g_def| generics(db, g_def));
335 let filler = &mut Filler { db, subst: &subst, trait_env, generics };
236) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>> {
237 let mut filler = Filler::new(db, trait_env, subst);
336238 let body = db.mir_body_for_closure(closure)?;
337239 let mut body = (*body).clone();
338240 filler.fill_body(&mut body)?;
src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs+36-30
......@@ -11,8 +11,7 @@ use hir_expand::{Lookup, name::Name};
1111use la_arena::ArenaMap;
1212
1313use crate::{
14 ClosureId,
15 db::HirDatabase,
14 db::{HirDatabase, InternedClosureId},
1615 display::{ClosureStyle, DisplayTarget, HirDisplay},
1716 mir::{PlaceElem, ProjectionElem, StatementKind, TerminatorKind},
1817};
......@@ -37,8 +36,8 @@ macro_rules! wln {
3736 };
3837}
3938
40impl MirBody {
41 pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
39impl<'db> MirBody<'db> {
40 pub fn pretty_print(&self, db: &'db dyn HirDatabase, display_target: DisplayTarget) -> String {
4241 let hir_body = db.body(self.owner);
4342 let mut ctx = MirPrettyCtx::new(self, &hir_body, db, display_target);
4443 ctx.for_body(|this| match ctx.body.owner {
......@@ -81,7 +80,7 @@ impl MirBody {
8180
8281 // String with lines is rendered poorly in `dbg` macros, which I use very much, so this
8382 // function exists to solve that.
84 pub fn dbg(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> impl Debug {
83 pub fn dbg(&self, db: &'db dyn HirDatabase, display_target: DisplayTarget) -> impl Debug {
8584 struct StringDbg(String);
8685 impl Debug for StringDbg {
8786 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
......@@ -92,17 +91,17 @@ impl MirBody {
9291 }
9392}
9493
95struct MirPrettyCtx<'a> {
96 body: &'a MirBody,
94struct MirPrettyCtx<'a, 'db> {
95 body: &'a MirBody<'db>,
9796 hir_body: &'a Body,
98 db: &'a dyn HirDatabase,
97 db: &'db dyn HirDatabase,
9998 result: String,
10099 indent: String,
101 local_to_binding: ArenaMap<LocalId, BindingId>,
100 local_to_binding: ArenaMap<LocalId<'db>, BindingId>,
102101 display_target: DisplayTarget,
103102}
104103
105impl Write for MirPrettyCtx<'_> {
104impl Write for MirPrettyCtx<'_, '_> {
106105 fn write_str(&mut self, s: &str) -> std::fmt::Result {
107106 let mut it = s.split('\n'); // note: `.lines()` is wrong here
108107 self.write(it.next().unwrap_or_default());
......@@ -114,12 +113,12 @@ impl Write for MirPrettyCtx<'_> {
114113 }
115114}
116115
117enum LocalName {
118 Unknown(LocalId),
119 Binding(Name, LocalId),
116enum LocalName<'db> {
117 Unknown(LocalId<'db>),
118 Binding(Name, LocalId<'db>),
120119}
121120
122impl HirDisplay for LocalName {
121impl<'db> HirDisplay for LocalName<'db> {
123122 fn hir_fmt(
124123 &self,
125124 f: &mut crate::display::HirFormatter<'_>,
......@@ -133,8 +132,8 @@ impl HirDisplay for LocalName {
133132 }
134133}
135134
136impl<'a> MirPrettyCtx<'a> {
137 fn for_body(&mut self, name: impl FnOnce(&mut MirPrettyCtx<'_>)) {
135impl<'a, 'db> MirPrettyCtx<'a, 'db> {
136 fn for_body(&mut self, name: impl FnOnce(&mut MirPrettyCtx<'_, 'db>)) {
138137 name(self);
139138 self.with_block(|this| {
140139 this.locals();
......@@ -146,8 +145,8 @@ impl<'a> MirPrettyCtx<'a> {
146145 }
147146 }
148147
149 fn for_closure(&mut self, closure: ClosureId) {
150 let body = match self.db.mir_body_for_closure(closure.into()) {
148 fn for_closure(&mut self, closure: InternedClosureId) {
149 let body = match self.db.mir_body_for_closure(closure) {
151150 Ok(it) => it,
152151 Err(e) => {
153152 wln!(self, "// error in {closure:?}: {e:?}");
......@@ -168,7 +167,7 @@ impl<'a> MirPrettyCtx<'a> {
168167 self.indent = ctx.indent;
169168 }
170169
171 fn with_block(&mut self, f: impl FnOnce(&mut MirPrettyCtx<'_>)) {
170 fn with_block(&mut self, f: impl FnOnce(&mut MirPrettyCtx<'_, 'db>)) {
172171 self.indent += " ";
173172 wln!(self, "{{");
174173 f(self);
......@@ -180,9 +179,9 @@ impl<'a> MirPrettyCtx<'a> {
180179 }
181180
182181 fn new(
183 body: &'a MirBody,
182 body: &'a MirBody<'db>,
184183 hir_body: &'a Body,
185 db: &'a dyn HirDatabase,
184 db: &'db dyn HirDatabase,
186185 display_target: DisplayTarget,
187186 ) -> Self {
188187 let local_to_binding = body.local_to_binding_map();
......@@ -217,14 +216,14 @@ impl<'a> MirPrettyCtx<'a> {
217216 }
218217 }
219218
220 fn local_name(&self, local: LocalId) -> LocalName {
219 fn local_name(&self, local: LocalId<'db>) -> LocalName<'db> {
221220 match self.local_to_binding.get(local) {
222221 Some(b) => LocalName::Binding(self.hir_body[*b].name.clone(), local),
223222 None => LocalName::Unknown(local),
224223 }
225224 }
226225
227 fn basic_block_id(&self, basic_block_id: BasicBlockId) -> String {
226 fn basic_block_id(&self, basic_block_id: BasicBlockId<'db>) -> String {
228227 format!("'bb{}", u32::from(basic_block_id.into_raw()))
229228 }
230229
......@@ -312,8 +311,12 @@ impl<'a> MirPrettyCtx<'a> {
312311 }
313312 }
314313
315 fn place(&mut self, p: &Place) {
316 fn f(this: &mut MirPrettyCtx<'_>, local: LocalId, projections: &[PlaceElem]) {
314 fn place(&mut self, p: &Place<'db>) {
315 fn f<'db>(
316 this: &mut MirPrettyCtx<'_, 'db>,
317 local: LocalId<'db>,
318 projections: &[PlaceElem<'db>],
319 ) {
317320 let Some((last, head)) = projections.split_last() else {
318321 // no projection
319322 w!(this, "{}", this.local_name(local).display_test(this.db, this.display_target));
......@@ -373,19 +376,19 @@ impl<'a> MirPrettyCtx<'a> {
373376 f(self, p.local, p.projection.lookup(&self.body.projection_store));
374377 }
375378
376 fn operand(&mut self, r: &Operand) {
379 fn operand(&mut self, r: &Operand<'db>) {
377380 match &r.kind {
378381 OperandKind::Copy(p) | OperandKind::Move(p) => {
379382 // MIR at the time of writing doesn't have difference between move and copy, so we show them
380383 // equally. Feel free to change it.
381384 self.place(p);
382385 }
383 OperandKind::Constant(c) => w!(self, "Const({})", self.hir_display(c)),
386 OperandKind::Constant { konst, .. } => w!(self, "Const({})", self.hir_display(konst)),
384387 OperandKind::Static(s) => w!(self, "Static({:?})", s),
385388 }
386389 }
387390
388 fn rvalue(&mut self, r: &Rvalue) {
391 fn rvalue(&mut self, r: &Rvalue<'db>) {
389392 match r {
390393 Rvalue::Use(op) => self.operand(op),
391394 Rvalue::Ref(r, p) => {
......@@ -475,7 +478,7 @@ impl<'a> MirPrettyCtx<'a> {
475478 }
476479 }
477480
478 fn operand_list(&mut self, it: &[Operand]) {
481 fn operand_list(&mut self, it: &[Operand<'db>]) {
479482 let mut it = it.iter();
480483 if let Some(first) = it.next() {
481484 self.operand(first);
......@@ -486,7 +489,10 @@ impl<'a> MirPrettyCtx<'a> {
486489 }
487490 }
488491
489 fn hir_display<T: HirDisplay>(&self, ty: &'a T) -> impl Display + 'a {
492 fn hir_display<'b, T: HirDisplay>(&self, ty: &'b T) -> impl Display + use<'a, 'b, 'db, T>
493 where
494 'db: 'b,
495 {
490496 ty.display_test(self.db, self.display_target)
491497 .with_closure_style(ClosureStyle::ClosureWithSubst)
492498 }
src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs+3
......@@ -33,6 +33,9 @@ pub use region::*;
3333pub use solver::*;
3434pub use ty::*;
3535
36pub use crate::lower_nextsolver::ImplTraitIdx;
37pub use rustc_ast_ir::Mutability;
38
3639pub type Binder<'db, T> = rustc_type_ir::Binder<DbInterner<'db>, T>;
3740pub type EarlyBinder<'db, T> = rustc_type_ir::EarlyBinder<DbInterner<'db>, T>;
3841pub type Canonical<'db, T> = rustc_type_ir::Canonical<DbInterner<'db>, T>;
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs+44-59
......@@ -4,10 +4,11 @@ use std::hash::Hash;
44
55use hir_def::{ConstParamId, TypeOrConstParamId};
66use intern::{Interned, Symbol};
7use macros::{TypeFoldable, TypeVisitable};
78use rustc_ast_ir::{try_visit, visit::VisitorResult};
89use rustc_type_ir::{
9 BoundVar, FlagComputation, Flags, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
10 TypeVisitable, TypeVisitableExt, WithCachedTypeInfo,
10 BoundVar, DebruijnIndex, FlagComputation, Flags, TypeFoldable, TypeSuperFoldable,
11 TypeSuperVisitable, TypeVisitable, TypeVisitableExt, WithCachedTypeInfo,
1112 inherent::{IntoKind, ParamEnv as _, PlaceholderLike, SliceLike},
1213 relate::Relate,
1314};
......@@ -23,7 +24,7 @@ use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder,
2324pub type ConstKind<'db> = rustc_type_ir::ConstKind<DbInterner<'db>>;
2425pub type UnevaluatedConst<'db> = rustc_type_ir::UnevaluatedConst<DbInterner<'db>>;
2526
26#[salsa::interned(constructor = new_, debug)]
27#[salsa::interned(constructor = new_)]
2728pub struct Const<'db> {
2829 #[returns(ref)]
2930 kind_: InternedWrapperNoDebug<WithCachedTypeInfo<ConstKind<'db>>>,
......@@ -41,13 +42,12 @@ impl<'db> Const<'db> {
4142 }
4243
4344 pub fn inner(&self) -> &WithCachedTypeInfo<ConstKind<'db>> {
44 salsa::with_attached_database(|db| {
45 crate::with_attached_db(|db| {
4546 let inner = &self.kind_(db).0;
4647 // SAFETY: The caller already has access to a `Const<'db>`, so borrowchecking will
4748 // make sure that our returned value is valid for the lifetime `'db`.
4849 unsafe { std::mem::transmute(inner) }
4950 })
50 .unwrap()
5151 }
5252
5353 pub fn error(interner: DbInterner<'db>) -> Self {
......@@ -62,6 +62,25 @@ impl<'db> Const<'db> {
6262 Const::new(interner, ConstKind::Placeholder(placeholder))
6363 }
6464
65 pub fn new_bound(interner: DbInterner<'db>, index: DebruijnIndex, bound: BoundConst) -> Self {
66 Const::new(interner, ConstKind::Bound(index, bound))
67 }
68
69 pub fn new_valtree(
70 interner: DbInterner<'db>,
71 ty: Ty<'db>,
72 memory: Box<[u8]>,
73 memory_map: MemoryMap<'db>,
74 ) -> Self {
75 Const::new(
76 interner,
77 ConstKind::Value(ValueConst {
78 ty,
79 value: Valtree::new(ConstBytes { memory, memory_map }),
80 }),
81 )
82 }
83
6584 pub fn is_ct_infer(&self) -> bool {
6685 matches!(&self.inner().internee, ConstKind::Infer(_))
6786 }
......@@ -78,6 +97,12 @@ impl<'db> Const<'db> {
7897 }
7998}
8099
100impl<'db> std::fmt::Debug for Const<'db> {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 self.inner().internee.fmt(f)
103 }
104}
105
81106impl<'db> std::fmt::Debug for InternedWrapperNoDebug<WithCachedTypeInfo<ConstKind<'db>>> {
82107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83108 self.0.internee.fmt(f)
......@@ -136,10 +161,13 @@ impl ParamConst {
136161/// A type-level constant value.
137162///
138163/// Represents a typed, fully evaluated constant.
139#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
164#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, TypeFoldable, TypeVisitable)]
140165pub struct ValueConst<'db> {
141 pub(crate) ty: Ty<'db>,
142 pub(crate) value: Valtree<'db>,
166 pub ty: Ty<'db>,
167 // FIXME: Should we ignore this for TypeVisitable, TypeFoldable?
168 #[type_visitable(ignore)]
169 #[type_foldable(identity)]
170 pub value: Valtree<'db>,
143171}
144172
145173impl<'db> ValueConst<'db> {
......@@ -159,33 +187,15 @@ impl<'db> rustc_type_ir::inherent::ValueConst<DbInterner<'db>> for ValueConst<'d
159187 }
160188}
161189
162impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for ValueConst<'db> {
163 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
164 &self,
165 visitor: &mut V,
166 ) -> V::Result {
167 self.ty.visit_with(visitor)
168 }
169}
170
171impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for ValueConst<'db> {
172 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
173 ValueConst { ty: self.ty.fold_with(folder), value: self.value }
174 }
175 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
176 self,
177 folder: &mut F,
178 ) -> Result<Self, F::Error> {
179 Ok(ValueConst { ty: self.ty.try_fold_with(folder)?, value: self.value })
180 }
181}
182
183190#[derive(Debug, Clone, PartialEq, Eq)]
184pub struct ConstBytes<'db>(pub Box<[u8]>, pub MemoryMap<'db>);
191pub struct ConstBytes<'db> {
192 pub memory: Box<[u8]>,
193 pub memory_map: MemoryMap<'db>,
194}
185195
186196impl Hash for ConstBytes<'_> {
187197 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
188 self.0.hash(state)
198 self.memory.hash(state)
189199 }
190200}
191201
......@@ -197,25 +207,23 @@ pub struct Valtree<'db> {
197207
198208impl<'db> Valtree<'db> {
199209 pub fn new(bytes: ConstBytes<'db>) -> Self {
200 salsa::with_attached_database(|db| unsafe {
210 crate::with_attached_db(|db| unsafe {
201211 // SAFETY: ¯\_(ツ)_/¯
202212 std::mem::transmute(Valtree::new_(db, bytes))
203213 })
204 .unwrap()
205214 }
206215
207216 pub fn inner(&self) -> &ConstBytes<'db> {
208 salsa::with_attached_database(|db| {
217 crate::with_attached_db(|db| {
209218 let inner = self.bytes_(db);
210219 // SAFETY: The caller already has access to a `Valtree<'db>`, so borrowchecking will
211220 // make sure that our returned value is valid for the lifetime `'db`.
212221 unsafe { std::mem::transmute(inner) }
213222 })
214 .unwrap()
215223 }
216224}
217225
218#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
226#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable)]
219227pub struct ExprConst;
220228
221229impl rustc_type_ir::inherent::ParamLike for ParamConst {
......@@ -415,29 +423,6 @@ impl<'db> PlaceholderLike<DbInterner<'db>> for PlaceholderConst {
415423 }
416424}
417425
418impl<'db> TypeVisitable<DbInterner<'db>> for ExprConst {
419 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
420 &self,
421 visitor: &mut V,
422 ) -> V::Result {
423 // Ensure we get back to this when we fill in the fields
424 let ExprConst = &self;
425 V::Result::output()
426 }
427}
428
429impl<'db> TypeFoldable<DbInterner<'db>> for ExprConst {
430 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
431 self,
432 folder: &mut F,
433 ) -> Result<Self, F::Error> {
434 Ok(ExprConst)
435 }
436 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
437 ExprConst
438 }
439}
440
441426impl<'db> Relate<DbInterner<'db>> for ExprConst {
442427 fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
443428 relation: &mut R,
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs+32-2
......@@ -1,8 +1,8 @@
11//! Definition of `SolverDefId`
22
33use hir_def::{
4 AdtId, CallableDefId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId,
5 StaticId, StructId, TraitId, TypeAliasId, UnionId,
4 AdtId, CallableDefId, ConstId, EnumId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId,
5 ImplId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
66};
77use rustc_type_ir::inherent;
88use stdx::impl_from;
......@@ -119,6 +119,16 @@ impl From<GenericDefId> for SolverDefId {
119119 }
120120}
121121
122impl From<GeneralConstId> for SolverDefId {
123 #[inline]
124 fn from(value: GeneralConstId) -> Self {
125 match value {
126 GeneralConstId::ConstId(const_id) => SolverDefId::ConstId(const_id),
127 GeneralConstId::StaticId(static_id) => SolverDefId::StaticId(static_id),
128 }
129 }
130}
131
122132impl TryFrom<SolverDefId> for GenericDefId {
123133 type Error = SolverDefId;
124134
......@@ -139,6 +149,26 @@ impl TryFrom<SolverDefId> for GenericDefId {
139149 }
140150}
141151
152impl SolverDefId {
153 #[inline]
154 #[track_caller]
155 pub fn expect_opaque_ty(self) -> InternedOpaqueTyId {
156 match self {
157 SolverDefId::InternedOpaqueTyId(it) => it,
158 _ => panic!("expected opaque type, found {self:?}"),
159 }
160 }
161
162 #[inline]
163 #[track_caller]
164 pub fn expect_type_alias(self) -> TypeAliasId {
165 match self {
166 SolverDefId::TypeAliasId(it) => it,
167 _ => panic!("expected type alias, found {self:?}"),
168 }
169 }
170}
171
142172impl<'db> inherent::DefId<DbInterner<'db>> for SolverDefId {
143173 fn as_local(self) -> Option<SolverDefId> {
144174 Some(self)
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fold.rs+23
......@@ -129,3 +129,26 @@ where
129129 if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
130130 }
131131}
132
133pub fn fold_tys<'db, T: TypeFoldable<DbInterner<'db>>>(
134 interner: DbInterner<'db>,
135 t: T,
136 callback: impl FnMut(Ty<'db>) -> Ty<'db>,
137) -> T {
138 struct Folder<'db, F> {
139 interner: DbInterner<'db>,
140 callback: F,
141 }
142 impl<'db, F: FnMut(Ty<'db>) -> Ty<'db>> TypeFolder<DbInterner<'db>> for Folder<'db, F> {
143 fn cx(&self) -> DbInterner<'db> {
144 self.interner
145 }
146
147 fn fold_ty(&mut self, t: Ty<'db>) -> Ty<'db> {
148 let t = t.super_fold_with(self);
149 (self.callback)(t)
150 }
151 }
152
153 t.fold_with(&mut Folder { interner, callback })
154}
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs+92-66
......@@ -1,7 +1,9 @@
11//! Things related to generic args in the next-trait-solver.
22
3use hir_def::GenericParamId;
3use hir_def::{GenericDefId, GenericParamId};
44use intern::{Interned, Symbol};
5use macros::{TypeFoldable, TypeVisitable};
6use rustc_type_ir::inherent::Const as _;
57use rustc_type_ir::{
68 ClosureArgs, CollectAndApply, ConstVid, CoroutineArgs, CoroutineClosureArgs, FnSig, FnSigTys,
79 GenericArgKind, IntTy, Interner, TermKind, TyKind, TyVid, TypeFoldable, TypeVisitable,
......@@ -22,7 +24,7 @@ use super::{
2224 interned_vec_db,
2325};
2426
25#[derive(Copy, Clone, PartialEq, Eq, Hash)]
27#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
2628pub enum GenericArg<'db> {
2729 Ty(Ty<'db>),
2830 Lifetime(Region<'db>),
......@@ -54,12 +56,27 @@ impl<'db> GenericArg<'db> {
5456 }
5557 }
5658
59 pub fn konst(self) -> Option<Const<'db>> {
60 match self.kind() {
61 GenericArgKind::Const(konst) => Some(konst),
62 _ => None,
63 }
64 }
65
5766 pub fn region(self) -> Option<Region<'db>> {
5867 match self.kind() {
5968 GenericArgKind::Lifetime(r) => Some(r),
6069 _ => None,
6170 }
6271 }
72
73 pub fn error_from_id(interner: DbInterner<'db>, id: GenericParamId) -> GenericArg<'db> {
74 match id {
75 GenericParamId::TypeParamId(_) => Ty::new_error(interner, ErrorGuaranteed).into(),
76 GenericParamId::ConstParamId(_) => Const::error(interner).into(),
77 GenericParamId::LifetimeParamId(_) => Region::error(interner).into(),
78 }
79 }
6380}
6481
6582impl<'db> From<Term<'db>> for GenericArg<'db> {
......@@ -71,7 +88,7 @@ impl<'db> From<Term<'db>> for GenericArg<'db> {
7188 }
7289}
7390
74#[derive(Copy, Clone, PartialEq, Eq, Hash)]
91#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
7592pub enum Term<'db> {
7693 Ty(Ty<'db>),
7794 Const(Const<'db>),
......@@ -129,39 +146,6 @@ impl<'db> IntoKind for GenericArg<'db> {
129146 }
130147}
131148
132impl<'db> TypeVisitable<DbInterner<'db>> for GenericArg<'db> {
133 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
134 &self,
135 visitor: &mut V,
136 ) -> V::Result {
137 match self {
138 GenericArg::Lifetime(lt) => lt.visit_with(visitor),
139 GenericArg::Ty(ty) => ty.visit_with(visitor),
140 GenericArg::Const(ct) => ct.visit_with(visitor),
141 }
142 }
143}
144
145impl<'db> TypeFoldable<DbInterner<'db>> for GenericArg<'db> {
146 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
147 self,
148 folder: &mut F,
149 ) -> Result<Self, F::Error> {
150 match self.kind() {
151 GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into),
152 GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into),
153 GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
154 }
155 }
156 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
157 match self.kind() {
158 GenericArgKind::Lifetime(lt) => lt.fold_with(folder).into(),
159 GenericArgKind::Type(ty) => ty.fold_with(folder).into(),
160 GenericArgKind::Const(ct) => ct.fold_with(folder).into(),
161 }
162 }
163}
164
165149impl<'db> Relate<DbInterner<'db>> for GenericArg<'db> {
166150 fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
167151 relation: &mut R,
......@@ -216,6 +200,66 @@ impl<'db> GenericArgs<'db> {
216200 interner.mk_args(&args)
217201 }
218202
203 /// Creates an all-error `GenericArgs`.
204 pub fn error_for_item(interner: DbInterner<'db>, def_id: SolverDefId) -> GenericArgs<'db> {
205 GenericArgs::for_item(interner, def_id, |_, _, id, _| {
206 GenericArg::error_from_id(interner, id)
207 })
208 }
209
210 /// Like `for_item`, but prefers the default of a parameter if it has any.
211 pub fn for_item_with_defaults<F>(
212 interner: DbInterner<'db>,
213 def_id: GenericDefId,
214 mut fallback: F,
215 ) -> GenericArgs<'db>
216 where
217 F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
218 {
219 let defaults = interner.db.generic_defaults_ns(def_id);
220 Self::for_item(interner, def_id.into(), |name, idx, id, prev| {
221 match defaults.get(idx as usize) {
222 Some(default) => default.instantiate(interner, prev),
223 None => fallback(name, idx, id, prev),
224 }
225 })
226 }
227
228 /// Like `for_item()`, but calls first uses the args from `first`.
229 pub fn fill_rest<F>(
230 interner: DbInterner<'db>,
231 def_id: SolverDefId,
232 first: impl IntoIterator<Item = GenericArg<'db>>,
233 mut fallback: F,
234 ) -> GenericArgs<'db>
235 where
236 F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
237 {
238 let mut iter = first.into_iter();
239 Self::for_item(interner, def_id, |name, idx, id, prev| {
240 iter.next().unwrap_or_else(|| fallback(name, idx, id, prev))
241 })
242 }
243
244 /// Appends default param values to `first` if needed. Params without default will call `fallback()`.
245 pub fn fill_with_defaults<F>(
246 interner: DbInterner<'db>,
247 def_id: GenericDefId,
248 first: impl IntoIterator<Item = GenericArg<'db>>,
249 mut fallback: F,
250 ) -> GenericArgs<'db>
251 where
252 F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
253 {
254 let defaults = interner.db.generic_defaults_ns(def_id);
255 Self::fill_rest(interner, def_id.into(), first, |name, idx, id, prev| {
256 defaults
257 .get(idx as usize)
258 .map(|default| default.instantiate(interner, prev))
259 .unwrap_or_else(|| fallback(name, idx, id, prev))
260 })
261 }
262
219263 fn fill_item<F>(
220264 args: &mut SmallVec<[GenericArg<'db>; 8]>,
221265 interner: DbInterner<'_>,
......@@ -271,6 +315,18 @@ impl<'db> GenericArgs<'db> {
271315 }
272316 }
273317 }
318
319 pub fn types(self) -> impl Iterator<Item = Ty<'db>> {
320 self.iter().filter_map(|it| it.as_type())
321 }
322
323 pub fn consts(self) -> impl Iterator<Item = Const<'db>> {
324 self.iter().filter_map(|it| it.as_const())
325 }
326
327 pub fn regions(self) -> impl Iterator<Item = Region<'db>> {
328 self.iter().filter_map(|it| it.as_region())
329 }
274330}
275331
276332impl<'db> rustc_type_ir::relate::Relate<DbInterner<'db>> for GenericArgs<'db> {
......@@ -487,36 +543,6 @@ impl<'db> From<Const<'db>> for Term<'db> {
487543 }
488544}
489545
490impl<'db> TypeVisitable<DbInterner<'db>> for Term<'db> {
491 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
492 &self,
493 visitor: &mut V,
494 ) -> V::Result {
495 match self {
496 Term::Ty(ty) => ty.visit_with(visitor),
497 Term::Const(ct) => ct.visit_with(visitor),
498 }
499 }
500}
501
502impl<'db> TypeFoldable<DbInterner<'db>> for Term<'db> {
503 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
504 self,
505 folder: &mut F,
506 ) -> Result<Self, F::Error> {
507 match self.kind() {
508 TermKind::Ty(ty) => ty.try_fold_with(folder).map(Into::into),
509 TermKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
510 }
511 }
512 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
513 match self.kind() {
514 TermKind::Ty(ty) => ty.fold_with(folder).into(),
515 TermKind::Const(ct) => ct.fold_with(folder).into(),
516 }
517 }
518}
519
520546impl<'db> Relate<DbInterner<'db>> for Term<'db> {
521547 fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
522548 relation: &mut R,
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs+114-2
......@@ -10,6 +10,7 @@ pub use at::DefineOpaqueTypes;
1010use ena::undo_log::UndoLogs;
1111use ena::unify as ut;
1212use hir_def::GenericParamId;
13use hir_def::lang_item::LangItem;
1314use intern::Symbol;
1415use opaque_types::{OpaqueHiddenType, OpaqueTypeStorage};
1516use region_constraints::{
......@@ -18,6 +19,7 @@ use region_constraints::{
1819pub use relate::StructurallyRelateAliases;
1920pub use relate::combine::PredicateEmittingRelation;
2021use rustc_hash::{FxHashMap, FxHashSet};
22use rustc_next_trait_solver::solve::SolverDelegateEvalExt;
2123use rustc_pattern_analysis::Captures;
2224use rustc_type_ir::error::{ExpectedFound, TypeError};
2325use rustc_type_ir::inherent::{
......@@ -38,7 +40,10 @@ use unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
3840
3941use crate::next_solver::fold::BoundVarReplacerDelegate;
4042use crate::next_solver::infer::opaque_types::table::OpaqueTypeStorageEntries;
41use crate::next_solver::{BoundConst, BoundRegion, BoundTy, BoundVarKind};
43use crate::next_solver::infer::select::EvaluationResult;
44use crate::next_solver::infer::traits::PredicateObligation;
45use crate::next_solver::obligation_ctxt::ObligationCtxt;
46use crate::next_solver::{BoundConst, BoundRegion, BoundTy, BoundVarKind, Goal, SolverContext};
4247
4348use super::generics::GenericParamDef;
4449use super::{
......@@ -62,7 +67,7 @@ pub(crate) mod traits;
6267mod type_variable;
6368mod unify_key;
6469
65/// `InferOk<'tcx, ()>` is used a lot. It may seem like a useless wrapper
70/// `InferOk<'db, ()>` is used a lot. It may seem like a useless wrapper
6671/// around `PredicateObligations`, but it has one important property:
6772/// because `InferOk` is marked with `#[must_use]`, if you have a method
6873/// `InferCtxt::f` that returns `InferResult<()>` and you call it with
......@@ -395,6 +400,102 @@ impl<'db> InferCtxt<'db> {
395400 self.typing_mode
396401 }
397402
403 /// See the comment on [OpaqueTypesJank](crate::solve::OpaqueTypesJank)
404 /// for more details.
405 pub fn predicate_may_hold_opaque_types_jank(
406 &self,
407 obligation: &PredicateObligation<'db>,
408 ) -> bool {
409 <&SolverContext<'db>>::from(self).root_goal_may_hold_opaque_types_jank(Goal::new(
410 self.interner,
411 obligation.param_env,
412 obligation.predicate,
413 ))
414 }
415
416 /// Evaluates whether the predicate can be satisfied in the given
417 /// `ParamEnv`, and returns `false` if not certain. However, this is
418 /// not entirely accurate if inference variables are involved.
419 ///
420 /// This version may conservatively fail when outlives obligations
421 /// are required. Therefore, this version should only be used for
422 /// optimizations or diagnostics and be treated as if it can always
423 /// return `false`.
424 ///
425 /// # Example
426 ///
427 /// ```
428 /// # #![allow(dead_code)]
429 /// trait Trait {}
430 ///
431 /// fn check<T: Trait>() {}
432 ///
433 /// fn foo<T: 'static>()
434 /// where
435 /// &'static T: Trait,
436 /// {
437 /// // Evaluating `&'?0 T: Trait` adds a `'?0: 'static` outlives obligation,
438 /// // which means that `predicate_must_hold_considering_regions` will return
439 /// // `false`.
440 /// check::<&'_ T>();
441 /// }
442 /// ```
443 fn predicate_must_hold_considering_regions(
444 &self,
445 obligation: &PredicateObligation<'db>,
446 ) -> bool {
447 self.evaluate_obligation(obligation).must_apply_considering_regions()
448 }
449
450 /// Evaluates whether the predicate can be satisfied in the given
451 /// `ParamEnv`, and returns `false` if not certain. However, this is
452 /// not entirely accurate if inference variables are involved.
453 ///
454 /// This version ignores all outlives constraints.
455 fn predicate_must_hold_modulo_regions(&self, obligation: &PredicateObligation<'db>) -> bool {
456 self.evaluate_obligation(obligation).must_apply_modulo_regions()
457 }
458
459 /// Evaluate a given predicate, capturing overflow and propagating it back.
460 fn evaluate_obligation(&self, obligation: &PredicateObligation<'db>) -> EvaluationResult {
461 let param_env = obligation.param_env;
462
463 self.probe(|snapshot| {
464 let mut ocx = ObligationCtxt::new(self);
465 ocx.register_obligation(obligation.clone());
466 let mut result = EvaluationResult::EvaluatedToOk;
467 for error in ocx.evaluate_obligations_error_on_ambiguity() {
468 if error.is_true_error() {
469 return EvaluationResult::EvaluatedToErr;
470 } else {
471 result = result.max(EvaluationResult::EvaluatedToAmbig);
472 }
473 }
474 if self.opaque_types_added_in_snapshot(snapshot) {
475 result = result.max(EvaluationResult::EvaluatedToOkModuloOpaqueTypes);
476 } else if self.region_constraints_added_in_snapshot(snapshot) {
477 result = result.max(EvaluationResult::EvaluatedToOkModuloRegions);
478 }
479 result
480 })
481 }
482
483 pub fn type_is_copy_modulo_regions(&self, param_env: ParamEnv<'db>, ty: Ty<'db>) -> bool {
484 let ty = self.resolve_vars_if_possible(ty);
485
486 let Some(copy_def_id) =
487 LangItem::Copy.resolve_trait(self.interner.db, self.interner.krate.unwrap())
488 else {
489 return false;
490 };
491
492 // This can get called from typeck (by euv), and `moves_by_default`
493 // rightly refuses to work with inference variables, but
494 // moves_by_default has a cache, which we want to use in other
495 // cases.
496 traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, copy_def_id)
497 }
498
398499 pub fn unresolved_variables(&self) -> Vec<Ty<'db>> {
399500 let mut inner = self.inner.borrow_mut();
400501 let mut vars: Vec<Ty<'db>> = inner
......@@ -682,6 +783,17 @@ impl<'db> InferCtxt<'db> {
682783 })
683784 }
684785
786 /// Like `fresh_args_for_item()`, but first uses the args from `first`.
787 pub fn fill_rest_fresh_args(
788 &self,
789 def_id: SolverDefId,
790 first: impl IntoIterator<Item = GenericArg<'db>>,
791 ) -> GenericArgs<'db> {
792 GenericArgs::fill_rest(self.interner, def_id, first, |name, index, kind, _| {
793 self.var_for_def(kind, name)
794 })
795 }
796
685797 /// Returns `true` if errors have been reported since this infcx was
686798 /// created. This is sometimes used as a heuristic to skip
687799 /// reporting errors that often occur as a result of earlier
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/resolve.rs+49-3
......@@ -2,11 +2,12 @@
22
33use rustc_type_ir::{
44 ConstKind, FallibleTypeFolder, InferConst, InferTy, RegionKind, TyKind, TypeFoldable,
5 TypeFolder, TypeSuperFoldable, TypeVisitableExt, data_structures::DelayedMap,
6 inherent::IntoKind,
5 TypeFolder, TypeSuperFoldable, TypeVisitableExt,
6 data_structures::DelayedMap,
7 inherent::{Const as _, IntoKind, Ty as _},
78};
89
9use crate::next_solver::{Const, DbInterner, Region, Ty};
10use crate::next_solver::{Const, DbInterner, ErrorGuaranteed, Region, Ty};
1011
1112use super::{FixupError, FixupResult, InferCtxt};
1213
......@@ -60,3 +61,48 @@ impl<'a, 'db> TypeFolder<DbInterner<'db>> for OpportunisticVarResolver<'a, 'db>
6061 }
6162 }
6263}
64
65pub struct ReplaceInferWithError<'db> {
66 interner: DbInterner<'db>,
67}
68
69impl<'db> ReplaceInferWithError<'db> {
70 #[inline]
71 pub fn new(interner: DbInterner<'db>) -> Self {
72 Self { interner }
73 }
74}
75
76impl<'db> TypeFolder<DbInterner<'db>> for ReplaceInferWithError<'db> {
77 fn cx(&self) -> DbInterner<'db> {
78 self.interner
79 }
80
81 fn fold_ty(&mut self, t: Ty<'db>) -> Ty<'db> {
82 if !t.has_infer() {
83 return t;
84 }
85
86 if t.is_infer() {
87 Ty::new_error(self.interner, ErrorGuaranteed)
88 } else {
89 t.super_fold_with(self)
90 }
91 }
92
93 fn fold_const(&mut self, c: Const<'db>) -> Const<'db> {
94 if !c.has_infer() {
95 return c;
96 }
97
98 if c.is_ct_infer() {
99 Const::new_error(self.interner, ErrorGuaranteed)
100 } else {
101 c.super_fold_with(self)
102 }
103 }
104
105 fn fold_region(&mut self, r: Region<'db>) -> Region<'db> {
106 if r.is_var() { Region::error(self.interner) } else { r }
107 }
108}
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/select.rs+83-2
......@@ -1,6 +1,7 @@
11use std::ops::ControlFlow;
22
33use hir_def::{ImplId, TraitId};
4use macros::{TypeFoldable, TypeVisitable};
45use rustc_type_ir::{
56 Interner,
67 solve::{BuiltinImplSource, CandidateSource, Certainty, inspect::ProbeKind},
......@@ -12,6 +13,7 @@ use crate::{
1213 Const, ErrorGuaranteed, GenericArgs, Goal, TraitRef, Ty, TypeError,
1314 infer::{
1415 InferCtxt,
16 select::EvaluationResult::*,
1517 traits::{Obligation, ObligationCause, PredicateObligation, TraitObligation},
1618 },
1719 inspect::{InspectCandidate, InspectGoal, ProofTreeVisitor},
......@@ -47,6 +49,83 @@ pub enum NotConstEvaluatable {
4749 MentionsParam,
4850}
4951
52/// The result of trait evaluation. The order is important
53/// here as the evaluation of a list is the maximum of the
54/// evaluations.
55///
56/// The evaluation results are ordered:
57/// - `EvaluatedToOk` implies `EvaluatedToOkModuloRegions`
58/// implies `EvaluatedToAmbig` implies `EvaluatedToAmbigStackDependent`
59/// - the "union" of evaluation results is equal to their maximum -
60/// all the "potential success" candidates can potentially succeed,
61/// so they are noops when unioned with a definite error, and within
62/// the categories it's easy to see that the unions are correct.
63#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
64pub enum EvaluationResult {
65 /// Evaluation successful.
66 EvaluatedToOk,
67 /// Evaluation successful, but there were unevaluated region obligations.
68 EvaluatedToOkModuloRegions,
69 /// Evaluation successful, but need to rerun because opaque types got
70 /// hidden types assigned without it being known whether the opaque types
71 /// are within their defining scope
72 EvaluatedToOkModuloOpaqueTypes,
73 /// Evaluation is known to be ambiguous -- it *might* hold for some
74 /// assignment of inference variables, but it might not.
75 ///
76 /// While this has the same meaning as `EvaluatedToAmbigStackDependent` -- we can't
77 /// know whether this obligation holds or not -- it is the result we
78 /// would get with an empty stack, and therefore is cacheable.
79 EvaluatedToAmbig,
80 /// Evaluation failed because of recursion involving inference
81 /// variables. We are somewhat imprecise there, so we don't actually
82 /// know the real result.
83 ///
84 /// This can't be trivially cached because the result depends on the
85 /// stack results.
86 EvaluatedToAmbigStackDependent,
87 /// Evaluation failed.
88 EvaluatedToErr,
89}
90
91impl EvaluationResult {
92 /// Returns `true` if this evaluation result is known to apply, even
93 /// considering outlives constraints.
94 pub fn must_apply_considering_regions(self) -> bool {
95 self == EvaluatedToOk
96 }
97
98 /// Returns `true` if this evaluation result is known to apply, ignoring
99 /// outlives constraints.
100 pub fn must_apply_modulo_regions(self) -> bool {
101 self <= EvaluatedToOkModuloRegions
102 }
103
104 pub fn may_apply(self) -> bool {
105 match self {
106 EvaluatedToOkModuloOpaqueTypes
107 | EvaluatedToOk
108 | EvaluatedToOkModuloRegions
109 | EvaluatedToAmbig
110 | EvaluatedToAmbigStackDependent => true,
111
112 EvaluatedToErr => false,
113 }
114 }
115
116 pub fn is_stack_dependent(self) -> bool {
117 match self {
118 EvaluatedToAmbigStackDependent => true,
119
120 EvaluatedToOkModuloOpaqueTypes
121 | EvaluatedToOk
122 | EvaluatedToOkModuloRegions
123 | EvaluatedToAmbig
124 | EvaluatedToErr => false,
125 }
126 }
127}
128
50129/// Indicates that trait evaluation caused overflow and in which pass.
51130#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
52131pub enum OverflowError {
......@@ -99,7 +178,7 @@ pub type SelectionResult<'db, T> = Result<Option<T>, SelectionError<'db>>;
99178/// ### The type parameter `N`
100179///
101180/// See explanation on `ImplSourceUserDefinedData`.
102#[derive(Debug, Clone, PartialEq, Eq, Hash)]
181#[derive(Debug, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
103182pub enum ImplSource<'db, N> {
104183 /// ImplSource identifying a particular impl.
105184 UserDefined(ImplSourceUserDefinedData<'db, N>),
......@@ -164,8 +243,10 @@ impl<'db, N> ImplSource<'db, N> {
164243/// is `Obligation`, as one might expect. During codegen, however, this
165244/// is `()`, because codegen only requires a shallow resolution of an
166245/// impl, and nested obligations are satisfied later.
167#[derive(Debug, Clone, PartialEq, Eq, Hash)]
246#[derive(Debug, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
168247pub struct ImplSourceUserDefinedData<'db, N> {
248 #[type_visitable(ignore)]
249 #[type_foldable(identity)]
169250 pub impl_def_id: ImplId,
170251 pub args: GenericArgs<'db>,
171252 pub nested: Vec<N>,
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/snapshot/mod.rs+13
......@@ -109,4 +109,17 @@ impl<'db> InferCtxt<'db> {
109109 self.rollback_to(snapshot);
110110 r
111111 }
112
113 /// Scan the constraints produced since `snapshot` and check whether
114 /// we added any region constraints.
115 pub fn region_constraints_added_in_snapshot(&self, snapshot: &CombinedSnapshot) -> bool {
116 self.inner
117 .borrow_mut()
118 .unwrap_region_constraints()
119 .region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
120 }
121
122 pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot) -> bool {
123 self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
124 }
112125}
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs+39-35
......@@ -7,16 +7,19 @@ use std::{
77 hash::{Hash, Hasher},
88};
99
10use hir_def::TraitId;
11use macros::{TypeFoldable, TypeVisitable};
1012use rustc_type_ir::elaborate::Elaboratable;
1113use rustc_type_ir::{
1214 PredicatePolarity, Upcast,
1315 solve::{Certainty, NoSolution},
1416};
1517use rustc_type_ir::{TypeFoldable, TypeVisitable};
18use tracing::debug;
1619
1720use crate::next_solver::{
1821 Binder, Clause, DbInterner, Goal, ParamEnv, PolyTraitPredicate, Predicate, SolverDefId, Span,
19 TraitPredicate, Ty,
22 TraitPredicate, TraitRef, Ty,
2023};
2124
2225use super::InferCtxt;
......@@ -63,8 +66,10 @@ impl ObligationCause {
6366/// either identifying an `impl` (e.g., `impl Eq for i32`) that
6467/// satisfies the obligation, or else finding a bound that is in
6568/// scope. The eventual result is usually a `Selection` (defined below).
66#[derive(Clone, Debug)]
69#[derive(Clone, Debug, TypeVisitable, TypeFoldable)]
6770pub struct Obligation<'db, T> {
71 #[type_foldable(identity)]
72 #[type_visitable(ignore)]
6873 /// The reason we have to prove this thing.
6974 pub cause: ObligationCause,
7075
......@@ -115,39 +120,6 @@ impl<'db> Elaboratable<DbInterner<'db>> for PredicateObligation<'db> {
115120 }
116121}
117122
118impl<'db, T: TypeVisitable<DbInterner<'db>>> TypeVisitable<DbInterner<'db>> for Obligation<'db, T> {
119 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
120 &self,
121 visitor: &mut V,
122 ) -> V::Result {
123 rustc_ast_ir::try_visit!(self.param_env.visit_with(visitor));
124 self.predicate.visit_with(visitor)
125 }
126}
127
128impl<'db, T: TypeFoldable<DbInterner<'db>>> TypeFoldable<DbInterner<'db>> for Obligation<'db, T> {
129 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
130 self,
131 folder: &mut F,
132 ) -> Result<Self, F::Error> {
133 Ok(Obligation {
134 cause: self.cause.clone(),
135 param_env: self.param_env.try_fold_with(folder)?,
136 predicate: self.predicate.try_fold_with(folder)?,
137 recursion_depth: self.recursion_depth,
138 })
139 }
140
141 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
142 Obligation {
143 cause: self.cause.clone(),
144 param_env: self.param_env.fold_with(folder),
145 predicate: self.predicate.fold_with(folder),
146 recursion_depth: self.recursion_depth,
147 }
148 }
149}
150
151123impl<'db, T: Copy> Obligation<'db, T> {
152124 pub fn as_goal(&self) -> Goal<'db, T> {
153125 Goal { param_env: self.param_env, predicate: self.predicate }
......@@ -237,3 +209,35 @@ impl<'db, O> Obligation<'db, O> {
237209 Obligation::with_depth(tcx, self.cause.clone(), self.recursion_depth, self.param_env, value)
238210 }
239211}
212
213/// Determines whether the type `ty` is known to meet `bound` and
214/// returns true if so. Returns false if `ty` either does not meet
215/// `bound` or is not known to meet bound (note that this is
216/// conservative towards *no impl*, which is the opposite of the
217/// `evaluate` methods).
218pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
219 infcx: &InferCtxt<'tcx>,
220 param_env: ParamEnv<'tcx>,
221 ty: Ty<'tcx>,
222 def_id: TraitId,
223) -> bool {
224 let trait_ref = TraitRef::new(infcx.interner, def_id.into(), [ty]);
225 pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref)
226}
227
228/// FIXME(@lcnr): this function doesn't seem right and shouldn't exist?
229///
230/// Ping me on zulip if you want to use this method and need help with finding
231/// an appropriate replacement.
232fn pred_known_to_hold_modulo_regions<'db>(
233 infcx: &InferCtxt<'db>,
234 param_env: ParamEnv<'db>,
235 pred: impl Upcast<DbInterner<'db>, Predicate<'db>>,
236) -> bool {
237 let obligation = Obligation::new(infcx.interner, ObligationCause::dummy(), param_env, pred);
238
239 let result = infcx.evaluate_obligation(&obligation);
240 debug!(?result);
241
242 result.must_apply_modulo_regions()
243}
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs+203-80
......@@ -1,75 +1,81 @@
11//! Things related to the Interner in the next-trait-solver.
2#![allow(unused)]
2#![allow(unused)] // FIXME(next-solver): Remove this.
3
4use std::{fmt, ops::ControlFlow};
5
6pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db};
37
48use base_db::Crate;
59use chalk_ir::{ProgramClauseImplication, SeparatorTraitRef, Variances};
6use hir_def::lang_item::LangItem;
7use hir_def::signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags};
8use hir_def::{AdtId, BlockId, GenericDefId, TypeAliasId, VariantId};
9use hir_def::{AttrDefId, Lookup};
10use hir_def::{CallableDefId, EnumVariantId, ItemContainerId, StructId, UnionId};
10use hir_def::{
11 AdtId, AttrDefId, BlockId, CallableDefId, EnumVariantId, GenericDefId, ItemContainerId, Lookup,
12 StructId, TypeAliasId, UnionId, VariantId,
13 lang_item::LangItem,
14 signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags},
15};
1116use intern::sym::non_exhaustive;
1217use intern::{Interned, impl_internable, sym};
1318use la_arena::Idx;
1419use rustc_abi::{Align, ReprFlags, ReprOptions};
20use rustc_ast_ir::visit::VisitorResult;
1521use rustc_hash::FxHashSet;
16use rustc_index::bit_set::DenseBitSet;
17use rustc_type_ir::elaborate::elaborate;
18use rustc_type_ir::error::TypeError;
19use rustc_type_ir::inherent::{
20 AdtDef as _, GenericArgs as _, GenericsOf, IntoKind, SliceLike as _, Span as _,
21};
22use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
23use rustc_type_ir::solve::SizedTraitKind;
22use rustc_index::{IndexVec, bit_set::DenseBitSet};
2423use rustc_type_ir::{
25 AliasTerm, AliasTermKind, AliasTy, AliasTyKind, EarlyBinder, FlagComputation, Flags,
26 ImplPolarity, InferTy, ProjectionPredicate, TraitPredicate, TraitRef, Upcast,
24 AliasTerm, AliasTermKind, AliasTy, AliasTyKind, BoundVar, CollectAndApply, DebruijnIndex,
25 EarlyBinder, FlagComputation, Flags, GenericArgKind, ImplPolarity, InferTy,
26 ProjectionPredicate, RegionKind, TermKind, TraitPredicate, TraitRef, TypeVisitableExt,
27 UniverseIndex, Upcast, Variance, WithCachedTypeInfo,
28 elaborate::{self, elaborate},
29 error::TypeError,
30 inherent::{
31 self, AdtDef as _, Const as _, GenericArgs as _, GenericsOf, IntoKind, ParamEnv as _,
32 Region as _, SliceLike as _, Span as _, Ty as _,
33 },
34 ir_print,
35 lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem},
36 relate,
37 solve::SizedTraitKind,
2738};
2839use salsa::plumbing::AsId;
2940use smallvec::{SmallVec, smallvec};
30use std::fmt;
31use std::ops::ControlFlow;
3241use syntax::ast::SelfParamKind;
42use tracing::debug;
3343use triomphe::Arc;
3444
35use rustc_ast_ir::visit::VisitorResult;
36use rustc_index::IndexVec;
37use rustc_type_ir::TypeVisitableExt;
38use rustc_type_ir::{
39 BoundVar, CollectAndApply, DebruijnIndex, GenericArgKind, RegionKind, TermKind, UniverseIndex,
40 Variance, WithCachedTypeInfo, elaborate,
41 inherent::{self, Const as _, Region as _, Ty as _},
42 ir_print, relate,
43};
44
45use crate::lower_nextsolver::{self, TyLoweringContext};
46use crate::method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TyFingerprint};
47use crate::next_solver::infer::InferCtxt;
48use crate::next_solver::util::{ContainsTypeErrors, explicit_item_bounds, for_trait_impls};
49use crate::next_solver::{
50 AdtIdWrapper, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper,
51 CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, ImplIdWrapper, InternedWrapperNoDebug,
52 RegionAssumptions, SolverContext, SolverDefIds, TraitIdWrapper, TypeAliasIdWrapper,
45use crate::{
46 ConstScalar, FnAbi, Interner,
47 db::HirDatabase,
48 lower_nextsolver::{self, TyLoweringContext},
49 method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TyFingerprint},
50 next_solver::{
51 AdtIdWrapper, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper,
52 CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, ImplIdWrapper, InternedWrapperNoDebug,
53 RegionAssumptions, SolverContext, SolverDefIds, TraitIdWrapper, TypeAliasIdWrapper,
54 TypingMode,
55 infer::{
56 DbInternerInferExt, InferCtxt,
57 traits::{Obligation, ObligationCause},
58 },
59 obligation_ctxt::ObligationCtxt,
60 util::{ContainsTypeErrors, explicit_item_bounds, for_trait_impls},
61 },
5362};
54use crate::{ConstScalar, FnAbi, Interner, db::HirDatabase};
5563
56use super::generics::generics;
57use super::util::sizedness_constraint_for_ty;
5864use super::{
5965 Binder, BoundExistentialPredicate, BoundExistentialPredicates, BoundTy, BoundTyKind, Clause,
60 Clauses, Const, ConstKind, ErrorGuaranteed, ExprConst, ExternalConstraints,
66 ClauseKind, Clauses, Const, ConstKind, ErrorGuaranteed, ExprConst, ExternalConstraints,
6167 ExternalConstraintsData, GenericArg, GenericArgs, InternedClausesWrapper, ParamConst, ParamEnv,
6268 ParamTy, PlaceholderConst, PlaceholderTy, PredefinedOpaques, PredefinedOpaquesData, Predicate,
63 PredicateKind, Term, Ty, TyKind, Tys, ValueConst,
69 PredicateKind, SolverDefId, Term, Ty, TyKind, Tys, Valtree, ValueConst,
6470 abi::Safety,
6571 fold::{BoundVarReplacer, BoundVarReplacerDelegate, FnMutDelegate},
66 generics::Generics,
72 generics::{Generics, generics},
6773 mapping::ChalkToNextSolver,
6874 region::{
6975 BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, PlaceholderRegion, Region,
7076 },
77 util::sizedness_constraint_for_ty,
7178};
72use super::{ClauseKind, SolverDefId, Valtree};
7379
7480#[macro_export]
7581#[doc(hidden)]
......@@ -127,11 +133,10 @@ macro_rules! _interned_vec_nolifetime_salsa {
127133
128134 pub fn inner(&self) -> &smallvec::SmallVec<[$ty; 2]> {
129135 // SAFETY: ¯\_(ツ)_/¯
130 salsa::with_attached_database(|db| {
136 $crate::with_attached_db(|db| {
131137 let inner = self.inner_(db);
132138 unsafe { std::mem::transmute(inner) }
133139 })
134 .unwrap()
135140 }
136141 }
137142
......@@ -230,11 +235,10 @@ macro_rules! _interned_vec_db {
230235
231236 pub fn inner(&self) -> &smallvec::SmallVec<[$ty<'db>; 2]> {
232237 // SAFETY: ¯\_(ツ)_/¯
233 salsa::with_attached_database(|db| {
238 $crate::with_attached_db(|db| {
234239 let inner = self.inner_(db);
235240 unsafe { std::mem::transmute(inner) }
236241 })
237 .unwrap()
238242 }
239243 }
240244
......@@ -285,14 +289,11 @@ unsafe impl Sync for DbInterner<'_> {}
285289impl<'db> DbInterner<'db> {
286290 // FIXME(next-solver): remove this method
287291 pub fn conjure() -> DbInterner<'db> {
288 salsa::with_attached_database(|db| DbInterner {
289 db: unsafe {
290 std::mem::transmute::<&dyn HirDatabase, &'db dyn HirDatabase>(db.as_view())
291 },
292 crate::with_attached_db(|db| DbInterner {
293 db: unsafe { std::mem::transmute::<&dyn HirDatabase, &'db dyn HirDatabase>(db) },
292294 krate: None,
293295 block: None,
294296 })
295 .expect("db is expected to be attached")
296297 }
297298
298299 pub fn new_with(
......@@ -303,6 +304,7 @@ impl<'db> DbInterner<'db> {
303304 DbInterner { db, krate, block }
304305 }
305306
307 #[inline]
306308 pub fn db(&self) -> &'db dyn HirDatabase {
307309 self.db
308310 }
......@@ -585,12 +587,11 @@ impl AdtDef {
585587 }
586588
587589 pub fn inner(&self) -> &AdtDefInner {
588 salsa::with_attached_database(|db| {
590 crate::with_attached_db(|db| {
589591 let inner = self.data_(db);
590592 // SAFETY: ¯\_(ツ)_/¯
591593 unsafe { std::mem::transmute(inner) }
592594 })
593 .unwrap()
594595 }
595596
596597 pub fn is_enum(&self) -> bool {
......@@ -708,21 +709,20 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
708709
709710impl fmt::Debug for AdtDef {
710711 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
711 salsa::with_attached_database(|db| match self.inner().id {
712 crate::with_attached_db(|db| match self.inner().id {
712713 AdtId::StructId(struct_id) => {
713 let data = db.as_view::<dyn HirDatabase>().struct_signature(struct_id);
714 let data = db.struct_signature(struct_id);
714715 f.write_str(data.name.as_str())
715716 }
716717 AdtId::UnionId(union_id) => {
717 let data = db.as_view::<dyn HirDatabase>().union_signature(union_id);
718 let data = db.union_signature(union_id);
718719 f.write_str(data.name.as_str())
719720 }
720721 AdtId::EnumId(enum_id) => {
721 let data = db.as_view::<dyn HirDatabase>().enum_signature(enum_id);
722 let data = db.enum_signature(enum_id);
722723 f.write_str(data.name.as_str())
723724 }
724725 })
725 .unwrap_or_else(|| f.write_str(&format!("AdtDef({:?})", self.inner().id)))
726726 }
727727}
728728
......@@ -778,13 +778,12 @@ impl<'db> Pattern<'db> {
778778 }
779779
780780 pub fn inner(&self) -> &PatternKind<'db> {
781 salsa::with_attached_database(|db| {
781 crate::with_attached_db(|db| {
782782 let inner = &self.kind_(db).0;
783783 // SAFETY: The caller already has access to a `Ty<'db>`, so borrowchecking will
784784 // make sure that our returned value is valid for the lifetime `'db`.
785785 unsafe { std::mem::transmute(inner) }
786786 })
787 .unwrap()
788787 }
789788}
790789
......@@ -1020,17 +1019,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
10201019 self,
10211020 f: impl FnOnce(&mut rustc_type_ir::search_graph::GlobalCache<Self>) -> R,
10221021 ) -> R {
1023 salsa::with_attached_database(|db| {
1024 tls_cache::with_cache(
1025 unsafe {
1026 std::mem::transmute::<&dyn HirDatabase, &'db dyn HirDatabase>(
1027 db.as_view::<dyn HirDatabase>(),
1028 )
1029 },
1030 f,
1031 )
1032 })
1033 .unwrap()
1022 tls_cache::with_cache(self.db, f)
10341023 }
10351024
10361025 fn canonical_param_env_cache_get_or_insert<R>(
......@@ -1118,7 +1107,15 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
11181107 fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> AliasTyKind {
11191108 match alias.def_id {
11201109 SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque,
1121 SolverDefId::TypeAliasId(_) => AliasTyKind::Projection,
1110 SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
1111 ItemContainerId::ImplId(impl_)
1112 if self.db.impl_signature(impl_).target_trait.is_none() =>
1113 {
1114 AliasTyKind::Inherent
1115 }
1116 ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => AliasTyKind::Projection,
1117 _ => AliasTyKind::Free,
1118 },
11221119 _ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
11231120 }
11241121 }
......@@ -1129,7 +1126,19 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
11291126 ) -> rustc_type_ir::AliasTermKind {
11301127 match alias.def_id {
11311128 SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy,
1132 SolverDefId::TypeAliasId(_) => AliasTermKind::ProjectionTy,
1129 SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
1130 ItemContainerId::ImplId(impl_)
1131 if self.db.impl_signature(impl_).target_trait.is_none() =>
1132 {
1133 AliasTermKind::InherentTy
1134 }
1135 ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => {
1136 AliasTermKind::ProjectionTy
1137 }
1138 _ => AliasTermKind::FreeTy,
1139 },
1140 // rustc creates an `AnonConst` for consts, and evaluates them with CTFE (normalizing projections
1141 // via selection, similar to ours `find_matching_impl()`, and not with the trait solver), so mimic it.
11331142 SolverDefId::ConstId(_) => AliasTermKind::UnevaluatedConst,
11341143 _ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
11351144 }
......@@ -1616,7 +1625,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
16161625 mut f: impl FnMut(Self::ImplId),
16171626 ) {
16181627 let trait_ = trait_.0;
1619 let self_ty_fp = TyFingerprint::for_trait_impl_ns(&self_ty);
1628 let self_ty_fp = TyFingerprint::for_trait_impl(self_ty);
16201629 let fps: &[TyFingerprint] = match self_ty.kind() {
16211630 TyKind::Infer(InferTy::IntVar(..)) => &ALL_INT_FPS,
16221631 TyKind::Infer(InferTy::FloatVar(..)) => &ALL_FLOAT_FPS,
......@@ -1692,8 +1701,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
16921701 }
16931702
16941703 fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool {
1695 // FIXME
1696 false
1704 self.db.impl_signature(impl_def_id.0).is_default()
16971705 }
16981706
16991707 #[tracing::instrument(skip(self), ret)]
......@@ -1747,7 +1755,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
17471755 }
17481756
17491757 fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed {
1750 panic!("Bug encountered in next-trait-solver.")
1758 panic!("Bug encountered in next-trait-solver: {}", msg.to_string())
17511759 }
17521760
17531761 fn is_general_coroutine(self, coroutine_def_id: Self::CoroutineId) -> bool {
......@@ -1907,7 +1915,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
19071915 match impl_trait_id {
19081916 crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
19091917 let infer = self.db().infer(func.into());
1910 EarlyBinder::bind(infer.type_of_rpit[idx].to_nextsolver(self))
1918 EarlyBinder::bind(infer.type_of_rpit[idx.to_nextsolver(self)])
19111919 }
19121920 crate::ImplTraitId::TypeAliasImplTrait(..)
19131921 | crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => {
......@@ -1945,7 +1953,11 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
19451953 false
19461954 }
19471955
1948 fn impl_specializes(self, impl_def_id: Self::ImplId, victim_def_id: Self::ImplId) -> bool {
1956 fn impl_specializes(
1957 self,
1958 specializing_impl_def_id: Self::ImplId,
1959 parent_impl_def_id: Self::ImplId,
1960 ) -> bool {
19491961 false
19501962 }
19511963
......@@ -2106,6 +2118,117 @@ TrivialTypeTraversalImpls! {
21062118 Placeholder<BoundVar>,
21072119}
21082120
2121mod tls_db {
2122 use std::{cell::Cell, ptr::NonNull};
2123
2124 use crate::db::HirDatabase;
2125
2126 struct Attached {
2127 database: Cell<Option<NonNull<dyn HirDatabase>>>,
2128 }
2129
2130 impl Attached {
2131 #[inline]
2132 fn attach<R>(&self, db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2133 struct DbGuard<'s> {
2134 state: Option<&'s Attached>,
2135 }
2136
2137 impl<'s> DbGuard<'s> {
2138 #[inline]
2139 fn new(attached: &'s Attached, db: &dyn HirDatabase) -> Self {
2140 match attached.database.get() {
2141 Some(current_db) => {
2142 let new_db = NonNull::from(db);
2143 if !std::ptr::addr_eq(current_db.as_ptr(), new_db.as_ptr()) {
2144 panic!(
2145 "Cannot change attached database. This is likely a bug.\n\
2146 If this is not a bug, you can use `attach_db_allow_change()`."
2147 );
2148 }
2149 Self { state: None }
2150 }
2151 None => {
2152 // Otherwise, set the database.
2153 attached.database.set(Some(NonNull::from(db)));
2154 Self { state: Some(attached) }
2155 }
2156 }
2157 }
2158 }
2159
2160 impl Drop for DbGuard<'_> {
2161 #[inline]
2162 fn drop(&mut self) {
2163 // Reset database to null if we did anything in `DbGuard::new`.
2164 if let Some(attached) = self.state {
2165 attached.database.set(None);
2166 }
2167 }
2168 }
2169
2170 let _guard = DbGuard::new(self, db);
2171 op()
2172 }
2173
2174 #[inline]
2175 fn attach_allow_change<R>(&self, db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2176 struct DbGuard<'s> {
2177 state: &'s Attached,
2178 prev: Option<NonNull<dyn HirDatabase>>,
2179 }
2180
2181 impl<'s> DbGuard<'s> {
2182 #[inline]
2183 fn new(attached: &'s Attached, db: &dyn HirDatabase) -> Self {
2184 let prev = attached.database.replace(Some(NonNull::from(db)));
2185 Self { state: attached, prev }
2186 }
2187 }
2188
2189 impl Drop for DbGuard<'_> {
2190 #[inline]
2191 fn drop(&mut self) {
2192 self.state.database.set(self.prev);
2193 }
2194 }
2195
2196 let _guard = DbGuard::new(self, db);
2197 op()
2198 }
2199
2200 #[inline]
2201 fn with<R>(&self, op: impl FnOnce(&dyn HirDatabase) -> R) -> R {
2202 let db = self.database.get().expect("Try to use attached db, but not db is attached");
2203
2204 // SAFETY: The db is attached, so it must be valid.
2205 op(unsafe { db.as_ref() })
2206 }
2207 }
2208
2209 thread_local! {
2210 static GLOBAL_DB: Attached = const { Attached { database: Cell::new(None) } };
2211 }
2212
2213 #[inline]
2214 pub fn attach_db<R>(db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2215 GLOBAL_DB.with(|global_db| global_db.attach(db, op))
2216 }
2217
2218 #[inline]
2219 pub fn attach_db_allow_change<R>(db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2220 GLOBAL_DB.with(|global_db| global_db.attach_allow_change(db, op))
2221 }
2222
2223 #[inline]
2224 pub fn with_attached_db<R>(op: impl FnOnce(&dyn HirDatabase) -> R) -> R {
2225 GLOBAL_DB.with(
2226 #[inline]
2227 |a| a.with(op),
2228 )
2229 }
2230}
2231
21092232mod tls_cache {
21102233 use crate::db::HirDatabase;
21112234
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs+13-31
......@@ -16,10 +16,10 @@ impl<'db> IrPrint<ty::AliasTy<Self>> for DbInterner<'db> {
1616 }
1717
1818 fn print_debug(t: &ty::AliasTy<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 salsa::with_attached_database(|db| match t.def_id {
19 crate::with_attached_db(|db| match t.def_id {
2020 SolverDefId::TypeAliasId(id) => fmt.write_str(&format!(
2121 "AliasTy({:?}[{:?}])",
22 db.as_view::<dyn HirDatabase>().type_alias_signature(id).name.as_str(),
22 db.type_alias_signature(id).name.as_str(),
2323 t.args
2424 )),
2525 SolverDefId::InternedOpaqueTyId(id) => {
......@@ -27,7 +27,6 @@ impl<'db> IrPrint<ty::AliasTy<Self>> for DbInterner<'db> {
2727 }
2828 _ => panic!("Expected TypeAlias or OpaqueTy."),
2929 })
30 .unwrap_or_else(|| fmt.write_str(&format!("AliasTy({:?}[{:?}])", t.def_id, t.args)))
3130 }
3231}
3332
......@@ -37,10 +36,10 @@ impl<'db> IrPrint<ty::AliasTerm<Self>> for DbInterner<'db> {
3736 }
3837
3938 fn print_debug(t: &ty::AliasTerm<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 salsa::with_attached_database(|db| match t.def_id {
39 crate::with_attached_db(|db| match t.def_id {
4140 SolverDefId::TypeAliasId(id) => fmt.write_str(&format!(
4241 "AliasTerm({:?}[{:?}])",
43 db.as_view::<dyn HirDatabase>().type_alias_signature(id).name.as_str(),
42 db.type_alias_signature(id).name.as_str(),
4443 t.args
4544 )),
4645 SolverDefId::InternedOpaqueTyId(id) => {
......@@ -48,7 +47,6 @@ impl<'db> IrPrint<ty::AliasTerm<Self>> for DbInterner<'db> {
4847 }
4948 _ => panic!("Expected TypeAlias or OpaqueTy."),
5049 })
51 .unwrap_or_else(|| fmt.write_str(&format!("AliasTerm({:?}[{:?}])", t.def_id, t.args)))
5250 }
5351}
5452impl<'db> IrPrint<ty::TraitRef<Self>> for DbInterner<'db> {
......@@ -57,7 +55,7 @@ impl<'db> IrPrint<ty::TraitRef<Self>> for DbInterner<'db> {
5755 }
5856
5957 fn print_debug(t: &ty::TraitRef<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 salsa::with_attached_database(|db| {
58 crate::with_attached_db(|db| {
6159 let trait_ = t.def_id.0;
6260 let self_ty = &t.args.as_slice()[0];
6361 let trait_args = &t.args.as_slice()[1..];
......@@ -65,18 +63,17 @@ impl<'db> IrPrint<ty::TraitRef<Self>> for DbInterner<'db> {
6563 fmt.write_str(&format!(
6664 "{:?}: {}",
6765 self_ty,
68 db.as_view::<dyn HirDatabase>().trait_signature(trait_).name.as_str()
66 db.trait_signature(trait_).name.as_str()
6967 ))
7068 } else {
7169 fmt.write_str(&format!(
7270 "{:?}: {}<{:?}>",
7371 self_ty,
74 db.as_view::<dyn HirDatabase>().trait_signature(trait_).name.as_str(),
72 db.trait_signature(trait_).name.as_str(),
7573 trait_args
7674 ))
7775 }
7876 })
79 .unwrap_or_else(|| fmt.write_str(&format!("TraitRef({:?}[{:?}])", t.def_id, t.args)))
8077 }
8178}
8279impl<'db> IrPrint<ty::TraitPredicate<Self>> for DbInterner<'db> {
......@@ -118,17 +115,14 @@ impl<'db> IrPrint<ty::ExistentialTraitRef<Self>> for DbInterner<'db> {
118115 t: &ty::ExistentialTraitRef<Self>,
119116 fmt: &mut std::fmt::Formatter<'_>,
120117 ) -> std::fmt::Result {
121 salsa::with_attached_database(|db| {
118 crate::with_attached_db(|db| {
122119 let trait_ = t.def_id.0;
123120 fmt.write_str(&format!(
124121 "ExistentialTraitRef({:?}[{:?}])",
125 db.as_view::<dyn HirDatabase>().trait_signature(trait_).name.as_str(),
122 db.trait_signature(trait_).name.as_str(),
126123 t.args
127124 ))
128125 })
129 .unwrap_or_else(|| {
130 fmt.write_str(&format!("ExistentialTraitRef({:?}[{:?}])", t.def_id, t.args))
131 })
132126 }
133127}
134128impl<'db> IrPrint<ty::ExistentialProjection<Self>> for DbInterner<'db> {
......@@ -143,24 +137,18 @@ impl<'db> IrPrint<ty::ExistentialProjection<Self>> for DbInterner<'db> {
143137 t: &ty::ExistentialProjection<Self>,
144138 fmt: &mut std::fmt::Formatter<'_>,
145139 ) -> std::fmt::Result {
146 salsa::with_attached_database(|db| {
140 crate::with_attached_db(|db| {
147141 let id = match t.def_id {
148142 SolverDefId::TypeAliasId(id) => id,
149143 _ => panic!("Expected trait."),
150144 };
151145 fmt.write_str(&format!(
152146 "ExistentialProjection(({:?}[{:?}]) -> {:?})",
153 db.as_view::<dyn HirDatabase>().type_alias_signature(id).name.as_str(),
147 db.type_alias_signature(id).name.as_str(),
154148 t.args,
155149 t.term
156150 ))
157151 })
158 .unwrap_or_else(|| {
159 fmt.write_str(&format!(
160 "ExistentialProjection(({:?}[{:?}]) -> {:?})",
161 t.def_id, t.args, t.term
162 ))
163 })
164152 }
165153}
166154impl<'db> IrPrint<ty::ProjectionPredicate<Self>> for DbInterner<'db> {
......@@ -175,24 +163,18 @@ impl<'db> IrPrint<ty::ProjectionPredicate<Self>> for DbInterner<'db> {
175163 t: &ty::ProjectionPredicate<Self>,
176164 fmt: &mut std::fmt::Formatter<'_>,
177165 ) -> std::fmt::Result {
178 salsa::with_attached_database(|db| {
166 crate::with_attached_db(|db| {
179167 let id = match t.projection_term.def_id {
180168 SolverDefId::TypeAliasId(id) => id,
181169 _ => panic!("Expected trait."),
182170 };
183171 fmt.write_str(&format!(
184172 "ProjectionPredicate(({:?}[{:?}]) -> {:?})",
185 db.as_view::<dyn HirDatabase>().type_alias_signature(id).name.as_str(),
173 db.type_alias_signature(id).name.as_str(),
186174 t.projection_term.args,
187175 t.term
188176 ))
189177 })
190 .unwrap_or_else(|| {
191 fmt.write_str(&format!(
192 "ProjectionPredicate(({:?}[{:?}]) -> {:?})",
193 t.projection_term.def_id, t.projection_term.args, t.term
194 ))
195 })
196178 }
197179}
198180impl<'db> IrPrint<ty::NormalizesTo<Self>> for DbInterner<'db> {
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/mapping.rs+45-3
......@@ -143,10 +143,29 @@ pub trait ChalkToNextSolver<'db, Out> {
143143 fn to_nextsolver(&self, interner: DbInterner<'db>) -> Out;
144144}
145145
146impl<'db, A, OutA, B, OutB> ChalkToNextSolver<'db, (OutA, OutB)> for (A, B)
147where
148 A: ChalkToNextSolver<'db, OutA>,
149 B: ChalkToNextSolver<'db, OutB>,
150{
151 fn to_nextsolver(&self, interner: DbInterner<'db>) -> (OutA, OutB) {
152 (self.0.to_nextsolver(interner), self.1.to_nextsolver(interner))
153 }
154}
155
146156pub trait NextSolverToChalk<'db, Out> {
147157 fn to_chalk(self, interner: DbInterner<'db>) -> Out;
148158}
149159
160impl<'db, T, Out> NextSolverToChalk<'db, Option<Out>> for Option<T>
161where
162 T: NextSolverToChalk<'db, Out>,
163{
164 fn to_chalk(self, interner: DbInterner<'db>) -> Option<Out> {
165 self.map(|it| it.to_chalk(interner))
166 }
167}
168
150169impl NextSolverToChalk<'_, chalk_ir::Mutability> for rustc_ast_ir::Mutability {
151170 fn to_chalk(self, interner: DbInterner<'_>) -> chalk_ir::Mutability {
152171 match self {
......@@ -520,7 +539,7 @@ impl<'db> ChalkToNextSolver<'db, Const<'db>> for chalk_ir::Const<Interner> {
520539 ConstScalar::Bytes(bytes, memory) => {
521540 rustc_type_ir::ConstKind::Value(ValueConst::new(
522541 data.ty.to_nextsolver(interner),
523 ConstBytes(bytes.clone(), memory.clone()),
542 ConstBytes { memory: bytes.clone(), memory_map: memory.clone() },
524543 ))
525544 }
526545 ConstScalar::UnevaluatedConst(c, subst) => {
......@@ -633,6 +652,16 @@ impl<'db> ChalkToNextSolver<'db, GenericArg<'db>> for chalk_ir::GenericArg<Inter
633652 }
634653}
635654
655impl<'db> NextSolverToChalk<'db, crate::GenericArg> for GenericArg<'db> {
656 fn to_chalk(self, interner: DbInterner<'db>) -> crate::GenericArg {
657 match self {
658 GenericArg::Ty(ty) => ty.to_chalk(interner).cast(Interner),
659 GenericArg::Lifetime(region) => region.to_chalk(interner).cast(Interner),
660 GenericArg::Const(konst) => konst.to_chalk(interner).cast(Interner),
661 }
662 }
663}
664
636665impl<'db> ChalkToNextSolver<'db, GenericArgs<'db>> for chalk_ir::Substitution<Interner> {
637666 fn to_nextsolver(&self, interner: DbInterner<'db>) -> GenericArgs<'db> {
638667 GenericArgs::new_from_iter(
......@@ -642,6 +671,17 @@ impl<'db> ChalkToNextSolver<'db, GenericArgs<'db>> for chalk_ir::Substitution<In
642671 }
643672}
644673
674impl<'db> ChalkToNextSolver<'db, crate::lower_nextsolver::ImplTraitIdx<'db>>
675 for crate::ImplTraitIdx
676{
677 fn to_nextsolver(
678 &self,
679 interner: DbInterner<'db>,
680 ) -> crate::lower_nextsolver::ImplTraitIdx<'db> {
681 crate::lower_nextsolver::ImplTraitIdx::from_raw(self.into_raw())
682 }
683}
684
645685impl<'db> NextSolverToChalk<'db, chalk_ir::Substitution<Interner>> for GenericArgs<'db> {
646686 fn to_chalk(self, interner: DbInterner<'db>) -> chalk_ir::Substitution<Interner> {
647687 convert_args_for_result(interner, self.as_slice())
......@@ -1670,8 +1710,10 @@ pub fn convert_const_for_result<'db>(
16701710 let bytes = value_const.value.inner();
16711711 let value = chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst {
16721712 // SAFETY: we will never actually use this without a database
1673 interned: ConstScalar::Bytes(bytes.0.clone(), unsafe {
1674 std::mem::transmute::<MemoryMap<'db>, MemoryMap<'static>>(bytes.1.clone())
1713 interned: ConstScalar::Bytes(bytes.memory.clone(), unsafe {
1714 std::mem::transmute::<MemoryMap<'db>, MemoryMap<'static>>(
1715 bytes.memory_map.clone(),
1716 )
16751717 }),
16761718 });
16771719 return chalk_ir::ConstData {
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs+2-4
......@@ -24,12 +24,11 @@ impl<'db> PredefinedOpaques<'db> {
2424 }
2525
2626 pub fn inner(&self) -> &PredefinedOpaquesData<'db> {
27 salsa::with_attached_database(|db| {
27 crate::with_attached_db(|db| {
2828 let inner = self.kind_(db);
2929 // SAFETY: ¯\_(ツ)_/¯
3030 unsafe { std::mem::transmute(inner) }
3131 })
32 .unwrap()
3332 }
3433}
3534
......@@ -96,12 +95,11 @@ impl<'db> ExternalConstraints<'db> {
9695 }
9796
9897 pub fn inner(&self) -> &ExternalConstraintsData<'db> {
99 salsa::with_attached_database(|db| {
98 crate::with_attached_db(|db| {
10099 let inner = self.kind_(db);
101100 // SAFETY: ¯\_(ツ)_/¯
102101 unsafe { std::mem::transmute(inner) }
103102 })
104 .unwrap()
105103 }
106104}
107105
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs+4-27
......@@ -3,6 +3,7 @@
33use std::cmp::Ordering;
44
55use intern::Interned;
6use macros::{TypeFoldable, TypeVisitable};
67use rustc_ast_ir::try_visit;
78use rustc_type_ir::{
89 self as ty, CollectAndApply, DebruijnIndex, EarlyBinder, FlagComputation, Flags,
......@@ -232,13 +233,12 @@ impl<'db> Predicate<'db> {
232233 }
233234
234235 pub fn inner(&self) -> &WithCachedTypeInfo<Binder<'db, PredicateKind<'db>>> {
235 salsa::with_attached_database(|db| {
236 crate::with_attached_db(|db| {
236237 let inner = &self.kind_(db).0;
237238 // SAFETY: The caller already has access to a `Predicate<'db>`, so borrowchecking will
238239 // make sure that our returned value is valid for the lifetime `'db`.
239240 unsafe { std::mem::transmute(inner) }
240241 })
241 .unwrap()
242242 }
243243
244244 /// Flips the polarity of a Predicate.
......@@ -303,13 +303,12 @@ impl<'db> Clauses<'db> {
303303 }
304304
305305 pub fn inner(&self) -> &InternedClausesWrapper<'db> {
306 salsa::with_attached_database(|db| {
306 crate::with_attached_db(|db| {
307307 let inner = self.inner_(db);
308308 // SAFETY: The caller already has access to a `Clauses<'db>`, so borrowchecking will
309309 // make sure that our returned value is valid for the lifetime `'db`.
310310 unsafe { std::mem::transmute(inner) }
311311 })
312 .unwrap()
313312 }
314313}
315314
......@@ -426,7 +425,7 @@ impl<'db> rustc_type_ir::TypeSuperVisitable<DbInterner<'db>> for Clauses<'db> {
426425pub struct Clause<'db>(pub(crate) Predicate<'db>);
427426
428427// We could cram the reveal into the clauses like rustc does, probably
429#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
428#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable)]
430429pub struct ParamEnv<'db> {
431430 pub(crate) clauses: Clauses<'db>,
432431}
......@@ -437,28 +436,6 @@ impl<'db> ParamEnv<'db> {
437436 }
438437}
439438
440impl<'db> TypeVisitable<DbInterner<'db>> for ParamEnv<'db> {
441 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
442 &self,
443 visitor: &mut V,
444 ) -> V::Result {
445 try_visit!(self.clauses.visit_with(visitor));
446 V::Result::output()
447 }
448}
449
450impl<'db> TypeFoldable<DbInterner<'db>> for ParamEnv<'db> {
451 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
452 self,
453 folder: &mut F,
454 ) -> Result<Self, F::Error> {
455 Ok(ParamEnv { clauses: self.clauses.try_fold_with(folder)? })
456 }
457 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
458 ParamEnv { clauses: self.clauses.fold_with(folder) }
459 }
460}
461
462439impl<'db> rustc_type_ir::inherent::ParamEnv<DbInterner<'db>> for ParamEnv<'db> {
463440 fn caller_bounds(self) -> impl rustc_type_ir::inherent::SliceLike<Item = Clause<'db>> {
464441 self.clauses
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs+22-4
......@@ -3,7 +3,8 @@
33use hir_def::LifetimeParamId;
44use intern::{Interned, Symbol};
55use rustc_type_ir::{
6 BoundVar, Flags, INNERMOST, RegionVid, TypeFlags, TypeFoldable, TypeVisitable, VisitorResult,
6 BoundVar, DebruijnIndex, Flags, INNERMOST, RegionVid, TypeFlags, TypeFoldable, TypeVisitable,
7 VisitorResult,
78 inherent::{IntoKind, PlaceholderLike, SliceLike},
89 relate::Relate,
910};
......@@ -17,25 +18,30 @@ use super::{
1718
1819pub type RegionKind<'db> = rustc_type_ir::RegionKind<DbInterner<'db>>;
1920
20#[salsa::interned(constructor = new_, debug)]
21#[salsa::interned(constructor = new_)]
2122pub struct Region<'db> {
2223 #[returns(ref)]
2324 kind_: RegionKind<'db>,
2425}
2526
27impl std::fmt::Debug for Region<'_> {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 self.kind().fmt(f)
30 }
31}
32
2633impl<'db> Region<'db> {
2734 pub fn new(interner: DbInterner<'db>, kind: RegionKind<'db>) -> Self {
2835 Region::new_(interner.db(), kind)
2936 }
3037
3138 pub fn inner(&self) -> &RegionKind<'db> {
32 salsa::with_attached_database(|db| {
39 crate::with_attached_db(|db| {
3340 let inner = self.kind_(db);
3441 // SAFETY: The caller already has access to a `Region<'db>`, so borrowchecking will
3542 // make sure that our returned value is valid for the lifetime `'db`.
3643 unsafe { std::mem::transmute::<&RegionKind<'_>, &RegionKind<'db>>(inner) }
3744 })
38 .unwrap()
3945 }
4046
4147 pub fn new_early_param(
......@@ -57,6 +63,14 @@ impl<'db> Region<'db> {
5763 Region::new(interner, RegionKind::ReErased)
5864 }
5965
66 pub fn new_bound(
67 interner: DbInterner<'db>,
68 index: DebruijnIndex,
69 bound: BoundRegion,
70 ) -> Region<'db> {
71 Region::new(interner, RegionKind::ReBound(index, bound))
72 }
73
6074 pub fn is_placeholder(&self) -> bool {
6175 matches!(self.inner(), RegionKind::RePlaceholder(..))
6276 }
......@@ -69,6 +83,10 @@ impl<'db> Region<'db> {
6983 matches!(self.inner(), RegionKind::ReVar(_))
7084 }
7185
86 pub fn is_error(&self) -> bool {
87 matches!(self.inner(), RegionKind::ReError(_))
88 }
89
7290 pub fn error(interner: DbInterner<'db>) -> Self {
7391 Region::new(interner, RegionKind::ReError(ErrorGuaranteed))
7492 }
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs+45-20
......@@ -149,13 +149,9 @@ impl<'db> SolverDelegate for SolverContext<'db> {
149149 fn fetch_eligible_assoc_item(
150150 &self,
151151 goal_trait_ref: rustc_type_ir::TraitRef<Self::Interner>,
152 trait_assoc_def_id: <Self::Interner as rustc_type_ir::Interner>::DefId,
152 trait_assoc_def_id: SolverDefId,
153153 impl_id: ImplIdWrapper,
154 ) -> Result<Option<<Self::Interner as rustc_type_ir::Interner>::DefId>, ErrorGuaranteed> {
155 let trait_assoc_id = match trait_assoc_def_id {
156 SolverDefId::TypeAliasId(id) => id,
157 _ => panic!("Unexpected SolverDefId"),
158 };
154 ) -> Result<Option<SolverDefId>, ErrorGuaranteed> {
159155 let trait_ = self
160156 .0
161157 .interner
......@@ -167,18 +163,47 @@ impl<'db> SolverDelegate for SolverContext<'db> {
167163 .def_id
168164 .0;
169165 let trait_data = trait_.trait_items(self.0.interner.db());
170 let id =
171 impl_id.0.impl_items(self.0.interner.db()).items.iter().find_map(|item| -> Option<_> {
172 match item {
173 (_, AssocItemId::TypeAliasId(type_alias)) => {
174 let name = &self.0.interner.db().type_alias_signature(*type_alias).name;
175 let found_trait_assoc_id = trait_data.associated_type_by_name(name)?;
176 (found_trait_assoc_id == trait_assoc_id).then_some(*type_alias)
177 }
178 _ => None,
179 }
180 });
181 Ok(id.map(SolverDefId::TypeAliasId))
166 let impl_items = impl_id.0.impl_items(self.0.interner.db());
167 let id = match trait_assoc_def_id {
168 SolverDefId::TypeAliasId(trait_assoc_id) => {
169 let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id);
170 impl_items
171 .items
172 .iter()
173 .find_map(|(impl_assoc_name, impl_assoc_id)| {
174 if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id
175 && *impl_assoc_name == trait_assoc_data.name
176 {
177 Some(impl_assoc_id)
178 } else {
179 None
180 }
181 })
182 .map(SolverDefId::TypeAliasId)
183 }
184 SolverDefId::ConstId(trait_assoc_id) => {
185 let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id);
186 let trait_assoc_name = trait_assoc_data
187 .name
188 .as_ref()
189 .expect("unnamed consts should not get passed to the solver");
190 impl_items
191 .items
192 .iter()
193 .find_map(|(impl_assoc_name, impl_assoc_id)| {
194 if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id
195 && impl_assoc_name == trait_assoc_name
196 {
197 Some(impl_assoc_id)
198 } else {
199 None
200 }
201 })
202 .map(SolverDefId::ConstId)
203 }
204 _ => panic!("Unexpected SolverDefId"),
205 };
206 Ok(id)
182207 }
183208
184209 fn is_transmutable(
......@@ -200,9 +225,9 @@ impl<'db> SolverDelegate for SolverContext<'db> {
200225 SolverDefId::StaticId(c) => GeneralConstId::StaticId(c),
201226 _ => unreachable!(),
202227 };
203 let subst = uv.args.to_chalk(self.interner);
228 let subst = uv.args;
204229 let ec = self.cx().db.const_eval(c, subst, None).ok()?;
205 Some(ec.to_nextsolver(self.interner))
230 Some(ec)
206231 }
207232
208233 fn compute_goal_fast_path(
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs+282-14
......@@ -3,18 +3,22 @@
33use std::iter;
44use std::ops::ControlFlow;
55
6use hir_def::{GenericDefId, TypeOrConstParamId, TypeParamId};
6use hir_def::{
7 AdtId, DefWithBodyId, GenericDefId, HasModule, TypeOrConstParamId, TypeParamId,
8 hir::generics::{TypeOrConstParamData, TypeParamProvenance},
9 lang_item::LangItem,
10};
11use hir_def::{TraitId, type_ref::Rawness};
712use intern::{Interned, Symbol, sym};
813use rustc_abi::{Float, Integer, Size};
914use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult};
10use rustc_type_ir::TyVid;
1115use rustc_type_ir::{
12 BoundVar, ClosureKind, CollectAndApply, FlagComputation, Flags, FloatTy, FloatVid, InferTy,
13 IntTy, IntVid, Interner, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
14 TypeVisitableExt, TypeVisitor, UintTy, WithCachedTypeInfo,
16 AliasTyKind, BoundVar, ClosureKind, CollectAndApply, FlagComputation, Flags, FloatTy, FloatVid,
17 InferTy, IntTy, IntVid, Interner, TyVid, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
18 TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, WithCachedTypeInfo,
1519 inherent::{
16 Abi, AdtDef, BoundVarLike, Const as _, GenericArgs as _, IntoKind, ParamLike,
17 PlaceholderLike, Safety as _, SliceLike, Ty as _,
20 Abi, AdtDef as _, BoundExistentialPredicates, BoundVarLike, Const as _, GenericArgs as _,
21 IntoKind, ParamLike, PlaceholderLike, Safety as _, SliceLike, Ty as _,
1822 },
1923 relate::Relate,
2024 solve::SizedTraitKind,
......@@ -24,13 +28,14 @@ use salsa::plumbing::{AsId, FromId};
2428use smallvec::SmallVec;
2529
2630use crate::{
27 FnAbi,
31 FnAbi, ImplTraitId,
2832 db::HirDatabase,
2933 interner::InternedWrapperNoDebug,
3034 next_solver::{
31 CallableIdWrapper, ClosureIdWrapper, Const, CoroutineIdWrapper, FnSig, GenericArg,
32 PolyFnSig, TypeAliasIdWrapper,
35 AdtDef, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const,
36 CoroutineIdWrapper, FnSig, GenericArg, PolyFnSig, Region, TraitRef, TypeAliasIdWrapper,
3337 abi::Safety,
38 mapping::ChalkToNextSolver,
3439 util::{CoroutineArgsExt, IntegerTypeExt},
3540 },
3641};
......@@ -66,13 +71,16 @@ impl<'db> Ty<'db> {
6671 }
6772
6873 pub fn inner(&self) -> &WithCachedTypeInfo<TyKind<'db>> {
69 salsa::with_attached_database(|db| {
74 crate::with_attached_db(|db| {
7075 let inner = &self.kind_(db).0;
7176 // SAFETY: The caller already has access to a `Ty<'db>`, so borrowchecking will
7277 // make sure that our returned value is valid for the lifetime `'db`.
7378 unsafe { std::mem::transmute(inner) }
7479 })
75 .unwrap()
80 }
81
82 pub fn new_adt(interner: DbInterner<'db>, adt_id: AdtId, args: GenericArgs<'db>) -> Self {
83 Ty::new(interner, TyKind::Adt(AdtDef::new(adt_id, interner), args))
7684 }
7785
7886 pub fn new_param(interner: DbInterner<'db>, id: TypeParamId, index: u32, name: Symbol) -> Self {
......@@ -337,6 +345,23 @@ impl<'db> Ty<'db> {
337345 matches!(self.kind(), TyKind::Tuple(tys) if tys.inner().is_empty())
338346 }
339347
348 #[inline]
349 pub fn is_raw_ptr(self) -> bool {
350 matches!(self.kind(), TyKind::RawPtr(..))
351 }
352
353 pub fn is_union(self) -> bool {
354 self.as_adt().is_some_and(|(adt, _)| matches!(adt, AdtId::UnionId(_)))
355 }
356
357 #[inline]
358 pub fn as_adt(self) -> Option<(AdtId, GenericArgs<'db>)> {
359 match self.kind() {
360 TyKind::Adt(adt_def, args) => Some((adt_def.def_id().0, args)),
361 _ => None,
362 }
363 }
364
340365 #[inline]
341366 pub fn ty_vid(self) -> Option<TyVid> {
342367 match self.kind() {
......@@ -370,8 +395,245 @@ impl<'db> Ty<'db> {
370395
371396 /// Whether the type contains some non-lifetime, aka. type or const, error type.
372397 pub fn references_non_lt_error(self) -> bool {
373 self.references_error() && self.visit_with(&mut ReferencesNonLifetimeError).is_break()
398 references_non_lt_error(&self)
399 }
400
401 pub fn callable_sig(self, interner: DbInterner<'db>) -> Option<Binder<'db, FnSig<'db>>> {
402 match self.kind() {
403 TyKind::FnDef(callable, args) => {
404 Some(interner.fn_sig(callable).instantiate(interner, args))
405 }
406 TyKind::FnPtr(sig, hdr) => Some(sig.with(hdr)),
407 TyKind::Closure(closure_id, closure_args) => closure_args
408 .split_closure_args_untupled()
409 .closure_sig_as_fn_ptr_ty
410 .callable_sig(interner),
411 _ => None,
412 }
413 }
414
415 pub fn as_reference(self) -> Option<(Ty<'db>, Region<'db>, Mutability)> {
416 match self.kind() {
417 TyKind::Ref(region, ty, mutability) => Some((ty, region, mutability)),
418 _ => None,
419 }
420 }
421
422 pub fn as_reference_or_ptr(self) -> Option<(Ty<'db>, Rawness, Mutability)> {
423 match self.kind() {
424 TyKind::Ref(_, ty, mutability) => Some((ty, Rawness::Ref, mutability)),
425 TyKind::RawPtr(ty, mutability) => Some((ty, Rawness::RawPtr, mutability)),
426 _ => None,
427 }
374428 }
429
430 pub fn as_tuple(self) -> Option<Tys<'db>> {
431 match self.kind() {
432 TyKind::Tuple(tys) => Some(tys),
433 _ => None,
434 }
435 }
436
437 pub fn dyn_trait(self) -> Option<TraitId> {
438 let TyKind::Dynamic(bounds, _) = self.kind() else { return None };
439 Some(bounds.principal_def_id()?.0)
440 }
441
442 pub fn strip_references(self) -> Ty<'db> {
443 let mut t = self;
444 while let TyKind::Ref(_lifetime, ty, _mutability) = t.kind() {
445 t = ty;
446 }
447 t
448 }
449
450 pub fn strip_reference(self) -> Ty<'db> {
451 self.as_reference().map_or(self, |(ty, _, _)| ty)
452 }
453
454 /// Replace infer vars with errors.
455 ///
456 /// This needs to be called for every type that may contain infer vars and is yielded to outside inference,
457 /// as things other than inference do not expect to see infer vars.
458 pub fn replace_infer_with_error(self, interner: DbInterner<'db>) -> Ty<'db> {
459 self.fold_with(&mut crate::next_solver::infer::resolve::ReplaceInferWithError::new(
460 interner,
461 ))
462 }
463
464 pub fn from_builtin_type(
465 interner: DbInterner<'db>,
466 ty: hir_def::builtin_type::BuiltinType,
467 ) -> Ty<'db> {
468 let kind = match ty {
469 hir_def::builtin_type::BuiltinType::Char => TyKind::Char,
470 hir_def::builtin_type::BuiltinType::Bool => TyKind::Bool,
471 hir_def::builtin_type::BuiltinType::Str => TyKind::Str,
472 hir_def::builtin_type::BuiltinType::Int(int) => TyKind::Int(match int {
473 hir_def::builtin_type::BuiltinInt::Isize => rustc_type_ir::IntTy::Isize,
474 hir_def::builtin_type::BuiltinInt::I8 => rustc_type_ir::IntTy::I8,
475 hir_def::builtin_type::BuiltinInt::I16 => rustc_type_ir::IntTy::I16,
476 hir_def::builtin_type::BuiltinInt::I32 => rustc_type_ir::IntTy::I32,
477 hir_def::builtin_type::BuiltinInt::I64 => rustc_type_ir::IntTy::I64,
478 hir_def::builtin_type::BuiltinInt::I128 => rustc_type_ir::IntTy::I128,
479 }),
480 hir_def::builtin_type::BuiltinType::Uint(uint) => TyKind::Uint(match uint {
481 hir_def::builtin_type::BuiltinUint::Usize => rustc_type_ir::UintTy::Usize,
482 hir_def::builtin_type::BuiltinUint::U8 => rustc_type_ir::UintTy::U8,
483 hir_def::builtin_type::BuiltinUint::U16 => rustc_type_ir::UintTy::U16,
484 hir_def::builtin_type::BuiltinUint::U32 => rustc_type_ir::UintTy::U32,
485 hir_def::builtin_type::BuiltinUint::U64 => rustc_type_ir::UintTy::U64,
486 hir_def::builtin_type::BuiltinUint::U128 => rustc_type_ir::UintTy::U128,
487 }),
488 hir_def::builtin_type::BuiltinType::Float(float) => TyKind::Float(match float {
489 hir_def::builtin_type::BuiltinFloat::F16 => rustc_type_ir::FloatTy::F16,
490 hir_def::builtin_type::BuiltinFloat::F32 => rustc_type_ir::FloatTy::F32,
491 hir_def::builtin_type::BuiltinFloat::F64 => rustc_type_ir::FloatTy::F64,
492 hir_def::builtin_type::BuiltinFloat::F128 => rustc_type_ir::FloatTy::F128,
493 }),
494 };
495 Ty::new(interner, kind)
496 }
497
498 pub fn as_builtin(self) -> Option<hir_def::builtin_type::BuiltinType> {
499 let builtin = match self.kind() {
500 TyKind::Char => hir_def::builtin_type::BuiltinType::Char,
501 TyKind::Bool => hir_def::builtin_type::BuiltinType::Bool,
502 TyKind::Str => hir_def::builtin_type::BuiltinType::Str,
503 TyKind::Int(int) => hir_def::builtin_type::BuiltinType::Int(match int {
504 rustc_type_ir::IntTy::Isize => hir_def::builtin_type::BuiltinInt::Isize,
505 rustc_type_ir::IntTy::I8 => hir_def::builtin_type::BuiltinInt::I8,
506 rustc_type_ir::IntTy::I16 => hir_def::builtin_type::BuiltinInt::I16,
507 rustc_type_ir::IntTy::I32 => hir_def::builtin_type::BuiltinInt::I32,
508 rustc_type_ir::IntTy::I64 => hir_def::builtin_type::BuiltinInt::I64,
509 rustc_type_ir::IntTy::I128 => hir_def::builtin_type::BuiltinInt::I128,
510 }),
511 TyKind::Uint(uint) => hir_def::builtin_type::BuiltinType::Uint(match uint {
512 rustc_type_ir::UintTy::Usize => hir_def::builtin_type::BuiltinUint::Usize,
513 rustc_type_ir::UintTy::U8 => hir_def::builtin_type::BuiltinUint::U8,
514 rustc_type_ir::UintTy::U16 => hir_def::builtin_type::BuiltinUint::U16,
515 rustc_type_ir::UintTy::U32 => hir_def::builtin_type::BuiltinUint::U32,
516 rustc_type_ir::UintTy::U64 => hir_def::builtin_type::BuiltinUint::U64,
517 rustc_type_ir::UintTy::U128 => hir_def::builtin_type::BuiltinUint::U128,
518 }),
519 TyKind::Float(float) => hir_def::builtin_type::BuiltinType::Float(match float {
520 rustc_type_ir::FloatTy::F16 => hir_def::builtin_type::BuiltinFloat::F16,
521 rustc_type_ir::FloatTy::F32 => hir_def::builtin_type::BuiltinFloat::F32,
522 rustc_type_ir::FloatTy::F64 => hir_def::builtin_type::BuiltinFloat::F64,
523 rustc_type_ir::FloatTy::F128 => hir_def::builtin_type::BuiltinFloat::F128,
524 }),
525 _ => return None,
526 };
527 Some(builtin)
528 }
529
530 // FIXME: Should this be here?
531 pub fn impl_trait_bounds(self, db: &'db dyn HirDatabase) -> Option<Vec<Clause<'db>>> {
532 let interner = DbInterner::new_with(db, None, None);
533
534 match self.kind() {
535 TyKind::Alias(AliasTyKind::Opaque, opaque_ty) => {
536 match db.lookup_intern_impl_trait_id(opaque_ty.def_id.expect_opaque_ty()) {
537 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
538 db.return_type_impl_traits_ns(func).map(|it| {
539 let data = (*it).as_ref().map_bound(|rpit| {
540 &rpit.impl_traits[idx.to_nextsolver(interner)].predicates
541 });
542 data.iter_instantiated_copied(interner, opaque_ty.args.as_slice())
543 .collect()
544 })
545 }
546 ImplTraitId::TypeAliasImplTrait(alias, idx) => {
547 db.type_alias_impl_traits_ns(alias).map(|it| {
548 let data = (*it).as_ref().map_bound(|rpit| {
549 &rpit.impl_traits[idx.to_nextsolver(interner)].predicates
550 });
551 data.iter_instantiated_copied(interner, opaque_ty.args.as_slice())
552 .collect()
553 })
554 }
555 ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
556 let krate = def.module(db).krate();
557 if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
558 // This is only used by type walking.
559 // Parameters will be walked outside, and projection predicate is not used.
560 // So just provide the Future trait.
561 let impl_bound = TraitRef::new(
562 interner,
563 future_trait.into(),
564 GenericArgs::new_from_iter(interner, []),
565 )
566 .upcast(interner);
567 Some(vec![impl_bound])
568 } else {
569 None
570 }
571 }
572 }
573 }
574 TyKind::Param(param) => {
575 // FIXME: We shouldn't use `param.id` here.
576 let generic_params = db.generic_params(param.id.parent());
577 let param_data = &generic_params[param.id.local_id()];
578 match param_data {
579 TypeOrConstParamData::TypeParamData(p) => match p.provenance {
580 TypeParamProvenance::ArgumentImplTrait => {
581 let predicates = db
582 .generic_predicates_ns(param.id.parent())
583 .instantiate_identity()
584 .into_iter()
585 .flatten()
586 .filter(|wc| match wc.kind().skip_binder() {
587 ClauseKind::Trait(tr) => tr.self_ty() == self,
588 ClauseKind::Projection(pred) => pred.self_ty() == self,
589 ClauseKind::TypeOutlives(pred) => pred.0 == self,
590 _ => false,
591 })
592 .collect::<Vec<_>>();
593
594 Some(predicates)
595 }
596 _ => None,
597 },
598 _ => None,
599 }
600 }
601 _ => None,
602 }
603 }
604
605 /// FIXME: Get rid of this, it's not a good abstraction
606 pub fn equals_ctor(self, other: Ty<'db>) -> bool {
607 match (self.kind(), other.kind()) {
608 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt.def_id() == adt2.def_id(),
609 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_, _), TyKind::Array(_, _)) => {
610 true
611 }
612 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
613 (TyKind::Alias(_, alias, ..), TyKind::Alias(_, alias2)) => {
614 alias.def_id == alias2.def_id
615 }
616 (TyKind::Foreign(ty_id, ..), TyKind::Foreign(ty_id2, ..)) => ty_id == ty_id2,
617 (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
618 (TyKind::Ref(.., mutability), TyKind::Ref(.., mutability2))
619 | (TyKind::RawPtr(.., mutability), TyKind::RawPtr(.., mutability2)) => {
620 mutability == mutability2
621 }
622 (TyKind::FnPtr(sig, hdr), TyKind::FnPtr(sig2, hdr2)) => sig == sig2 && hdr == hdr2,
623 (TyKind::Tuple(tys), TyKind::Tuple(tys2)) => tys.len() == tys2.len(),
624 (TyKind::Str, TyKind::Str)
625 | (TyKind::Never, TyKind::Never)
626 | (TyKind::Char, TyKind::Char)
627 | (TyKind::Bool, TyKind::Bool) => true,
628 (TyKind::Int(int), TyKind::Int(int2)) => int == int2,
629 (TyKind::Float(float), TyKind::Float(float2)) => float == float2,
630 _ => false,
631 }
632 }
633}
634
635pub fn references_non_lt_error<'db, T: TypeVisitableExt<DbInterner<'db>>>(t: &T) -> bool {
636 t.references_error() && t.visit_with(&mut ReferencesNonLifetimeError).is_break()
375637}
376638
377639struct ReferencesNonLifetimeError;
......@@ -928,11 +1190,17 @@ impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> {
9281190
9291191interned_vec_db!(Tys, Ty);
9301192
1193impl<'db> Tys<'db> {
1194 pub fn inputs(&self) -> &[Ty<'db>] {
1195 self.as_slice().split_last().unwrap().1
1196 }
1197}
1198
9311199impl<'db> rustc_type_ir::inherent::Tys<DbInterner<'db>> for Tys<'db> {
9321200 fn inputs(self) -> <DbInterner<'db> as rustc_type_ir::Interner>::FnInputTys {
9331201 Tys::new_from_iter(
9341202 DbInterner::conjure(),
935 self.as_slice().split_last().unwrap().1.iter().cloned(),
1203 self.as_slice().split_last().unwrap().1.iter().copied(),
9361204 )
9371205 }
9381206
src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs+2-2
......@@ -413,7 +413,7 @@ pub(crate) fn for_trait_impls(
413413 let trait_module = trait_id.module(db);
414414 let type_module = match self_ty_fp {
415415 Some(TyFingerprint::Adt(adt_id)) => Some(adt_id.module(db)),
416 Some(TyFingerprint::ForeignType(type_id)) => Some(from_foreign_def_id(type_id).module(db)),
416 Some(TyFingerprint::ForeignType(type_id)) => Some(type_id.module(db)),
417417 Some(TyFingerprint::Dyn(trait_id)) => Some(trait_id.module(db)),
418418 _ => None,
419419 };
......@@ -486,7 +486,7 @@ pub fn sizedness_constraint_for_ty<'db>(
486486
487487 Tuple(tys) => tys
488488 .into_iter()
489 .last()
489 .next_back()
490490 .and_then(|ty| sizedness_constraint_for_ty(interner, sizedness, ty)),
491491
492492 Adt(adt, args) => {
src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs+2-3
......@@ -10,7 +10,7 @@ use base_db::{
1010use hir_def::{ModuleId, db::DefDatabase, nameres::crate_def_map};
1111use hir_expand::EditionedFileId;
1212use rustc_hash::FxHashMap;
13use salsa::{AsDynDatabase, Durability};
13use salsa::Durability;
1414use span::FileId;
1515use syntax::TextRange;
1616use test_utils::extract_annotations;
......@@ -191,8 +191,7 @@ impl TestDB {
191191 // This is pretty horrible, but `Debug` is the only way to inspect
192192 // QueryDescriptor at the moment.
193193 salsa::EventKind::WillExecute { database_key } => {
194 let ingredient = self
195 .as_dyn_database()
194 let ingredient = (self as &dyn salsa::Database)
196195 .ingredient_debug_name(database_key.ingredient_index());
197196 Some(ingredient.to_string())
198197 }
src/tools/rust-analyzer/crates/hir-ty/src/tests.rs+281-275
......@@ -36,10 +36,11 @@ use test_fixture::WithFixture;
3636use triomphe::Arc;
3737
3838use crate::{
39 InferenceResult, Ty,
39 InferenceResult,
4040 db::HirDatabase,
4141 display::{DisplayTarget, HirDisplay},
4242 infer::{Adjustment, TypeMismatch},
43 next_solver::Ty,
4344 setup_tracing,
4445 test_db::TestDB,
4546};
......@@ -78,172 +79,172 @@ fn check_impl(
7879 let _tracing = setup_tracing();
7980 let (db, files) = TestDB::with_many_files(ra_fixture);
8081
81 let mut had_annotations = false;
82 let mut mismatches = FxHashMap::default();
83 let mut types = FxHashMap::default();
84 let mut adjustments = FxHashMap::default();
85 for (file_id, annotations) in db.extract_annotations() {
86 for (range, expected) in annotations {
87 let file_range = FileRange { file_id, range };
88 if only_types {
89 types.insert(file_range, expected);
90 } else if expected.starts_with("type: ") {
91 types.insert(file_range, expected.trim_start_matches("type: ").to_owned());
92 } else if expected.starts_with("expected") {
93 mismatches.insert(file_range, expected);
94 } else if expected.starts_with("adjustments:") {
95 adjustments.insert(
96 file_range,
97 expected.trim_start_matches("adjustments:").trim().to_owned(),
98 );
99 } else {
100 panic!("unexpected annotation: {expected} @ {range:?}");
82 crate::attach_db(&db, || {
83 let mut had_annotations = false;
84 let mut mismatches = FxHashMap::default();
85 let mut types = FxHashMap::default();
86 let mut adjustments = FxHashMap::default();
87 for (file_id, annotations) in db.extract_annotations() {
88 for (range, expected) in annotations {
89 let file_range = FileRange { file_id, range };
90 if only_types {
91 types.insert(file_range, expected);
92 } else if expected.starts_with("type: ") {
93 types.insert(file_range, expected.trim_start_matches("type: ").to_owned());
94 } else if expected.starts_with("expected") {
95 mismatches.insert(file_range, expected);
96 } else if expected.starts_with("adjustments:") {
97 adjustments.insert(
98 file_range,
99 expected.trim_start_matches("adjustments:").trim().to_owned(),
100 );
101 } else {
102 panic!("unexpected annotation: {expected} @ {range:?}");
103 }
104 had_annotations = true;
101105 }
102 had_annotations = true;
103106 }
104 }
105 assert!(had_annotations || allow_none, "no `//^` annotations found");
106
107 let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
108 for file_id in files {
109 let module = db.module_for_file_opt(file_id.file_id(&db));
110 let module = match module {
111 Some(m) => m,
112 None => continue,
113 };
114 let def_map = module.def_map(&db);
115 visit_module(&db, def_map, module.local_id, &mut |it| {
116 let def = match it {
117 ModuleDefId::FunctionId(it) => it.into(),
118 ModuleDefId::EnumVariantId(it) => it.into(),
119 ModuleDefId::ConstId(it) => it.into(),
120 ModuleDefId::StaticId(it) => it.into(),
121 _ => return,
107 assert!(had_annotations || allow_none, "no `//^` annotations found");
108
109 let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
110 for file_id in files {
111 let module = db.module_for_file_opt(file_id.file_id(&db));
112 let module = match module {
113 Some(m) => m,
114 None => continue,
122115 };
123 defs.push((def, module.krate()))
124 });
125 }
126 defs.sort_by_key(|(def, _)| match def {
127 DefWithBodyId::FunctionId(it) => {
128 let loc = it.lookup(&db);
129 loc.source(&db).value.syntax().text_range().start()
130 }
131 DefWithBodyId::ConstId(it) => {
132 let loc = it.lookup(&db);
133 loc.source(&db).value.syntax().text_range().start()
134 }
135 DefWithBodyId::StaticId(it) => {
136 let loc = it.lookup(&db);
137 loc.source(&db).value.syntax().text_range().start()
138 }
139 DefWithBodyId::VariantId(it) => {
140 let loc = it.lookup(&db);
141 loc.source(&db).value.syntax().text_range().start()
116 let def_map = module.def_map(&db);
117 visit_module(&db, def_map, module.local_id, &mut |it| {
118 let def = match it {
119 ModuleDefId::FunctionId(it) => it.into(),
120 ModuleDefId::EnumVariantId(it) => it.into(),
121 ModuleDefId::ConstId(it) => it.into(),
122 ModuleDefId::StaticId(it) => it.into(),
123 _ => return,
124 };
125 defs.push((def, module.krate()))
126 });
142127 }
143 });
144 let mut unexpected_type_mismatches = String::new();
145 for (def, krate) in defs {
146 let display_target = DisplayTarget::from_crate(&db, krate);
147 let (body, body_source_map) = db.body_with_source_map(def);
148 let inference_result = db.infer(def);
149
150 for (pat, mut ty) in inference_result.type_of_pat.iter() {
151 if let Pat::Bind { id, .. } = body[pat] {
152 ty = &inference_result.type_of_binding[id];
128 defs.sort_by_key(|(def, _)| match def {
129 DefWithBodyId::FunctionId(it) => {
130 let loc = it.lookup(&db);
131 loc.source(&db).value.syntax().text_range().start()
153132 }
154 let node = match pat_node(&body_source_map, pat, &db) {
155 Some(value) => value,
156 None => continue,
157 };
158 let range = node.as_ref().original_file_range_rooted(&db);
159 if let Some(expected) = types.remove(&range) {
160 let actual = salsa::attach(&db, || {
161 if display_source {
133 DefWithBodyId::ConstId(it) => {
134 let loc = it.lookup(&db);
135 loc.source(&db).value.syntax().text_range().start()
136 }
137 DefWithBodyId::StaticId(it) => {
138 let loc = it.lookup(&db);
139 loc.source(&db).value.syntax().text_range().start()
140 }
141 DefWithBodyId::VariantId(it) => {
142 let loc = it.lookup(&db);
143 loc.source(&db).value.syntax().text_range().start()
144 }
145 });
146 let mut unexpected_type_mismatches = String::new();
147 for (def, krate) in defs {
148 let display_target = DisplayTarget::from_crate(&db, krate);
149 let (body, body_source_map) = db.body_with_source_map(def);
150 let inference_result = db.infer(def);
151
152 for (pat, mut ty) in inference_result.type_of_pat.iter() {
153 if let Pat::Bind { id, .. } = body[pat] {
154 ty = &inference_result.type_of_binding[id];
155 }
156 let node = match pat_node(&body_source_map, pat, &db) {
157 Some(value) => value,
158 None => continue,
159 };
160 let range = node.as_ref().original_file_range_rooted(&db);
161 if let Some(expected) = types.remove(&range) {
162 let actual = if display_source {
162163 ty.display_source_code(&db, def.module(&db), true).unwrap()
163164 } else {
164165 ty.display_test(&db, display_target).to_string()
165 }
166 });
167 assert_eq!(actual, expected, "type annotation differs at {:#?}", range.range);
166 };
167 assert_eq!(actual, expected, "type annotation differs at {:#?}", range.range);
168 }
168169 }
169 }
170170
171 for (expr, ty) in inference_result.type_of_expr.iter() {
172 let node = match expr_node(&body_source_map, expr, &db) {
173 Some(value) => value,
174 None => continue,
175 };
176 let range = node.as_ref().original_file_range_rooted(&db);
177 if let Some(expected) = types.remove(&range) {
178 let actual = salsa::attach(&db, || {
179 if display_source {
171 for (expr, ty) in inference_result.type_of_expr.iter() {
172 let node = match expr_node(&body_source_map, expr, &db) {
173 Some(value) => value,
174 None => continue,
175 };
176 let range = node.as_ref().original_file_range_rooted(&db);
177 if let Some(expected) = types.remove(&range) {
178 let actual = if display_source {
180179 ty.display_source_code(&db, def.module(&db), true).unwrap()
181180 } else {
182181 ty.display_test(&db, display_target).to_string()
183 }
184 });
185 assert_eq!(actual, expected, "type annotation differs at {:#?}", range.range);
186 }
187 if let Some(expected) = adjustments.remove(&range) {
188 let adjustments = inference_result
189 .expr_adjustments
190 .get(&expr)
191 .map_or_else(Default::default, |it| &**it);
192 assert_eq!(
193 expected,
194 adjustments
195 .iter()
196 .map(|Adjustment { kind, .. }| format!("{kind:?}"))
197 .join(", ")
198 );
182 };
183 assert_eq!(actual, expected, "type annotation differs at {:#?}", range.range);
184 }
185 if let Some(expected) = adjustments.remove(&range) {
186 let adjustments = inference_result
187 .expr_adjustments
188 .get(&expr)
189 .map_or_else(Default::default, |it| &**it);
190 assert_eq!(
191 expected,
192 adjustments
193 .iter()
194 .map(|Adjustment { kind, .. }| format!("{kind:?}"))
195 .join(", ")
196 );
197 }
199198 }
200 }
201199
202 for (expr_or_pat, mismatch) in inference_result.type_mismatches() {
203 let Some(node) = (match expr_or_pat {
204 hir_def::hir::ExprOrPatId::ExprId(expr) => expr_node(&body_source_map, expr, &db),
205 hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(&body_source_map, pat, &db),
206 }) else {
207 continue;
208 };
209 let range = node.as_ref().original_file_range_rooted(&db);
210 let actual = salsa::attach(&db, || {
211 format!(
200 for (expr_or_pat, mismatch) in inference_result.type_mismatches() {
201 let Some(node) = (match expr_or_pat {
202 hir_def::hir::ExprOrPatId::ExprId(expr) => {
203 expr_node(&body_source_map, expr, &db)
204 }
205 hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(&body_source_map, pat, &db),
206 }) else {
207 continue;
208 };
209 let range = node.as_ref().original_file_range_rooted(&db);
210 let actual = format!(
212211 "expected {}, got {}",
213212 mismatch.expected.display_test(&db, display_target),
214213 mismatch.actual.display_test(&db, display_target)
215 )
216 });
217 match mismatches.remove(&range) {
218 Some(annotation) => assert_eq!(actual, annotation),
219 None => format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual),
214 );
215 match mismatches.remove(&range) {
216 Some(annotation) => assert_eq!(actual, annotation),
217 None => {
218 format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual)
219 }
220 }
220221 }
221222 }
222 }
223223
224 let mut buf = String::new();
225 if !unexpected_type_mismatches.is_empty() {
226 format_to!(buf, "Unexpected type mismatches:\n{}", unexpected_type_mismatches);
227 }
228 if !mismatches.is_empty() {
229 format_to!(buf, "Unchecked mismatch annotations:\n");
230 for m in mismatches {
231 format_to!(buf, "{:?}: {}\n", m.0.range, m.1);
224 let mut buf = String::new();
225 if !unexpected_type_mismatches.is_empty() {
226 format_to!(buf, "Unexpected type mismatches:\n{}", unexpected_type_mismatches);
232227 }
233 }
234 if !types.is_empty() {
235 format_to!(buf, "Unchecked type annotations:\n");
236 for t in types {
237 format_to!(buf, "{:?}: type {}\n", t.0.range, t.1);
228 if !mismatches.is_empty() {
229 format_to!(buf, "Unchecked mismatch annotations:\n");
230 for m in mismatches {
231 format_to!(buf, "{:?}: {}\n", m.0.range, m.1);
232 }
238233 }
239 }
240 if !adjustments.is_empty() {
241 format_to!(buf, "Unchecked adjustments annotations:\n");
242 for t in adjustments {
243 format_to!(buf, "{:?}: type {:?}\n", t.0.range, t.1);
234 if !types.is_empty() {
235 format_to!(buf, "Unchecked type annotations:\n");
236 for t in types {
237 format_to!(buf, "{:?}: type {}\n", t.0.range, t.1);
238 }
244239 }
245 }
246 assert!(buf.is_empty(), "{}", buf);
240 if !adjustments.is_empty() {
241 format_to!(buf, "Unchecked adjustments annotations:\n");
242 for t in adjustments {
243 format_to!(buf, "{:?}: type {:?}\n", t.0.range, t.1);
244 }
245 }
246 assert!(buf.is_empty(), "{}", buf);
247 });
247248}
248249
249250fn expr_node(
......@@ -282,139 +283,140 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
282283 let _tracing = setup_tracing();
283284 let (db, file_id) = TestDB::with_single_file(content);
284285
285 let mut buf = String::new();
286
287 let mut infer_def = |inference_result: Arc<InferenceResult>,
288 body: Arc<Body>,
289 body_source_map: Arc<BodySourceMap>,
290 krate: Crate| {
291 let display_target = DisplayTarget::from_crate(&db, krate);
292 let mut types: Vec<(InFile<SyntaxNode>, &Ty)> = Vec::new();
293 let mut mismatches: Vec<(InFile<SyntaxNode>, &TypeMismatch)> = Vec::new();
294
295 if let Some(self_param) = body.self_param {
296 let ty = &inference_result.type_of_binding[self_param];
297 if let Some(syntax_ptr) = body_source_map.self_param_syntax() {
298 let root = db.parse_or_expand(syntax_ptr.file_id);
299 let node = syntax_ptr.map(|ptr| ptr.to_node(&root).syntax().clone());
300 types.push((node, ty));
286 crate::attach_db(&db, || {
287 let mut buf = String::new();
288
289 let mut infer_def = |inference_result: Arc<InferenceResult<'_>>,
290 body: Arc<Body>,
291 body_source_map: Arc<BodySourceMap>,
292 krate: Crate| {
293 let display_target = DisplayTarget::from_crate(&db, krate);
294 let mut types: Vec<(InFile<SyntaxNode>, &Ty<'_>)> = Vec::new();
295 let mut mismatches: Vec<(InFile<SyntaxNode>, &TypeMismatch<'_>)> = Vec::new();
296
297 if let Some(self_param) = body.self_param {
298 let ty = &inference_result.type_of_binding[self_param];
299 if let Some(syntax_ptr) = body_source_map.self_param_syntax() {
300 let root = db.parse_or_expand(syntax_ptr.file_id);
301 let node = syntax_ptr.map(|ptr| ptr.to_node(&root).syntax().clone());
302 types.push((node, ty));
303 }
301304 }
302 }
303305
304 for (pat, mut ty) in inference_result.type_of_pat.iter() {
305 if let Pat::Bind { id, .. } = body[pat] {
306 ty = &inference_result.type_of_binding[id];
307 }
308 let node = match body_source_map.pat_syntax(pat) {
309 Ok(sp) => {
310 let root = db.parse_or_expand(sp.file_id);
311 sp.map(|ptr| ptr.to_node(&root).syntax().clone())
306 for (pat, mut ty) in inference_result.type_of_pat.iter() {
307 if let Pat::Bind { id, .. } = body[pat] {
308 ty = &inference_result.type_of_binding[id];
309 }
310 let node = match body_source_map.pat_syntax(pat) {
311 Ok(sp) => {
312 let root = db.parse_or_expand(sp.file_id);
313 sp.map(|ptr| ptr.to_node(&root).syntax().clone())
314 }
315 Err(SyntheticSyntax) => continue,
316 };
317 types.push((node.clone(), ty));
318 if let Some(mismatch) = inference_result.type_mismatch_for_pat(pat) {
319 mismatches.push((node, mismatch));
312320 }
313 Err(SyntheticSyntax) => continue,
314 };
315 types.push((node.clone(), ty));
316 if let Some(mismatch) = inference_result.type_mismatch_for_pat(pat) {
317 mismatches.push((node, mismatch));
318321 }
319 }
320322
321 for (expr, ty) in inference_result.type_of_expr.iter() {
322 let node = match body_source_map.expr_syntax(expr) {
323 Ok(sp) => {
324 let root = db.parse_or_expand(sp.file_id);
325 sp.map(|ptr| ptr.to_node(&root).syntax().clone())
323 for (expr, ty) in inference_result.type_of_expr.iter() {
324 let node = match body_source_map.expr_syntax(expr) {
325 Ok(sp) => {
326 let root = db.parse_or_expand(sp.file_id);
327 sp.map(|ptr| ptr.to_node(&root).syntax().clone())
328 }
329 Err(SyntheticSyntax) => continue,
330 };
331 types.push((node.clone(), ty));
332 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) {
333 mismatches.push((node, mismatch));
326334 }
327 Err(SyntheticSyntax) => continue,
328 };
329 types.push((node.clone(), ty));
330 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) {
331 mismatches.push((node, mismatch));
332335 }
333 }
334336
335 // sort ranges for consistency
336 types.sort_by_key(|(node, _)| {
337 let range = node.value.text_range();
338 (range.start(), range.end())
339 });
340 for (node, ty) in &types {
341 let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.value.clone()) {
342 (self_param.name().unwrap().syntax().text_range(), "self".to_owned())
343 } else {
344 (node.value.text_range(), node.value.text().to_string().replace('\n', " "))
345 };
346 let macro_prefix = if node.file_id != file_id { "!" } else { "" };
347 format_to!(
348 buf,
349 "{}{:?} '{}': {}\n",
350 macro_prefix,
351 range,
352 ellipsize(text, 15),
353 ty.display_test(&db, display_target)
354 );
355 }
356 if include_mismatches {
357 mismatches.sort_by_key(|(node, _)| {
337 // sort ranges for consistency
338 types.sort_by_key(|(node, _)| {
358339 let range = node.value.text_range();
359340 (range.start(), range.end())
360341 });
361 for (src_ptr, mismatch) in &mismatches {
362 let range = src_ptr.value.text_range();
363 let macro_prefix = if src_ptr.file_id != file_id { "!" } else { "" };
342 for (node, ty) in &types {
343 let (range, text) =
344 if let Some(self_param) = ast::SelfParam::cast(node.value.clone()) {
345 (self_param.name().unwrap().syntax().text_range(), "self".to_owned())
346 } else {
347 (node.value.text_range(), node.value.text().to_string().replace('\n', " "))
348 };
349 let macro_prefix = if node.file_id != file_id { "!" } else { "" };
364350 format_to!(
365351 buf,
366 "{}{:?}: expected {}, got {}\n",
352 "{}{:?} '{}': {}\n",
367353 macro_prefix,
368354 range,
369 mismatch.expected.display_test(&db, display_target),
370 mismatch.actual.display_test(&db, display_target),
355 ellipsize(text, 15),
356 ty.display_test(&db, display_target)
371357 );
372358 }
373 }
374 };
375
376 let module = db.module_for_file(file_id.file_id(&db));
377 let def_map = module.def_map(&db);
378
379 let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
380 visit_module(&db, def_map, module.local_id, &mut |it| {
381 let def = match it {
382 ModuleDefId::FunctionId(it) => it.into(),
383 ModuleDefId::EnumVariantId(it) => it.into(),
384 ModuleDefId::ConstId(it) => it.into(),
385 ModuleDefId::StaticId(it) => it.into(),
386 _ => return,
359 if include_mismatches {
360 mismatches.sort_by_key(|(node, _)| {
361 let range = node.value.text_range();
362 (range.start(), range.end())
363 });
364 for (src_ptr, mismatch) in &mismatches {
365 let range = src_ptr.value.text_range();
366 let macro_prefix = if src_ptr.file_id != file_id { "!" } else { "" };
367 format_to!(
368 buf,
369 "{}{:?}: expected {}, got {}\n",
370 macro_prefix,
371 range,
372 mismatch.expected.display_test(&db, display_target),
373 mismatch.actual.display_test(&db, display_target),
374 );
375 }
376 }
387377 };
388 defs.push((def, module.krate()))
389 });
390 defs.sort_by_key(|(def, _)| match def {
391 DefWithBodyId::FunctionId(it) => {
392 let loc = it.lookup(&db);
393 loc.source(&db).value.syntax().text_range().start()
394 }
395 DefWithBodyId::ConstId(it) => {
396 let loc = it.lookup(&db);
397 loc.source(&db).value.syntax().text_range().start()
398 }
399 DefWithBodyId::StaticId(it) => {
400 let loc = it.lookup(&db);
401 loc.source(&db).value.syntax().text_range().start()
402 }
403 DefWithBodyId::VariantId(it) => {
404 let loc = it.lookup(&db);
405 loc.source(&db).value.syntax().text_range().start()
406 }
407 });
408 for (def, krate) in defs {
409 let (body, source_map) = db.body_with_source_map(def);
410 let infer = db.infer(def);
411 salsa::attach(&db, || {
378
379 let module = db.module_for_file(file_id.file_id(&db));
380 let def_map = module.def_map(&db);
381
382 let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
383 visit_module(&db, def_map, module.local_id, &mut |it| {
384 let def = match it {
385 ModuleDefId::FunctionId(it) => it.into(),
386 ModuleDefId::EnumVariantId(it) => it.into(),
387 ModuleDefId::ConstId(it) => it.into(),
388 ModuleDefId::StaticId(it) => it.into(),
389 _ => return,
390 };
391 defs.push((def, module.krate()))
392 });
393 defs.sort_by_key(|(def, _)| match def {
394 DefWithBodyId::FunctionId(it) => {
395 let loc = it.lookup(&db);
396 loc.source(&db).value.syntax().text_range().start()
397 }
398 DefWithBodyId::ConstId(it) => {
399 let loc = it.lookup(&db);
400 loc.source(&db).value.syntax().text_range().start()
401 }
402 DefWithBodyId::StaticId(it) => {
403 let loc = it.lookup(&db);
404 loc.source(&db).value.syntax().text_range().start()
405 }
406 DefWithBodyId::VariantId(it) => {
407 let loc = it.lookup(&db);
408 loc.source(&db).value.syntax().text_range().start()
409 }
410 });
411 for (def, krate) in defs {
412 let (body, source_map) = db.body_with_source_map(def);
413 let infer = db.infer(def);
412414 infer_def(infer, body, source_map, krate);
413 })
414 }
415 }
415416
416 buf.truncate(buf.trim_end().len());
417 buf
417 buf.truncate(buf.trim_end().len());
418 buf
419 })
418420}
419421
420422pub(crate) fn visit_module(
......@@ -556,15 +558,17 @@ fn salsa_bug() {
556558 ",
557559 );
558560
559 let module = db.module_for_file(pos.file_id.file_id(&db));
560 let crate_def_map = module.def_map(&db);
561 visit_module(&db, crate_def_map, module.local_id, &mut |def| {
562 db.infer(match def {
563 ModuleDefId::FunctionId(it) => it.into(),
564 ModuleDefId::EnumVariantId(it) => it.into(),
565 ModuleDefId::ConstId(it) => it.into(),
566 ModuleDefId::StaticId(it) => it.into(),
567 _ => return,
561 crate::attach_db(&db, || {
562 let module = db.module_for_file(pos.file_id.file_id(&db));
563 let crate_def_map = module.def_map(&db);
564 visit_module(&db, crate_def_map, module.local_id, &mut |def| {
565 db.infer(match def {
566 ModuleDefId::FunctionId(it) => it.into(),
567 ModuleDefId::EnumVariantId(it) => it.into(),
568 ModuleDefId::ConstId(it) => it.into(),
569 ModuleDefId::StaticId(it) => it.into(),
570 _ => return,
571 });
568572 });
569573 });
570574
......@@ -595,15 +599,17 @@ fn salsa_bug() {
595599
596600 db.set_file_text(pos.file_id.file_id(&db), new_text);
597601
598 let module = db.module_for_file(pos.file_id.file_id(&db));
599 let crate_def_map = module.def_map(&db);
600 visit_module(&db, crate_def_map, module.local_id, &mut |def| {
601 db.infer(match def {
602 ModuleDefId::FunctionId(it) => it.into(),
603 ModuleDefId::EnumVariantId(it) => it.into(),
604 ModuleDefId::ConstId(it) => it.into(),
605 ModuleDefId::StaticId(it) => it.into(),
606 _ => return,
602 crate::attach_db(&db, || {
603 let module = db.module_for_file(pos.file_id.file_id(&db));
604 let crate_def_map = module.def_map(&db);
605 visit_module(&db, crate_def_map, module.local_id, &mut |def| {
606 db.infer(match def {
607 ModuleDefId::FunctionId(it) => it.into(),
608 ModuleDefId::EnumVariantId(it) => it.into(),
609 ModuleDefId::ConstId(it) => it.into(),
610 ModuleDefId::StaticId(it) => it.into(),
611 _ => return,
612 });
607613 });
608 });
614 })
609615}
src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs+101-90
......@@ -2,111 +2,121 @@ use expect_test::{Expect, expect};
22use hir_def::db::DefDatabase;
33use hir_expand::{HirFileId, files::InFileWrapper};
44use itertools::Itertools;
5use salsa::plumbing::FromId;
65use span::TextRange;
76use syntax::{AstNode, AstPtr};
87use test_fixture::WithFixture;
98
10use crate::db::{HirDatabase, InternedClosureId};
11use crate::display::{DisplayTarget, HirDisplay};
12use crate::mir::MirSpan;
13use crate::test_db::TestDB;
9use crate::{
10 db::HirDatabase,
11 display::{DisplayTarget, HirDisplay},
12 mir::MirSpan,
13 test_db::TestDB,
14};
1415
1516use super::{setup_tracing, visit_module};
1617
1718fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
1819 let _tracing = setup_tracing();
1920 let (db, file_id) = TestDB::with_single_file(ra_fixture);
20 let module = db.module_for_file(file_id.file_id(&db));
21 let def_map = module.def_map(&db);
21 crate::attach_db(&db, || {
22 let module = db.module_for_file(file_id.file_id(&db));
23 let def_map = module.def_map(&db);
2224
23 let mut defs = Vec::new();
24 visit_module(&db, def_map, module.local_id, &mut |it| defs.push(it));
25 let mut defs = Vec::new();
26 visit_module(&db, def_map, module.local_id, &mut |it| defs.push(it));
2527
26 let mut captures_info = Vec::new();
27 for def in defs {
28 let def = match def {
29 hir_def::ModuleDefId::FunctionId(it) => it.into(),
30 hir_def::ModuleDefId::EnumVariantId(it) => it.into(),
31 hir_def::ModuleDefId::ConstId(it) => it.into(),
32 hir_def::ModuleDefId::StaticId(it) => it.into(),
33 _ => continue,
34 };
35 let infer = db.infer(def);
36 let db = &db;
37 captures_info.extend(infer.closure_info.iter().flat_map(|(closure_id, (captures, _))| {
38 let closure = db.lookup_intern_closure(InternedClosureId::from_id(closure_id.0));
39 let source_map = db.body_with_source_map(closure.0).1;
40 let closure_text_range = source_map
41 .expr_syntax(closure.1)
42 .expect("failed to map closure to SyntaxNode")
43 .value
44 .text_range();
45 captures.iter().map(move |capture| {
46 fn text_range<N: AstNode>(
47 db: &TestDB,
48 syntax: InFileWrapper<HirFileId, AstPtr<N>>,
49 ) -> TextRange {
50 let root = syntax.file_syntax(db);
51 syntax.value.to_node(&root).syntax().text_range()
52 }
53
54 // FIXME: Deduplicate this with hir::Local::sources().
55 let (body, source_map) = db.body_with_source_map(closure.0);
56 let local_text_range = match body.self_param.zip(source_map.self_param_syntax()) {
57 Some((param, source)) if param == capture.local() => {
58 format!("{:?}", text_range(db, source))
59 }
60 _ => source_map
61 .patterns_for_binding(capture.local())
62 .iter()
63 .map(|&definition| {
64 text_range(db, source_map.pat_syntax(definition).unwrap())
65 })
66 .map(|it| format!("{it:?}"))
67 .join(", "),
68 };
69 let place = capture.display_place(closure.0, db);
70 let capture_ty = salsa::attach(db, || {
71 capture
72 .ty
73 .skip_binders()
74 .display_test(db, DisplayTarget::from_crate(db, module.krate()))
75 .to_string()
76 });
77 let spans = capture
78 .spans()
79 .iter()
80 .flat_map(|span| match *span {
81 MirSpan::ExprId(expr) => {
82 vec![text_range(db, source_map.expr_syntax(expr).unwrap())]
83 }
84 MirSpan::PatId(pat) => {
85 vec![text_range(db, source_map.pat_syntax(pat).unwrap())]
28 let mut captures_info = Vec::new();
29 for def in defs {
30 let def = match def {
31 hir_def::ModuleDefId::FunctionId(it) => it.into(),
32 hir_def::ModuleDefId::EnumVariantId(it) => it.into(),
33 hir_def::ModuleDefId::ConstId(it) => it.into(),
34 hir_def::ModuleDefId::StaticId(it) => it.into(),
35 _ => continue,
36 };
37 let infer = db.infer(def);
38 let db = &db;
39 captures_info.extend(infer.closure_info.iter().flat_map(
40 |(closure_id, (captures, _))| {
41 let closure = db.lookup_intern_closure(*closure_id);
42 let source_map = db.body_with_source_map(closure.0).1;
43 let closure_text_range = source_map
44 .expr_syntax(closure.1)
45 .expect("failed to map closure to SyntaxNode")
46 .value
47 .text_range();
48 captures.iter().map(move |capture| {
49 fn text_range<N: AstNode>(
50 db: &TestDB,
51 syntax: InFileWrapper<HirFileId, AstPtr<N>>,
52 ) -> TextRange {
53 let root = syntax.file_syntax(db);
54 syntax.value.to_node(&root).syntax().text_range()
8655 }
87 MirSpan::BindingId(binding) => source_map
88 .patterns_for_binding(binding)
56
57 // FIXME: Deduplicate this with hir::Local::sources().
58 let (body, source_map) = db.body_with_source_map(closure.0);
59 let local_text_range =
60 match body.self_param.zip(source_map.self_param_syntax()) {
61 Some((param, source)) if param == capture.local() => {
62 format!("{:?}", text_range(db, source))
63 }
64 _ => source_map
65 .patterns_for_binding(capture.local())
66 .iter()
67 .map(|&definition| {
68 text_range(db, source_map.pat_syntax(definition).unwrap())
69 })
70 .map(|it| format!("{it:?}"))
71 .join(", "),
72 };
73 let place = capture.display_place(closure.0, db);
74 let capture_ty = capture
75 .ty
76 .skip_binder()
77 .display_test(db, DisplayTarget::from_crate(db, module.krate()))
78 .to_string();
79 let spans = capture
80 .spans()
8981 .iter()
90 .map(|pat| text_range(db, source_map.pat_syntax(*pat).unwrap()))
91 .collect(),
92 MirSpan::SelfParam => {
93 vec![text_range(db, source_map.self_param_syntax().unwrap())]
94 }
95 MirSpan::Unknown => Vec::new(),
96 })
97 .sorted_by_key(|it| it.start())
98 .map(|it| format!("{it:?}"))
99 .join(",");
82 .flat_map(|span| match *span {
83 MirSpan::ExprId(expr) => {
84 vec![text_range(db, source_map.expr_syntax(expr).unwrap())]
85 }
86 MirSpan::PatId(pat) => {
87 vec![text_range(db, source_map.pat_syntax(pat).unwrap())]
88 }
89 MirSpan::BindingId(binding) => source_map
90 .patterns_for_binding(binding)
91 .iter()
92 .map(|pat| text_range(db, source_map.pat_syntax(*pat).unwrap()))
93 .collect(),
94 MirSpan::SelfParam => {
95 vec![text_range(db, source_map.self_param_syntax().unwrap())]
96 }
97 MirSpan::Unknown => Vec::new(),
98 })
99 .sorted_by_key(|it| it.start())
100 .map(|it| format!("{it:?}"))
101 .join(",");
100102
101 (closure_text_range, local_text_range, spans, place, capture_ty, capture.kind())
102 })
103 }));
104 }
105 captures_info.sort_unstable_by_key(|(closure_text_range, local_text_range, ..)| {
106 (closure_text_range.start(), local_text_range.clone())
107 });
103 (
104 closure_text_range,
105 local_text_range,
106 spans,
107 place,
108 capture_ty,
109 capture.kind(),
110 )
111 })
112 },
113 ));
114 }
115 captures_info.sort_unstable_by_key(|(closure_text_range, local_text_range, ..)| {
116 (closure_text_range.start(), local_text_range.clone())
117 });
108118
109 let rendered = captures_info
119 let rendered = captures_info
110120 .iter()
111121 .map(|(closure_text_range, local_text_range, spans, place, capture_ty, capture_kind)| {
112122 format!(
......@@ -115,7 +125,8 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec
115125 })
116126 .join("\n");
117127
118 expect.assert_eq(&rendered);
128 expect.assert_eq(&rendered);
129 })
119130}
120131
121132#[test]
src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs+8-8
......@@ -49,7 +49,7 @@ fn let_stmt_coerce() {
4949//- minicore: coerce_unsized
5050fn test() {
5151 let x: &[isize] = &[1];
52 // ^^^^ adjustments: Deref(None), Borrow(Ref('?1, Not)), Pointer(Unsize)
52 // ^^^^ adjustments: Deref(None), Borrow(Ref('?2, Not)), Pointer(Unsize)
5353 let x: *const [isize] = &[1];
5454 // ^^^^ adjustments: Deref(None), Borrow(RawPtr(Not)), Pointer(Unsize)
5555}
......@@ -268,7 +268,7 @@ fn takes_ref_str(x: &str) {}
268268fn returns_string() -> String { loop {} }
269269fn test() {
270270 takes_ref_str(&{ returns_string() });
271 // ^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(None), Deref(Some(OverloadedDeref(Some(Not)))), Borrow(Ref('{error}, Not))
271 // ^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(None), Deref(Some(OverloadedDeref(Some(Not)))), Borrow(Ref('{region error}, Not))
272272}
273273"#,
274274 );
......@@ -567,7 +567,7 @@ trait Foo {}
567567fn test(f: impl Foo, g: &(impl Foo + ?Sized)) {
568568 let _: &dyn Foo = &f;
569569 let _: &dyn Foo = g;
570 //^ expected &'? (dyn Foo + '?), got &'? impl Foo + ?Sized
570 //^ expected &'? (dyn Foo + 'static), got &'? impl Foo + ?Sized
571571}
572572 "#,
573573 );
......@@ -833,11 +833,11 @@ struct V<T> { t: T }
833833fn main() {
834834 let a: V<&dyn Tr>;
835835 (a,) = V { t: &S };
836 //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,)
836 //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + 'static)>,)
837837
838838 let mut a: V<&dyn Tr> = V { t: &S };
839839 (a,) = V { t: &S };
840 //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,)
840 //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + 'static)>,)
841841}
842842 "#,
843843 );
......@@ -854,8 +854,8 @@ impl core::cmp::PartialEq for Struct {
854854}
855855fn test() {
856856 Struct == Struct;
857 // ^^^^^^ adjustments: Borrow(Ref('{error}, Not))
858 // ^^^^^^ adjustments: Borrow(Ref('{error}, Not))
857 // ^^^^^^ adjustments: Borrow(Ref('{region error}, Not))
858 // ^^^^^^ adjustments: Borrow(Ref('{region error}, Not))
859859}",
860860 );
861861}
......@@ -871,7 +871,7 @@ impl core::ops::AddAssign for Struct {
871871}
872872fn test() {
873873 Struct += Struct;
874 // ^^^^^^ adjustments: Borrow(Ref('{error}, Mut))
874 // ^^^^^^ adjustments: Borrow(Ref('{region error}, Mut))
875875 // ^^^^^^ adjustments:
876876}",
877877 );
src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs+4-4
......@@ -67,11 +67,11 @@ trait B: A {}
6767
6868fn test<'a>(
6969 _: &(dyn A<Assoc = ()> + Send),
70 //^ &(dyn A<Assoc = ()> + Send)
70 //^ &(dyn A<Assoc = ()> + Send + 'static)
7171 _: &'a (dyn Send + A<Assoc = ()>),
72 //^ &'a (dyn A<Assoc = ()> + Send)
72 //^ &'a (dyn A<Assoc = ()> + Send + 'static)
7373 _: &dyn B<Assoc = ()>,
74 //^ &(dyn B<Assoc = ()>)
74 //^ &(dyn B<Assoc = ()> + 'static)
7575) {}
7676 "#,
7777 );
......@@ -85,7 +85,7 @@ fn render_dyn_for_ty() {
8585trait Foo<'a> {}
8686
8787fn foo(foo: &dyn for<'a> Foo<'a>) {}
88 // ^^^ &dyn Foo<'?>
88 // ^^^ &(dyn Foo<'?> + 'static)
8989"#,
9090 );
9191}
src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs+12-11
......@@ -44,7 +44,7 @@ fn foo() -> i32 {
4444 "body_shim",
4545 "body_with_source_map_shim",
4646 "trait_environment_shim",
47 "return_type_impl_traits_shim",
47 "return_type_impl_traits_ns_shim",
4848 "expr_scopes_shim",
4949 "lang_item",
5050 "crate_lang_items",
......@@ -131,7 +131,7 @@ fn baz() -> i32 {
131131 "body_shim",
132132 "body_with_source_map_shim",
133133 "trait_environment_shim",
134 "return_type_impl_traits_shim",
134 "return_type_impl_traits_ns_shim",
135135 "expr_scopes_shim",
136136 "lang_item",
137137 "crate_lang_items",
......@@ -143,7 +143,7 @@ fn baz() -> i32 {
143143 "body_shim",
144144 "body_with_source_map_shim",
145145 "trait_environment_shim",
146 "return_type_impl_traits_shim",
146 "return_type_impl_traits_ns_shim",
147147 "expr_scopes_shim",
148148 "infer_shim",
149149 "function_signature_shim",
......@@ -151,7 +151,7 @@ fn baz() -> i32 {
151151 "body_shim",
152152 "body_with_source_map_shim",
153153 "trait_environment_shim",
154 "return_type_impl_traits_shim",
154 "return_type_impl_traits_ns_shim",
155155 "expr_scopes_shim",
156156 ]
157157 "#]],
......@@ -586,7 +586,7 @@ fn main() {
586586 "attrs_shim",
587587 "attrs_shim",
588588 "generic_predicates_ns_shim",
589 "return_type_impl_traits_shim",
589 "return_type_impl_traits_ns_shim",
590590 "infer_shim",
591591 "function_signature_shim",
592592 "function_signature_with_source_map_shim",
......@@ -594,7 +594,7 @@ fn main() {
594594 "expr_scopes_shim",
595595 "struct_signature_shim",
596596 "struct_signature_with_source_map_shim",
597 "generic_predicates_shim",
597 "generic_predicates_ns_shim",
598598 "value_ty_shim",
599599 "VariantFields::firewall_",
600600 "VariantFields::query_",
......@@ -610,7 +610,7 @@ fn main() {
610610 "impl_self_ty_with_diagnostics_shim",
611611 "generic_predicates_ns_shim",
612612 "value_ty_shim",
613 "generic_predicates_shim",
613 "generic_predicates_ns_shim",
614614 ]
615615 "#]],
616616 );
......@@ -683,11 +683,12 @@ fn main() {
683683 "attrs_shim",
684684 "attrs_shim",
685685 "generic_predicates_ns_shim",
686 "return_type_impl_traits_shim",
686 "return_type_impl_traits_ns_shim",
687687 "infer_shim",
688688 "function_signature_with_source_map_shim",
689689 "expr_scopes_shim",
690690 "struct_signature_with_source_map_shim",
691 "generic_predicates_ns_shim",
691692 "VariantFields::query_",
692693 "inherent_impls_in_crate_shim",
693694 "impl_signature_with_source_map_shim",
......@@ -697,7 +698,7 @@ fn main() {
697698 "impl_trait_with_diagnostics_shim",
698699 "impl_self_ty_with_diagnostics_shim",
699700 "generic_predicates_ns_shim",
700 "generic_predicates_shim",
701 "generic_predicates_ns_shim",
701702 ]
702703 "#]],
703704 );
......@@ -709,8 +710,8 @@ fn execute_assert_events(
709710 required: &[(&str, usize)],
710711 expect: Expect,
711712) {
712 let (executed, events) = db.log_executed(f);
713 salsa::attach(db, || {
713 crate::attach_db(db, || {
714 let (executed, events) = db.log_executed(f);
714715 for (event, count) in required {
715716 let n = executed.iter().filter(|it| it.contains(event)).count();
716717 assert_eq!(
src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs+4-4
......@@ -199,8 +199,8 @@ fn expr_macro_def_expanded_in_various_places() {
199199 100..119 'for _ ...!() {}': fn into_iter<isize>(isize) -> <isize as IntoIterator>::IntoIter
200200 100..119 'for _ ...!() {}': <isize as IntoIterator>::IntoIter
201201 100..119 'for _ ...!() {}': !
202 100..119 'for _ ...!() {}': <isize as IntoIterator>::IntoIter
203 100..119 'for _ ...!() {}': &'? mut <isize as IntoIterator>::IntoIter
202 100..119 'for _ ...!() {}': {unknown}
203 100..119 'for _ ...!() {}': &'? mut {unknown}
204204 100..119 'for _ ...!() {}': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
205205 100..119 'for _ ...!() {}': Option<<{unknown} as Iterator>::Item>
206206 100..119 'for _ ...!() {}': ()
......@@ -293,8 +293,8 @@ fn expr_macro_rules_expanded_in_various_places() {
293293 114..133 'for _ ...!() {}': fn into_iter<isize>(isize) -> <isize as IntoIterator>::IntoIter
294294 114..133 'for _ ...!() {}': <isize as IntoIterator>::IntoIter
295295 114..133 'for _ ...!() {}': !
296 114..133 'for _ ...!() {}': <isize as IntoIterator>::IntoIter
297 114..133 'for _ ...!() {}': &'? mut <isize as IntoIterator>::IntoIter
296 114..133 'for _ ...!() {}': {unknown}
297 114..133 'for _ ...!() {}': &'? mut {unknown}
298298 114..133 'for _ ...!() {}': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
299299 114..133 'for _ ...!() {}': Option<<{unknown} as Iterator>::Item>
300300 114..133 'for _ ...!() {}': ()
src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs+3-3
......@@ -1157,9 +1157,9 @@ fn dyn_trait_super_trait_not_in_scope() {
11571157 51..55 'self': &'? Self
11581158 64..69 '{ 0 }': u32
11591159 66..67 '0': u32
1160 176..177 'd': &'? (dyn Trait + '?)
1160 176..177 'd': &'? (dyn Trait + 'static)
11611161 191..207 '{ ...o(); }': ()
1162 197..198 'd': &'? (dyn Trait + '?)
1162 197..198 'd': &'? (dyn Trait + 'static)
11631163 197..204 'd.foo()': u32
11641164 "#]],
11651165 );
......@@ -2050,7 +2050,7 @@ impl dyn Error + Send {
20502050 /// Attempts to downcast the box to a concrete type.
20512051 pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
20522052 let err: Box<dyn Error> = self;
2053 // ^^^^ expected Box<dyn Error + '?>, got Box<dyn Error + Send + 'static>
2053 // ^^^^ expected Box<dyn Error + 'static>, got Box<dyn Error + Send + 'static>
20542054 // FIXME, type mismatch should not occur
20552055 <dyn Error>::downcast(err).map_err(|_| loop {})
20562056 //^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + 'static>) -> Result<Box<{unknown}>, Box<dyn Error + 'static>>
src/tools/rust-analyzer/crates/hir-ty/src/tests/opaque_types.rs+1
......@@ -31,6 +31,7 @@ fn test() {
3131}
3232
3333#[test]
34#[ignore = "FIXME(next-solver): This currently generates a type mismatch, need to switch opaque type handling to the solver"]
3435fn associated_type_impl_traits_complex() {
3536 check_types(
3637 r#"
src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs+4-4
......@@ -1257,8 +1257,8 @@ fn test() {
12571257 16..66 'for _ ... }': fn into_iter<()>(()) -> <() as IntoIterator>::IntoIter
12581258 16..66 'for _ ... }': <() as IntoIterator>::IntoIter
12591259 16..66 'for _ ... }': !
1260 16..66 'for _ ... }': <() as IntoIterator>::IntoIter
1261 16..66 'for _ ... }': &'? mut <() as IntoIterator>::IntoIter
1260 16..66 'for _ ... }': {unknown}
1261 16..66 'for _ ... }': &'? mut {unknown}
12621262 16..66 'for _ ... }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
12631263 16..66 'for _ ... }': Option<<{unknown} as Iterator>::Item>
12641264 16..66 'for _ ... }': ()
......@@ -2363,8 +2363,8 @@ fn test() {
23632363 108..125 '{ ... }': usize
23642364 118..119 'N': usize
23652365 139..157 '{ ...= N; }': ()
2366 149..150 '_': Foo<_>
2367 153..154 'N': Foo<_>
2366 149..150 '_': Foo<N>
2367 153..154 'N': Foo<N>
23682368 "#]],
23692369 );
23702370}
src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs+1-1
......@@ -84,7 +84,7 @@ fn test() -> i32 {
8484 307..359 'core::...n Foo)': DynMetadata<dyn Foo + '?>
8585 327..328 '0': usize
8686 327..340 '0 as *const F': *const F
87 327..358 '0 as *...yn Foo': *const (dyn Foo + '?)
87 327..358 '0 as *...yn Foo': *const (dyn Foo + 'static)
8888 370..371 'f': F
8989 374..378 'F {}': F
9090 388..395 'fat_ptr': *const (dyn Foo + '?)
src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs+1-34
......@@ -2743,7 +2743,7 @@ impl B for Astruct {}
27432743 725..754 '#[rust...1i32])': Box<[i32; 1], Global>
27442744 747..753 '[1i32]': [i32; 1]
27452745 748..752 '1i32': i32
2746 765..766 'v': Vec<Box<dyn B + '?, Global>, Global>
2746 765..766 'v': Vec<Box<dyn B + 'static, Global>, Global>
27472747 786..803 '<[_]> ...to_vec': fn into_vec<Box<dyn B + '?, Global>, Global>(Box<[Box<dyn B + '?, Global>], Global>) -> Vec<Box<dyn B + '?, Global>, Global>
27482748 786..860 '<[_]> ...ct)]))': Vec<Box<dyn B + '?, Global>, Global>
27492749 804..859 '#[rust...uct)])': Box<[Box<dyn B + '?, Global>; 1], Global>
......@@ -3692,39 +3692,6 @@ fn main() {
36923692 );
36933693}
36943694
3695#[test]
3696fn infer_bad_lang_item() {
3697 check_infer(
3698 r#"
3699#[lang="eq"]
3700pub trait Eq {
3701 fn eq(&self, ) -> bool;
3702
3703}
3704
3705#[lang="shr"]
3706pub trait Shr<RHS,Result> {
3707 fn shr(&self, rhs: &RHS) -> Result;
3708}
3709
3710fn test() -> bool {
3711 1 >> 1;
3712 1 == 1;
3713}
3714"#,
3715 expect![[r#"
3716 39..43 'self': &'? Self
3717 114..118 'self': &'? Self
3718 120..123 'rhs': &'? RHS
3719 163..190 '{ ...= 1; }': bool
3720 169..170 '1': i32
3721 169..175 '1 >> 1': {unknown}
3722 181..182 '1': i32
3723 181..187 '1 == 1': {unknown}
3724 "#]],
3725 );
3726}
3727
37283695#[test]
37293696fn macro_semitransparent_hygiene() {
37303697 check_types(
src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs+27-27
......@@ -1480,24 +1480,24 @@ fn test(x: Box<dyn Trait<u64>>, y: &dyn Trait<u64>) {
14801480 expect![[r#"
14811481 29..33 'self': &'? Self
14821482 54..58 'self': &'? Self
1483 206..208 '{}': Box<dyn Trait<u64> + '?>
1484 218..219 'x': Box<dyn Trait<u64> + '?>
1485 242..243 'y': &'? (dyn Trait<u64> + '?)
1483 206..208 '{}': Box<dyn Trait<u64> + 'static>
1484 218..219 'x': Box<dyn Trait<u64> + 'static>
1485 242..243 'y': &'? (dyn Trait<u64> + 'static)
14861486 262..379 '{ ...2(); }': ()
1487 268..269 'x': Box<dyn Trait<u64> + '?>
1488 275..276 'y': &'? (dyn Trait<u64> + '?)
1487 268..269 'x': Box<dyn Trait<u64> + 'static>
1488 275..276 'y': &'? (dyn Trait<u64> + 'static)
14891489 286..287 'z': Box<dyn Trait<u64> + '?>
14901490 290..293 'bar': fn bar() -> Box<dyn Trait<u64> + 'static>
14911491 290..295 'bar()': Box<dyn Trait<u64> + 'static>
1492 301..302 'x': Box<dyn Trait<u64> + '?>
1492 301..302 'x': Box<dyn Trait<u64> + 'static>
14931493 301..308 'x.foo()': u64
1494 314..315 'y': &'? (dyn Trait<u64> + '?)
1494 314..315 'y': &'? (dyn Trait<u64> + 'static)
14951495 314..321 'y.foo()': u64
14961496 327..328 'z': Box<dyn Trait<u64> + '?>
14971497 327..334 'z.foo()': u64
1498 340..341 'x': Box<dyn Trait<u64> + '?>
1498 340..341 'x': Box<dyn Trait<u64> + 'static>
14991499 340..348 'x.foo2()': i64
1500 354..355 'y': &'? (dyn Trait<u64> + '?)
1500 354..355 'y': &'? (dyn Trait<u64> + 'static)
15011501 354..362 'y.foo2()': i64
15021502 368..369 'z': Box<dyn Trait<u64> + '?>
15031503 368..376 'z.foo2()': i64
......@@ -1528,7 +1528,7 @@ fn test(s: S<u32, i32>) {
15281528 expect![[r#"
15291529 32..36 'self': &'? Self
15301530 102..106 'self': &'? S<T, U>
1531 128..139 '{ loop {} }': &'? (dyn Trait<T, U> + '?)
1531 128..139 '{ loop {} }': &'? (dyn Trait<T, U> + 'static)
15321532 130..137 'loop {}': !
15331533 135..137 '{}': ()
15341534 175..179 'self': &'? Self
......@@ -1561,18 +1561,18 @@ fn test(x: Trait, y: &Trait) -> u64 {
15611561}"#,
15621562 expect![[r#"
15631563 26..30 'self': &'? Self
1564 60..62 '{}': dyn Trait + '?
1565 72..73 'x': dyn Trait + '?
1566 82..83 'y': &'? (dyn Trait + '?)
1564 60..62 '{}': dyn Trait + 'static
1565 72..73 'x': dyn Trait + 'static
1566 82..83 'y': &'? (dyn Trait + 'static)
15671567 100..175 '{ ...o(); }': u64
1568 106..107 'x': dyn Trait + '?
1569 113..114 'y': &'? (dyn Trait + '?)
1568 106..107 'x': dyn Trait + 'static
1569 113..114 'y': &'? (dyn Trait + 'static)
15701570 124..125 'z': dyn Trait + '?
15711571 128..131 'bar': fn bar() -> dyn Trait + 'static
15721572 128..133 'bar()': dyn Trait + 'static
1573 139..140 'x': dyn Trait + '?
1573 139..140 'x': dyn Trait + 'static
15741574 139..146 'x.foo()': u64
1575 152..153 'y': &'? (dyn Trait + '?)
1575 152..153 'y': &'? (dyn Trait + 'static)
15761576 152..159 'y.foo()': u64
15771577 165..166 'z': dyn Trait + '?
15781578 165..172 'z.foo()': u64
......@@ -1594,7 +1594,7 @@ fn main() {
15941594 expect![[r#"
15951595 31..35 'self': &'? S
15961596 37..39 '{}': ()
1597 47..48 '_': &'? (dyn Fn(S) + '?)
1597 47..48 '_': &'? (dyn Fn(S) + 'static)
15981598 58..60 '{}': ()
15991599 71..105 '{ ...()); }': ()
16001600 77..78 'f': fn f(&'? (dyn Fn(S) + 'static))
......@@ -2948,13 +2948,13 @@ fn test(x: &dyn Foo) {
29482948 foo(x);
29492949}"#,
29502950 expect![[r#"
2951 21..22 'x': &'? (dyn Foo + '?)
2951 21..22 'x': &'? (dyn Foo + 'static)
29522952 34..36 '{}': ()
2953 46..47 'x': &'? (dyn Foo + '?)
2953 46..47 'x': &'? (dyn Foo + 'static)
29542954 59..74 '{ foo(x); }': ()
29552955 65..68 'foo': fn foo(&'? (dyn Foo + 'static))
29562956 65..71 'foo(x)': ()
2957 69..70 'x': &'? (dyn Foo + '?)
2957 69..70 'x': &'? (dyn Foo + 'static)
29582958 "#]],
29592959 );
29602960}
......@@ -3230,13 +3230,13 @@ fn foo() {
32303230 218..324 '{ ...&s); }': ()
32313231 228..229 's': Option<i32>
32323232 232..236 'None': Option<i32>
3233 246..247 'f': Box<dyn FnOnce(&'? Option<i32>) + '?>
3234 281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>) + '?>
3233 246..247 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static>
3234 281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>) + 'static>
32353235 294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'? Option<i32>)
32363236 300..307 '|ps| {}': impl FnOnce(&'? Option<i32>)
32373237 301..303 'ps': &'? Option<i32>
32383238 305..307 '{}': ()
3239 316..317 'f': Box<dyn FnOnce(&'? Option<i32>) + '?>
3239 316..317 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static>
32403240 316..321 'f(&s)': ()
32413241 318..320 '&s': &'? Option<i32>
32423242 319..320 's': Option<i32>
......@@ -4272,10 +4272,10 @@ fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) {
42724272 "#,
42734273 expect![[r#"
42744274 90..94 'self': &'? Self
4275 127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + '?)
4275 127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static)
42764276 164..195 '{ ...f(); }': ()
4277 170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + '?)
4278 170..184 'v.get::<i32>()': <dyn Trait<Assoc<i32> = &'a i32> + '? as Trait>::Assoc<i32>
4277 170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static)
4278 170..184 'v.get::<i32>()': <dyn Trait<Assoc<i32> = &'a i32> + 'static as Trait>::Assoc<i32>
42794279 170..192 'v.get:...eref()': {unknown}
42804280 "#]],
42814281 );
src/tools/rust-analyzer/crates/hir-ty/src/traits.rs+87-10
......@@ -12,7 +12,7 @@ use intern::sym;
1212use rustc_next_trait_solver::solve::{HasChanged, SolverDelegateEvalExt};
1313use rustc_type_ir::{
1414 InferCtxtLike, TypingMode,
15 inherent::{SliceLike, Span as _},
15 inherent::{IntoKind, SliceLike, Span as _, Ty as _},
1616 solve::Certainty,
1717};
1818use span::Edition;
......@@ -23,11 +23,12 @@ use crate::{
2323 AliasEq, AliasTy, Canonical, DomainGoal, Goal, InEnvironment, Interner, ProjectionTy,
2424 ProjectionTyExt, TraitRefExt, Ty, TyKind, TypeFlags, WhereClause,
2525 db::HirDatabase,
26 infer::unify::InferenceTable,
26 from_assoc_type_id,
2727 next_solver::{
2828 DbInterner, GenericArg, ParamEnv, Predicate, SolverContext, Span,
29 infer::{DbInternerInferExt, InferCtxt},
30 mapping::{ChalkToNextSolver, convert_canonical_args_for_result},
29 infer::{DbInternerInferExt, InferCtxt, traits::ObligationCause},
30 mapping::{ChalkToNextSolver, NextSolverToChalk, convert_canonical_args_for_result},
31 obligation_ctxt::ObligationCtxt,
3132 util::mini_canonicalize,
3233 },
3334 utils::UnevaluatedConstEvaluatorFolder,
......@@ -43,7 +44,7 @@ pub struct TraitEnvironment<'db> {
4344 pub krate: Crate,
4445 pub block: Option<BlockId>,
4546 // FIXME make this a BTreeMap
46 traits_from_clauses: Box<[(Ty, TraitId)]>,
47 traits_from_clauses: Box<[(crate::next_solver::Ty<'db>, TraitId)]>,
4748 pub env: ParamEnv<'db>,
4849}
4950
......@@ -60,7 +61,7 @@ impl<'db> TraitEnvironment<'db> {
6061 pub fn new(
6162 krate: Crate,
6263 block: Option<BlockId>,
63 traits_from_clauses: Box<[(Ty, TraitId)]>,
64 traits_from_clauses: Box<[(crate::next_solver::Ty<'db>, TraitId)]>,
6465 env: ParamEnv<'db>,
6566 ) -> Arc<Self> {
6667 Arc::new(TraitEnvironment { krate, block, traits_from_clauses, env })
......@@ -71,13 +72,28 @@ impl<'db> TraitEnvironment<'db> {
7172 Arc::make_mut(this).block = Some(block);
7273 }
7374
74 pub fn traits_in_scope_from_clauses(&self, ty: Ty) -> impl Iterator<Item = TraitId> + '_ {
75 pub fn traits_in_scope_from_clauses(
76 &self,
77 ty: crate::next_solver::Ty<'db>,
78 ) -> impl Iterator<Item = TraitId> + '_ {
7579 self.traits_from_clauses
7680 .iter()
7781 .filter_map(move |(self_ty, trait_id)| (*self_ty == ty).then_some(*trait_id))
7882 }
7983}
8084
85/// This should be used in `hir` only.
86pub fn structurally_normalize_ty<'db>(
87 infcx: &InferCtxt<'db>,
88 ty: crate::next_solver::Ty<'db>,
89 env: Arc<TraitEnvironment<'db>>,
90) -> crate::next_solver::Ty<'db> {
91 let crate::next_solver::TyKind::Alias(..) = ty.kind() else { return ty };
92 let mut ocx = ObligationCtxt::new(infcx);
93 let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env.env, ty).unwrap_or(ty);
94 ty.replace_infer_with_error(infcx.interner)
95}
96
8197pub(crate) fn normalize_projection_query<'db>(
8298 db: &'db dyn HirDatabase,
8399 projection: ProjectionTy,
......@@ -93,9 +109,30 @@ pub(crate) fn normalize_projection_query<'db>(
93109 return TyKind::Error.intern(Interner);
94110 }
95111
96 let mut table = InferenceTable::new(db, env);
97 let ty = table.normalize_projection_ty(projection);
98 table.resolve_completely(ty)
112 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
113 // FIXME(next-solver): I believe this should use `PostAnalysis` (this is only used for IDE things),
114 // but this causes some bug because of our incorrect impl of `type_of_opaque_hir_typeck()` for TAIT
115 // and async blocks.
116 let infcx = interner.infer_ctxt().build(TypingMode::Analysis {
117 defining_opaque_types_and_generators: crate::next_solver::SolverDefIds::new_from_iter(
118 interner,
119 [],
120 ),
121 });
122 let alias_ty = crate::next_solver::Ty::new_alias(
123 interner,
124 rustc_type_ir::AliasTyKind::Projection,
125 crate::next_solver::AliasTy::new(
126 interner,
127 from_assoc_type_id(projection.associated_ty_id).into(),
128 <crate::Substitution as ChalkToNextSolver<crate::next_solver::GenericArgs<'_>>>::to_nextsolver(&projection.substitution, interner),
129 ),
130 );
131 let mut ctxt = crate::next_solver::obligation_ctxt::ObligationCtxt::new(&infcx);
132 let normalized = ctxt
133 .structurally_normalize_ty(&ObligationCause::dummy(), env.env, alias_ty)
134 .unwrap_or(alias_ty);
135 normalized.replace_infer_with_error(interner).to_chalk(interner)
99136}
100137
101138fn identity_subst(
......@@ -419,3 +456,43 @@ impl FnTrait {
419456 self.lang_item().resolve_trait(db, krate)
420457 }
421458}
459
460/// This should not be used in `hir-ty`, only in `hir`.
461pub fn implements_trait_unique<'db>(
462 ty: crate::next_solver::Ty<'db>,
463 db: &'db dyn HirDatabase,
464 env: Arc<TraitEnvironment<'db>>,
465 trait_: TraitId,
466) -> bool {
467 implements_trait_unique_impl(db, env, trait_, &mut |infcx| {
468 infcx.fill_rest_fresh_args(trait_.into(), [ty.into()])
469 })
470}
471
472/// This should not be used in `hir-ty`, only in `hir`.
473pub fn implements_trait_unique_with_args<'db>(
474 db: &'db dyn HirDatabase,
475 env: Arc<TraitEnvironment<'db>>,
476 trait_: TraitId,
477 args: crate::next_solver::GenericArgs<'db>,
478) -> bool {
479 implements_trait_unique_impl(db, env, trait_, &mut |_| args)
480}
481
482fn implements_trait_unique_impl<'db>(
483 db: &'db dyn HirDatabase,
484 env: Arc<TraitEnvironment<'db>>,
485 trait_: TraitId,
486 create_args: &mut dyn FnMut(&InferCtxt<'db>) -> crate::next_solver::GenericArgs<'db>,
487) -> bool {
488 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
489 // FIXME(next-solver): I believe this should be `PostAnalysis`.
490 let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
491
492 let args = create_args(&infcx);
493 let trait_ref = rustc_type_ir::TraitRef::new_from_args(interner, trait_.into(), args);
494 let goal = crate::next_solver::Goal::new(interner, env.env, trait_ref);
495
496 let result = crate::traits::next_trait_solve_in_ctxt(&infcx, goal);
497 matches!(result, Ok((_, Certainty::Yes)))
498}
src/tools/rust-analyzer/crates/hir-ty/src/utils.rs+7-15
......@@ -20,11 +20,10 @@ use hir_expand::name::Name;
2020use intern::sym;
2121use rustc_abi::TargetDataLayout;
2222use rustc_hash::FxHashSet;
23use rustc_type_ir::inherent::{GenericArgs, IntoKind, SliceLike};
23use rustc_type_ir::inherent::{IntoKind, SliceLike};
2424use smallvec::{SmallVec, smallvec};
2525use span::Edition;
2626
27use crate::next_solver::mapping::NextSolverToChalk;
2827use crate::{
2928 ChalkTraitId, Const, ConstScalar, Interner, Substitution, TargetFeatures, TraitRef,
3029 TraitRefExt, Ty,
......@@ -34,7 +33,7 @@ use crate::{
3433 mir::pad16,
3534 next_solver::{
3635 DbInterner,
37 mapping::{ChalkToNextSolver, convert_args_for_result},
36 mapping::{ChalkToNextSolver, NextSolverToChalk, convert_args_for_result},
3837 },
3938 to_chalk_trait_id,
4039};
......@@ -196,15 +195,6 @@ pub(super) fn associated_type_by_name_including_super_traits(
196195pub(crate) struct ClosureSubst<'a>(pub(crate) &'a Substitution);
197196
198197impl<'a> ClosureSubst<'a> {
199 pub(crate) fn parent_subst(&self, db: &dyn HirDatabase) -> Substitution {
200 let interner = DbInterner::new_with(db, None, None);
201 let subst =
202 <Substitution as ChalkToNextSolver<crate::next_solver::GenericArgs<'_>>>::to_nextsolver(
203 self.0, interner,
204 );
205 subst.split_closure_args().parent_args.to_chalk(interner)
206 }
207
208198 pub(crate) fn sig_ty(&self, db: &dyn HirDatabase) -> Ty {
209199 let interner = DbInterner::new_with(db, None, None);
210200 let subst =
......@@ -310,10 +300,12 @@ impl FallibleTypeFolder<Interner> for UnevaluatedConstEvaluatorFolder<'_> {
310300 if let chalk_ir::ConstValue::Concrete(c) = &constant.data(Interner).value
311301 && let ConstScalar::UnevaluatedConst(id, subst) = &c.interned
312302 {
313 if let Ok(eval) = self.db.const_eval(*id, subst.clone(), None) {
314 return Ok(eval);
303 let interner = DbInterner::conjure();
304 if let Ok(eval) = self.db.const_eval(*id, subst.to_nextsolver(interner), None) {
305 return Ok(eval.to_chalk(interner));
315306 } else {
316 return Ok(unknown_const(constant.data(Interner).ty.clone()));
307 return Ok(unknown_const(constant.data(Interner).ty.to_nextsolver(interner))
308 .to_chalk(interner));
317309 }
318310 }
319311 Ok(constant)
src/tools/rust-analyzer/crates/hir-ty/src/variance.rs+80-78
......@@ -1001,84 +1001,86 @@ struct FixedPoint<T, U, V>(&'static FixedPoint<(), T, U>, V);
10011001 // ));
10021002 let (db, file_id) = TestDB::with_single_file(ra_fixture);
10031003
1004 let mut defs: Vec<GenericDefId> = Vec::new();
1005 let module = db.module_for_file_opt(file_id.file_id(&db)).unwrap();
1006 let def_map = module.def_map(&db);
1007 crate::tests::visit_module(&db, def_map, module.local_id, &mut |it| {
1008 defs.push(match it {
1009 ModuleDefId::FunctionId(it) => it.into(),
1010 ModuleDefId::AdtId(it) => it.into(),
1011 ModuleDefId::ConstId(it) => it.into(),
1012 ModuleDefId::TraitId(it) => it.into(),
1013 ModuleDefId::TypeAliasId(it) => it.into(),
1014 _ => return,
1015 })
1016 });
1017 let defs = defs
1018 .into_iter()
1019 .filter_map(|def| {
1020 Some((
1021 def,
1022 match def {
1023 GenericDefId::FunctionId(it) => {
1024 let loc = it.lookup(&db);
1025 loc.source(&db).value.name().unwrap()
1026 }
1027 GenericDefId::AdtId(AdtId::EnumId(it)) => {
1028 let loc = it.lookup(&db);
1029 loc.source(&db).value.name().unwrap()
1030 }
1031 GenericDefId::AdtId(AdtId::StructId(it)) => {
1032 let loc = it.lookup(&db);
1033 loc.source(&db).value.name().unwrap()
1034 }
1035 GenericDefId::AdtId(AdtId::UnionId(it)) => {
1036 let loc = it.lookup(&db);
1037 loc.source(&db).value.name().unwrap()
1038 }
1039 GenericDefId::TraitId(it) => {
1040 let loc = it.lookup(&db);
1041 loc.source(&db).value.name().unwrap()
1042 }
1043 GenericDefId::TypeAliasId(it) => {
1044 let loc = it.lookup(&db);
1045 loc.source(&db).value.name().unwrap()
1046 }
1047 GenericDefId::ImplId(_) => return None,
1048 GenericDefId::ConstId(_) => return None,
1049 GenericDefId::StaticId(_) => return None,
1050 },
1051 ))
1052 })
1053 .sorted_by_key(|(_, n)| n.syntax().text_range().start());
1054 let mut res = String::new();
1055 for (def, name) in defs {
1056 let Some(variances) = db.variances_of(def) else {
1057 continue;
1058 };
1059 format_to!(
1060 res,
1061 "{name}[{}]\n",
1062 generics(&db, def)
1063 .iter()
1064 .map(|(_, param)| match param {
1065 GenericParamDataRef::TypeParamData(type_param_data) => {
1066 type_param_data.name.as_ref().unwrap()
1067 }
1068 GenericParamDataRef::ConstParamData(const_param_data) =>
1069 &const_param_data.name,
1070 GenericParamDataRef::LifetimeParamData(lifetime_param_data) => {
1071 &lifetime_param_data.name
1072 }
1073 })
1074 .zip_eq(&*variances)
1075 .format_with(", ", |(name, var), f| f(&format_args!(
1076 "{}: {var}",
1077 name.as_str()
1078 )))
1079 );
1080 }
1004 crate::attach_db(&db, || {
1005 let mut defs: Vec<GenericDefId> = Vec::new();
1006 let module = db.module_for_file_opt(file_id.file_id(&db)).unwrap();
1007 let def_map = module.def_map(&db);
1008 crate::tests::visit_module(&db, def_map, module.local_id, &mut |it| {
1009 defs.push(match it {
1010 ModuleDefId::FunctionId(it) => it.into(),
1011 ModuleDefId::AdtId(it) => it.into(),
1012 ModuleDefId::ConstId(it) => it.into(),
1013 ModuleDefId::TraitId(it) => it.into(),
1014 ModuleDefId::TypeAliasId(it) => it.into(),
1015 _ => return,
1016 })
1017 });
1018 let defs = defs
1019 .into_iter()
1020 .filter_map(|def| {
1021 Some((
1022 def,
1023 match def {
1024 GenericDefId::FunctionId(it) => {
1025 let loc = it.lookup(&db);
1026 loc.source(&db).value.name().unwrap()
1027 }
1028 GenericDefId::AdtId(AdtId::EnumId(it)) => {
1029 let loc = it.lookup(&db);
1030 loc.source(&db).value.name().unwrap()
1031 }
1032 GenericDefId::AdtId(AdtId::StructId(it)) => {
1033 let loc = it.lookup(&db);
1034 loc.source(&db).value.name().unwrap()
1035 }
1036 GenericDefId::AdtId(AdtId::UnionId(it)) => {
1037 let loc = it.lookup(&db);
1038 loc.source(&db).value.name().unwrap()
1039 }
1040 GenericDefId::TraitId(it) => {
1041 let loc = it.lookup(&db);
1042 loc.source(&db).value.name().unwrap()
1043 }
1044 GenericDefId::TypeAliasId(it) => {
1045 let loc = it.lookup(&db);
1046 loc.source(&db).value.name().unwrap()
1047 }
1048 GenericDefId::ImplId(_) => return None,
1049 GenericDefId::ConstId(_) => return None,
1050 GenericDefId::StaticId(_) => return None,
1051 },
1052 ))
1053 })
1054 .sorted_by_key(|(_, n)| n.syntax().text_range().start());
1055 let mut res = String::new();
1056 for (def, name) in defs {
1057 let Some(variances) = db.variances_of(def) else {
1058 continue;
1059 };
1060 format_to!(
1061 res,
1062 "{name}[{}]\n",
1063 generics(&db, def)
1064 .iter()
1065 .map(|(_, param)| match param {
1066 GenericParamDataRef::TypeParamData(type_param_data) => {
1067 type_param_data.name.as_ref().unwrap()
1068 }
1069 GenericParamDataRef::ConstParamData(const_param_data) =>
1070 &const_param_data.name,
1071 GenericParamDataRef::LifetimeParamData(lifetime_param_data) => {
1072 &lifetime_param_data.name
1073 }
1074 })
1075 .zip_eq(&*variances)
1076 .format_with(", ", |(name, var), f| f(&format_args!(
1077 "{}: {var}",
1078 name.as_str()
1079 )))
1080 );
1081 }
10811082
1082 expected.assert_eq(&res);
1083 expected.assert_eq(&res);
1084 })
10831085 }
10841086}
src/tools/rust-analyzer/crates/hir/src/attrs.rs+3-11
......@@ -14,11 +14,7 @@ use hir_expand::{
1414 mod_path::{ModPath, PathKind},
1515 name::Name,
1616};
17use hir_ty::{
18 db::HirDatabase,
19 method_resolution,
20 next_solver::{DbInterner, mapping::ChalkToNextSolver},
21};
17use hir_ty::{db::HirDatabase, method_resolution};
2218
2319use crate::{
2420 Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl,
......@@ -261,7 +257,7 @@ fn resolve_impl_trait_item<'db>(
261257 name: &Name,
262258 ns: Option<Namespace>,
263259) -> Option<DocLinkDef> {
264 let canonical = ty.canonical();
260 let canonical = ty.canonical(db);
265261 let krate = ty.krate(db);
266262 let environment = resolver
267263 .generic_def()
......@@ -275,11 +271,7 @@ fn resolve_impl_trait_item<'db>(
275271 //
276272 // FIXME: resolve type aliases (which are not yielded by iterate_path_candidates)
277273 _ = method_resolution::iterate_path_candidates(
278 &canonical.to_nextsolver(DbInterner::new_with(
279 db,
280 Some(environment.krate),
281 environment.block,
282 )),
274 &canonical,
283275 db,
284276 environment,
285277 &traits_in_scope,
src/tools/rust-analyzer/crates/hir/src/diagnostics.rs+9-12
......@@ -620,7 +620,7 @@ impl<'db> AnyDiagnostic<'db> {
620620 pub(crate) fn inference_diagnostic(
621621 db: &'db dyn HirDatabase,
622622 def: DefWithBodyId,
623 d: &InferenceDiagnostic,
623 d: &InferenceDiagnostic<'db>,
624624 source_map: &hir_def::expr_store::BodySourceMap,
625625 sig_map: &hir_def::expr_store::ExpressionStoreSourceMap,
626626 ) -> Option<AnyDiagnostic<'db>> {
......@@ -666,8 +666,7 @@ impl<'db> AnyDiagnostic<'db> {
666666 }
667667 InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
668668 let call_expr = expr_syntax(*call_expr)?;
669 ExpectedFunction { call: call_expr, found: Type::new(db, def, found.clone()) }
670 .into()
669 ExpectedFunction { call: call_expr, found: Type::new(db, def, *found) }.into()
671670 }
672671 InferenceDiagnostic::UnresolvedField {
673672 expr,
......@@ -679,7 +678,7 @@ impl<'db> AnyDiagnostic<'db> {
679678 UnresolvedField {
680679 expr,
681680 name: name.clone(),
682 receiver: Type::new(db, def, receiver.clone()),
681 receiver: Type::new(db, def, *receiver),
683682 method_with_same_name_exists: *method_with_same_name_exists,
684683 }
685684 .into()
......@@ -695,10 +694,8 @@ impl<'db> AnyDiagnostic<'db> {
695694 UnresolvedMethodCall {
696695 expr,
697696 name: name.clone(),
698 receiver: Type::new(db, def, receiver.clone()),
699 field_with_same_name: field_with_same_name
700 .clone()
701 .map(|ty| Type::new(db, def, ty)),
697 receiver: Type::new(db, def, *receiver),
698 field_with_same_name: (*field_with_same_name).map(|ty| Type::new(db, def, ty)),
702699 assoc_func_with_same_name: assoc_func_with_same_name.map(Into::into),
703700 }
704701 .into()
......@@ -725,7 +722,7 @@ impl<'db> AnyDiagnostic<'db> {
725722 }
726723 InferenceDiagnostic::TypedHole { expr, expected } => {
727724 let expr = expr_syntax(*expr)?;
728 TypedHole { expr, expected: Type::new(db, def, expected.clone()) }.into()
725 TypedHole { expr, expected: Type::new(db, def, *expected) }.into()
729726 }
730727 &InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
731728 let expr_or_pat = match pat {
......@@ -742,12 +739,12 @@ impl<'db> AnyDiagnostic<'db> {
742739 }
743740 InferenceDiagnostic::CastToUnsized { expr, cast_ty } => {
744741 let expr = expr_syntax(*expr)?;
745 CastToUnsized { expr, cast_ty: Type::new(db, def, cast_ty.clone()) }.into()
742 CastToUnsized { expr, cast_ty: Type::new(db, def, *cast_ty) }.into()
746743 }
747744 InferenceDiagnostic::InvalidCast { expr, error, expr_ty, cast_ty } => {
748745 let expr = expr_syntax(*expr)?;
749 let expr_ty = Type::new(db, def, expr_ty.clone());
750 let cast_ty = Type::new(db, def, cast_ty.clone());
746 let expr_ty = Type::new(db, def, *expr_ty);
747 let cast_ty = Type::new(db, def, *cast_ty);
751748 InvalidCast { expr, error: *error, expr_ty, cast_ty }.into()
752749 }
753750 InferenceDiagnostic::TyDiagnostic { source, diag } => {
src/tools/rust-analyzer/crates/hir/src/display.rs+3-3
......@@ -11,7 +11,7 @@ use hir_def::{
1111 type_ref::{TypeBound, TypeRef, TypeRefId},
1212};
1313use hir_ty::{
14 AliasEq, AliasTy, Interner, ProjectionTyExt, TraitRefExt, TyKind, WhereClause,
14 AliasEq, AliasTy, Interner, ProjectionTyExt, TraitRefExt, TyBuilder, TyKind, WhereClause,
1515 db::HirDatabase,
1616 display::{
1717 HirDisplay, HirDisplayError, HirDisplayWithExpressionStore, HirFormatter, SizedByDefault,
......@@ -23,8 +23,8 @@ use itertools::Itertools;
2323use crate::{
2424 Adt, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum,
2525 ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, LifetimeParam,
26 Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, TyBuilder,
27 Type, TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, Variant,
26 Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, Type,
27 TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, Variant,
2828};
2929
3030impl HirDisplay for Function {
src/tools/rust-analyzer/crates/hir/src/has_source.rs+1-1
......@@ -238,7 +238,7 @@ impl HasSource for Param<'_> {
238238 .map(|value| InFile { file_id, value })
239239 }
240240 Callee::Closure(closure, _) => {
241 let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure.into());
241 let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure);
242242 let (_, source_map) = db.body_with_source_map(owner);
243243 let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?;
244244 let root = db.parse_or_expand(file_id);
src/tools/rust-analyzer/crates/hir/src/lib.rs+572-849
......@@ -71,29 +71,31 @@ use hir_expand::{
7171 proc_macro::ProcMacroKind,
7272};
7373use hir_ty::{
74 AliasTy, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
75 GenericArgData, Interner, ParamKind, ProjectionTy, QuantifiedWhereClause, Scalar, Substitution,
76 TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyLoweringDiagnostic,
77 ValueTyDefId, WhereClause, all_super_traits, autoderef, check_orphan_rules,
78 consteval::{ConstExt, try_const_usize, unknown_const_as_generic},
74 TraitEnvironment, TyDefId, TyLoweringDiagnostic, ValueTyDefId, all_super_traits, autoderef,
75 check_orphan_rules,
76 consteval::try_const_usize,
77 db::InternedClosureId,
7978 diagnostics::BodyValidationDiagnostic,
80 direct_super_traits, error_lifetime, known_const_to_ast,
79 direct_super_traits, known_const_to_ast,
8180 layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
8281 method_resolution,
8382 mir::{MutBorrowKind, interpret_mir},
8483 next_solver::{
85 ClauseKind, DbInterner, GenericArgs,
86 infer::InferCtxt,
87 mapping::{ChalkToNextSolver, NextSolverToChalk, convert_ty_for_result},
84 AliasTy, Canonical, ClauseKind, ConstKind, DbInterner, ErrorGuaranteed, GenericArg,
85 GenericArgs, PolyFnSig, Region, SolverDefId, Ty, TyKind, TypingMode,
86 infer::{DbInternerInferExt, InferCtxt},
8887 },
89 primitive::UintTy,
90 traits::FnTrait,
88 traits::{self, FnTrait, structurally_normalize_ty},
9189};
9290use itertools::Itertools;
9391use rustc_hash::FxHashSet;
92use rustc_type_ir::{
93 AliasTyKind, TypeSuperVisitable, TypeVisitable, TypeVisitor,
94 inherent::{AdtDef, IntoKind, SliceLike, Term as _, Ty as _},
95};
9496use smallvec::SmallVec;
9597use span::{AstIdNode, Edition, FileId};
96use stdx::{format_to, impl_from, never, variance::PhantomCovariantLifetime};
98use stdx::{format_to, impl_from, never};
9799use syntax::{
98100 AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, T, TextRange, ToSmolStr,
99101 ast::{self, HasAttrs as _, HasName, HasVisibility as _},
......@@ -112,7 +114,6 @@ pub use crate::{
112114 VisibleTraits,
113115 },
114116};
115use rustc_type_ir::inherent::{IntoKind, SliceLike};
116117
117118// Be careful with these re-exports.
118119//
......@@ -156,18 +157,20 @@ pub use {
156157 proc_macro::{ProcMacros, ProcMacrosBuilder},
157158 tt,
158159 },
160 // FIXME: Properly encapsulate mir
161 hir_ty::mir,
159162 hir_ty::{
160 CastError, DropGlue, FnAbi, PointerCast, Safety, Variance,
163 CastError, FnAbi, PointerCast, Variance, attach_db, attach_db_allow_change,
161164 consteval::ConstEvalError,
162165 diagnostics::UnsafetyReason,
163166 display::{ClosureStyle, DisplayTarget, HirDisplay, HirDisplayError, HirWrite},
167 drop::DropGlue,
164168 dyn_compatibility::{DynCompatibilityViolation, MethodViolationCode},
165169 layout::LayoutError,
166170 method_resolution::TyFingerprint,
167171 mir::{MirEvalError, MirLowerError},
172 next_solver::abi::Safety,
168173 },
169 // FIXME: Properly encapsulate mir
170 hir_ty::{Interner as ChalkTyInterner, mir},
171174 intern::{Symbol, sym},
172175};
173176
......@@ -748,12 +751,15 @@ impl Module {
748751
749752 let inherent_impls = db.inherent_impls_in_crate(self.id.krate());
750753
754 let interner = DbInterner::new_with(db, Some(self.id.krate()), self.id.containing_block());
755 let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
756
751757 let mut impl_assoc_items_scratch = vec![];
752758 for impl_def in self.impl_defs(db) {
753759 GenericDef::Impl(impl_def).diagnostics(db, acc);
754760
755761 let loc = impl_def.id.lookup(db);
756 let source_map = db.impl_signature_with_source_map(impl_def.id).1;
762 let (impl_signature, source_map) = db.impl_signature_with_source_map(impl_def.id);
757763 expr_store_diagnostics(db, acc, &source_map);
758764
759765 let file_id = loc.id.file_id;
......@@ -782,10 +788,17 @@ impl Module {
782788 }
783789
784790 let trait_ = impl_def.trait_(db);
785 let trait_is_unsafe = trait_.is_some_and(|t| t.is_unsafe(db));
791 let mut trait_is_unsafe = trait_.is_some_and(|t| t.is_unsafe(db));
786792 let impl_is_negative = impl_def.is_negative(db);
787793 let impl_is_unsafe = impl_def.is_unsafe(db);
788794
795 let trait_is_unresolved = trait_.is_none() && impl_signature.target_trait.is_some();
796 if trait_is_unresolved {
797 // Ignore trait safety errors when the trait is unresolved, as otherwise we'll treat it as safe,
798 // which may not be correct.
799 trait_is_unsafe = impl_is_unsafe;
800 }
801
789802 let drop_maybe_dangle = (|| {
790803 // FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper
791804 let trait_ = trait_?;
......@@ -865,26 +878,15 @@ impl Module {
865878 .collect();
866879
867880 if !missing.is_empty() {
868 let interner = DbInterner::new_with(db, None, None);
869 let args: crate::next_solver::GenericArgs<'_> =
870 hir_ty::generics::generics(db, impl_def.id.into())
871 .placeholder_subst(db)
872 .to_nextsolver(interner);
873 let self_ty =
874 db.impl_self_ty(impl_def.id).instantiate(interner, args).to_chalk(interner);
875 let self_ty = if let TyKind::Alias(AliasTy::Projection(projection)) =
876 self_ty.kind(Interner)
877 {
878 db.normalize_projection(
879 projection.clone(),
880 db.trait_environment(impl_def.id.into()),
881 )
882 } else {
883 self_ty
884 };
881 let self_ty = db.impl_self_ty(impl_def.id).instantiate_identity();
882 let self_ty = structurally_normalize_ty(
883 &infcx,
884 self_ty,
885 db.trait_environment(impl_def.id.into()),
886 );
885887 let self_ty_is_guaranteed_unsized = matches!(
886 self_ty.kind(Interner),
887 TyKind::Dyn(..) | TyKind::Slice(..) | TyKind::Str
888 self_ty.kind(),
889 TyKind::Dynamic(..) | TyKind::Slice(..) | TyKind::Str
888890 );
889891 if self_ty_is_guaranteed_unsized {
890892 missing.retain(|(_, assoc_item)| {
......@@ -1287,19 +1289,15 @@ impl TupleField {
12871289 }
12881290
12891291 pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> {
1292 let interner = DbInterner::new_with(db, None, None);
12901293 let ty = db
12911294 .infer(self.owner)
12921295 .tuple_field_access_type(self.tuple)
1293 .as_slice(Interner)
1296 .as_slice()
12941297 .get(self.index as usize)
1295 .and_then(|arg| arg.ty(Interner))
1296 .cloned()
1297 .unwrap_or_else(|| TyKind::Error.intern(Interner));
1298 Type {
1299 env: db.trait_environment_for_body(self.owner),
1300 ty,
1301 _pd: PhantomCovariantLifetime::new(),
1302 }
1298 .copied()
1299 .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed));
1300 Type { env: db.trait_environment_for_body(self.owner), ty }
13031301 }
13041302}
13051303
......@@ -1367,17 +1365,9 @@ impl Field {
13671365 VariantDef::Union(it) => it.id.into(),
13681366 VariantDef::Variant(it) => it.parent_enum(db).id.into(),
13691367 };
1370 let mut generics = generics.map(|it| it.ty);
1371 let substs = TyBuilder::subst_for_def(db, def_id, None)
1372 .fill(|x| match x {
1373 ParamKind::Type => {
1374 generics.next().unwrap_or_else(|| TyKind::Error.intern(Interner)).cast(Interner)
1375 }
1376 ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
1377 ParamKind::Lifetime => error_lifetime().cast(Interner),
1378 })
1379 .build();
1380 let ty = db.field_types(var_id)[self.id].clone().substitute(Interner, &substs);
1368 let interner = DbInterner::new_with(db, None, None);
1369 let args = generic_args_from_tys(interner, def_id.into(), generics.map(|ty| ty.ty));
1370 let ty = db.field_types_ns(var_id)[self.id].instantiate(interner, args);
13811371 Type::new(db, var_id, ty)
13821372 }
13831373
......@@ -1437,8 +1427,8 @@ impl Struct {
14371427 Type::from_def(db, self.id)
14381428 }
14391429
1440 pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type<'_> {
1441 Type::from_def_placeholders(db, self.id)
1430 pub fn ty_params(self, db: &dyn HirDatabase) -> Type<'_> {
1431 Type::from_def_params(db, self.id)
14421432 }
14431433
14441434 pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type<'_> {
......@@ -1526,8 +1516,8 @@ impl Union {
15261516 Type::from_def(db, self.id)
15271517 }
15281518
1529 pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type<'_> {
1530 Type::from_def_placeholders(db, self.id)
1519 pub fn ty_params(self, db: &dyn HirDatabase) -> Type<'_> {
1520 Type::from_def_params(db, self.id)
15311521 }
15321522
15331523 pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type<'_> {
......@@ -1593,40 +1583,43 @@ impl Enum {
15931583 Type::from_def(db, self.id)
15941584 }
15951585
1596 pub fn ty_placeholders<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
1597 Type::from_def_placeholders(db, self.id)
1586 pub fn ty_params<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
1587 Type::from_def_params(db, self.id)
15981588 }
15991589
16001590 /// The type of the enum variant bodies.
16011591 pub fn variant_body_ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
1592 let interner = DbInterner::new_with(db, None, None);
16021593 Type::new_for_crate(
16031594 self.id.lookup(db).container.krate(),
1604 TyBuilder::builtin(match db.enum_signature(self.id).variant_body_type() {
1595 match db.enum_signature(self.id).variant_body_type() {
16051596 layout::IntegerType::Pointer(sign) => match sign {
1606 true => hir_def::builtin_type::BuiltinType::Int(
1607 hir_def::builtin_type::BuiltinInt::Isize,
1608 ),
1609 false => hir_def::builtin_type::BuiltinType::Uint(
1610 hir_def::builtin_type::BuiltinUint::Usize,
1611 ),
1597 true => Ty::new_int(interner, rustc_type_ir::IntTy::Isize),
1598 false => Ty::new_uint(interner, rustc_type_ir::UintTy::Usize),
16121599 },
16131600 layout::IntegerType::Fixed(i, sign) => match sign {
1614 true => hir_def::builtin_type::BuiltinType::Int(match i {
1615 layout::Integer::I8 => hir_def::builtin_type::BuiltinInt::I8,
1616 layout::Integer::I16 => hir_def::builtin_type::BuiltinInt::I16,
1617 layout::Integer::I32 => hir_def::builtin_type::BuiltinInt::I32,
1618 layout::Integer::I64 => hir_def::builtin_type::BuiltinInt::I64,
1619 layout::Integer::I128 => hir_def::builtin_type::BuiltinInt::I128,
1620 }),
1621 false => hir_def::builtin_type::BuiltinType::Uint(match i {
1622 layout::Integer::I8 => hir_def::builtin_type::BuiltinUint::U8,
1623 layout::Integer::I16 => hir_def::builtin_type::BuiltinUint::U16,
1624 layout::Integer::I32 => hir_def::builtin_type::BuiltinUint::U32,
1625 layout::Integer::I64 => hir_def::builtin_type::BuiltinUint::U64,
1626 layout::Integer::I128 => hir_def::builtin_type::BuiltinUint::U128,
1627 }),
1601 true => Ty::new_int(
1602 interner,
1603 match i {
1604 layout::Integer::I8 => rustc_type_ir::IntTy::I8,
1605 layout::Integer::I16 => rustc_type_ir::IntTy::I16,
1606 layout::Integer::I32 => rustc_type_ir::IntTy::I32,
1607 layout::Integer::I64 => rustc_type_ir::IntTy::I64,
1608 layout::Integer::I128 => rustc_type_ir::IntTy::I128,
1609 },
1610 ),
1611 false => Ty::new_uint(
1612 interner,
1613 match i {
1614 layout::Integer::I8 => rustc_type_ir::UintTy::U8,
1615 layout::Integer::I16 => rustc_type_ir::UintTy::U16,
1616 layout::Integer::I32 => rustc_type_ir::UintTy::U32,
1617 layout::Integer::I64 => rustc_type_ir::UintTy::U64,
1618 layout::Integer::I128 => rustc_type_ir::UintTy::U128,
1619 },
1620 ),
16281621 },
1629 }),
1622 },
16301623 )
16311624 }
16321625
......@@ -1720,7 +1713,7 @@ impl Variant {
17201713 self.source(db)?.value.expr()
17211714 }
17221715
1723 pub fn eval(self, db: &dyn HirDatabase) -> Result<i128, ConstEvalError> {
1716 pub fn eval(self, db: &dyn HirDatabase) -> Result<i128, ConstEvalError<'_>> {
17241717 db.const_eval_discriminant(self.into())
17251718 }
17261719
......@@ -1802,26 +1795,18 @@ impl_from!(Struct, Union, Enum for Adt);
18021795
18031796impl Adt {
18041797 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
1805 let subst = db.generic_defaults(self.into());
1806 (subst.is_empty() && db.generic_params(self.into()).len_type_or_consts() != 0)
1807 || subst.iter().any(|ty| match ty.skip_binders().data(Interner) {
1808 GenericArgData::Ty(it) => it.is_unknown(),
1809 _ => false,
1810 })
1798 has_non_default_type_params(db, self.into())
18111799 }
18121800
18131801 pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
18141802 let env = db.trait_environment(self.into());
18151803 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
1816 db.layout_of_adt(
1817 self.into(),
1818 TyBuilder::adt(db, self.into())
1819 .fill_with_defaults(db, || TyKind::Error.intern(Interner))
1820 .build_into_subst()
1821 .to_nextsolver(interner),
1822 env,
1823 )
1824 .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).id).unwrap()))
1804 let adt_id = AdtId::from(self);
1805 let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, _, id, _| {
1806 GenericArg::error_from_id(interner, id)
1807 });
1808 db.layout_of_adt(adt_id, args, env)
1809 .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).id).unwrap()))
18251810 }
18261811
18271812 /// Turns this ADT into a type. Any type parameters of the ADT will be
......@@ -1840,18 +1825,12 @@ impl Adt {
18401825 args: impl IntoIterator<Item = Type<'db>>,
18411826 ) -> Type<'db> {
18421827 let id = AdtId::from(self);
1843 let mut it = args.into_iter().map(|t| t.ty);
1844 let ty = TyBuilder::def_ty(db, id.into(), None)
1845 .fill(|x| {
1846 let r = it.next().unwrap_or_else(|| TyKind::Error.intern(Interner));
1847 match x {
1848 ParamKind::Type => r.cast(Interner),
1849 ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
1850 ParamKind::Lifetime => error_lifetime().cast(Interner),
1851 }
1852 })
1853 .build(DbInterner::conjure())
1854 .to_chalk(DbInterner::conjure());
1828 let interner = DbInterner::new_with(db, None, None);
1829 let ty = Ty::new_adt(
1830 interner,
1831 id,
1832 generic_args_from_tys(interner, id.into(), args.into_iter().map(|ty| ty.ty)),
1833 );
18551834 Type::new(db, id, ty)
18561835 }
18571836
......@@ -2061,8 +2040,8 @@ impl DefWithBody {
20612040 acc.push(
20622041 TypeMismatch {
20632042 expr_or_pat,
2064 expected: Type::new(db, DefWithBodyId::from(self), mismatch.expected.clone()),
2065 actual: Type::new(db, DefWithBodyId::from(self), mismatch.actual.clone()),
2043 expected: Type::new(db, DefWithBodyId::from(self), mismatch.expected),
2044 actual: Type::new(db, DefWithBodyId::from(self), mismatch.actual),
20662045 }
20672046 .into(),
20682047 );
......@@ -2132,10 +2111,7 @@ impl DefWithBody {
21322111 }
21332112 mir::MirSpan::Unknown => continue,
21342113 };
2135 acc.push(
2136 MovedOutOfRef { ty: Type::new_for_crate(krate, moof.ty.clone()), span }
2137 .into(),
2138 )
2114 acc.push(MovedOutOfRef { ty: Type::new_for_crate(krate, moof.ty), span }.into())
21392115 }
21402116 let mol = &borrowck_result.mutability_of_locals;
21412117 for (binding_id, binding_data) in body.bindings() {
......@@ -2285,30 +2261,24 @@ impl Function {
22852261
22862262 pub fn fn_ptr_type(self, db: &dyn HirDatabase) -> Type<'_> {
22872263 let resolver = self.id.resolver(db);
2288 let substs = TyBuilder::placeholder_subst(db, self.id);
22892264 let interner = DbInterner::new_with(db, None, None);
2290 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2291 let callable_sig = db
2292 .callable_item_signature(self.id.into())
2293 .instantiate(interner, args)
2294 .skip_binder()
2295 .to_chalk(interner);
2296 let ty = TyKind::Function(callable_sig.to_fn_ptr()).intern(Interner);
2265 // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
2266 let callable_sig = db.callable_item_signature(self.id.into()).instantiate_identity();
2267 let ty = Ty::new_fn_ptr(interner, callable_sig);
22972268 Type::new_with_resolver_inner(db, &resolver, ty)
22982269 }
22992270
2271 // FIXME: Find a better API to express all combinations here, perhaps we should have `PreInstantiationType`?
2272
23002273 /// Get this function's return type
23012274 pub fn ret_type(self, db: &dyn HirDatabase) -> Type<'_> {
23022275 let resolver = self.id.resolver(db);
2303 let substs = TyBuilder::placeholder_subst(db, self.id);
2304 let interner = DbInterner::new_with(db, None, None);
2305 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2276 // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
23062277 let ty = db
23072278 .callable_item_signature(self.id.into())
2308 .instantiate(interner, args)
2279 .instantiate_identity()
23092280 .skip_binder()
2310 .output()
2311 .to_chalk(interner);
2281 .output();
23122282 Type::new_with_resolver_inner(db, &resolver, ty)
23132283 }
23142284
......@@ -2319,32 +2289,15 @@ impl Function {
23192289 generics: impl Iterator<Item = Type<'db>>,
23202290 ) -> Type<'db> {
23212291 let resolver = self.id.resolver(db);
2322 let parent_id: Option<GenericDefId> = match self.id.lookup(db).container {
2323 ItemContainerId::ImplId(it) => Some(it.into()),
2324 ItemContainerId::TraitId(it) => Some(it.into()),
2325 ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
2326 };
2327 let mut generics = generics.map(|it| it.ty);
2328 let mut filler = |x: &_| match x {
2329 ParamKind::Type => {
2330 generics.next().unwrap_or_else(|| TyKind::Error.intern(Interner)).cast(Interner)
2331 }
2332 ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
2333 ParamKind::Lifetime => error_lifetime().cast(Interner),
2334 };
2335
2336 let parent_substs =
2337 parent_id.map(|id| TyBuilder::subst_for_def(db, id, None).fill(&mut filler).build());
2338 let substs = TyBuilder::subst_for_def(db, self.id, parent_substs).fill(&mut filler).build();
2292 let interner = DbInterner::new_with(db, None, None);
2293 let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty));
23392294
23402295 let interner = DbInterner::new_with(db, None, None);
2341 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
23422296 let ty = db
23432297 .callable_item_signature(self.id.into())
23442298 .instantiate(interner, args)
23452299 .skip_binder()
2346 .output()
2347 .to_chalk(interner);
2300 .output();
23482301 Type::new_with_resolver_inner(db, &resolver, ty)
23492302 }
23502303
......@@ -2353,18 +2306,17 @@ impl Function {
23532306 return None;
23542307 }
23552308 let resolver = self.id.resolver(db);
2356 let substs = TyBuilder::placeholder_subst(db, self.id);
2357 let interner = DbInterner::new_with(db, None, None);
2358 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2309 // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
23592310 let ret_ty = db
23602311 .callable_item_signature(self.id.into())
2361 .instantiate(interner, args)
2312 .instantiate_identity()
23622313 .skip_binder()
2363 .output()
2364 .to_chalk(interner);
2314 .output();
23652315 for pred in ret_ty.impl_trait_bounds(db).into_iter().flatten() {
2366 if let WhereClause::AliasEq(output_eq) = pred.into_value_and_skipped_binders().0 {
2367 return Type::new_with_resolver_inner(db, &resolver, output_eq.ty).into();
2316 if let ClauseKind::Projection(projection) = pred.kind().skip_binder()
2317 && let Some(output_ty) = projection.term.as_type()
2318 {
2319 return Type::new_with_resolver_inner(db, &resolver, output_ty).into();
23682320 }
23692321 }
23702322 None
......@@ -2380,24 +2332,15 @@ impl Function {
23802332
23812333 pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param<'_>> {
23822334 let environment = db.trait_environment(self.id.into());
2383 let substs = TyBuilder::placeholder_subst(db, self.id);
2384 let interner = DbInterner::new_with(db, None, None);
2385 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2386 let callable_sig = db
2387 .callable_item_signature(self.id.into())
2388 .instantiate(interner, args)
2389 .skip_binder()
2390 .to_chalk(interner);
2335 // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
2336 let callable_sig =
2337 db.callable_item_signature(self.id.into()).instantiate_identity().skip_binder();
23912338 callable_sig
2392 .params()
2339 .inputs()
23932340 .iter()
23942341 .enumerate()
23952342 .map(|(idx, ty)| {
2396 let ty = Type {
2397 env: environment.clone(),
2398 ty: ty.clone(),
2399 _pd: PhantomCovariantLifetime::new(),
2400 };
2343 let ty = Type { env: environment.clone(), ty };
24012344 Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx }
24022345 })
24032346 .collect()
......@@ -2414,26 +2357,17 @@ impl Function {
24142357
24152358 pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec<Param<'_>> {
24162359 let environment = db.trait_environment(self.id.into());
2417 let substs = TyBuilder::placeholder_subst(db, self.id);
2418 let interner = DbInterner::new_with(db, None, None);
2419 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2420 let callable_sig = db
2421 .callable_item_signature(self.id.into())
2422 .instantiate(interner, args)
2423 .skip_binder()
2424 .to_chalk(interner);
2360 // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
2361 let callable_sig =
2362 db.callable_item_signature(self.id.into()).instantiate_identity().skip_binder();
24252363 let skip = if db.function_signature(self.id).has_self_param() { 1 } else { 0 };
24262364 callable_sig
2427 .params()
2365 .inputs()
24282366 .iter()
24292367 .enumerate()
24302368 .skip(skip)
24312369 .map(|(idx, ty)| {
2432 let ty = Type {
2433 env: environment.clone(),
2434 ty: ty.clone(),
2435 _pd: PhantomCovariantLifetime::new(),
2436 };
2370 let ty = Type { env: environment.clone(), ty };
24372371 Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx }
24382372 })
24392373 .collect()
......@@ -2446,50 +2380,18 @@ impl Function {
24462380 generics: impl Iterator<Item = Type<'db>>,
24472381 ) -> Vec<Param<'db>> {
24482382 let environment = db.trait_environment(self.id.into());
2449 let parent_id: Option<GenericDefId> = match self.id.lookup(db).container {
2450 ItemContainerId::ImplId(it) => Some(it.into()),
2451 ItemContainerId::TraitId(it) => Some(it.into()),
2452 ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
2453 };
2454 let mut generics = generics.map(|it| it.ty);
2455 let parent_substs = parent_id.map(|id| {
2456 TyBuilder::subst_for_def(db, id, None)
2457 .fill(|x| match x {
2458 ParamKind::Type => generics
2459 .next()
2460 .unwrap_or_else(|| TyKind::Error.intern(Interner))
2461 .cast(Interner),
2462 ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
2463 ParamKind::Lifetime => error_lifetime().cast(Interner),
2464 })
2465 .build()
2466 });
2467
2468 let substs = TyBuilder::subst_for_def(db, self.id, parent_substs)
2469 .fill(|_| {
2470 let ty = generics.next().unwrap_or_else(|| TyKind::Error.intern(Interner));
2471 GenericArg::new(Interner, GenericArgData::Ty(ty))
2472 })
2473 .build();
24742383 let interner = DbInterner::new_with(db, None, None);
2475 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2476 let callable_sig = db
2477 .callable_item_signature(self.id.into())
2478 .instantiate(interner, args)
2479 .skip_binder()
2480 .to_chalk(interner);
2384 let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty));
2385 let callable_sig =
2386 db.callable_item_signature(self.id.into()).instantiate(interner, args).skip_binder();
24812387 let skip = if db.function_signature(self.id).has_self_param() { 1 } else { 0 };
24822388 callable_sig
2483 .params()
2389 .inputs()
24842390 .iter()
24852391 .enumerate()
24862392 .skip(skip)
24872393 .map(|(idx, ty)| {
2488 let ty = Type {
2489 env: environment.clone(),
2490 ty: ty.clone(),
2491 _pd: PhantomCovariantLifetime::new(),
2492 };
2394 let ty = Type { env: environment.clone(), ty };
24932395 Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx }
24942396 })
24952397 .collect()
......@@ -2628,10 +2530,11 @@ impl Function {
26282530 self,
26292531 db: &dyn HirDatabase,
26302532 span_formatter: impl Fn(FileId, TextRange) -> String,
2631 ) -> Result<String, ConstEvalError> {
2533 ) -> Result<String, ConstEvalError<'_>> {
2534 let interner = DbInterner::new_with(db, None, None);
26322535 let body = db.monomorphized_mir_body(
26332536 self.id.into(),
2634 Substitution::empty(Interner),
2537 GenericArgs::new_from_iter(interner, []),
26352538 db.trait_environment(self.id.into()),
26362539 )?;
26372540 let (result, output) = interpret_mir(db, body, false, None)?;
......@@ -2670,18 +2573,18 @@ pub enum Access {
26702573 Owned,
26712574}
26722575
2673impl From<hir_ty::Mutability> for Access {
2674 fn from(mutability: hir_ty::Mutability) -> Access {
2576impl From<hir_ty::next_solver::Mutability> for Access {
2577 fn from(mutability: hir_ty::next_solver::Mutability) -> Access {
26752578 match mutability {
2676 hir_ty::Mutability::Not => Access::Shared,
2677 hir_ty::Mutability::Mut => Access::Exclusive,
2579 hir_ty::next_solver::Mutability::Not => Access::Shared,
2580 hir_ty::next_solver::Mutability::Mut => Access::Exclusive,
26782581 }
26792582 }
26802583}
26812584
26822585#[derive(Clone, PartialEq, Eq, Hash, Debug)]
26832586pub struct Param<'db> {
2684 func: Callee,
2587 func: Callee<'db>,
26852588 /// The index in parameter list, including self parameter.
26862589 idx: usize,
26872590 ty: Type<'db>,
......@@ -2727,7 +2630,7 @@ impl<'db> Param<'db> {
27272630 }
27282631 }
27292632 Callee::Closure(closure, _) => {
2730 let c = db.lookup_intern_closure(closure.into());
2633 let c = db.lookup_intern_closure(closure);
27312634 let body = db.body(c.0);
27322635 if let Expr::Closure { args, .. } = &body[c.1]
27332636 && let Pat::Bind { id, .. } = &body[args[self.idx]]
......@@ -2771,17 +2674,12 @@ impl SelfParam {
27712674 }
27722675
27732676 pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> {
2774 let substs = TyBuilder::placeholder_subst(db, self.func);
2775 let interner = DbInterner::new_with(db, None, None);
2776 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2777 let callable_sig = db
2778 .callable_item_signature(self.func.into())
2779 .instantiate(interner, args)
2780 .skip_binder()
2781 .to_chalk(interner);
2677 // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
2678 let callable_sig =
2679 db.callable_item_signature(self.func.into()).instantiate_identity().skip_binder();
27822680 let environment = db.trait_environment(self.func.into());
2783 let ty = callable_sig.params()[0].clone();
2784 Type { env: environment, ty, _pd: PhantomCovariantLifetime::new() }
2681 let ty = callable_sig.inputs().as_slice()[0];
2682 Type { env: environment, ty }
27852683 }
27862684
27872685 // FIXME: Find better API to also handle const generics
......@@ -2790,36 +2688,13 @@ impl SelfParam {
27902688 db: &'db dyn HirDatabase,
27912689 generics: impl Iterator<Item = Type<'db>>,
27922690 ) -> Type<'db> {
2793 let parent_id: GenericDefId = match self.func.lookup(db).container {
2794 ItemContainerId::ImplId(it) => it.into(),
2795 ItemContainerId::TraitId(it) => it.into(),
2796 ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
2797 panic!("Never get here")
2798 }
2799 };
2800
2801 let mut generics = generics.map(|it| it.ty);
2802 let mut filler = |x: &_| match x {
2803 ParamKind::Type => {
2804 generics.next().unwrap_or_else(|| TyKind::Error.intern(Interner)).cast(Interner)
2805 }
2806 ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
2807 ParamKind::Lifetime => error_lifetime().cast(Interner),
2808 };
2809
2810 let parent_substs = TyBuilder::subst_for_def(db, parent_id, None).fill(&mut filler).build();
2811 let substs =
2812 TyBuilder::subst_for_def(db, self.func, Some(parent_substs)).fill(&mut filler).build();
28132691 let interner = DbInterner::new_with(db, None, None);
2814 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
2815 let callable_sig = db
2816 .callable_item_signature(self.func.into())
2817 .instantiate(interner, args)
2818 .skip_binder()
2819 .to_chalk(interner);
2692 let args = generic_args_from_tys(interner, self.func.into(), generics.map(|ty| ty.ty));
2693 let callable_sig =
2694 db.callable_item_signature(self.func.into()).instantiate(interner, args).skip_binder();
28202695 let environment = db.trait_environment(self.func.into());
2821 let ty = callable_sig.params()[0].clone();
2822 Type { env: environment, ty, _pd: PhantomCovariantLifetime::new() }
2696 let ty = callable_sig.inputs().as_slice()[0];
2697 Type { env: environment, ty }
28232698 }
28242699}
28252700
......@@ -2912,9 +2787,11 @@ impl Const {
29122787 }
29132788
29142789 /// Evaluate the constant.
2915 pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst, ConstEvalError> {
2916 db.const_eval(self.id.into(), Substitution::empty(Interner), None)
2917 .map(|it| EvaluatedConst { const_: it, def: self.id.into() })
2790 pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst<'_>, ConstEvalError<'_>> {
2791 let interner = DbInterner::new_with(db, None, None);
2792 let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity();
2793 db.const_eval(self.id.into(), GenericArgs::new_from_iter(interner, []), None)
2794 .map(|it| EvaluatedConst { const_: it, def: self.id.into(), ty })
29182795 }
29192796}
29202797
......@@ -2924,27 +2801,28 @@ impl HasVisibility for Const {
29242801 }
29252802}
29262803
2927pub struct EvaluatedConst {
2804pub struct EvaluatedConst<'db> {
29282805 def: DefWithBodyId,
2929 const_: hir_ty::Const,
2806 const_: hir_ty::next_solver::Const<'db>,
2807 ty: Ty<'db>,
29302808}
29312809
2932impl EvaluatedConst {
2810impl<'db> EvaluatedConst<'db> {
29332811 pub fn render(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
29342812 format!("{}", self.const_.display(db, display_target))
29352813 }
29362814
2937 pub fn render_debug(&self, db: &dyn HirDatabase) -> Result<String, MirEvalError> {
2938 let data = self.const_.data(Interner);
2939 if let TyKind::Scalar(s) = data.ty.kind(Interner)
2940 && matches!(s, Scalar::Int(_) | Scalar::Uint(_))
2941 && let hir_ty::ConstValue::Concrete(c) = &data.value
2942 && let hir_ty::ConstScalar::Bytes(b, _) = &c.interned
2815 pub fn render_debug(&self, db: &'db dyn HirDatabase) -> Result<String, MirEvalError<'db>> {
2816 let kind = self.const_.kind();
2817 if let ConstKind::Value(c) = kind
2818 && let ty = c.ty.kind()
2819 && let TyKind::Int(_) | TyKind::Uint(_) = ty
29432820 {
2821 let b = &c.value.inner().memory;
29442822 let value = u128::from_le_bytes(mir::pad16(b, false));
2945 let value_signed = i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_))));
2823 let value_signed = i128::from_le_bytes(mir::pad16(b, matches!(ty, TyKind::Int(_))));
29462824 let mut result =
2947 if let Scalar::Int(_) = s { value_signed.to_string() } else { value.to_string() };
2825 if let TyKind::Int(_) = ty { value_signed.to_string() } else { value.to_string() };
29482826 if value >= 10 {
29492827 format_to!(result, " ({value:#X})");
29502828 return Ok(result);
......@@ -2952,7 +2830,7 @@ impl EvaluatedConst {
29522830 return Ok(result);
29532831 }
29542832 }
2955 mir::render_const_using_debug_impl(db, self.def, &self.const_)
2833 mir::render_const_using_debug_impl(db, self.def, self.const_, self.ty)
29562834 }
29572835}
29582836
......@@ -2990,9 +2868,11 @@ impl Static {
29902868 }
29912869
29922870 /// Evaluate the static initializer.
2993 pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst, ConstEvalError> {
2994 db.const_eval(self.id.into(), Substitution::empty(Interner), None)
2995 .map(|it| EvaluatedConst { const_: it, def: self.id.into() })
2871 pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst<'_>, ConstEvalError<'_>> {
2872 let interner = DbInterner::new_with(db, None, None);
2873 let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity();
2874 db.const_eval(self.id.into(), GenericArgs::new_from_iter(interner, []), None)
2875 .map(|it| EvaluatedConst { const_: it, def: self.id.into(), ty })
29962876 }
29972877}
29982878
......@@ -3113,12 +2993,7 @@ pub struct TypeAlias {
31132993
31142994impl TypeAlias {
31152995 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
3116 let subst = db.generic_defaults(self.id.into());
3117 (subst.is_empty() && db.generic_params(self.id.into()).len_type_or_consts() != 0)
3118 || subst.iter().any(|ty| match ty.skip_binders().data(Interner) {
3119 GenericArgData::Ty(it) => it.is_unknown(),
3120 _ => false,
3121 })
2996 has_non_default_type_params(db, self.id.into())
31222997 }
31232998
31242999 pub fn module(self, db: &dyn HirDatabase) -> Module {
......@@ -3129,8 +3004,8 @@ impl TypeAlias {
31293004 Type::from_def(db, self.id)
31303005 }
31313006
3132 pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type<'_> {
3133 Type::from_def_placeholders(db, self.id)
3007 pub fn ty_params(self, db: &dyn HirDatabase) -> Type<'_> {
3008 Type::from_def_params(db, self.id)
31343009 }
31353010
31363011 pub fn name(self, db: &dyn HirDatabase) -> Name {
......@@ -3183,7 +3058,8 @@ impl BuiltinType {
31833058
31843059 pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
31853060 let core = Crate::core(db).map(|core| core.id).unwrap_or_else(|| db.all_crates()[0]);
3186 Type::new_for_crate(core, TyBuilder::builtin(self.inner))
3061 let interner = DbInterner::new_with(db, None, None);
3062 Type::new_for_crate(core, Ty::from_builtin_type(interner, self.inner))
31873063 }
31883064
31893065 pub fn name(self) -> Name {
......@@ -3859,14 +3735,13 @@ impl GenericDef {
38593735#[derive(Debug)]
38603736pub struct GenericSubstitution<'db> {
38613737 def: GenericDefId,
3862 subst: Substitution,
3738 subst: GenericArgs<'db>,
38633739 env: Arc<TraitEnvironment<'db>>,
3864 _pd: PhantomCovariantLifetime<'db>,
38653740}
38663741
38673742impl<'db> GenericSubstitution<'db> {
3868 fn new(def: GenericDefId, subst: Substitution, env: Arc<TraitEnvironment<'db>>) -> Self {
3869 Self { def, subst, env, _pd: PhantomCovariantLifetime::new() }
3743 fn new(def: GenericDefId, subst: GenericArgs<'db>, env: Arc<TraitEnvironment<'db>>) -> Self {
3744 Self { def, subst, env }
38703745 }
38713746
38723747 pub fn types(&self, db: &'db dyn HirDatabase) -> Vec<(Symbol, Type<'db>)> {
......@@ -3896,26 +3771,23 @@ impl<'db> GenericSubstitution<'db> {
38963771 TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()),
38973772 TypeOrConstParamData::ConstParamData(_) => None,
38983773 });
3899 let parent_len = self.subst.len(Interner)
3774 let parent_len = self.subst.len()
39003775 - generics
39013776 .iter_type_or_consts()
39023777 .filter(|g| matches!(g.1, TypeOrConstParamData::TypeParamData(..)))
39033778 .count();
3904 let container_params = self.subst.as_slice(Interner)[..parent_len]
3779 let container_params = self.subst.as_slice()[..parent_len]
39053780 .iter()
3906 .filter_map(|param| param.ty(Interner).cloned())
3781 .filter_map(|param| param.ty())
39073782 .zip(container_type_params.into_iter().flatten());
3908 let self_params = self.subst.as_slice(Interner)[parent_len..]
3783 let self_params = self.subst.as_slice()[parent_len..]
39093784 .iter()
3910 .filter_map(|param| param.ty(Interner).cloned())
3785 .filter_map(|param| param.ty())
39113786 .zip(type_params);
39123787 container_params
39133788 .chain(self_params)
39143789 .filter_map(|(ty, name)| {
3915 Some((
3916 name?.symbol().clone(),
3917 Type { ty, env: self.env.clone(), _pd: PhantomCovariantLifetime::new() },
3918 ))
3790 Some((name?.symbol().clone(), Type { ty, env: self.env.clone() }))
39193791 })
39203792 .collect()
39213793 }
......@@ -4021,7 +3893,7 @@ impl Local {
40213893 pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
40223894 let def = self.parent;
40233895 let infer = db.infer(def);
4024 let ty = infer[self.binding_id].clone();
3896 let ty = infer[self.binding_id];
40253897 Type::new(db, def, ty)
40263898 }
40273899
......@@ -4277,8 +4149,10 @@ impl TypeParam {
42774149
42784150 pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
42794151 let resolver = self.id.parent().resolver(db);
4280 let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx_no_index(db, self.id.into()))
4281 .intern(Interner);
4152 let interner = DbInterner::new_with(db, None, None);
4153 let index = hir_ty::param_idx(db, self.id.into()).unwrap();
4154 let name = self.name(db).symbol().clone();
4155 let ty = Ty::new_param(interner, self.id, index as u32, name);
42824156 Type::new_with_resolver_inner(db, &resolver, ty)
42834157 }
42844158
......@@ -4298,9 +4172,9 @@ impl TypeParam {
42984172 pub fn default(self, db: &dyn HirDatabase) -> Option<Type<'_>> {
42994173 let ty = generic_arg_from_param(db, self.id.into())?;
43004174 let resolver = self.id.parent().resolver(db);
4301 match ty.data(Interner) {
4302 GenericArgData::Ty(it) if *it.kind(Interner) != TyKind::Error => {
4303 Some(Type::new_with_resolver_inner(db, &resolver, it.clone()))
4175 match ty {
4176 GenericArg::Ty(it) if !it.is_ty_error() => {
4177 Some(Type::new_with_resolver_inner(db, &resolver, it))
43044178 }
43054179 _ => None,
43064180 }
......@@ -4361,7 +4235,7 @@ impl ConstParam {
43614235 }
43624236
43634237 pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
4364 Type::new(db, self.id.parent(), db.const_param_ty(self.id))
4238 Type::new(db, self.id.parent(), db.const_param_ty_ns(self.id))
43654239 }
43664240
43674241 pub fn default(
......@@ -4370,17 +4244,16 @@ impl ConstParam {
43704244 display_target: DisplayTarget,
43714245 ) -> Option<ast::ConstArg> {
43724246 let arg = generic_arg_from_param(db, self.id.into())?;
4373 known_const_to_ast(arg.constant(Interner)?, db, display_target)
4247 known_const_to_ast(arg.konst()?, db, display_target)
43744248 }
43754249}
43764250
4377fn generic_arg_from_param(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<GenericArg> {
4251fn generic_arg_from_param(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<GenericArg<'_>> {
43784252 let local_idx = hir_ty::param_idx(db, id)?;
4379 let defaults = db.generic_defaults(id.parent);
4380 let ty = defaults.get(local_idx)?.clone();
4381 let full_subst = TyBuilder::placeholder_subst(db, id.parent);
4382 let subst = &full_subst.as_slice(Interner)[..local_idx];
4383 Some(ty.substitute(Interner, &subst))
4253 let defaults = db.generic_defaults_ns(id.parent);
4254 let ty = defaults.get(local_idx)?;
4255 // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
4256 Some(ty.instantiate_identity())
43844257}
43854258
43864259#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
......@@ -4462,11 +4335,8 @@ impl Impl {
44624335 module.id.def_map(db)[module.id.local_id].scope.impls().map(Into::into).collect()
44634336 }
44644337
4465 pub fn all_for_type<'db>(
4466 db: &'db dyn HirDatabase,
4467 Type { ty, env, _pd: _ }: Type<'db>,
4468 ) -> Vec<Impl> {
4469 let def_crates = match method_resolution::def_crates(db, &ty, env.krate) {
4338 pub fn all_for_type<'db>(db: &'db dyn HirDatabase, Type { ty, env }: Type<'db>) -> Vec<Impl> {
4339 let def_crates = match method_resolution::def_crates(db, ty, env.krate) {
44704340 Some(def_crates) => def_crates,
44714341 None => return Vec::new(),
44724342 };
......@@ -4474,10 +4344,10 @@ impl Impl {
44744344 let filter = |impl_def: &Impl| {
44754345 let self_ty = impl_def.self_ty(db);
44764346 let rref = self_ty.remove_ref();
4477 ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty))
4347 ty.equals_ctor(rref.as_ref().map_or(self_ty.ty, |it| it.ty))
44784348 };
44794349
4480 let fp = TyFingerprint::for_inherent_impl(&ty);
4350 let fp = TyFingerprint::for_inherent_impl(ty);
44814351 let fp = match fp {
44824352 Some(fp) => fp,
44834353 None => return Vec::new(),
......@@ -4487,7 +4357,7 @@ impl Impl {
44874357 def_crates.iter().for_each(|&id| {
44884358 all.extend(
44894359 db.inherent_impls_in_crate(id)
4490 .for_self_ty(&ty)
4360 .for_self_ty(ty)
44914361 .iter()
44924362 .cloned()
44934363 .map(Self::from)
......@@ -4508,11 +4378,10 @@ impl Impl {
45084378 );
45094379 }
45104380
4511 if let Some(block) = ty.adt_id(Interner).and_then(|def| def.0.module(db).containing_block())
4512 {
4381 if let Some(block) = ty.as_adt().and_then(|(def, _)| def.module(db).containing_block()) {
45134382 if let Some(inherent_impls) = db.inherent_impls_in_block(block) {
45144383 all.extend(
4515 inherent_impls.for_self_ty(&ty).iter().cloned().map(Self::from).filter(filter),
4384 inherent_impls.for_self_ty(ty).iter().cloned().map(Self::from).filter(filter),
45164385 );
45174386 }
45184387 if let Some(trait_impls) = db.trait_impls_in_block(block) {
......@@ -4558,10 +4427,8 @@ impl Impl {
45584427
45594428 pub fn self_ty(self, db: &dyn HirDatabase) -> Type<'_> {
45604429 let resolver = self.id.resolver(db);
4561 let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
4562 let substs = TyBuilder::placeholder_subst(db, self.id);
4563 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
4564 let ty = db.impl_self_ty(self.id).instantiate(interner, args).to_chalk(interner);
4430 // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
4431 let ty = db.impl_self_ty(self.id).instantiate_identity();
45654432 Type::new_with_resolver_inner(db, &resolver, ty)
45664433 }
45674434
......@@ -4623,7 +4490,6 @@ impl Impl {
46234490pub struct TraitRef<'db> {
46244491 env: Arc<TraitEnvironment<'db>>,
46254492 trait_ref: hir_ty::next_solver::TraitRef<'db>,
4626 _pd: PhantomCovariantLifetime<'db>,
46274493}
46284494
46294495impl<'db> TraitRef<'db> {
......@@ -4635,7 +4501,7 @@ impl<'db> TraitRef<'db> {
46354501 let env = resolver
46364502 .generic_def()
46374503 .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d));
4638 TraitRef { env, trait_ref, _pd: PhantomCovariantLifetime::new() }
4504 TraitRef { env, trait_ref }
46394505 }
46404506
46414507 pub fn trait_(&self) -> Trait {
......@@ -4644,57 +4510,51 @@ impl<'db> TraitRef<'db> {
46444510
46454511 pub fn self_ty(&self) -> TypeNs<'_> {
46464512 let ty = self.trait_ref.self_ty();
4647 TypeNs { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() }
4513 TypeNs { env: self.env.clone(), ty }
46484514 }
46494515
46504516 /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
46514517 /// first argument is the `Self` type.
46524518 pub fn get_type_argument(&self, idx: usize) -> Option<TypeNs<'db>> {
4653 self.trait_ref.args.as_slice().get(idx).and_then(|arg| arg.ty()).map(|ty| TypeNs {
4654 env: self.env.clone(),
4655 ty,
4656 _pd: PhantomCovariantLifetime::new(),
4657 })
4519 self.trait_ref
4520 .args
4521 .as_slice()
4522 .get(idx)
4523 .and_then(|arg| arg.ty())
4524 .map(|ty| TypeNs { env: self.env.clone(), ty })
46584525 }
46594526}
46604527
46614528#[derive(Clone, Debug, PartialEq, Eq, Hash)]
4662pub struct Closure {
4663 id: ClosureId,
4664 subst: Substitution,
4529pub struct Closure<'db> {
4530 id: InternedClosureId,
4531 subst: GenericArgs<'db>,
46654532}
46664533
4667impl From<Closure> for ClosureId {
4668 fn from(value: Closure) -> Self {
4669 value.id
4670 }
4671}
4672
4673impl Closure {
4674 fn as_ty(self) -> Ty {
4675 TyKind::Closure(self.id, self.subst).intern(Interner)
4534impl<'db> Closure<'db> {
4535 fn as_ty(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
4536 let interner = DbInterner::new_with(db, None, None);
4537 Ty::new_closure(interner, self.id.into(), self.subst)
46764538 }
46774539
46784540 pub fn display_with_id(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
4679 self.clone()
4680 .as_ty()
4541 self.as_ty(db)
46814542 .display(db, display_target)
46824543 .with_closure_style(ClosureStyle::ClosureWithId)
46834544 .to_string()
46844545 }
46854546
46864547 pub fn display_with_impl(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
4687 self.clone()
4688 .as_ty()
4548 self.as_ty(db)
46894549 .display(db, display_target)
46904550 .with_closure_style(ClosureStyle::ImplFn)
46914551 .to_string()
46924552 }
46934553
4694 pub fn captured_items(&self, db: &dyn HirDatabase) -> Vec<ClosureCapture> {
4695 let owner = db.lookup_intern_closure((self.id).into()).0;
4696 let infer = &db.infer(owner);
4697 let info = infer.closure_info(&self.id);
4554 pub fn captured_items(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db>> {
4555 let owner = db.lookup_intern_closure(self.id).0;
4556 let infer = db.infer(owner);
4557 let info = infer.closure_info(self.id);
46984558 info.0
46994559 .iter()
47004560 .cloned()
......@@ -4702,36 +4562,33 @@ impl Closure {
47024562 .collect()
47034563 }
47044564
4705 pub fn capture_types<'db>(&self, db: &'db dyn HirDatabase) -> Vec<Type<'db>> {
4706 let owner = db.lookup_intern_closure((self.id).into()).0;
4707 let infer = &db.infer(owner);
4708 let (captures, _) = infer.closure_info(&self.id);
4565 pub fn capture_types(&self, db: &'db dyn HirDatabase) -> Vec<Type<'db>> {
4566 let owner = db.lookup_intern_closure(self.id).0;
4567 let infer = db.infer(owner);
4568 let (captures, _) = infer.closure_info(self.id);
4569 let env = db.trait_environment_for_body(owner);
47094570 captures
47104571 .iter()
4711 .map(|capture| Type {
4712 env: db.trait_environment_for_body(owner),
4713 ty: capture.ty(db, &self.subst),
4714 _pd: PhantomCovariantLifetime::new(),
4715 })
4572 .map(|capture| Type { env: env.clone(), ty: capture.ty(db, self.subst) })
47164573 .collect()
47174574 }
47184575
47194576 pub fn fn_trait(&self, db: &dyn HirDatabase) -> FnTrait {
4720 let owner = db.lookup_intern_closure((self.id).into()).0;
4721 let infer = &db.infer(owner);
4722 let info = infer.closure_info(&self.id);
4577 let owner = db.lookup_intern_closure(self.id).0;
4578 let infer = db.infer(owner);
4579 let info = infer.closure_info(self.id);
47234580 info.1
47244581 }
47254582}
47264583
47274584#[derive(Clone, Debug, PartialEq, Eq)]
4728pub struct ClosureCapture {
4585pub struct ClosureCapture<'db> {
47294586 owner: DefWithBodyId,
4730 closure: ClosureId,
4731 capture: hir_ty::CapturedItem,
4587 closure: InternedClosureId,
4588 capture: hir_ty::CapturedItem<'db>,
47324589}
47334590
4734impl ClosureCapture {
4591impl<'db> ClosureCapture<'db> {
47354592 pub fn local(&self) -> Local {
47364593 Local { parent: self.owner, binding_id: self.capture.local() }
47374594 }
......@@ -4845,15 +4702,14 @@ impl CaptureUsageSource {
48454702#[derive(Clone, PartialEq, Eq, Debug, Hash)]
48464703pub struct Type<'db> {
48474704 env: Arc<TraitEnvironment<'db>>,
4848 ty: Ty,
4849 _pd: PhantomCovariantLifetime<'db>,
4705 ty: Ty<'db>,
48504706}
48514707
48524708impl<'db> Type<'db> {
48534709 pub(crate) fn new_with_resolver(
48544710 db: &'db dyn HirDatabase,
48554711 resolver: &Resolver<'_>,
4856 ty: Ty,
4712 ty: Ty<'db>,
48574713 ) -> Self {
48584714 Type::new_with_resolver_inner(db, resolver, ty)
48594715 }
......@@ -4861,275 +4717,252 @@ impl<'db> Type<'db> {
48614717 pub(crate) fn new_with_resolver_inner(
48624718 db: &'db dyn HirDatabase,
48634719 resolver: &Resolver<'_>,
4864 ty: Ty,
4720 ty: Ty<'db>,
48654721 ) -> Self {
48664722 let environment = resolver
48674723 .generic_def()
48684724 .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d));
4869 Type { env: environment, ty, _pd: PhantomCovariantLifetime::new() }
4725 Type { env: environment, ty }
48704726 }
48714727
4872 pub(crate) fn new_for_crate(krate: base_db::Crate, ty: Ty) -> Self {
4873 Type { env: TraitEnvironment::empty(krate), ty, _pd: PhantomCovariantLifetime::new() }
4728 pub(crate) fn new_for_crate(krate: base_db::Crate, ty: Ty<'db>) -> Self {
4729 Type { env: TraitEnvironment::empty(krate), ty }
48744730 }
48754731
4876 fn new(db: &'db dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Self {
4732 fn new(db: &'db dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty<'db>) -> Self {
48774733 let resolver = lexical_env.resolver(db);
48784734 let environment = resolver
48794735 .generic_def()
48804736 .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d));
4881 Type { env: environment, ty, _pd: PhantomCovariantLifetime::new() }
4737 Type { env: environment, ty }
48824738 }
48834739
48844740 fn from_def(db: &'db dyn HirDatabase, def: impl Into<TyDefId> + HasResolver) -> Self {
48854741 let interner = DbInterner::new_with(db, None, None);
48864742 let ty = db.ty(def.into());
4887 let substs = TyBuilder::unknown_subst(
4888 db,
4889 match def.into() {
4890 TyDefId::AdtId(it) => GenericDefId::AdtId(it),
4891 TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
4892 TyDefId::BuiltinType(_) => {
4893 return Type::new(db, def, ty.skip_binder().to_chalk(interner));
4894 }
4895 },
4896 );
4897 let args: hir_ty::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
4898 Type::new(db, def, ty.instantiate(interner, args).to_chalk(interner))
4743 let def = match def.into() {
4744 TyDefId::AdtId(it) => GenericDefId::AdtId(it),
4745 TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
4746 TyDefId::BuiltinType(_) => {
4747 return Type::new(db, def, ty.skip_binder());
4748 }
4749 };
4750 let args = GenericArgs::error_for_item(interner, def.into());
4751 Type::new(db, def, ty.instantiate(interner, args))
48994752 }
49004753
4901 fn from_def_placeholders(
4902 db: &'db dyn HirDatabase,
4903 def: impl Into<TyDefId> + HasResolver,
4904 ) -> Self {
4905 let interner = DbInterner::new_with(db, None, None);
4754 // FIXME: We shouldn't leak `TyKind::Param`s.
4755 fn from_def_params(db: &'db dyn HirDatabase, def: impl Into<TyDefId> + HasResolver) -> Self {
49064756 let ty = db.ty(def.into());
4907 let substs = TyBuilder::placeholder_subst(
4908 db,
4909 match def.into() {
4910 TyDefId::AdtId(it) => GenericDefId::AdtId(it),
4911 TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
4912 TyDefId::BuiltinType(_) => {
4913 return Type::new(db, def, ty.skip_binder().to_chalk(interner));
4914 }
4915 },
4916 );
4917 let args: hir_ty::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
4918 Type::new(db, def, ty.instantiate(interner, args).to_chalk(interner))
4757 Type::new(db, def, ty.instantiate_identity())
49194758 }
49204759
49214760 fn from_value_def(
49224761 db: &'db dyn HirDatabase,
49234762 def: impl Into<ValueTyDefId> + HasResolver,
49244763 ) -> Self {
4764 let interner = DbInterner::new_with(db, None, None);
49254765 let Some(ty) = db.value_ty(def.into()) else {
4926 return Type::new(db, def, TyKind::Error.intern(Interner));
4766 return Type::new(db, def, Ty::new_error(interner, ErrorGuaranteed));
49274767 };
4928 let interner = DbInterner::new_with(db, None, None);
4929 let substs = TyBuilder::unknown_subst(
4930 db,
4931 match def.into() {
4932 ValueTyDefId::ConstId(it) => GenericDefId::ConstId(it),
4933 ValueTyDefId::FunctionId(it) => GenericDefId::FunctionId(it),
4934 ValueTyDefId::StructId(it) => GenericDefId::AdtId(AdtId::StructId(it)),
4935 ValueTyDefId::UnionId(it) => GenericDefId::AdtId(AdtId::UnionId(it)),
4936 ValueTyDefId::EnumVariantId(it) => {
4937 GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
4938 }
4939 ValueTyDefId::StaticId(_) => {
4940 return Type::new(db, def, ty.skip_binder().to_chalk(interner));
4941 }
4942 },
4943 );
4944 let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
4945 Type::new(db, def, ty.instantiate(interner, args).to_chalk(interner))
4768 let def = match def.into() {
4769 ValueTyDefId::ConstId(it) => GenericDefId::ConstId(it),
4770 ValueTyDefId::FunctionId(it) => GenericDefId::FunctionId(it),
4771 ValueTyDefId::StructId(it) => GenericDefId::AdtId(AdtId::StructId(it)),
4772 ValueTyDefId::UnionId(it) => GenericDefId::AdtId(AdtId::UnionId(it)),
4773 ValueTyDefId::EnumVariantId(it) => {
4774 GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
4775 }
4776 ValueTyDefId::StaticId(_) => {
4777 return Type::new(db, def, ty.skip_binder());
4778 }
4779 };
4780 let args = GenericArgs::error_for_item(interner, def.into());
4781 Type::new(db, def, ty.instantiate(interner, args))
49464782 }
49474783
49484784 pub fn new_slice(ty: Self) -> Self {
4949 Type { env: ty.env, ty: TyBuilder::slice(ty.ty), _pd: PhantomCovariantLifetime::new() }
4785 let interner = DbInterner::conjure();
4786 Type { env: ty.env, ty: Ty::new_slice(interner, ty.ty) }
49504787 }
49514788
49524789 pub fn new_tuple(krate: base_db::Crate, tys: &[Self]) -> Self {
4953 let tys = tys.iter().map(|it| it.ty.clone());
4954 Type {
4955 env: TraitEnvironment::empty(krate),
4956 ty: TyBuilder::tuple_with(tys),
4957 _pd: PhantomCovariantLifetime::new(),
4958 }
4790 let tys = tys.iter().map(|it| it.ty);
4791 let interner = DbInterner::conjure();
4792 Type { env: TraitEnvironment::empty(krate), ty: Ty::new_tup_from_iter(interner, tys) }
49594793 }
49604794
49614795 pub fn is_unit(&self) -> bool {
4962 matches!(self.ty.kind(Interner), TyKind::Tuple(0, ..))
4796 self.ty.is_unit()
49634797 }
49644798
49654799 pub fn is_bool(&self) -> bool {
4966 matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Bool))
4800 matches!(self.ty.kind(), TyKind::Bool)
49674801 }
49684802
49694803 pub fn is_str(&self) -> bool {
4970 matches!(self.ty.kind(Interner), TyKind::Str)
4804 matches!(self.ty.kind(), TyKind::Str)
49714805 }
49724806
49734807 pub fn is_never(&self) -> bool {
4974 matches!(self.ty.kind(Interner), TyKind::Never)
4808 matches!(self.ty.kind(), TyKind::Never)
49754809 }
49764810
49774811 pub fn is_mutable_reference(&self) -> bool {
4978 matches!(self.ty.kind(Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
4812 matches!(self.ty.kind(), TyKind::Ref(.., hir_ty::next_solver::Mutability::Mut))
49794813 }
49804814
49814815 pub fn is_reference(&self) -> bool {
4982 matches!(self.ty.kind(Interner), TyKind::Ref(..))
4816 matches!(self.ty.kind(), TyKind::Ref(..))
49834817 }
49844818
49854819 pub fn contains_reference(&self, db: &'db dyn HirDatabase) -> bool {
4986 return go(db, &self.ty);
4820 let interner = DbInterner::new_with(db, None, None);
4821 return self.ty.visit_with(&mut Visitor { interner }).is_break();
49874822
49884823 fn is_phantom_data(db: &dyn HirDatabase, adt_id: AdtId) -> bool {
49894824 match adt_id {
4990 hir_def::AdtId::StructId(s) => {
4825 AdtId::StructId(s) => {
49914826 let flags = db.struct_signature(s).flags;
49924827 flags.contains(StructFlags::IS_PHANTOM_DATA)
49934828 }
4994 hir_def::AdtId::UnionId(_) => false,
4995 hir_def::AdtId::EnumId(_) => false,
4829 AdtId::UnionId(_) | AdtId::EnumId(_) => false,
49964830 }
49974831 }
49984832
4999 fn go(db: &dyn HirDatabase, ty: &Ty) -> bool {
5000 match ty.kind(Interner) {
5001 // Reference itself
5002 TyKind::Ref(_, _, _) => true,
4833 struct Visitor<'db> {
4834 interner: DbInterner<'db>,
4835 }
50034836
5004 // For non-phantom_data adts we check variants/fields as well as generic parameters
5005 TyKind::Adt(adt_id, substitution) if !is_phantom_data(db, adt_id.0) => {
5006 let _variant_id_to_fields = |id: VariantId| {
5007 let variant_data = &id.fields(db);
5008 if variant_data.fields().is_empty() {
5009 vec![]
5010 } else {
5011 let field_types = db.field_types(id);
5012 variant_data
5013 .fields()
5014 .iter()
5015 .map(|(idx, _)| {
5016 field_types[idx].clone().substitute(Interner, substitution)
5017 })
5018 .filter(|it| !it.contains_unknown())
5019 .collect()
5020 }
5021 };
5022 let variant_id_to_fields = |_: VariantId| vec![];
4837 impl<'db> TypeVisitor<DbInterner<'db>> for Visitor<'db> {
4838 type Result = ControlFlow<()>;
50234839
5024 let variants = match adt_id.0 {
5025 hir_def::AdtId::StructId(id) => {
5026 vec![variant_id_to_fields(id.into())]
5027 }
5028 hir_def::AdtId::EnumId(id) => id
5029 .enum_variants(db)
5030 .variants
5031 .iter()
5032 .map(|&(variant_id, _, _)| variant_id_to_fields(variant_id.into()))
5033 .collect(),
5034 hir_def::AdtId::UnionId(id) => {
5035 vec![variant_id_to_fields(id.into())]
5036 }
5037 };
4840 fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
4841 match ty.kind() {
4842 // Reference itself
4843 TyKind::Ref(..) => ControlFlow::Break(()),
50384844
5039 variants
5040 .into_iter()
5041 .flat_map(|variant| variant.into_iter())
5042 .any(|ty| go(db, &ty))
5043 || substitution
5044 .iter(Interner)
5045 .filter_map(|x| x.ty(Interner))
5046 .any(|ty| go(db, ty))
5047 }
5048 // And for `PhantomData<T>`, we check `T`.
5049 TyKind::Adt(_, substitution)
5050 | TyKind::Tuple(_, substitution)
5051 | TyKind::OpaqueType(_, substitution)
5052 | TyKind::AssociatedType(_, substitution)
5053 | TyKind::Alias(AliasTy::Projection(ProjectionTy { substitution, .. }))
5054 | TyKind::FnDef(_, substitution) => {
5055 substitution.iter(Interner).filter_map(|x| x.ty(Interner)).any(|ty| go(db, ty))
5056 }
4845 // For non-phantom_data adts we check variants/fields as well as generic parameters
4846 TyKind::Adt(adt_def, args)
4847 if !is_phantom_data(self.interner.db(), adt_def.def_id().0) =>
4848 {
4849 let _variant_id_to_fields = |id: VariantId| {
4850 let variant_data = &id.fields(self.interner.db());
4851 if variant_data.fields().is_empty() {
4852 vec![]
4853 } else {
4854 let field_types = self.interner.db().field_types_ns(id);
4855 variant_data
4856 .fields()
4857 .iter()
4858 .map(|(idx, _)| {
4859 field_types[idx].instantiate(self.interner, args)
4860 })
4861 .filter(|it| !it.references_non_lt_error())
4862 .collect()
4863 }
4864 };
4865 let variant_id_to_fields = |_: VariantId| vec![];
50574866
5058 // For `[T]` or `*T` we check `T`
5059 TyKind::Array(ty, _) | TyKind::Slice(ty) | TyKind::Raw(_, ty) => go(db, ty),
4867 let variants: Vec<Vec<Ty<'db>>> = match adt_def.def_id().0 {
4868 AdtId::StructId(id) => {
4869 vec![variant_id_to_fields(id.into())]
4870 }
4871 AdtId::EnumId(id) => id
4872 .enum_variants(self.interner.db())
4873 .variants
4874 .iter()
4875 .map(|&(variant_id, _, _)| variant_id_to_fields(variant_id.into()))
4876 .collect(),
4877 AdtId::UnionId(id) => {
4878 vec![variant_id_to_fields(id.into())]
4879 }
4880 };
50604881
5061 // Consider everything else as not reference
5062 _ => false,
4882 variants
4883 .into_iter()
4884 .flat_map(|variant| variant.into_iter())
4885 .try_for_each(|ty| ty.visit_with(self))?;
4886 args.visit_with(self)
4887 }
4888 // And for `PhantomData<T>`, we check `T`.
4889 _ => ty.super_visit_with(self),
4890 }
50634891 }
50644892 }
50654893 }
50664894
50674895 pub fn as_reference(&self) -> Option<(Type<'db>, Mutability)> {
5068 let (ty, _lt, m) = self.ty.as_reference()?;
5069 let m = Mutability::from_mutable(matches!(m, hir_ty::Mutability::Mut));
5070 Some((self.derived(ty.clone()), m))
4896 let TyKind::Ref(_lt, ty, m) = self.ty.kind() else { return None };
4897 let m = Mutability::from_mutable(matches!(m, hir_ty::next_solver::Mutability::Mut));
4898 Some((self.derived(ty), m))
50714899 }
50724900
50734901 pub fn add_reference(&self, mutability: Mutability) -> Self {
4902 let interner = DbInterner::conjure();
50744903 let ty_mutability = match mutability {
5075 Mutability::Shared => hir_ty::Mutability::Not,
5076 Mutability::Mut => hir_ty::Mutability::Mut,
4904 Mutability::Shared => hir_ty::next_solver::Mutability::Not,
4905 Mutability::Mut => hir_ty::next_solver::Mutability::Mut,
50774906 };
5078 self.derived(TyKind::Ref(ty_mutability, error_lifetime(), self.ty.clone()).intern(Interner))
4907 self.derived(Ty::new_ref(interner, Region::error(interner), self.ty, ty_mutability))
50794908 }
50804909
50814910 pub fn is_slice(&self) -> bool {
5082 matches!(self.ty.kind(Interner), TyKind::Slice(..))
4911 matches!(self.ty.kind(), TyKind::Slice(..))
50834912 }
50844913
50854914 pub fn is_usize(&self) -> bool {
5086 matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
4915 matches!(self.ty.kind(), TyKind::Uint(rustc_type_ir::UintTy::Usize))
50874916 }
50884917
50894918 pub fn is_float(&self) -> bool {
5090 matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Float(_)))
4919 matches!(self.ty.kind(), TyKind::Float(_))
50914920 }
50924921
50934922 pub fn is_char(&self) -> bool {
5094 matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Char))
4923 matches!(self.ty.kind(), TyKind::Char)
50954924 }
50964925
50974926 pub fn is_int_or_uint(&self) -> bool {
5098 matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)))
4927 matches!(self.ty.kind(), TyKind::Int(_) | TyKind::Uint(_))
50994928 }
51004929
51014930 pub fn is_scalar(&self) -> bool {
5102 matches!(self.ty.kind(Interner), TyKind::Scalar(_))
4931 matches!(
4932 self.ty.kind(),
4933 TyKind::Bool | TyKind::Char | TyKind::Int(_) | TyKind::Uint(_) | TyKind::Float(_)
4934 )
51034935 }
51044936
51054937 pub fn is_tuple(&self) -> bool {
5106 matches!(self.ty.kind(Interner), TyKind::Tuple(..))
4938 matches!(self.ty.kind(), TyKind::Tuple(..))
51074939 }
51084940
51094941 pub fn remove_ref(&self) -> Option<Type<'db>> {
5110 match &self.ty.kind(Interner) {
5111 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
4942 match self.ty.kind() {
4943 TyKind::Ref(_, ty, _) => Some(self.derived(ty)),
51124944 _ => None,
51134945 }
51144946 }
51154947
51164948 pub fn as_slice(&self) -> Option<Type<'db>> {
5117 match &self.ty.kind(Interner) {
5118 TyKind::Slice(ty) => Some(self.derived(ty.clone())),
4949 match self.ty.kind() {
4950 TyKind::Slice(ty) => Some(self.derived(ty)),
51194951 _ => None,
51204952 }
51214953 }
51224954
51234955 pub fn strip_references(&self) -> Self {
5124 self.derived(self.ty.strip_references().clone())
4956 self.derived(self.ty.strip_references())
51254957 }
51264958
4959 // FIXME: This is the same as `remove_ref()`, remove one of these methods.
51274960 pub fn strip_reference(&self) -> Self {
5128 self.derived(self.ty.strip_reference().clone())
4961 self.derived(self.ty.strip_reference())
51294962 }
51304963
51314964 pub fn is_unknown(&self) -> bool {
5132 self.ty.is_unknown()
4965 self.ty.is_ty_error()
51334966 }
51344967
51354968 /// Checks that particular type `ty` implements `std::future::IntoFuture` or
......@@ -5145,9 +4978,7 @@ impl<'db> Type<'db> {
51454978 })
51464979 .or_else(|| LangItem::Future.resolve_trait(db, self.env.krate))?;
51474980
5148 let canonical_ty =
5149 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
5150 if !method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, trait_) {
4981 if !traits::implements_trait_unique(self.ty, db, self.env.clone(), trait_) {
51514982 return None;
51524983 }
51534984
......@@ -5175,9 +5006,7 @@ impl<'db> Type<'db> {
51755006 let Some(iterator_trait) = LangItem::Iterator.resolve_trait(db, self.env.krate) else {
51765007 return false;
51775008 };
5178 let canonical_ty =
5179 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
5180 method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, iterator_trait)
5009 traits::implements_trait_unique(self.ty, db, self.env.clone(), iterator_trait)
51815010 }
51825011
51835012 /// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
......@@ -5190,9 +5019,7 @@ impl<'db> Type<'db> {
51905019 },
51915020 )?;
51925021
5193 let canonical_ty =
5194 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
5195 if !method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, trait_) {
5022 if !traits::implements_trait_unique(self.ty, db, self.env.clone(), trait_) {
51965023 return None;
51975024 }
51985025
......@@ -5212,43 +5039,18 @@ impl<'db> Type<'db> {
52125039 None => return false,
52135040 };
52145041
5215 let canonical_ty =
5216 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
5217 method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, fnonce_trait)
5042 traits::implements_trait_unique(self.ty, db, self.env.clone(), fnonce_trait)
52185043 }
52195044
52205045 // FIXME: Find better API that also handles const generics
52215046 pub fn impls_trait(&self, db: &'db dyn HirDatabase, trait_: Trait, args: &[Type<'db>]) -> bool {
5222 let mut it = args.iter().map(|t| t.ty.clone());
5223 let trait_ref = TyBuilder::trait_ref(db, trait_.id)
5224 .push(self.ty.clone())
5225 .fill(|x| {
5226 match x {
5227 ParamKind::Type => {
5228 it.next().unwrap_or_else(|| TyKind::Error.intern(Interner)).cast(Interner)
5229 }
5230 ParamKind::Const(ty) => {
5231 // FIXME: this code is not covered in tests.
5232 unknown_const_as_generic(ty.clone())
5233 }
5234 ParamKind::Lifetime => error_lifetime().cast(Interner),
5235 }
5236 })
5237 .build();
5238
5239 let goal = Canonical {
5240 value: hir_ty::InEnvironment::new(
5241 &self.env.env.to_chalk(DbInterner::new_with(
5242 db,
5243 Some(self.env.krate),
5244 self.env.block,
5245 )),
5246 trait_ref.cast(Interner),
5247 ),
5248 binders: CanonicalVarKinds::empty(Interner),
5249 };
5250
5251 !db.trait_solve(self.env.krate, self.env.block, goal).no_solution()
5047 let interner = DbInterner::new_with(db, None, None);
5048 let args = generic_args_from_tys(
5049 interner,
5050 trait_.id.into(),
5051 std::iter::once(self.ty).chain(args.iter().map(|ty| ty.ty)),
5052 );
5053 traits::implements_trait_unique_with_args(db, self.env.clone(), trait_.id, args)
52525054 }
52535055
52545056 pub fn normalize_trait_assoc_type(
......@@ -5257,27 +5059,25 @@ impl<'db> Type<'db> {
52575059 args: &[Type<'db>],
52585060 alias: TypeAlias,
52595061 ) -> Option<Type<'db>> {
5260 let mut args = args.iter();
5261 let trait_id = match alias.id.lookup(db).container {
5262 ItemContainerId::TraitId(id) => id,
5263 _ => unreachable!("non assoc type alias reached in normalize_trait_assoc_type()"),
5264 };
5265 let parent_subst = TyBuilder::subst_for_def(db, trait_id, None)
5266 .push(self.ty.clone())
5267 .fill(|it| {
5268 // FIXME: this code is not covered in tests.
5269 match it {
5270 ParamKind::Type => args.next().unwrap().ty.clone().cast(Interner),
5271 ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
5272 ParamKind::Lifetime => error_lifetime().cast(Interner),
5273 }
5274 })
5275 .build();
5062 let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block);
5063 let args = generic_args_from_tys(
5064 interner,
5065 alias.id.into(),
5066 std::iter::once(self.ty).chain(args.iter().map(|ty| ty.ty)),
5067 );
52765068 // FIXME: We don't handle GATs yet.
5277 let projection = TyBuilder::assoc_type_projection(db, alias.id, Some(parent_subst)).build();
5069 let projection = Ty::new_alias(
5070 interner,
5071 AliasTyKind::Projection,
5072 AliasTy::new(interner, alias.id.into(), args),
5073 );
52785074
5279 let ty = db.normalize_projection(projection, self.env.clone());
5280 if ty.is_unknown() { None } else { Some(self.derived(ty)) }
5075 // FIXME(next-solver): This needs to be `PostAnalysis`, but this currently causes errors due to our incorrect
5076 // handling of opaques. `non_body_analysis()` will also cause errors (from not revealing opaques inside their
5077 // defining places), so we choose between two bad options.
5078 let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
5079 let ty = structurally_normalize_ty(&infcx, projection, self.env.clone());
5080 if ty.is_ty_error() { None } else { Some(self.derived(ty)) }
52815081 }
52825082
52835083 pub fn is_copy(&self, db: &'db dyn HirDatabase) -> bool {
......@@ -5288,23 +5088,27 @@ impl<'db> Type<'db> {
52885088 }
52895089
52905090 pub fn as_callable(&self, db: &'db dyn HirDatabase) -> Option<Callable<'db>> {
5291 let callee = match self.ty.kind(Interner) {
5292 TyKind::Closure(id, subst) => Callee::Closure(*id, subst.clone()),
5293 TyKind::Function(_) => Callee::FnPtr,
5294 TyKind::FnDef(..) => Callee::Def(self.ty.callable_def(db)?),
5091 let interner = DbInterner::new_with(db, None, None);
5092 let callee = match self.ty.kind() {
5093 TyKind::Closure(id, subst) => Callee::Closure(id.0, subst),
5094 TyKind::FnPtr(..) => Callee::FnPtr,
5095 TyKind::FnDef(id, _) => Callee::Def(id.0),
52955096 kind => {
52965097 // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment
5297 let (ty, kind) = if let TyKind::Ref(_, _, ty) = kind {
5298 (ty, ty.kind(Interner))
5098 let (ty, kind) = if let TyKind::Ref(_, ty, _) = kind {
5099 (ty, ty.kind())
52995100 } else {
5300 (&self.ty, kind)
5101 (self.ty, kind)
53015102 };
53025103 if let TyKind::Closure(closure, subst) = kind {
5303 let sig = ty.callable_sig(db)?;
5104 let sig = subst
5105 .split_closure_args_untupled()
5106 .closure_sig_as_fn_ptr_ty
5107 .callable_sig(interner)?;
53045108 return Some(Callable {
53055109 ty: self.clone(),
53065110 sig,
5307 callee: Callee::Closure(*closure, subst.clone()),
5111 callee: Callee::Closure(closure.0, subst),
53085112 is_bound_method: false,
53095113 });
53105114 }
......@@ -5318,32 +5122,32 @@ impl<'db> Type<'db> {
53185122 }
53195123 };
53205124
5321 let sig = self.ty.callable_sig(db)?;
5125 let sig = self.ty.callable_sig(interner)?;
53225126 Some(Callable { ty: self.clone(), sig, callee, is_bound_method: false })
53235127 }
53245128
53255129 pub fn is_closure(&self) -> bool {
5326 matches!(self.ty.kind(Interner), TyKind::Closure { .. })
5130 matches!(self.ty.kind(), TyKind::Closure { .. })
53275131 }
53285132
5329 pub fn as_closure(&self) -> Option<Closure> {
5330 match self.ty.kind(Interner) {
5331 TyKind::Closure(id, subst) => Some(Closure { id: *id, subst: subst.clone() }),
5133 pub fn as_closure(&self) -> Option<Closure<'db>> {
5134 match self.ty.kind() {
5135 TyKind::Closure(id, subst) => Some(Closure { id: id.0, subst }),
53325136 _ => None,
53335137 }
53345138 }
53355139
53365140 pub fn is_fn(&self) -> bool {
5337 matches!(self.ty.kind(Interner), TyKind::FnDef(..) | TyKind::Function { .. })
5141 matches!(self.ty.kind(), TyKind::FnDef(..) | TyKind::FnPtr { .. })
53385142 }
53395143
53405144 pub fn is_array(&self) -> bool {
5341 matches!(self.ty.kind(Interner), TyKind::Array(..))
5145 matches!(self.ty.kind(), TyKind::Array(..))
53425146 }
53435147
53445148 pub fn is_packed(&self, db: &'db dyn HirDatabase) -> bool {
5345 let adt_id = match *self.ty.kind(Interner) {
5346 TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
5149 let adt_id = match self.ty.kind() {
5150 TyKind::Adt(adt_def, ..) => adt_def.def_id().0,
53475151 _ => return false,
53485152 };
53495153
......@@ -5355,99 +5159,64 @@ impl<'db> Type<'db> {
53555159 }
53565160
53575161 pub fn is_raw_ptr(&self) -> bool {
5358 matches!(self.ty.kind(Interner), TyKind::Raw(..))
5162 matches!(self.ty.kind(), TyKind::RawPtr(..))
53595163 }
53605164
53615165 pub fn remove_raw_ptr(&self) -> Option<Type<'db>> {
5362 if let TyKind::Raw(_, ty) = self.ty.kind(Interner) {
5363 Some(self.derived(ty.clone()))
5364 } else {
5365 None
5366 }
5166 if let TyKind::RawPtr(ty, _) = self.ty.kind() { Some(self.derived(ty)) } else { None }
53675167 }
53685168
53695169 pub fn contains_unknown(&self) -> bool {
5370 // FIXME: When we get rid of `ConstScalar::Unknown`, we can just look at precomputed
5371 // `TypeFlags` in `TyData`.
5372 return go(&self.ty);
5373
5374 fn go(ty: &Ty) -> bool {
5375 match ty.kind(Interner) {
5376 TyKind::Error => true,
5377
5378 TyKind::Adt(_, substs)
5379 | TyKind::AssociatedType(_, substs)
5380 | TyKind::Tuple(_, substs)
5381 | TyKind::OpaqueType(_, substs)
5382 | TyKind::FnDef(_, substs)
5383 | TyKind::Closure(_, substs) => {
5384 substs.iter(Interner).filter_map(|a| a.ty(Interner)).any(go)
5385 }
5386
5387 TyKind::Array(_ty, len) if len.is_unknown() => true,
5388 TyKind::Array(ty, _)
5389 | TyKind::Slice(ty)
5390 | TyKind::Raw(_, ty)
5391 | TyKind::Ref(_, _, ty) => go(ty),
5392
5393 TyKind::Scalar(_)
5394 | TyKind::Str
5395 | TyKind::Never
5396 | TyKind::Placeholder(_)
5397 | TyKind::BoundVar(_)
5398 | TyKind::InferenceVar(_, _)
5399 | TyKind::Dyn(_)
5400 | TyKind::Function(_)
5401 | TyKind::Alias(_)
5402 | TyKind::Foreign(_)
5403 | TyKind::Coroutine(..)
5404 | TyKind::CoroutineWitness(..) => false,
5405 }
5406 }
5170 self.ty.references_non_lt_error()
54075171 }
54085172
54095173 pub fn fields(&self, db: &'db dyn HirDatabase) -> Vec<(Field, Self)> {
5410 let (variant_id, substs) = match self.ty.kind(Interner) {
5411 TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), substs) => ((*s).into(), substs),
5412 TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), substs) => ((*u).into(), substs),
5174 let interner = DbInterner::new_with(db, None, None);
5175 let (variant_id, substs) = match self.ty.kind() {
5176 TyKind::Adt(adt_def, substs) => {
5177 let id = match adt_def.def_id().0 {
5178 AdtId::StructId(id) => id.into(),
5179 AdtId::UnionId(id) => id.into(),
5180 AdtId::EnumId(_) => return Vec::new(),
5181 };
5182 (id, substs)
5183 }
54135184 _ => return Vec::new(),
54145185 };
54155186
5416 db.field_types(variant_id)
5187 db.field_types_ns(variant_id)
54175188 .iter()
54185189 .map(|(local_id, ty)| {
54195190 let def = Field { parent: variant_id.into(), id: local_id };
5420 let ty = ty.clone().substitute(Interner, substs);
5191 let ty = ty.instantiate(interner, substs);
54215192 (def, self.derived(ty))
54225193 })
54235194 .collect()
54245195 }
54255196
54265197 pub fn tuple_fields(&self, _db: &'db dyn HirDatabase) -> Vec<Self> {
5427 if let TyKind::Tuple(_, substs) = &self.ty.kind(Interner) {
5428 substs
5429 .iter(Interner)
5430 .map(|ty| self.derived(ty.assert_ty_ref(Interner).clone()))
5431 .collect()
5198 if let TyKind::Tuple(substs) = self.ty.kind() {
5199 substs.iter().map(|ty| self.derived(ty)).collect()
54325200 } else {
54335201 Vec::new()
54345202 }
54355203 }
54365204
54375205 pub fn as_array(&self, db: &'db dyn HirDatabase) -> Option<(Self, usize)> {
5438 if let TyKind::Array(ty, len) = &self.ty.kind(Interner) {
5439 try_const_usize(db, len).map(|it| (self.derived(ty.clone()), it as usize))
5206 if let TyKind::Array(ty, len) = self.ty.kind() {
5207 try_const_usize(db, len).map(|it| (self.derived(ty), it as usize))
54405208 } else {
54415209 None
54425210 }
54435211 }
54445212
54455213 pub fn fingerprint_for_trait_impl(&self) -> Option<TyFingerprint> {
5446 TyFingerprint::for_trait_impl(&self.ty)
5214 TyFingerprint::for_trait_impl(self.ty)
54475215 }
54485216
5449 pub(crate) fn canonical(&self) -> Canonical<Ty> {
5450 hir_ty::replace_errors_with_variables(&self.ty)
5217 pub(crate) fn canonical(&self, db: &'db dyn HirDatabase) -> Canonical<'db, Ty<'db>> {
5218 let interner = DbInterner::new_with(db, None, None);
5219 hir_ty::replace_errors_with_variables(interner, &self.ty)
54515220 }
54525221
54535222 /// Returns types that this type dereferences to (including this type itself). The returned
......@@ -5459,9 +5228,10 @@ impl<'db> Type<'db> {
54595228 self.autoderef_(db).map(move |ty| self.derived(ty))
54605229 }
54615230
5462 fn autoderef_(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Ty> {
5231 fn autoderef_(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Ty<'db>> {
5232 let interner = DbInterner::new_with(db, None, None);
54635233 // There should be no inference vars in types passed here
5464 let canonical = hir_ty::replace_errors_with_variables(&self.ty);
5234 let canonical = hir_ty::replace_errors_with_variables(interner, &self.ty);
54655235 autoderef(db, self.env.clone(), canonical)
54665236 }
54675237
......@@ -5487,14 +5257,15 @@ impl<'db> Type<'db> {
54875257 krate: Crate,
54885258 callback: &mut dyn FnMut(AssocItemId) -> bool,
54895259 ) {
5490 let def_crates = match method_resolution::def_crates(db, &self.ty, krate.id) {
5260 let ty_ns = self.ty;
5261 let def_crates = match method_resolution::def_crates(db, ty_ns, krate.id) {
54915262 Some(it) => it,
54925263 None => return,
54935264 };
54945265 for krate in def_crates {
54955266 let impls = db.inherent_impls_in_crate(krate);
54965267
5497 for impl_def in impls.for_self_ty(&self.ty) {
5268 for impl_def in impls.for_self_ty(ty_ns) {
54985269 for &(_, item) in impl_def.impl_items(db).items.iter() {
54995270 if callback(item) {
55005271 return;
......@@ -5523,15 +5294,13 @@ impl<'db> Type<'db> {
55235294 /// - "U"
55245295 /// ```
55255296 pub fn type_arguments(&self) -> impl Iterator<Item = Type<'db>> + '_ {
5526 self.ty
5527 .strip_references()
5528 .as_adt()
5529 .map(|(_, substs)| substs)
5530 .or_else(|| self.ty.strip_references().as_tuple())
5531 .into_iter()
5532 .flat_map(|substs| substs.iter(Interner))
5533 .filter_map(|arg| arg.ty(Interner).cloned())
5534 .map(move |ty| self.derived(ty))
5297 match self.ty.strip_references().kind() {
5298 TyKind::Adt(_, substs) => Either::Left(substs.types().map(move |ty| self.derived(ty))),
5299 TyKind::Tuple(substs) => {
5300 Either::Right(Either::Left(substs.iter().map(move |ty| self.derived(ty))))
5301 }
5302 _ => Either::Right(Either::Right(std::iter::empty())),
5303 }
55355304 }
55365305
55375306 /// Iterates its type and const arguments
......@@ -5561,15 +5330,13 @@ impl<'db> Type<'db> {
55615330 .strip_references()
55625331 .as_adt()
55635332 .into_iter()
5564 .flat_map(|(_, substs)| substs.iter(Interner))
5565 .filter_map(move |arg| {
5566 // arg can be either a `Ty` or `constant`
5567 if let Some(ty) = arg.ty(Interner) {
5568 Some(format_smolstr!("{}", ty.display(db, display_target)))
5569 } else {
5570 arg.constant(Interner)
5571 .map(|const_| format_smolstr!("{}", const_.display(db, display_target)))
5333 .flat_map(|(_, substs)| substs.iter())
5334 .filter_map(move |arg| match arg {
5335 GenericArg::Ty(ty) => Some(format_smolstr!("{}", ty.display(db, display_target))),
5336 GenericArg::Const(const_) => {
5337 Some(format_smolstr!("{}", const_.display(db, display_target)))
55725338 }
5339 GenericArg::Lifetime(_) => None,
55735340 })
55745341 }
55755342
......@@ -5686,8 +5453,9 @@ impl<'db> Type<'db> {
56865453 ?name,
56875454 )
56885455 .entered();
5456 let interner = DbInterner::new_with(db, None, None);
56895457 // There should be no inference vars in types passed here
5690 let canonical = hir_ty::replace_errors_with_variables(&self.ty);
5458 let canonical = hir_ty::replace_errors_with_variables(interner, &self.ty);
56915459
56925460 let krate = scope.krate();
56935461 let environment = scope
......@@ -5696,11 +5464,7 @@ impl<'db> Type<'db> {
56965464 .map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d));
56975465
56985466 _ = method_resolution::iterate_method_candidates_dyn(
5699 &canonical.to_nextsolver(DbInterner::new_with(
5700 db,
5701 Some(environment.krate),
5702 environment.block,
5703 )),
5467 &canonical,
57045468 db,
57055469 environment,
57065470 traits_in_scope,
......@@ -5778,7 +5542,8 @@ impl<'db> Type<'db> {
57785542 }
57795543 }
57805544
5781 let canonical = hir_ty::replace_errors_with_variables(&self.ty);
5545 let interner = DbInterner::new_with(db, None, None);
5546 let canonical = hir_ty::replace_errors_with_variables(interner, &self.ty);
57825547
57835548 let krate = scope.krate();
57845549 let environment = scope
......@@ -5787,11 +5552,7 @@ impl<'db> Type<'db> {
57875552 .map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d));
57885553
57895554 _ = method_resolution::iterate_path_candidates(
5790 &canonical.to_nextsolver(DbInterner::new_with(
5791 db,
5792 Some(environment.krate),
5793 environment.block,
5794 )),
5555 &canonical,
57955556 db,
57965557 environment,
57975558 traits_in_scope,
......@@ -5830,7 +5591,7 @@ impl<'db> Type<'db> {
58305591 pub fn env_traits(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Trait> {
58315592 let _p = tracing::info_span!("env_traits").entered();
58325593 self.autoderef_(db)
5833 .filter(|ty| matches!(ty.kind(Interner), TyKind::Placeholder(_)))
5594 .filter(|ty| matches!(ty.kind(), TyKind::Param(_)))
58345595 .flat_map(|ty| {
58355596 self.env
58365597 .traits_in_scope_from_clauses(ty)
......@@ -5841,136 +5602,66 @@ impl<'db> Type<'db> {
58415602
58425603 pub fn as_impl_traits(&self, db: &'db dyn HirDatabase) -> Option<impl Iterator<Item = Trait>> {
58435604 self.ty.impl_trait_bounds(db).map(|it| {
5844 it.into_iter().filter_map(|pred| match pred.skip_binders() {
5845 hir_ty::WhereClause::Implemented(trait_ref) => {
5846 Some(Trait::from(trait_ref.hir_trait_id()))
5847 }
5605 it.into_iter().filter_map(|pred| match pred.kind().skip_binder() {
5606 ClauseKind::Trait(trait_ref) => Some(Trait::from(trait_ref.def_id().0)),
58485607 _ => None,
58495608 })
58505609 })
58515610 }
58525611
58535612 pub fn as_associated_type_parent_trait(&self, db: &'db dyn HirDatabase) -> Option<Trait> {
5854 self.ty.associated_type_parent_trait(db).map(Into::into)
5613 let TyKind::Alias(AliasTyKind::Projection, alias) = self.ty.kind() else { return None };
5614 match alias.def_id.expect_type_alias().loc(db).container {
5615 ItemContainerId::TraitId(id) => Some(Trait { id }),
5616 _ => None,
5617 }
58555618 }
58565619
5857 fn derived(&self, ty: Ty) -> Self {
5858 Type { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() }
5620 fn derived(&self, ty: Ty<'db>) -> Self {
5621 Type { env: self.env.clone(), ty }
58595622 }
58605623
5861 /// Visits every type, including generic arguments, in this type. `cb` is called with type
5624 /// Visits every type, including generic arguments, in this type. `callback` is called with type
58625625 /// itself first, and then with its generic arguments.
5863 pub fn walk(&self, db: &'db dyn HirDatabase, mut cb: impl FnMut(Type<'db>)) {
5864 fn walk_substs<'db>(
5626 pub fn walk(&self, db: &'db dyn HirDatabase, callback: impl FnMut(Type<'db>)) {
5627 struct Visitor<'db, F> {
58655628 db: &'db dyn HirDatabase,
5866 type_: &Type<'db>,
5867 substs: &Substitution,
5868 cb: &mut impl FnMut(Type<'db>),
5869 ) {
5870 for ty in substs.iter(Interner).filter_map(|a| a.ty(Interner)) {
5871 walk_type(db, &type_.derived(ty.clone()), cb);
5872 }
5629 env: Arc<TraitEnvironment<'db>>,
5630 callback: F,
5631 visited: FxHashSet<Ty<'db>>,
58735632 }
5633 impl<'db, F> TypeVisitor<DbInterner<'db>> for Visitor<'db, F>
5634 where
5635 F: FnMut(Type<'db>),
5636 {
5637 type Result = ();
58745638
5875 fn walk_bounds<'db>(
5876 db: &'db dyn HirDatabase,
5877 type_: &Type<'db>,
5878 bounds: &[QuantifiedWhereClause],
5879 cb: &mut impl FnMut(Type<'db>),
5880 ) {
5881 for pred in bounds {
5882 if let WhereClause::Implemented(trait_ref) = pred.skip_binders() {
5883 cb(type_.clone());
5884 // skip the self type. it's likely the type we just got the bounds from
5885 if let [self_ty, params @ ..] = trait_ref.substitution.as_slice(Interner) {
5886 for ty in
5887 params.iter().filter(|&ty| ty != self_ty).filter_map(|a| a.ty(Interner))
5888 {
5889 walk_type(db, &type_.derived(ty.clone()), cb);
5890 }
5891 }
5639 fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
5640 if !self.visited.insert(ty) {
5641 return;
58925642 }
5893 }
5894 }
58955643
5896 fn walk_type<'db>(
5897 db: &'db dyn HirDatabase,
5898 type_: &Type<'db>,
5899 cb: &mut impl FnMut(Type<'db>),
5900 ) {
5901 let ty = type_.ty.strip_references();
5902 match ty.kind(Interner) {
5903 TyKind::Adt(_, substs) => {
5904 cb(type_.derived(ty.clone()));
5905 walk_substs(db, type_, substs, cb);
5906 }
5907 TyKind::AssociatedType(_, substs)
5908 | TyKind::Alias(AliasTy::Projection(hir_ty::ProjectionTy {
5909 substitution: substs,
5910 ..
5911 })) => {
5912 if ty.associated_type_parent_trait(db).is_some() {
5913 cb(type_.derived(ty.clone()));
5914 }
5915 walk_substs(db, type_, substs, cb);
5916 }
5917 TyKind::OpaqueType(_, subst) => {
5918 if let Some(bounds) = ty.impl_trait_bounds(db) {
5919 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
5920 }
5644 (self.callback)(Type { env: self.env.clone(), ty });
59215645
5922 walk_substs(db, type_, subst, cb);
5646 if let Some(bounds) = ty.impl_trait_bounds(self.db) {
5647 bounds.visit_with(self);
59235648 }
5924 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
5925 if let Some(bounds) = ty.impl_trait_bounds(db) {
5926 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
5927 }
59285649
5929 walk_substs(db, type_, &opaque_ty.substitution, cb);
5930 }
5931 TyKind::Placeholder(_) => {
5932 cb(type_.derived(ty.clone()));
5933 if let Some(bounds) = ty.impl_trait_bounds(db) {
5934 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
5935 }
5936 }
5937 TyKind::Dyn(bounds) => {
5938 walk_bounds(
5939 db,
5940 &type_.derived(ty.clone()),
5941 bounds.bounds.skip_binders().interned(),
5942 cb,
5943 );
5944 }
5945
5946 TyKind::Ref(_, _, ty)
5947 | TyKind::Raw(_, ty)
5948 | TyKind::Array(ty, _)
5949 | TyKind::Slice(ty) => {
5950 walk_type(db, &type_.derived(ty.clone()), cb);
5951 }
5952
5953 TyKind::FnDef(_, substs)
5954 | TyKind::Tuple(_, substs)
5955 | TyKind::Closure(.., substs) => {
5956 walk_substs(db, type_, substs, cb);
5957 }
5958 TyKind::Function(hir_ty::FnPointer { substitution, .. }) => {
5959 walk_substs(db, type_, &substitution.0, cb);
5960 }
5961
5962 _ => {}
5650 ty.super_visit_with(self);
59635651 }
59645652 }
59655653
5966 walk_type(db, self, &mut cb);
5654 let mut visitor =
5655 Visitor { db, env: self.env.clone(), callback, visited: FxHashSet::default() };
5656 self.ty.visit_with(&mut visitor);
59675657 }
59685658 /// Check if type unifies with another type.
59695659 ///
59705660 /// Note that we consider placeholder types to unify with everything.
59715661 /// For example `Option<T>` and `Option<U>` unify although there is unresolved goal `T = U`.
59725662 pub fn could_unify_with(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool {
5973 let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), other.ty.clone()));
5663 let interner = DbInterner::new_with(db, None, None);
5664 let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, other.ty));
59745665 hir_ty::could_unify(db, self.env.clone(), &tys)
59755666 }
59765667
......@@ -5979,66 +5670,62 @@ impl<'db> Type<'db> {
59795670 /// This means that placeholder types are not considered to unify if there are any bounds set on
59805671 /// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U`
59815672 pub fn could_unify_with_deeply(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool {
5982 let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), other.ty.clone()));
5673 let interner = DbInterner::new_with(db, None, None);
5674 let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, other.ty));
59835675 hir_ty::could_unify_deeply(db, self.env.clone(), &tys)
59845676 }
59855677
59865678 pub fn could_coerce_to(&self, db: &'db dyn HirDatabase, to: &Type<'db>) -> bool {
5987 let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), to.ty.clone()));
5679 let interner = DbInterner::new_with(db, None, None);
5680 let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, to.ty));
59885681 hir_ty::could_coerce(db, self.env.clone(), &tys)
59895682 }
59905683
5991 pub fn as_type_param(&self, db: &'db dyn HirDatabase) -> Option<TypeParam> {
5992 match self.ty.kind(Interner) {
5993 TyKind::Placeholder(p) => Some(TypeParam {
5994 id: TypeParamId::from_unchecked(hir_ty::from_placeholder_idx(db, *p).0),
5995 }),
5684 pub fn as_type_param(&self, _db: &'db dyn HirDatabase) -> Option<TypeParam> {
5685 match self.ty.kind() {
5686 TyKind::Param(param) => Some(TypeParam { id: param.id }),
59965687 _ => None,
59975688 }
59985689 }
59995690
60005691 /// Returns unique `GenericParam`s contained in this type.
60015692 pub fn generic_params(&self, db: &'db dyn HirDatabase) -> FxHashSet<GenericParam> {
6002 hir_ty::collect_placeholders(&self.ty, db)
5693 hir_ty::collect_params(&self.ty)
60035694 .into_iter()
60045695 .map(|id| TypeOrConstParam { id }.split(db).either_into())
60055696 .collect()
60065697 }
60075698
60085699 pub fn layout(&self, db: &'db dyn HirDatabase) -> Result<Layout, LayoutError> {
6009 let interner = DbInterner::new_with(db, None, None);
6010 db.layout_of_ty(self.ty.to_nextsolver(interner), self.env.clone())
5700 db.layout_of_ty(self.ty, self.env.clone())
60115701 .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap()))
60125702 }
60135703
60145704 pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue {
6015 db.has_drop_glue(self.ty.clone(), self.env.clone())
5705 let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block);
5706 // FIXME: This should be `PostAnalysis` I believe.
5707 let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
5708 hir_ty::drop::has_drop_glue(&infcx, self.ty, self.env.clone())
60165709 }
60175710}
60185711
60195712#[derive(Clone, PartialEq, Eq, Debug, Hash)]
60205713pub struct TypeNs<'db> {
60215714 env: Arc<TraitEnvironment<'db>>,
6022 ty: hir_ty::next_solver::Ty<'db>,
6023 _pd: PhantomCovariantLifetime<'db>,
5715 ty: Ty<'db>,
60245716}
60255717
60265718impl<'db> TypeNs<'db> {
6027 fn new(
6028 db: &'db dyn HirDatabase,
6029 lexical_env: impl HasResolver,
6030 ty: hir_ty::next_solver::Ty<'db>,
6031 ) -> Self {
5719 fn new(db: &'db dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty<'db>) -> Self {
60325720 let resolver = lexical_env.resolver(db);
60335721 let environment = resolver
60345722 .generic_def()
60355723 .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d));
6036 TypeNs { env: environment, ty, _pd: PhantomCovariantLifetime::new() }
5724 TypeNs { env: environment, ty }
60375725 }
60385726
6039 pub fn to_type(&self, db: &'db dyn HirDatabase) -> Type<'db> {
6040 let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block);
6041 Type { env: self.env.clone(), ty: convert_ty_for_result(interner, self.ty), _pd: self._pd }
5727 pub fn to_type(&self, _db: &'db dyn HirDatabase) -> Type<'db> {
5728 Type { env: self.env.clone(), ty: self.ty }
60425729 }
60435730
60445731 // FIXME: Find better API that also handles const generics
......@@ -6094,40 +5781,38 @@ impl InlineAsmOperand {
60945781#[derive(Debug)]
60955782pub struct Callable<'db> {
60965783 ty: Type<'db>,
6097 sig: CallableSig,
6098 callee: Callee,
5784 sig: PolyFnSig<'db>,
5785 callee: Callee<'db>,
60995786 /// Whether this is a method that was called with method call syntax.
61005787 is_bound_method: bool,
61015788}
61025789
61035790#[derive(Clone, PartialEq, Eq, Hash, Debug)]
6104enum Callee {
5791enum Callee<'db> {
61055792 Def(CallableDefId),
6106 Closure(ClosureId, Substitution),
5793 Closure(InternedClosureId, GenericArgs<'db>),
61075794 FnPtr,
61085795 FnImpl(FnTrait),
61095796}
61105797
6111pub enum CallableKind {
5798pub enum CallableKind<'db> {
61125799 Function(Function),
61135800 TupleStruct(Struct),
61145801 TupleEnumVariant(Variant),
6115 Closure(Closure),
5802 Closure(Closure<'db>),
61165803 FnPtr,
61175804 FnImpl(FnTrait),
61185805}
61195806
61205807impl<'db> Callable<'db> {
6121 pub fn kind(&self) -> CallableKind {
5808 pub fn kind(&self) -> CallableKind<'db> {
61225809 match self.callee {
61235810 Callee::Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()),
61245811 Callee::Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()),
61255812 Callee::Def(CallableDefId::EnumVariantId(it)) => {
61265813 CallableKind::TupleEnumVariant(it.into())
61275814 }
6128 Callee::Closure(id, ref subst) => {
6129 CallableKind::Closure(Closure { id, subst: subst.clone() })
6130 }
5815 Callee::Closure(id, ref subst) => CallableKind::Closure(Closure { id, subst: *subst }),
61315816 Callee::FnPtr => CallableKind::FnPtr,
61325817 Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_),
61335818 }
......@@ -6138,25 +5823,31 @@ impl<'db> Callable<'db> {
61385823 _ => return None,
61395824 };
61405825 let func = Function { id: func };
6141 Some((func.self_param(db)?, self.ty.derived(self.sig.params()[0].clone())))
5826 Some((
5827 func.self_param(db)?,
5828 self.ty.derived(self.sig.skip_binder().inputs_and_output.inputs()[0]),
5829 ))
61425830 }
61435831 pub fn n_params(&self) -> usize {
6144 self.sig.params().len() - if self.is_bound_method { 1 } else { 0 }
5832 self.sig.skip_binder().inputs_and_output.inputs().len()
5833 - if self.is_bound_method { 1 } else { 0 }
61455834 }
61465835 pub fn params(&self) -> Vec<Param<'db>> {
61475836 self.sig
6148 .params()
5837 .skip_binder()
5838 .inputs_and_output
5839 .inputs()
61495840 .iter()
61505841 .enumerate()
61515842 .skip(if self.is_bound_method { 1 } else { 0 })
6152 .map(|(idx, ty)| (idx, self.ty.derived(ty.clone())))
5843 .map(|(idx, ty)| (idx, self.ty.derived(*ty)))
61535844 .map(|(idx, ty)| Param { func: self.callee.clone(), idx, ty })
61545845 .collect()
61555846 }
61565847 pub fn return_type(&self) -> Type<'db> {
6157 self.ty.derived(self.sig.ret().clone())
5848 self.ty.derived(self.sig.skip_binder().output())
61585849 }
6159 pub fn sig(&self) -> &CallableSig {
5850 pub fn sig(&self) -> impl Eq {
61605851 &self.sig
61615852 }
61625853
......@@ -6708,5 +6399,37 @@ fn as_name_opt(name: Option<impl AsName>) -> Name {
67086399 name.map_or_else(Name::missing, |name| name.as_name())
67096400}
67106401
6402fn generic_args_from_tys<'db>(
6403 interner: DbInterner<'db>,
6404 def_id: SolverDefId,
6405 args: impl IntoIterator<Item = Ty<'db>>,
6406) -> GenericArgs<'db> {
6407 let mut args = args.into_iter();
6408 GenericArgs::for_item(interner, def_id, |_, _, id, _| {
6409 if matches!(id, GenericParamId::TypeParamId(_))
6410 && let Some(arg) = args.next()
6411 {
6412 arg.into()
6413 } else {
6414 next_solver::GenericArg::error_from_id(interner, id)
6415 }
6416 })
6417}
6418
6419fn has_non_default_type_params(db: &dyn HirDatabase, generic_def: GenericDefId) -> bool {
6420 let params = db.generic_params(generic_def);
6421 let defaults = db.generic_defaults_ns(generic_def);
6422 params
6423 .iter_type_or_consts()
6424 .filter(|(_, param)| matches!(param, TypeOrConstParamData::TypeParamData(_)))
6425 .map(|(local_id, _)| TypeOrConstParamId { parent: generic_def, local_id })
6426 .any(|param| {
6427 let Some(param) = hir_ty::param_idx(db, param) else {
6428 return false;
6429 };
6430 defaults.get(param).is_none()
6431 })
6432}
6433
67116434pub use hir_ty::next_solver;
67126435pub use hir_ty::setup_tracing;
src/tools/rust-analyzer/crates/hir/src/semantics.rs+19-9
......@@ -28,7 +28,10 @@ use hir_expand::{
2828 mod_path::{ModPath, PathKind},
2929 name::AsName,
3030};
31use hir_ty::diagnostics::{unsafe_operations, unsafe_operations_for_body};
31use hir_ty::{
32 diagnostics::{unsafe_operations, unsafe_operations_for_body},
33 next_solver::DbInterner,
34};
3235use intern::{Interned, Symbol, sym};
3336use itertools::Itertools;
3437use rustc_hash::{FxHashMap, FxHashSet};
......@@ -1553,8 +1556,8 @@ impl<'db> SemanticsImpl<'db> {
15531556
15541557 pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjustment<'db>>> {
15551558 let mutability = |m| match m {
1556 hir_ty::Mutability::Not => Mutability::Shared,
1557 hir_ty::Mutability::Mut => Mutability::Mut,
1559 hir_ty::next_solver::Mutability::Not => Mutability::Shared,
1560 hir_ty::next_solver::Mutability::Mut => Mutability::Mut,
15581561 };
15591562
15601563 let analyzer = self.analyze(expr.syntax())?;
......@@ -1565,7 +1568,7 @@ impl<'db> SemanticsImpl<'db> {
15651568 it.iter()
15661569 .map(|adjust| {
15671570 let target =
1568 Type::new_with_resolver(self.db, &analyzer.resolver, adjust.target.clone());
1571 Type::new_with_resolver(self.db, &analyzer.resolver, adjust.target);
15691572 let kind = match adjust.kind {
15701573 hir_ty::Adjust::NeverToAny => Adjust::NeverToAny,
15711574 hir_ty::Adjust::Deref(Some(hir_ty::OverloadedDeref(m))) => {
......@@ -1652,11 +1655,18 @@ impl<'db> SemanticsImpl<'db> {
16521655 func: Function,
16531656 subst: impl IntoIterator<Item = Type<'db>>,
16541657 ) -> Option<Function> {
1655 let mut substs = hir_ty::TyBuilder::subst_for_def(self.db, TraitId::from(trait_), None);
1656 for s in subst {
1657 substs = substs.push(s.ty);
1658 }
1659 Some(self.db.lookup_impl_method(env.env, func.into(), substs.build()).0.into())
1658 let interner = DbInterner::new_with(self.db, None, None);
1659 let mut subst = subst.into_iter();
1660 let substs = hir_ty::next_solver::GenericArgs::for_item(
1661 interner,
1662 trait_.id.into(),
1663 |_, _, id, _| {
1664 assert!(matches!(id, hir_def::GenericParamId::TypeParamId(_)), "expected a type");
1665 subst.next().expect("too few subst").ty.into()
1666 },
1667 );
1668 assert!(subst.next().is_none(), "too many subst");
1669 Some(self.db.lookup_impl_method(env.env, func.into(), substs).0.into())
16601670 }
16611671
16621672 fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option<StructId> {
src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs+127-130
......@@ -7,18 +7,10 @@
77//! purely for "IDE needs".
88use std::iter::{self, once};
99
10use crate::{
11 Adt, AssocItem, BindingMode, BuiltinAttr, BuiltinType, Callable, Const, DeriveHelper, Field,
12 Function, GenericSubstitution, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait,
13 TupleField, Type, TypeAlias, Variant,
14 db::HirDatabase,
15 semantics::{PathResolution, PathResolutionPerNs},
16};
17use base_db::salsa;
1810use either::Either;
1911use hir_def::{
2012 AdtId, AssocItemId, CallableDefId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId,
21 ItemContainerId, LocalFieldId, Lookup, ModuleDefId, StructId, TraitId, VariantId,
13 LocalFieldId, ModuleDefId, StructId, TraitId, VariantId,
2214 expr_store::{
2315 Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, HygieneId,
2416 lower::ExprCollector,
......@@ -37,22 +29,24 @@ use hir_expand::{
3729 name::{AsName, Name},
3830};
3931use hir_ty::{
40 Adjustment, AliasTy, InferenceResult, Interner, LifetimeElisionKind, ProjectionTy,
41 Substitution, ToChalk, TraitEnvironment, Ty, TyExt, TyKind, TyLoweringContext,
32 Adjustment, InferenceResult, LifetimeElisionKind, TraitEnvironment, TyLoweringContext,
4233 diagnostics::{
4334 InsideUnsafeBlock, record_literal_missing_fields, record_pattern_missing_fields,
4435 unsafe_operations,
4536 },
46 from_assoc_type_id,
4737 lang_items::lang_items_for_bin_op,
4838 method_resolution,
4939 next_solver::{
50 DbInterner,
51 mapping::{ChalkToNextSolver, NextSolverToChalk},
40 DbInterner, ErrorGuaranteed, GenericArgs, Ty, TyKind, TypingMode, infer::DbInternerInferExt,
5241 },
42 traits::structurally_normalize_ty,
5343};
5444use intern::sym;
5545use itertools::Itertools;
46use rustc_type_ir::{
47 AliasTyKind,
48 inherent::{AdtDef, IntoKind, Ty as _},
49};
5650use smallvec::SmallVec;
5751use stdx::never;
5852use syntax::{
......@@ -61,22 +55,30 @@ use syntax::{
6155};
6256use triomphe::Arc;
6357
58use crate::{
59 Adt, AssocItem, BindingMode, BuiltinAttr, BuiltinType, Callable, Const, DeriveHelper, Field,
60 Function, GenericSubstitution, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait,
61 TupleField, Type, TypeAlias, Variant,
62 db::HirDatabase,
63 semantics::{PathResolution, PathResolutionPerNs},
64};
65
6466/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
6567/// original source files. It should not be used inside the HIR itself.
6668#[derive(Debug)]
6769pub(crate) struct SourceAnalyzer<'db> {
6870 pub(crate) file_id: HirFileId,
6971 pub(crate) resolver: Resolver<'db>,
70 pub(crate) body_or_sig: Option<BodyOrSig>,
72 pub(crate) body_or_sig: Option<BodyOrSig<'db>>,
7173}
7274
7375#[derive(Debug)]
74pub(crate) enum BodyOrSig {
76pub(crate) enum BodyOrSig<'db> {
7577 Body {
7678 def: DefWithBodyId,
7779 body: Arc<Body>,
7880 source_map: Arc<BodySourceMap>,
79 infer: Option<Arc<InferenceResult>>,
81 infer: Option<Arc<InferenceResult<'db>>>,
8082 },
8183 // To be folded into body once it is considered one
8284 VariantFields {
......@@ -116,7 +118,7 @@ impl<'db> SourceAnalyzer<'db> {
116118 def: DefWithBodyId,
117119 node @ InFile { file_id, .. }: InFile<&SyntaxNode>,
118120 offset: Option<TextSize>,
119 infer: Option<Arc<InferenceResult>>,
121 infer: Option<Arc<InferenceResult<'db>>>,
120122 ) -> SourceAnalyzer<'db> {
121123 let (body, source_map) = db.body_with_source_map(def);
122124 let scopes = db.expr_scopes(def);
......@@ -182,7 +184,9 @@ impl<'db> SourceAnalyzer<'db> {
182184 }
183185
184186 // FIXME: Remove this
185 fn body_(&self) -> Option<(DefWithBodyId, &Body, &BodySourceMap, Option<&InferenceResult>)> {
187 fn body_(
188 &self,
189 ) -> Option<(DefWithBodyId, &Body, &BodySourceMap, Option<&InferenceResult<'db>>)> {
186190 self.body_or_sig.as_ref().and_then(|it| match it {
187191 BodyOrSig::Body { def, body, source_map, infer } => {
188192 Some((*def, &**body, &**source_map, infer.as_deref()))
......@@ -191,7 +195,7 @@ impl<'db> SourceAnalyzer<'db> {
191195 })
192196 }
193197
194 fn infer(&self) -> Option<&InferenceResult> {
198 fn infer(&self) -> Option<&InferenceResult<'db>> {
195199 self.body_or_sig.as_ref().and_then(|it| match it {
196200 BodyOrSig::Sig { .. } => None,
197201 BodyOrSig::VariantFields { .. } => None,
......@@ -250,7 +254,7 @@ impl<'db> SourceAnalyzer<'db> {
250254 if let Pat::Bind { id, .. } = self.store()?[pat_id.as_pat()?] { Some(id) } else { None }
251255 }
252256
253 pub(crate) fn expr_adjustments(&self, expr: &ast::Expr) -> Option<&[Adjustment]> {
257 pub(crate) fn expr_adjustments(&self, expr: &ast::Expr) -> Option<&[Adjustment<'db>]> {
254258 // It is safe to omit destructuring assignments here because they have no adjustments (neither
255259 // expressions nor patterns).
256260 let expr_id = self.expr_id(expr.clone())?.as_expr()?;
......@@ -288,9 +292,9 @@ impl<'db> SourceAnalyzer<'db> {
288292 let coerced = expr_id
289293 .as_expr()
290294 .and_then(|expr_id| infer.expr_adjustment(expr_id))
291 .and_then(|adjusts| adjusts.last().map(|adjust| adjust.target.clone()));
292 let ty = infer[expr_id].clone();
293 let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty);
295 .and_then(|adjusts| adjusts.last().map(|adjust| adjust.target));
296 let ty = infer[expr_id];
297 let mk_ty = |ty: Ty<'db>| Type::new_with_resolver(db, &self.resolver, ty);
294298 Some((mk_ty(ty), coerced.map(mk_ty)))
295299 }
296300
......@@ -311,8 +315,8 @@ impl<'db> SourceAnalyzer<'db> {
311315 }
312316 };
313317
314 let ty = infer[expr_or_pat_id].clone();
315 let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty);
318 let ty = infer[expr_or_pat_id];
319 let mk_ty = |ty: Ty<'db>| Type::new_with_resolver(db, &self.resolver, ty);
316320 Some((mk_ty(ty), coerced.map(mk_ty)))
317321 }
318322
......@@ -323,8 +327,8 @@ impl<'db> SourceAnalyzer<'db> {
323327 ) -> Option<Type<'db>> {
324328 let binding_id = self.binding_id_of_pat(pat)?;
325329 let infer = self.infer()?;
326 let ty = infer[binding_id].clone();
327 let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty);
330 let ty = infer[binding_id];
331 let mk_ty = |ty: Ty<'db>| Type::new_with_resolver(db, &self.resolver, ty);
328332 Some(mk_ty(ty))
329333 }
330334
......@@ -334,7 +338,7 @@ impl<'db> SourceAnalyzer<'db> {
334338 _param: &ast::SelfParam,
335339 ) -> Option<Type<'db>> {
336340 let binding = self.body()?.self_param?;
337 let ty = self.infer()?[binding].clone();
341 let ty = self.infer()?[binding];
338342 Some(Type::new_with_resolver(db, &self.resolver, ty))
339343 }
340344
......@@ -347,8 +351,10 @@ impl<'db> SourceAnalyzer<'db> {
347351 let infer = self.infer()?;
348352 infer.binding_mode(id.as_pat()?).map(|bm| match bm {
349353 hir_ty::BindingMode::Move => BindingMode::Move,
350 hir_ty::BindingMode::Ref(hir_ty::Mutability::Mut) => BindingMode::Ref(Mutability::Mut),
351 hir_ty::BindingMode::Ref(hir_ty::Mutability::Not) => {
354 hir_ty::BindingMode::Ref(hir_ty::next_solver::Mutability::Mut) => {
355 BindingMode::Ref(Mutability::Mut)
356 }
357 hir_ty::BindingMode::Ref(hir_ty::next_solver::Mutability::Not) => {
352358 BindingMode::Ref(Mutability::Shared)
353359 }
354360 })
......@@ -364,7 +370,7 @@ impl<'db> SourceAnalyzer<'db> {
364370 infer
365371 .pat_adjustment(pat_id.as_pat()?)?
366372 .iter()
367 .map(|ty| Type::new_with_resolver(db, &self.resolver, ty.clone()))
373 .map(|ty| Type::new_with_resolver(db, &self.resolver, *ty))
368374 .collect(),
369375 )
370376 }
......@@ -375,11 +381,10 @@ impl<'db> SourceAnalyzer<'db> {
375381 call: &ast::MethodCallExpr,
376382 ) -> Option<Callable<'db>> {
377383 let expr_id = self.expr_id(call.clone().into())?.as_expr()?;
378 let (func, substs) = self.infer()?.method_resolution(expr_id)?;
384 let (func, args) = self.infer()?.method_resolution(expr_id)?;
379385 let interner = DbInterner::new_with(db, None, None);
380 let args: hir_ty::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
381386 let ty = db.value_ty(func.into())?.instantiate(interner, args);
382 let ty = Type::new_with_resolver(db, &self.resolver, ty.to_chalk(interner));
387 let ty = Type::new_with_resolver(db, &self.resolver, ty);
383388 let mut res = ty.as_callable(db)?;
384389 res.is_bound_method = true;
385390 Some(res)
......@@ -443,17 +448,13 @@ impl<'db> SourceAnalyzer<'db> {
443448 fn field_subst(
444449 &self,
445450 field_expr: ExprId,
446 infer: &InferenceResult,
451 infer: &InferenceResult<'db>,
447452 db: &'db dyn HirDatabase,
448453 ) -> Option<GenericSubstitution<'db>> {
449454 let body = self.store()?;
450455 if let Expr::Field { expr: object_expr, name: _ } = body[field_expr] {
451456 let (adt, subst) = infer.type_of_expr_with_adjust(object_expr)?.as_adt()?;
452 return Some(GenericSubstitution::new(
453 adt.into(),
454 subst.clone(),
455 self.trait_environment(db),
456 ));
457 return Some(GenericSubstitution::new(adt.into(), subst, self.trait_environment(db)));
457458 }
458459 None
459460 }
......@@ -536,7 +537,7 @@ impl<'db> SourceAnalyzer<'db> {
536537 db: &'db dyn HirDatabase,
537538 await_expr: &ast::AwaitExpr,
538539 ) -> Option<FunctionId> {
539 let mut ty = self.ty_of_expr(await_expr.expr()?)?.clone();
540 let mut ty = self.ty_of_expr(await_expr.expr()?)?;
540541
541542 let into_future_trait = self
542543 .resolver
......@@ -544,7 +545,7 @@ impl<'db> SourceAnalyzer<'db> {
544545 .map(Trait::from);
545546
546547 if let Some(into_future_trait) = into_future_trait {
547 let type_ = Type::new_with_resolver(db, &self.resolver, ty.clone());
548 let type_ = Type::new_with_resolver(db, &self.resolver, ty);
548549 if type_.impls_trait(db, into_future_trait, &[]) {
549550 let items = into_future_trait.items(db);
550551 let into_future_type = items.into_iter().find_map(|item| match item {
......@@ -560,11 +561,11 @@ impl<'db> SourceAnalyzer<'db> {
560561 }
561562 }
562563
563 let future_trait = LangItem::Future.resolve_trait(db, self.resolver.krate())?;
564564 let poll_fn = LangItem::FuturePoll.resolve_function(db, self.resolver.krate())?;
565565 // HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
566566 // doesn't have any generic parameters, so we skip building another subst for `poll()`.
567 let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build();
567 let interner = DbInterner::new_with(db, None, None);
568 let substs = GenericArgs::new_from_iter(interner, [ty.into()]);
568569 Some(self.resolve_impl_method_or_trait_def(db, poll_fn, substs))
569570 }
570571
......@@ -573,7 +574,7 @@ impl<'db> SourceAnalyzer<'db> {
573574 db: &'db dyn HirDatabase,
574575 prefix_expr: &ast::PrefixExpr,
575576 ) -> Option<FunctionId> {
576 let (op_trait, op_fn) = match prefix_expr.op_kind()? {
577 let (_op_trait, op_fn) = match prefix_expr.op_kind()? {
577578 ast::UnaryOp::Deref => {
578579 // This can be either `Deref::deref` or `DerefMut::deref_mut`.
579580 // Since deref kind is inferenced and stored in `InferenceResult.method_resolution`,
......@@ -603,9 +604,10 @@ impl<'db> SourceAnalyzer<'db> {
603604
604605 let ty = self.ty_of_expr(prefix_expr.expr()?)?;
605606
607 let interner = DbInterner::new_with(db, None, None);
606608 // HACK: subst for all methods coincides with that for their trait because the methods
607609 // don't have any generic parameters, so we skip building another subst for the methods.
608 let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build();
610 let substs = GenericArgs::new_from_iter(interner, [ty.into()]);
609611
610612 Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
611613 }
......@@ -618,27 +620,25 @@ impl<'db> SourceAnalyzer<'db> {
618620 let base_ty = self.ty_of_expr(index_expr.base()?)?;
619621 let index_ty = self.ty_of_expr(index_expr.index()?)?;
620622
621 let (index_trait, index_fn) =
623 let (_index_trait, index_fn) =
622624 self.lang_trait_fn(db, LangItem::Index, &Name::new_symbol_root(sym::index))?;
623 let (op_trait, op_fn) = self
625 let op_fn = self
624626 .infer()
625627 .and_then(|infer| {
626628 let expr = self.expr_id(index_expr.clone().into())?.as_expr()?;
627629 let (func, _) = infer.method_resolution(expr)?;
628 let (index_mut_trait, index_mut_fn) = self.lang_trait_fn(
630 let (_index_mut_trait, index_mut_fn) = self.lang_trait_fn(
629631 db,
630632 LangItem::IndexMut,
631633 &Name::new_symbol_root(sym::index_mut),
632634 )?;
633 if func == index_mut_fn { Some((index_mut_trait, index_mut_fn)) } else { None }
635 if func == index_mut_fn { Some(index_mut_fn) } else { None }
634636 })
635 .unwrap_or((index_trait, index_fn));
637 .unwrap_or(index_fn);
636638 // HACK: subst for all methods coincides with that for their trait because the methods
637639 // don't have any generic parameters, so we skip building another subst for the methods.
638 let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None)
639 .push(base_ty.clone())
640 .push(index_ty.clone())
641 .build();
640 let interner = DbInterner::new_with(db, None, None);
641 let substs = GenericArgs::new_from_iter(interner, [base_ty.into(), index_ty.into()]);
642642 Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
643643 }
644644
......@@ -651,14 +651,12 @@ impl<'db> SourceAnalyzer<'db> {
651651 let lhs = self.ty_of_expr(binop_expr.lhs()?)?;
652652 let rhs = self.ty_of_expr(binop_expr.rhs()?)?;
653653
654 let (op_trait, op_fn) = lang_items_for_bin_op(op)
654 let (_op_trait, op_fn) = lang_items_for_bin_op(op)
655655 .and_then(|(name, lang_item)| self.lang_trait_fn(db, lang_item, &name))?;
656656 // HACK: subst for `index()` coincides with that for `Index` because `index()` itself
657657 // doesn't have any generic parameters, so we skip building another subst for `index()`.
658 let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None)
659 .push(lhs.clone())
660 .push(rhs.clone())
661 .build();
658 let interner = DbInterner::new_with(db, None, None);
659 let substs = GenericArgs::new_from_iter(interner, [lhs.into(), rhs.into()]);
662660
663661 Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
664662 }
......@@ -671,13 +669,10 @@ impl<'db> SourceAnalyzer<'db> {
671669 let ty = self.ty_of_expr(try_expr.expr()?)?;
672670
673671 let op_fn = LangItem::TryTraitBranch.resolve_function(db, self.resolver.krate())?;
674 let op_trait = match op_fn.lookup(db).container {
675 ItemContainerId::TraitId(id) => id,
676 _ => return None,
677 };
678672 // HACK: subst for `branch()` coincides with that for `Try` because `branch()` itself
679673 // doesn't have any generic parameters, so we skip building another subst for `branch()`.
680 let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build();
674 let interner = DbInterner::new_with(db, None, None);
675 let substs = GenericArgs::new_from_iter(interner, [ty.into()]);
681676
682677 Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
683678 }
......@@ -690,6 +685,7 @@ impl<'db> SourceAnalyzer<'db> {
690685 let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
691686 let expr = ast::Expr::from(record_expr);
692687 let expr_id = self.store_sm()?.node_expr(InFile::new(self.file_id, &expr))?;
688 let interner = DbInterner::new_with(db, None, None);
693689
694690 let ast_name = field.field_name()?;
695691 let local_name = ast_name.as_name();
......@@ -717,12 +713,12 @@ impl<'db> SourceAnalyzer<'db> {
717713 let variant_data = variant.fields(db);
718714 let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
719715 let field_ty =
720 db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
716 (*db.field_types_ns(variant).get(field.local_id)?).instantiate(interner, subst);
721717 Some((
722718 field.into(),
723719 local,
724720 Type::new_with_resolver(db, &self.resolver, field_ty),
725 GenericSubstitution::new(adt.into(), subst.clone(), self.trait_environment(db)),
721 GenericSubstitution::new(adt.into(), subst, self.trait_environment(db)),
726722 ))
727723 }
728724
......@@ -731,6 +727,7 @@ impl<'db> SourceAnalyzer<'db> {
731727 db: &'db dyn HirDatabase,
732728 field: &ast::RecordPatField,
733729 ) -> Option<(Field, Type<'db>, GenericSubstitution<'db>)> {
730 let interner = DbInterner::new_with(db, None, None);
734731 let field_name = field.field_name()?.as_name();
735732 let record_pat = ast::RecordPat::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
736733 let pat_id = self.pat_id(&record_pat.into())?;
......@@ -739,11 +736,11 @@ impl<'db> SourceAnalyzer<'db> {
739736 let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? };
740737 let (adt, subst) = self.infer()?[pat_id.as_pat()?].as_adt()?;
741738 let field_ty =
742 db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
739 (*db.field_types_ns(variant).get(field.local_id)?).instantiate(interner, subst);
743740 Some((
744741 field.into(),
745742 Type::new_with_resolver(db, &self.resolver, field_ty),
746 GenericSubstitution::new(adt.into(), subst.clone(), self.trait_environment(db)),
743 GenericSubstitution::new(adt.into(), subst, self.trait_environment(db)),
747744 ))
748745 }
749746
......@@ -792,43 +789,40 @@ impl<'db> SourceAnalyzer<'db> {
792789 let container = self.type_of_type(db, &container)?;
793790
794791 let trait_env = container.env;
792
793 let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block);
794 let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
795
795796 let mut container = Either::Right(container.ty);
796797 for field_name in offset_of_expr.fields() {
797 if let Some(
798 TyKind::Alias(AliasTy::Projection(ProjectionTy { associated_ty_id, substitution }))
799 | TyKind::AssociatedType(associated_ty_id, substitution),
800 ) = container.as_ref().right().map(|it| it.kind(Interner))
801 {
802 let projection = ProjectionTy {
803 associated_ty_id: *associated_ty_id,
804 substitution: substitution.clone(),
805 };
806 container = Either::Right(db.normalize_projection(projection, trait_env.clone()));
798 if let Either::Right(container) = &mut container {
799 *container = structurally_normalize_ty(&infcx, *container, trait_env.clone());
807800 }
808 let handle_variants = |variant: VariantId, subst: &Substitution, container: &mut _| {
809 let fields = variant.fields(db);
810 let field = fields.field(&field_name.as_name())?;
811 let field_types = db.field_types(variant);
812 *container = Either::Right(field_types[field].clone().substitute(Interner, subst));
813 let generic_def = match variant {
814 VariantId::EnumVariantId(it) => it.loc(db).parent.into(),
815 VariantId::StructId(it) => it.into(),
816 VariantId::UnionId(it) => it.into(),
801 let handle_variants =
802 |variant: VariantId, subst: GenericArgs<'db>, container: &mut _| {
803 let fields = variant.fields(db);
804 let field = fields.field(&field_name.as_name())?;
805 let field_types = db.field_types_ns(variant);
806 *container = Either::Right(field_types[field].instantiate(interner, subst));
807 let generic_def = match variant {
808 VariantId::EnumVariantId(it) => it.loc(db).parent.into(),
809 VariantId::StructId(it) => it.into(),
810 VariantId::UnionId(it) => it.into(),
811 };
812 Some((
813 Either::Right(Field { parent: variant.into(), id: field }),
814 generic_def,
815 subst,
816 ))
817817 };
818 Some((
819 Either::Right(Field { parent: variant.into(), id: field }),
820 generic_def,
821 subst.clone(),
822 ))
823 };
824 let temp_ty = TyKind::Error.intern(Interner);
818 let temp_ty = Ty::new_error(interner, ErrorGuaranteed);
825819 let (field_def, generic_def, subst) =
826 match std::mem::replace(&mut container, Either::Right(temp_ty.clone())) {
820 match std::mem::replace(&mut container, Either::Right(temp_ty)) {
827821 Either::Left((variant_id, subst)) => {
828 handle_variants(VariantId::from(variant_id), &subst, &mut container)?
822 handle_variants(VariantId::from(variant_id), subst, &mut container)?
829823 }
830 Either::Right(container_ty) => match container_ty.kind(Interner) {
831 TyKind::Adt(adt_id, subst) => match adt_id.0 {
824 Either::Right(container_ty) => match container_ty.kind() {
825 TyKind::Adt(adt_def, subst) => match adt_def.def_id().0 {
832826 AdtId::StructId(id) => {
833827 handle_variants(id.into(), subst, &mut container)?
834828 }
......@@ -838,8 +832,8 @@ impl<'db> SourceAnalyzer<'db> {
838832 AdtId::EnumId(id) => {
839833 let variants = id.enum_variants(db);
840834 let variant = variants.variant(&field_name.as_name())?;
841 container = Either::Left((variant, subst.clone()));
842 (Either::Left(Variant { id: variant }), id.into(), subst.clone())
835 container = Either::Left((variant, subst));
836 (Either::Left(Variant { id: variant }), id.into(), subst)
843837 }
844838 },
845839 _ => return None,
......@@ -880,12 +874,10 @@ impl<'db> SourceAnalyzer<'db> {
880874 (assoc, subst)
881875 }
882876 Some(func_ty) => {
883 if let TyKind::FnDef(_fn_def, subs) = func_ty.kind(Interner) {
877 if let TyKind::FnDef(_fn_def, subs) = func_ty.kind() {
884878 let (fn_, subst) = self
885879 .resolve_impl_method_or_trait_def_with_subst(
886 db,
887 f_in_trait,
888 subs.clone(),
880 db, f_in_trait, subs,
889881 );
890882 let subst = GenericSubstitution::new(
891883 fn_.into(),
......@@ -1152,33 +1144,35 @@ impl<'db> SourceAnalyzer<'db> {
11521144 self.infer()?.type_of_expr_or_pat(expr_id)?
11531145 } else if let Some(pat) = ast::Pat::cast(parent) {
11541146 let pat_id = self.pat_id(&pat)?;
1155 &self.infer()?[pat_id]
1147 self.infer()?[pat_id]
11561148 } else {
11571149 return None;
11581150 };
11591151 let env = self.trait_environment(db);
1160 let (subst, expected_resolution) = match ty.kind(Interner) {
1161 TyKind::Adt(adt_id, subst) => (
1162 GenericSubstitution::new(adt_id.0.into(), subst.clone(), env),
1163 PathResolution::Def(ModuleDef::Adt(adt_id.0.into())),
1164 ),
1165 TyKind::AssociatedType(assoc_id, subst) => {
1166 let assoc_id = from_assoc_type_id(*assoc_id);
1152 let (subst, expected_resolution) = match ty.kind() {
1153 TyKind::Adt(adt_def, subst) => {
1154 let adt_id = adt_def.def_id().0;
11671155 (
1168 GenericSubstitution::new(assoc_id.into(), subst.clone(), env),
1156 GenericSubstitution::new(adt_id.into(), subst, env),
1157 PathResolution::Def(ModuleDef::Adt(adt_id.into())),
1158 )
1159 }
1160 TyKind::Alias(AliasTyKind::Projection, alias) => {
1161 let assoc_id = alias.def_id.expect_type_alias();
1162 (
1163 GenericSubstitution::new(assoc_id.into(), alias.args, env),
11691164 PathResolution::Def(ModuleDef::TypeAlias(assoc_id.into())),
11701165 )
11711166 }
11721167 TyKind::FnDef(fn_id, subst) => {
1173 let fn_id = ToChalk::from_chalk(db, *fn_id);
1174 let generic_def_id = match fn_id {
1168 let generic_def_id = match fn_id.0 {
11751169 CallableDefId::StructId(id) => id.into(),
11761170 CallableDefId::FunctionId(id) => id.into(),
11771171 CallableDefId::EnumVariantId(_) => return None,
11781172 };
11791173 (
1180 GenericSubstitution::new(generic_def_id, subst.clone(), env),
1181 PathResolution::Def(ModuleDefId::from(fn_id).into()),
1174 GenericSubstitution::new(generic_def_id, subst, env),
1175 PathResolution::Def(ModuleDefId::from(fn_id.0).into()),
11821176 )
11831177 }
11841178 _ => return None,
......@@ -1256,17 +1250,18 @@ impl<'db> SourceAnalyzer<'db> {
12561250 fn missing_fields(
12571251 &self,
12581252 db: &'db dyn HirDatabase,
1259 substs: &Substitution,
1253 substs: GenericArgs<'db>,
12601254 variant: VariantId,
12611255 missing_fields: Vec<LocalFieldId>,
12621256 ) -> Vec<(Field, Type<'db>)> {
1263 let field_types = db.field_types(variant);
1257 let interner = DbInterner::new_with(db, None, None);
1258 let field_types = db.field_types_ns(variant);
12641259
12651260 missing_fields
12661261 .into_iter()
12671262 .map(|local_id| {
12681263 let field = FieldId { parent: variant, local_id };
1269 let ty = field_types[local_id].clone().substitute(Interner, substs);
1264 let ty = field_types[local_id].instantiate(interner, substs);
12701265 (field.into(), Type::new_with_resolver_inner(db, &self.resolver, ty))
12711266 })
12721267 .collect()
......@@ -1379,7 +1374,7 @@ impl<'db> SourceAnalyzer<'db> {
13791374 &self,
13801375 db: &'db dyn HirDatabase,
13811376 func: FunctionId,
1382 substs: Substitution,
1377 substs: GenericArgs<'db>,
13831378 ) -> FunctionId {
13841379 self.resolve_impl_method_or_trait_def_with_subst(db, func, substs).0
13851380 }
......@@ -1388,8 +1383,8 @@ impl<'db> SourceAnalyzer<'db> {
13881383 &self,
13891384 db: &'db dyn HirDatabase,
13901385 func: FunctionId,
1391 substs: Substitution,
1392 ) -> (FunctionId, Substitution) {
1386 substs: GenericArgs<'db>,
1387 ) -> (FunctionId, GenericArgs<'db>) {
13931388 let owner = match self.resolver.body_owner() {
13941389 Some(it) => it,
13951390 None => return (func, substs),
......@@ -1402,14 +1397,16 @@ impl<'db> SourceAnalyzer<'db> {
14021397 &self,
14031398 db: &'db dyn HirDatabase,
14041399 const_id: ConstId,
1405 subs: Substitution,
1406 ) -> (ConstId, Substitution) {
1400 subs: GenericArgs<'db>,
1401 ) -> (ConstId, GenericArgs<'db>) {
14071402 let owner = match self.resolver.body_owner() {
14081403 Some(it) => it,
14091404 None => return (const_id, subs),
14101405 };
14111406 let env = db.trait_environment_for_body(owner);
1412 method_resolution::lookup_impl_const(db, env, const_id, subs)
1407 let interner = DbInterner::new_with(db, Some(env.krate), env.block);
1408 let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
1409 method_resolution::lookup_impl_const(&infcx, env, const_id, subs)
14131410 }
14141411
14151412 fn lang_trait_fn(
......@@ -1423,7 +1420,7 @@ impl<'db> SourceAnalyzer<'db> {
14231420 Some((trait_id, fn_id))
14241421 }
14251422
1426 fn ty_of_expr(&self, expr: ast::Expr) -> Option<&Ty> {
1423 fn ty_of_expr(&self, expr: ast::Expr) -> Option<Ty<'db>> {
14271424 self.infer()?.type_of_expr_or_pat(self.expr_id(expr)?)
14281425 }
14291426}
......@@ -1599,7 +1596,7 @@ fn resolve_hir_path_(
15991596 Some(unresolved) => resolver
16001597 .generic_def()
16011598 .and_then(|def| {
1602 salsa::attach(db, || {
1599 hir_ty::attach_db(db, || {
16031600 hir_ty::associated_type_shorthand_candidates(
16041601 db,
16051602 def,
src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs+13-9
......@@ -10,20 +10,21 @@
1010
1111use std::iter;
1212
13use hir_ty::TyBuilder;
14use hir_ty::db::HirDatabase;
15use hir_ty::mir::BorrowKind;
13use hir_ty::{
14 db::HirDatabase,
15 mir::BorrowKind,
16 next_solver::{DbInterner, Ty},
17};
1618use itertools::Itertools;
1719use rustc_hash::FxHashSet;
20use rustc_type_ir::inherent::Ty as _;
1821use span::Edition;
1922
2023use crate::{
2124 Adt, AssocItem, GenericDef, GenericParam, HasAttrs, HasVisibility, Impl, ModuleDef, ScopeDef,
22 Type, TypeParam,
25 Type, TypeParam, term_search::Expr,
2326};
2427
25use crate::term_search::Expr;
26
2728use super::{LookupTable, NewTypesKey, TermSearchCtx};
2829
2930/// # Trivial tactic
......@@ -596,10 +597,13 @@ pub(super) fn famous_types<'a, 'lt, 'db, DB: HirDatabase>(
596597) -> impl Iterator<Item = Expr<'db>> + use<'a, 'db, 'lt, DB> {
597598 let db = ctx.sema.db;
598599 let module = ctx.scope.module();
600 let interner = DbInterner::new_with(db, None, None);
601 let bool_ty = Ty::new_bool(interner);
602 let unit_ty = Ty::new_unit(interner);
599603 [
600 Expr::FamousType { ty: Type::new(db, module.id, TyBuilder::bool()), value: "true" },
601 Expr::FamousType { ty: Type::new(db, module.id, TyBuilder::bool()), value: "false" },
602 Expr::FamousType { ty: Type::new(db, module.id, TyBuilder::unit()), value: "()" },
604 Expr::FamousType { ty: Type::new(db, module.id, bool_ty), value: "true" },
605 Expr::FamousType { ty: Type::new(db, module.id, bool_ty), value: "false" },
606 Expr::FamousType { ty: Type::new(db, module.id, unit_ty), value: "()" },
603607 ]
604608 .into_iter()
605609 .inspect(|exprs| {
src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs+1-1
......@@ -38,7 +38,7 @@ impl AssistConfig {
3838 }
3939 }
4040
41 pub fn find_path_confg(&self, allow_unstable: bool) -> FindPathConfig {
41 pub fn find_path_config(&self, allow_unstable: bool) -> FindPathConfig {
4242 FindPathConfig {
4343 prefer_no_std: self.prefer_no_std,
4444 prefer_prelude: self.prefer_prelude,
src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs+18-2
......@@ -1,3 +1,4 @@
1use either::Either;
12use hir::HirDisplay;
23use ide_db::syntax_helpers::node_ext::walk_ty;
34use syntax::ast::{self, AstNode, LetStmt, Param};
......@@ -20,7 +21,8 @@ use crate::{AssistContext, AssistId, Assists};
2021// }
2122// ```
2223pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
23 let (ascribed_ty, expr, pat) = if let Some(let_stmt) = ctx.find_node_at_offset::<LetStmt>() {
24 let syntax_node = ctx.find_node_at_offset::<Either<LetStmt, Param>>()?;
25 let (ascribed_ty, expr, pat) = if let Either::Left(let_stmt) = syntax_node {
2426 let cursor_in_range = {
2527 let eq_range = let_stmt.eq_token()?.text_range();
2628 ctx.offset() < eq_range.start()
......@@ -31,7 +33,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
3133 }
3234
3335 (let_stmt.ty(), let_stmt.initializer(), let_stmt.pat()?)
34 } else if let Some(param) = ctx.find_node_at_offset::<Param>() {
36 } else if let Either::Right(param) = syntax_node {
3537 if param.syntax().ancestors().nth(2).and_then(ast::ClosureExpr::cast).is_none() {
3638 cov_mark::hit!(add_explicit_type_not_applicable_in_fn_param);
3739 return None;
......@@ -298,6 +300,20 @@ fn f() {
298300 let x: i32 = y;
299301 };
300302}
303"#,
304 );
305
306 check_assist(
307 add_explicit_type,
308 r#"
309fn f() {
310 let f: fn(i32) = |y$0| {};
311}
312"#,
313 r#"
314fn f() {
315 let f: fn(i32) = |y: i32| {};
316}
301317"#,
302318 );
303319 }
src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs+1-1
......@@ -80,7 +80,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
8080
8181 let scope = ctx.sema.scope(expr.syntax())?;
8282 let module = scope.module();
83 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(scope.krate()));
83 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(scope.krate()));
8484 let self_ty = if ctx.config.prefer_self_ty {
8585 scope
8686 .containing_function()
src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs+16-1
......@@ -18,7 +18,7 @@ use crate::{AssistContext, AssistId, Assists};
1818pub(crate) fn add_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
1919 let (fn_type, tail_expr, builder_edit_pos) = extract_tail(ctx)?;
2020 let module = ctx.sema.scope(tail_expr.syntax())?.module();
21 let ty = ctx.sema.type_of_expr(&peel_blocks(tail_expr.clone()))?.original();
21 let ty = ctx.sema.type_of_expr(&peel_blocks(tail_expr.clone()))?.adjusted();
2222 if ty.is_unit() {
2323 return None;
2424 }
......@@ -421,6 +421,21 @@ mod tests {
421421 );
422422 }
423423
424 #[test]
425 fn infer_coerced_return_type_closure() {
426 check_assist(
427 add_return_type,
428 r#"fn foo() {
429 let f = ||$0 {loop {}};
430 let _: fn() -> i8 = f;
431}"#,
432 r#"fn foo() {
433 let f = || -> i8 {loop {}};
434 let _: fn() -> i8 = f;
435}"#,
436 );
437 }
438
424439 #[test]
425440 fn not_applicable_ret_type_specified_closure() {
426441 cov_mark::check!(existing_ret_type_closure);
src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs+1-1
......@@ -346,7 +346,7 @@ fn augment_references_with_imports(
346346 ImportScope::find_insert_use_container(name.syntax(), &ctx.sema).and_then(
347347 |import_scope| {
348348 let cfg =
349 ctx.config.find_path_confg(ctx.sema.is_nightly(target_module.krate()));
349 ctx.config.find_path_config(ctx.sema.is_nightly(target_module.krate()));
350350 let path = ref_module
351351 .find_use_path(
352352 ctx.sema.db,
src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs+1-1
......@@ -506,7 +506,7 @@ fn wrap_capture_in_deref_if_needed(
506506 make::expr_prefix(T![*], capture_name).into()
507507}
508508
509fn capture_as_arg(ctx: &AssistContext<'_>, capture: &ClosureCapture) -> ast::Expr {
509fn capture_as_arg(ctx: &AssistContext<'_>, capture: &ClosureCapture<'_>) -> ast::Expr {
510510 let place = parse_expr_from_str(&capture.display_place_source_code(ctx.db()), ctx.edition())
511511 .expect("`display_place_source_code()` produced an invalid expr");
512512 let needs_mut = match capture.kind() {
src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs+1-1
......@@ -43,7 +43,7 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) -
4343 return None;
4444 }
4545
46 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(module.krate()));
46 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate()));
4747
4848 let src_type_path = {
4949 let src_type_path = src_type.syntax().descendants().find_map(ast::Path::cast)?;
src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs+88-16
......@@ -17,7 +17,7 @@ use syntax::{
1717use crate::{
1818 AssistId,
1919 assist_context::{AssistContext, Assists},
20 utils::invert_boolean_expression_legacy,
20 utils::{invert_boolean_expression_legacy, is_never_block},
2121};
2222
2323// Assist: convert_to_guarded_return
......@@ -54,9 +54,13 @@ fn if_expr_to_guarded_return(
5454 acc: &mut Assists,
5555 ctx: &AssistContext<'_>,
5656) -> Option<()> {
57 if if_expr.else_branch().is_some() {
58 return None;
59 }
57 let else_block = match if_expr.else_branch() {
58 Some(ast::ElseBranch::Block(block_expr)) if is_never_block(&ctx.sema, &block_expr) => {
59 Some(block_expr)
60 }
61 Some(_) => return None,
62 _ => None,
63 };
6064
6165 let cond = if_expr.condition()?;
6266
......@@ -96,7 +100,11 @@ fn if_expr_to_guarded_return(
96100
97101 let parent_container = parent_block.syntax().parent()?;
98102
99 let early_expression: ast::Expr = early_expression(parent_container, &ctx.sema)?;
103 let early_expression = else_block
104 .or_else(|| {
105 early_expression(parent_container, &ctx.sema).map(ast::make::tail_only_block_expr)
106 })?
107 .reset_indent();
100108
101109 then_block.syntax().first_child_or_token().map(|t| t.kind() == T!['{'])?;
102110
......@@ -123,21 +131,14 @@ fn if_expr_to_guarded_return(
123131 && let (Some(pat), Some(expr)) = (let_expr.pat(), let_expr.expr())
124132 {
125133 // If-let.
126 let let_else_stmt = make::let_else_stmt(
127 pat,
128 None,
129 expr,
130 ast::make::tail_only_block_expr(early_expression.clone()),
131 );
134 let let_else_stmt =
135 make::let_else_stmt(pat, None, expr, early_expression.clone());
132136 let let_else_stmt = let_else_stmt.indent(if_indent_level);
133137 let_else_stmt.syntax().clone()
134138 } else {
135139 // If.
136140 let new_expr = {
137 let then_branch = make::block_expr(
138 once(make::expr_stmt(early_expression.clone()).into()),
139 None,
140 );
141 let then_branch = clean_stmt_block(&early_expression);
141142 let cond = invert_boolean_expression_legacy(expr);
142143 make::expr_if(cond, then_branch, None).indent(if_indent_level)
143144 };
......@@ -182,7 +183,7 @@ fn let_stmt_to_guarded_return(
182183 let cursor_in_range =
183184 let_token_range.cover(let_pattern_range).contains_range(ctx.selection_trimmed());
184185
185 if !cursor_in_range {
186 if !cursor_in_range || let_stmt.let_else().is_some() {
186187 return None;
187188 }
188189
......@@ -272,6 +273,17 @@ fn flat_let_chain(mut expr: ast::Expr) -> Vec<ast::Expr> {
272273 chains
273274}
274275
276fn clean_stmt_block(block: &ast::BlockExpr) -> ast::BlockExpr {
277 if block.statements().next().is_none()
278 && let Some(tail_expr) = block.tail_expr()
279 && block.modifier().is_none()
280 {
281 make::block_expr(once(make::expr_stmt(tail_expr).into()), None)
282 } else {
283 block.clone()
284 }
285}
286
275287#[cfg(test)]
276288mod tests {
277289 use crate::tests::{check_assist, check_assist_not_applicable};
......@@ -421,6 +433,53 @@ fn main() {
421433 );
422434 }
423435
436 #[test]
437 fn convert_if_let_has_never_type_else_block() {
438 check_assist(
439 convert_to_guarded_return,
440 r#"
441fn main() {
442 if$0 let Ok(x) = Err(92) {
443 foo(x);
444 } else {
445 // needless comment
446 return;
447 }
448}
449"#,
450 r#"
451fn main() {
452 let Ok(x) = Err(92) else {
453 // needless comment
454 return;
455 };
456 foo(x);
457}
458"#,
459 );
460
461 check_assist(
462 convert_to_guarded_return,
463 r#"
464fn main() {
465 if$0 let Ok(x) = Err(92) {
466 foo(x);
467 } else {
468 return
469 }
470}
471"#,
472 r#"
473fn main() {
474 let Ok(x) = Err(92) else {
475 return
476 };
477 foo(x);
478}
479"#,
480 );
481 }
482
424483 #[test]
425484 fn convert_if_let_result_inside_let() {
426485 check_assist(
......@@ -911,6 +970,19 @@ fn main() {
911970 );
912971 }
913972
973 #[test]
974 fn ignore_let_else_branch() {
975 check_assist_not_applicable(
976 convert_to_guarded_return,
977 r#"
978//- minicore: option
979fn main() {
980 let$0 Some(x) = Some(2) else { return };
981}
982"#,
983 );
984 }
985
914986 #[test]
915987 fn ignore_statements_after_if() {
916988 check_assist_not_applicable(
src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs+1-1
......@@ -199,7 +199,7 @@ fn augment_references_with_imports(
199199 {
200200 visited_modules.insert(ref_module);
201201
202 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(ref_module.krate()));
202 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(ref_module.krate()));
203203 let import_scope =
204204 ImportScope::find_insert_use_container(new_name.syntax(), &ctx.sema);
205205 let path = ref_module
src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs+1-1
......@@ -88,7 +88,7 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option<Str
8888 let hir::Adt::Struct(struct_type) = ty.strip_references().as_adt()? else { return None };
8989
9090 let module = ctx.sema.scope(ident_pat.syntax())?.module();
91 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(module.krate()));
91 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate()));
9292 let struct_def = hir::ModuleDef::from(struct_type);
9393 let kind = struct_type.kind(ctx.db());
9494 let struct_def_path = module.find_path(ctx.db(), struct_def, cfg)?;
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs+1-3
......@@ -108,9 +108,7 @@ pub(crate) fn extract_expressions_from_format_string(
108108 match arg {
109109 Arg::Expr(s) => {
110110 // insert arg
111 // FIXME: use the crate's edition for parsing
112 let expr =
113 ast::Expr::parse(&s, syntax::Edition::CURRENT_FIXME).syntax_node();
111 let expr = ast::Expr::parse(&s, ctx.edition()).syntax_node();
114112 let mut expr_tt = utils::tt_from_syntax(expr);
115113 new_tt_bits.append(&mut expr_tt);
116114 }
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs+1-1
......@@ -209,7 +209,7 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
209209 FamousDefs(&ctx.sema, module.krate()).core_ops_ControlFlow();
210210
211211 if let Some(control_flow_enum) = control_flow_enum {
212 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(module.krate()));
212 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate()));
213213 let mod_path = module.find_use_path(
214214 ctx.sema.db,
215215 ModuleDef::from(control_flow_enum),
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs+1-1
......@@ -400,7 +400,7 @@ fn process_references(
400400 let segment = builder.make_mut(segment);
401401 let scope_node = builder.make_syntax_mut(scope_node);
402402 if !visited_modules.contains(&module) {
403 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(module.krate()));
403 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate()));
404404 let mod_path = module.find_use_path(
405405 ctx.sema.db,
406406 *enum_module_def,
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs+7-5
......@@ -61,11 +61,13 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
6161 generics.map(|it| make::generic_param_list(it.into_iter().cloned()));
6262
6363 // Replace original type with the alias
64 let ty_args = generic_params
65 .as_ref()
66 .map_or(String::new(), |it| it.to_generic_args().to_string());
67 // FIXME: replace with a `ast::make` constructor
68 let new_ty = make::ty(&format!("Type{ty_args}")).clone_for_update();
64 let ty_args = generic_params.as_ref().map(|it| it.to_generic_args().generic_args());
65 let new_ty = if let Some(ty_args) = ty_args {
66 make::generic_ty_path_segment(make::name_ref("Type"), ty_args)
67 } else {
68 make::path_segment(make::name_ref("Type"))
69 }
70 .clone_for_update();
6971 edit.replace(ty.syntax(), new_ty.syntax());
7072
7173 // Insert new alias
src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs created+1595
......@@ -0,0 +1,1595 @@
1use crate::{
2 AssistConfig,
3 assist_context::{AssistContext, Assists},
4};
5use hir::{HasCrate, Semantics};
6use ide_db::{
7 RootDatabase,
8 assists::{AssistId, AssistKind, ExprFillDefaultMode},
9 famous_defs::FamousDefs,
10 syntax_helpers::suggest_name,
11};
12use syntax::{
13 AstNode,
14 ast::{
15 self, AssocItem, BlockExpr, GenericParam, HasAttrs, HasGenericParams, HasName,
16 HasTypeBounds, HasVisibility, edit_in_place::Indent, make,
17 },
18 syntax_editor::Position,
19};
20
21// Assist: generate_blanket_trait_impl
22//
23// Generate blanket trait implementation.
24//
25// ```
26// trait $0Foo<T: Send>: ToOwned
27// where
28// Self::Owned: Default,
29// {
30// fn foo(&self) -> T;
31//
32// fn print_foo(&self) {
33// println!("{}", self.foo());
34// }
35// }
36// ```
37// ->
38// ```
39// trait Foo<T: Send>: ToOwned
40// where
41// Self::Owned: Default,
42// {
43// fn foo(&self) -> T;
44//
45// fn print_foo(&self) {
46// println!("{}", self.foo());
47// }
48// }
49//
50// impl<T: Send, T1: ToOwned + ?Sized> Foo<T> for $0T1
51// where
52// Self::Owned: Default,
53// {
54// fn foo(&self) -> T {
55// todo!()
56// }
57// }
58// ```
59pub(crate) fn generate_blanket_trait_impl(
60 acc: &mut Assists,
61 ctx: &AssistContext<'_>,
62) -> Option<()> {
63 let name = ctx.find_node_at_offset::<ast::Name>()?;
64 let traitd = ast::Trait::cast(name.syntax().parent()?)?;
65
66 if existing_any_impl(&traitd, &ctx.sema).is_some() {
67 cov_mark::hit!(existing_any_impl);
68 return None;
69 }
70
71 acc.add(
72 AssistId("generate_blanket_trait_impl", AssistKind::Generate, None),
73 "Generate blanket trait implementation",
74 name.syntax().text_range(),
75 |builder| {
76 let mut edit = builder.make_editor(traitd.syntax());
77 let namety = make::ty_path(make::path_from_text(&name.text()));
78 let trait_where_clause = traitd.where_clause().map(|it| it.clone_for_update());
79 let bounds = traitd.type_bound_list().and_then(exlucde_sized);
80 let is_unsafe = traitd.unsafe_token().is_some();
81 let thisname = this_name(&traitd);
82 let thisty = make::ty_path(make::path_from_text(&thisname.text()));
83 let indent = traitd.indent_level();
84
85 let gendecl = make::generic_param_list([GenericParam::TypeParam(make::type_param(
86 thisname.clone(),
87 apply_sized(has_sized(&traitd, &ctx.sema), bounds),
88 ))]);
89
90 let trait_gen_args =
91 traitd.generic_param_list().map(|param_list| param_list.to_generic_args());
92
93 if let Some(ref where_clause) = trait_where_clause {
94 where_clause.reindent_to(0.into());
95 }
96
97 let impl_ = make::impl_trait(
98 cfg_attrs(&traitd),
99 is_unsafe,
100 traitd.generic_param_list(),
101 trait_gen_args,
102 Some(gendecl),
103 None,
104 false,
105 namety,
106 thisty.clone(),
107 trait_where_clause,
108 None,
109 None,
110 )
111 .clone_for_update();
112
113 if let Some(trait_assoc_list) = traitd.assoc_item_list() {
114 let assoc_item_list = impl_.get_or_create_assoc_item_list();
115 for method in trait_assoc_list.assoc_items() {
116 let AssocItem::Fn(method) = method else {
117 continue;
118 };
119 if method.body().is_some() {
120 continue;
121 }
122 let f = todo_fn(&method, ctx.config).clone_for_update();
123 f.indent(1.into());
124 assoc_item_list.add_item(AssocItem::Fn(f));
125 }
126 }
127
128 impl_.indent(indent);
129
130 edit.insert_all(
131 Position::after(traitd.syntax()),
132 vec![
133 make::tokens::whitespace(&format!("\n\n{indent}")).into(),
134 impl_.syntax().clone().into(),
135 ],
136 );
137
138 if let Some(cap) = ctx.config.snippet_cap
139 && let Some(self_ty) = impl_.self_ty()
140 {
141 builder.add_tabstop_before(cap, self_ty);
142 }
143
144 builder.add_file_edits(ctx.vfs_file_id(), edit);
145 },
146 );
147
148 Some(())
149}
150
151fn existing_any_impl(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) -> Option<hir::Impl> {
152 let db = sema.db;
153 let traitd = sema.to_def(traitd)?;
154 traitd
155 .module(db)
156 .impl_defs(db)
157 .into_iter()
158 .find(|impl_| impl_.trait_(db).is_some_and(|it| it == traitd))
159}
160
161fn has_sized(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) -> bool {
162 if let Some(sized) = find_bound("Sized", traitd.type_bound_list()) {
163 sized.question_mark_token().is_none()
164 } else if let Some(is_sized) = where_clause_sized(traitd.where_clause()) {
165 is_sized
166 } else {
167 contained_owned_self_method(traitd.assoc_item_list())
168 || super_traits_has_sized(traitd, sema) == Some(true)
169 }
170}
171
172fn super_traits_has_sized(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) -> Option<bool> {
173 let traitd = sema.to_def(traitd)?;
174 let sized = FamousDefs(sema, traitd.krate(sema.db)).core_marker_Sized()?;
175
176 Some(traitd.all_supertraits(sema.db).contains(&sized))
177}
178
179fn contained_owned_self_method(item_list: Option<ast::AssocItemList>) -> bool {
180 item_list.into_iter().flat_map(|assoc_item_list| assoc_item_list.assoc_items()).any(|item| {
181 match item {
182 AssocItem::Fn(f) => {
183 has_owned_self(&f) && where_clause_sized(f.where_clause()).is_none()
184 }
185 _ => false,
186 }
187 })
188}
189
190fn has_owned_self(f: &ast::Fn) -> bool {
191 has_owned_self_param(f) || has_ret_owned_self(f)
192}
193
194fn has_owned_self_param(f: &ast::Fn) -> bool {
195 f.param_list()
196 .and_then(|param_list| param_list.self_param())
197 .is_some_and(|sp| sp.amp_token().is_none() && sp.colon_token().is_none())
198}
199
200fn has_ret_owned_self(f: &ast::Fn) -> bool {
201 f.ret_type()
202 .and_then(|ret| match ret.ty() {
203 Some(ast::Type::PathType(ty)) => ty.path(),
204 _ => None,
205 })
206 .is_some_and(|path| {
207 path.segment()
208 .and_then(|seg| seg.name_ref())
209 .is_some_and(|name| path.qualifier().is_none() && name.text() == "Self")
210 })
211}
212
213fn where_clause_sized(where_clause: Option<ast::WhereClause>) -> Option<bool> {
214 where_clause?.predicates().find_map(|pred| {
215 find_bound("Sized", pred.type_bound_list())
216 .map(|bound| bound.question_mark_token().is_none())
217 })
218}
219
220fn apply_sized(has_sized: bool, bounds: Option<ast::TypeBoundList>) -> Option<ast::TypeBoundList> {
221 if has_sized {
222 return bounds;
223 }
224 let bounds = bounds
225 .into_iter()
226 .flat_map(|bounds| bounds.bounds())
227 .chain([make::type_bound_text("?Sized")]);
228 make::type_bound_list(bounds)
229}
230
231fn exlucde_sized(bounds: ast::TypeBoundList) -> Option<ast::TypeBoundList> {
232 make::type_bound_list(bounds.bounds().filter(|bound| !ty_bound_is(bound, "Sized")))
233}
234
235fn this_name(traitd: &ast::Trait) -> ast::Name {
236 let has_iter = find_bound("Iterator", traitd.type_bound_list()).is_some();
237
238 let params = traitd
239 .generic_param_list()
240 .into_iter()
241 .flat_map(|param_list| param_list.generic_params())
242 .filter_map(|param| match param {
243 GenericParam::LifetimeParam(_) => None,
244 GenericParam::ConstParam(cp) => cp.name(),
245 GenericParam::TypeParam(tp) => tp.name(),
246 })
247 .map(|name| name.to_string())
248 .collect::<Vec<_>>();
249
250 let mut name_gen =
251 suggest_name::NameGenerator::new_with_names(params.iter().map(String::as_str));
252
253 make::name(&name_gen.suggest_name(if has_iter { "I" } else { "T" }))
254}
255
256fn find_bound(s: &str, bounds: Option<ast::TypeBoundList>) -> Option<ast::TypeBound> {
257 bounds.into_iter().flat_map(|bounds| bounds.bounds()).find(|bound| ty_bound_is(bound, s))
258}
259
260fn ty_bound_is(bound: &ast::TypeBound, s: &str) -> bool {
261 matches!(bound.ty(),
262 Some(ast::Type::PathType(ty)) if ty.path()
263 .and_then(|path| path.segment())
264 .and_then(|segment| segment.name_ref())
265 .is_some_and(|name| name.text() == s))
266}
267
268fn todo_fn(f: &ast::Fn, config: &AssistConfig) -> ast::Fn {
269 let params = f.param_list().unwrap_or_else(|| make::param_list(None, None));
270 make::fn_(
271 cfg_attrs(f),
272 f.visibility(),
273 f.name().unwrap_or_else(|| make::name("unnamed")),
274 f.generic_param_list(),
275 f.where_clause(),
276 params,
277 default_block(config),
278 f.ret_type(),
279 f.async_token().is_some(),
280 f.const_token().is_some(),
281 f.unsafe_token().is_some(),
282 f.gen_token().is_some(),
283 )
284}
285
286fn default_block(config: &AssistConfig) -> BlockExpr {
287 let expr = match config.expr_fill_default {
288 ExprFillDefaultMode::Todo => make::ext::expr_todo(),
289 ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
290 ExprFillDefaultMode::Default => make::ext::expr_todo(),
291 };
292 make::block_expr(None, Some(expr))
293}
294
295fn cfg_attrs(node: &impl HasAttrs) -> impl Iterator<Item = ast::Attr> {
296 node.attrs().filter(|attr| attr.as_simple_call().is_some_and(|(name, _arg)| name == "cfg"))
297}
298
299#[cfg(test)]
300mod test {
301
302 use super::*;
303 use crate::tests::{check_assist, check_assist_not_applicable};
304
305 #[test]
306 fn test_gen_blanket_works() {
307 check_assist(
308 generate_blanket_trait_impl,
309 r#"
310trait $0Foo<T: Send>: ToOwned
311where
312 Self::Owned: Default,
313{
314 fn foo(&self) -> T;
315
316 fn print_foo(&self) {
317 println!("{}", self.foo());
318 }
319}
320"#,
321 r#"
322trait Foo<T: Send>: ToOwned
323where
324 Self::Owned: Default,
325{
326 fn foo(&self) -> T;
327
328 fn print_foo(&self) {
329 println!("{}", self.foo());
330 }
331}
332
333impl<T: Send, T1: ToOwned + ?Sized> Foo<T> for $0T1
334where
335 Self::Owned: Default,
336{
337 fn foo(&self) -> T {
338 todo!()
339 }
340}
341"#,
342 );
343 }
344
345 #[test]
346 fn test_gen_blanket_sized() {
347 check_assist(
348 generate_blanket_trait_impl,
349 r#"
350trait $0Foo: Iterator + Sized {
351 fn foo(mut self) -> Self::Item {
352 self.next().unwrap()
353 }
354}
355"#,
356 r#"
357trait Foo: Iterator + Sized {
358 fn foo(mut self) -> Self::Item {
359 self.next().unwrap()
360 }
361}
362
363impl<I: Iterator> Foo for $0I {}
364"#,
365 );
366
367 check_assist(
368 generate_blanket_trait_impl,
369 r#"
370trait $0Foo: Iterator {
371 fn foo(self) -> Self::Item;
372}
373"#,
374 r#"
375trait Foo: Iterator {
376 fn foo(self) -> Self::Item;
377}
378
379impl<I: Iterator> Foo for $0I {
380 fn foo(self) -> Self::Item {
381 todo!()
382 }
383}
384"#,
385 );
386
387 check_assist(
388 generate_blanket_trait_impl,
389 r#"
390trait $0Foo {
391 fn foo(&self) -> Self;
392}
393"#,
394 r#"
395trait Foo {
396 fn foo(&self) -> Self;
397}
398
399impl<T> Foo for $0T {
400 fn foo(&self) -> Self {
401 todo!()
402 }
403}
404"#,
405 );
406 }
407
408 #[test]
409 fn test_gen_blanket_super_sized() {
410 check_assist(
411 generate_blanket_trait_impl,
412 r#"
413//- minicore: default
414trait $0Foo: Default {
415 fn foo(&self);
416}
417"#,
418 r#"
419trait Foo: Default {
420 fn foo(&self);
421}
422
423impl<T: Default> Foo for $0T {
424 fn foo(&self) {
425 todo!()
426 }
427}
428"#,
429 );
430 }
431
432 #[test]
433 fn test_gen_blanket_non_sized() {
434 check_assist(
435 generate_blanket_trait_impl,
436 r#"
437trait $0Foo: Iterator {
438 fn foo(&self) -> Self::Item;
439}
440"#,
441 r#"
442trait Foo: Iterator {
443 fn foo(&self) -> Self::Item;
444}
445
446impl<I: Iterator + ?Sized> Foo for $0I {
447 fn foo(&self) -> Self::Item {
448 todo!()
449 }
450}
451"#,
452 );
453 check_assist(
454 generate_blanket_trait_impl,
455 r#"
456trait $0Foo: Iterator {
457 fn foo(&self) -> Self::Item;
458
459 fn each(self) where Self: Sized;
460}
461"#,
462 r#"
463trait Foo: Iterator {
464 fn foo(&self) -> Self::Item;
465
466 fn each(self) where Self: Sized;
467}
468
469impl<I: Iterator + ?Sized> Foo for $0I {
470 fn foo(&self) -> Self::Item {
471 todo!()
472 }
473
474 fn each(self) where Self: Sized {
475 todo!()
476 }
477}
478"#,
479 );
480 check_assist(
481 generate_blanket_trait_impl,
482 r#"
483trait $0Foo: Iterator {
484 fn foo(&self) -> Self::Item;
485
486 fn each(&self) -> Self where Self: Sized;
487}
488"#,
489 r#"
490trait Foo: Iterator {
491 fn foo(&self) -> Self::Item;
492
493 fn each(&self) -> Self where Self: Sized;
494}
495
496impl<I: Iterator + ?Sized> Foo for $0I {
497 fn foo(&self) -> Self::Item {
498 todo!()
499 }
500
501 fn each(&self) -> Self where Self: Sized {
502 todo!()
503 }
504}
505"#,
506 );
507 }
508
509 #[test]
510 fn test_gen_blanket_indent() {
511 check_assist(
512 generate_blanket_trait_impl,
513 r#"
514mod foo {
515 trait $0Foo<T: Send>: ToOwned
516 where
517 Self::Owned: Default,
518 {
519 fn foo(&self) -> T;
520
521 fn print_foo(&self) {
522 println!("{}", self.foo());
523 }
524 }
525}
526 "#,
527 r#"
528mod foo {
529 trait Foo<T: Send>: ToOwned
530 where
531 Self::Owned: Default,
532 {
533 fn foo(&self) -> T;
534
535 fn print_foo(&self) {
536 println!("{}", self.foo());
537 }
538 }
539
540 impl<T: Send, T1: ToOwned + ?Sized> Foo<T> for $0T1
541 where
542 Self::Owned: Default,
543 {
544 fn foo(&self) -> T {
545 todo!()
546 }
547 }
548}
549 "#,
550 );
551 check_assist(
552 generate_blanket_trait_impl,
553 r#"
554mod foo {
555 trait $0Foo<T: Send>: ToOwned
556 where
557 Self::Owned: Default,
558 Self: Send,
559 {
560 fn foo(&self) -> T;
561
562 fn print_foo(&self) {
563 println!("{}", self.foo());
564 }
565 }
566}
567 "#,
568 r#"
569mod foo {
570 trait Foo<T: Send>: ToOwned
571 where
572 Self::Owned: Default,
573 Self: Send,
574 {
575 fn foo(&self) -> T;
576
577 fn print_foo(&self) {
578 println!("{}", self.foo());
579 }
580 }
581
582 impl<T: Send, T1: ToOwned + ?Sized> Foo<T> for $0T1
583 where
584 Self::Owned: Default,
585 Self: Send,
586 {
587 fn foo(&self) -> T {
588 todo!()
589 }
590 }
591}
592 "#,
593 );
594 check_assist(
595 generate_blanket_trait_impl,
596 r#"
597mod foo {
598 mod bar {
599 trait $0Foo<T: Send>: ToOwned
600 where
601 Self::Owned: Default,
602 Self: Send,
603 {
604 fn foo(&self) -> T;
605
606 fn print_foo(&self) {
607 println!("{}", self.foo());
608 }
609 }
610 }
611}
612 "#,
613 r#"
614mod foo {
615 mod bar {
616 trait Foo<T: Send>: ToOwned
617 where
618 Self::Owned: Default,
619 Self: Send,
620 {
621 fn foo(&self) -> T;
622
623 fn print_foo(&self) {
624 println!("{}", self.foo());
625 }
626 }
627
628 impl<T: Send, T1: ToOwned + ?Sized> Foo<T> for $0T1
629 where
630 Self::Owned: Default,
631 Self: Send,
632 {
633 fn foo(&self) -> T {
634 todo!()
635 }
636 }
637 }
638}
639 "#,
640 );
641 check_assist(
642 generate_blanket_trait_impl,
643 r#"
644mod foo {
645 trait $0Foo {
646 fn foo(&self) -> i32;
647
648 fn print_foo(&self) {
649 println!("{}", self.foo());
650 }
651 }
652}
653 "#,
654 r#"
655mod foo {
656 trait Foo {
657 fn foo(&self) -> i32;
658
659 fn print_foo(&self) {
660 println!("{}", self.foo());
661 }
662 }
663
664 impl<T: ?Sized> Foo for $0T {
665 fn foo(&self) -> i32 {
666 todo!()
667 }
668 }
669}
670 "#,
671 );
672 check_assist(
673 generate_blanket_trait_impl,
674 r#"
675mod foo {
676 mod bar {
677 trait $0Foo {
678 fn foo(&self) -> i32;
679
680 fn print_foo(&self) {
681 println!("{}", self.foo());
682 }
683 }
684 }
685}
686 "#,
687 r#"
688mod foo {
689 mod bar {
690 trait Foo {
691 fn foo(&self) -> i32;
692
693 fn print_foo(&self) {
694 println!("{}", self.foo());
695 }
696 }
697
698 impl<T: ?Sized> Foo for $0T {
699 fn foo(&self) -> i32 {
700 todo!()
701 }
702 }
703 }
704}
705 "#,
706 );
707 check_assist(
708 generate_blanket_trait_impl,
709 r#"
710mod foo {
711 mod bar {
712 #[cfg(test)]
713 trait $0Foo {
714 fn foo(&self) -> i32;
715
716 fn print_foo(&self) {
717 println!("{}", self.foo());
718 }
719 }
720 }
721}
722 "#,
723 r#"
724mod foo {
725 mod bar {
726 #[cfg(test)]
727 trait Foo {
728 fn foo(&self) -> i32;
729
730 fn print_foo(&self) {
731 println!("{}", self.foo());
732 }
733 }
734
735 #[cfg(test)]
736 impl<T: ?Sized> Foo for $0T {
737 fn foo(&self) -> i32 {
738 todo!()
739 }
740 }
741 }
742}
743 "#,
744 );
745 }
746
747 #[test]
748 fn test_gen_blanket_remove_attribute() {
749 check_assist(
750 generate_blanket_trait_impl,
751 r#"
752trait $0Foo<T: Send>: ToOwned
753where
754 Self::Owned: Default,
755{
756 #[doc(hidden)]
757 fn foo(&self) -> T;
758
759 /// foo
760 fn print_foo(&self) {
761 println!("{}", self.foo());
762 }
763}
764"#,
765 r#"
766trait Foo<T: Send>: ToOwned
767where
768 Self::Owned: Default,
769{
770 #[doc(hidden)]
771 fn foo(&self) -> T;
772
773 /// foo
774 fn print_foo(&self) {
775 println!("{}", self.foo());
776 }
777}
778
779impl<T: Send, T1: ToOwned + ?Sized> Foo<T> for $0T1
780where
781 Self::Owned: Default,
782{
783 fn foo(&self) -> T {
784 todo!()
785 }
786}
787"#,
788 );
789 }
790
791 #[test]
792 fn test_gen_blanket_not_gen_type_alias() {
793 check_assist(
794 generate_blanket_trait_impl,
795 r#"
796trait $0Foo<T: Send>: ToOwned
797where
798 Self::Owned: Default,
799{
800 type X: Sync;
801
802 fn foo(&self, x: Self::X) -> T;
803
804 fn print_foo(&self) {
805 println!("{}", self.foo());
806 }
807}
808"#,
809 r#"
810trait Foo<T: Send>: ToOwned
811where
812 Self::Owned: Default,
813{
814 type X: Sync;
815
816 fn foo(&self, x: Self::X) -> T;
817
818 fn print_foo(&self) {
819 println!("{}", self.foo());
820 }
821}
822
823impl<T: Send, T1: ToOwned + ?Sized> Foo<T> for $0T1
824where
825 Self::Owned: Default,
826{
827 fn foo(&self, x: Self::X) -> T {
828 todo!()
829 }
830}
831"#,
832 );
833 }
834
835 #[test]
836 fn test_gen_blanket_no_quick_bound() {
837 check_assist(
838 generate_blanket_trait_impl,
839 r#"
840trait $0Foo<T: Send>
841where
842 Self: ToOwned,
843 Self::Owned: Default,
844{
845 type X: Sync;
846
847 fn foo(&self, x: Self::X) -> T;
848
849 fn print_foo(&self) {
850 println!("{}", self.foo());
851 }
852}
853"#,
854 r#"
855trait Foo<T: Send>
856where
857 Self: ToOwned,
858 Self::Owned: Default,
859{
860 type X: Sync;
861
862 fn foo(&self, x: Self::X) -> T;
863
864 fn print_foo(&self) {
865 println!("{}", self.foo());
866 }
867}
868
869impl<T: Send, T1: ?Sized> Foo<T> for $0T1
870where
871 Self: ToOwned,
872 Self::Owned: Default,
873{
874 fn foo(&self, x: Self::X) -> T {
875 todo!()
876 }
877}
878"#,
879 );
880 }
881
882 #[test]
883 fn test_gen_blanket_no_where_clause() {
884 check_assist(
885 generate_blanket_trait_impl,
886 r#"
887trait $0Foo<T: Send> {
888 type X: Sync;
889
890 fn foo(&self, x: Self::X) -> T;
891
892 fn print_foo(&self) {
893 println!("{}", self.foo());
894 }
895}
896"#,
897 r#"
898trait Foo<T: Send> {
899 type X: Sync;
900
901 fn foo(&self, x: Self::X) -> T;
902
903 fn print_foo(&self) {
904 println!("{}", self.foo());
905 }
906}
907
908impl<T: Send, T1: ?Sized> Foo<T> for $0T1 {
909 fn foo(&self, x: Self::X) -> T {
910 todo!()
911 }
912}
913"#,
914 );
915 }
916
917 #[test]
918 fn test_gen_blanket_basic() {
919 check_assist(
920 generate_blanket_trait_impl,
921 r#"
922trait $0Foo {
923 type X: Sync;
924
925 fn foo(&self, x: Self::X) -> i32;
926
927 fn print_foo(&self) {
928 println!("{}", self.foo());
929 }
930}
931"#,
932 r#"
933trait Foo {
934 type X: Sync;
935
936 fn foo(&self, x: Self::X) -> i32;
937
938 fn print_foo(&self) {
939 println!("{}", self.foo());
940 }
941}
942
943impl<T: ?Sized> Foo for $0T {
944 fn foo(&self, x: Self::X) -> i32 {
945 todo!()
946 }
947}
948"#,
949 );
950 }
951
952 #[test]
953 fn test_gen_blanket_cfg_attrs() {
954 check_assist(
955 generate_blanket_trait_impl,
956 r#"
957#[cfg(test)]
958trait $0Foo {
959 fn foo(&self, x: i32) -> i32;
960
961 fn print_foo(&self) {
962 println!("{}", self.foo());
963 }
964}
965"#,
966 r#"
967#[cfg(test)]
968trait Foo {
969 fn foo(&self, x: i32) -> i32;
970
971 fn print_foo(&self) {
972 println!("{}", self.foo());
973 }
974}
975
976#[cfg(test)]
977impl<T: ?Sized> Foo for $0T {
978 fn foo(&self, x: i32) -> i32 {
979 todo!()
980 }
981}
982"#,
983 );
984 check_assist(
985 generate_blanket_trait_impl,
986 r#"
987#[cfg(test)]
988trait $0Foo {
989 /// ...
990 #[cfg(test)]
991 fn foo(&self, x: i32) -> i32;
992
993 fn print_foo(&self) {
994 println!("{}", self.foo());
995 }
996}
997"#,
998 r#"
999#[cfg(test)]
1000trait Foo {
1001 /// ...
1002 #[cfg(test)]
1003 fn foo(&self, x: i32) -> i32;
1004
1005 fn print_foo(&self) {
1006 println!("{}", self.foo());
1007 }
1008}
1009
1010#[cfg(test)]
1011impl<T: ?Sized> Foo for $0T {
1012 #[cfg(test)]
1013 fn foo(&self, x: i32) -> i32 {
1014 todo!()
1015 }
1016}
1017"#,
1018 );
1019 }
1020
1021 #[test]
1022 fn test_gen_blanket_empty_trait() {
1023 check_assist(
1024 generate_blanket_trait_impl,
1025 r#"
1026trait $0Foo {}
1027"#,
1028 r#"
1029trait Foo {}
1030
1031impl<T: ?Sized> Foo for $0T {}
1032"#,
1033 );
1034 }
1035
1036 #[test]
1037 fn test_gen_blanket_empty_trait_with_quick_bounds() {
1038 check_assist(
1039 generate_blanket_trait_impl,
1040 r#"
1041trait $0Foo: Copy {}
1042"#,
1043 r#"
1044trait Foo: Copy {}
1045
1046impl<T: Copy + ?Sized> Foo for $0T {}
1047"#,
1048 );
1049 }
1050
1051 #[test]
1052 fn test_gen_blanket_empty_trait_with_where_clause() {
1053 check_assist(
1054 generate_blanket_trait_impl,
1055 r#"
1056trait $0Foo where Self: Copy {}
1057"#,
1058 r#"
1059trait Foo where Self: Copy {}
1060
1061impl<T: ?Sized> Foo for $0T
1062where Self: Copy
1063{
1064}
1065"#,
1066 );
1067 }
1068
1069 #[test]
1070 fn test_gen_blanket_empty_trait_with_where_clause_comma() {
1071 check_assist(
1072 generate_blanket_trait_impl,
1073 r#"
1074trait $0Foo where Self: Copy, {}
1075"#,
1076 r#"
1077trait Foo where Self: Copy, {}
1078
1079impl<T: ?Sized> Foo for $0T
1080where Self: Copy,
1081{
1082}
1083"#,
1084 );
1085 }
1086
1087 #[test]
1088 fn test_gen_blanket_empty_trait_with_where_clause_newline() {
1089 check_assist(
1090 generate_blanket_trait_impl,
1091 r#"
1092trait $0Foo
1093where Self: Copy
1094{}
1095"#,
1096 r#"
1097trait Foo
1098where Self: Copy
1099{}
1100
1101impl<T: ?Sized> Foo for $0T
1102where Self: Copy
1103{
1104}
1105"#,
1106 );
1107 }
1108
1109 #[test]
1110 fn test_gen_blanket_empty_trait_with_where_clause_newline_newline() {
1111 check_assist(
1112 generate_blanket_trait_impl,
1113 r#"
1114trait $0Foo
1115where
1116 Self: Copy
1117{}
1118"#,
1119 r#"
1120trait Foo
1121where
1122 Self: Copy
1123{}
1124
1125impl<T: ?Sized> Foo for $0T
1126where
1127 Self: Copy
1128{
1129}
1130"#,
1131 );
1132 }
1133
1134 #[test]
1135 fn test_gen_blanket_empty_trait_with_where_clause_newline_newline_comma() {
1136 check_assist(
1137 generate_blanket_trait_impl,
1138 r#"
1139trait $0Foo
1140where
1141 Self: Copy,
1142{}
1143"#,
1144 r#"
1145trait Foo
1146where
1147 Self: Copy,
1148{}
1149
1150impl<T: ?Sized> Foo for $0T
1151where
1152 Self: Copy,
1153{
1154}
1155"#,
1156 );
1157 }
1158
1159 #[test]
1160 fn test_gen_blanket_empty_trait_with_multiple_where_clause() {
1161 check_assist(
1162 generate_blanket_trait_impl,
1163 r#"
1164trait $0Foo
1165where
1166 Self: Copy,
1167 (): Into<Self>,
1168{}
1169"#,
1170 r#"
1171trait Foo
1172where
1173 Self: Copy,
1174 (): Into<Self>,
1175{}
1176
1177impl<T: ?Sized> Foo for $0T
1178where
1179 Self: Copy,
1180 (): Into<Self>,
1181{
1182}
1183"#,
1184 );
1185 }
1186
1187 #[test]
1188 fn test_gen_blanket_empty_trait_with_multiple_bounds_where_clause() {
1189 check_assist(
1190 generate_blanket_trait_impl,
1191 r#"
1192trait $0Foo
1193where
1194 Self: Copy + Sync,
1195 (): Into<Self>,
1196{}
1197"#,
1198 r#"
1199trait Foo
1200where
1201 Self: Copy + Sync,
1202 (): Into<Self>,
1203{}
1204
1205impl<T: ?Sized> Foo for $0T
1206where
1207 Self: Copy + Sync,
1208 (): Into<Self>,
1209{
1210}
1211"#,
1212 );
1213 }
1214
1215 #[test]
1216 fn test_gen_blanket_empty_generate() {
1217 check_assist(
1218 generate_blanket_trait_impl,
1219 r#"
1220trait $0Foo {
1221 fn foo(&self) {}
1222}
1223"#,
1224 r#"
1225trait Foo {
1226 fn foo(&self) {}
1227}
1228
1229impl<T: ?Sized> Foo for $0T {}
1230"#,
1231 );
1232 }
1233
1234 #[test]
1235 fn test_gen_blanket_trait_with_doc() {
1236 check_assist(
1237 generate_blanket_trait_impl,
1238 r#"
1239/// some docs
1240trait $0Foo {}
1241"#,
1242 r#"
1243/// some docs
1244trait Foo {}
1245
1246impl<T: ?Sized> Foo for $0T {}
1247"#,
1248 );
1249 }
1250
1251 #[test]
1252 fn test_gen_blanket_multiple_method() {
1253 check_assist(
1254 generate_blanket_trait_impl,
1255 r#"
1256trait $0Foo {
1257 fn foo(&self);
1258 fn bar(&self);
1259}
1260"#,
1261 r#"
1262trait Foo {
1263 fn foo(&self);
1264 fn bar(&self);
1265}
1266
1267impl<T: ?Sized> Foo for $0T {
1268 fn foo(&self) {
1269 todo!()
1270 }
1271
1272 fn bar(&self) {
1273 todo!()
1274 }
1275}
1276"#,
1277 );
1278 }
1279
1280 #[test]
1281 fn test_gen_blanket_method_with_generic() {
1282 check_assist(
1283 generate_blanket_trait_impl,
1284 r#"
1285trait $0Foo {
1286 fn foo<T>(&self, value: i32) -> i32;
1287 fn bar<T>(&self, value: i32) -> i32 { todo!() }
1288}
1289"#,
1290 r#"
1291trait Foo {
1292 fn foo<T>(&self, value: i32) -> i32;
1293 fn bar<T>(&self, value: i32) -> i32 { todo!() }
1294}
1295
1296impl<T: ?Sized> Foo for $0T {
1297 fn foo<T>(&self, value: i32) -> i32 {
1298 todo!()
1299 }
1300}
1301"#,
1302 );
1303 }
1304
1305 #[test]
1306 fn test_gen_blanket_method_with_lifetimes() {
1307 check_assist(
1308 generate_blanket_trait_impl,
1309 r#"
1310trait $0Foo<'a> {
1311 fn foo(&self) -> &'a str;
1312}
1313"#,
1314 r#"
1315trait Foo<'a> {
1316 fn foo(&self) -> &'a str;
1317}
1318
1319impl<'a, T: ?Sized> Foo<'a> for $0T {
1320 fn foo(&self) -> &'a str {
1321 todo!()
1322 }
1323}
1324"#,
1325 );
1326 }
1327
1328 #[test]
1329 fn test_gen_blanket_method_with_lifetime_bounds() {
1330 check_assist(
1331 generate_blanket_trait_impl,
1332 r#"
1333trait $0Foo<'a: 'static> {
1334 fn foo(&self) -> &'a str;
1335}
1336"#,
1337 r#"
1338trait Foo<'a: 'static> {
1339 fn foo(&self) -> &'a str;
1340}
1341
1342impl<'a: 'static, T: ?Sized> Foo<'a> for $0T {
1343 fn foo(&self) -> &'a str {
1344 todo!()
1345 }
1346}
1347"#,
1348 );
1349 }
1350
1351 #[test]
1352 fn test_gen_blanket_method_with_lifetime_quick_bounds() {
1353 check_assist(
1354 generate_blanket_trait_impl,
1355 r#"
1356trait $0Foo<'a>: 'a {
1357 fn foo(&self) -> &'a str;
1358}
1359"#,
1360 r#"
1361trait Foo<'a>: 'a {
1362 fn foo(&self) -> &'a str;
1363}
1364
1365impl<'a, T: 'a + ?Sized> Foo<'a> for $0T {
1366 fn foo(&self) -> &'a str {
1367 todo!()
1368 }
1369}
1370"#,
1371 );
1372 }
1373
1374 #[test]
1375 fn test_gen_blanket_method_with_multiple_lifetimes() {
1376 check_assist(
1377 generate_blanket_trait_impl,
1378 r#"
1379trait $0Foo<'a, 'b> {
1380 fn foo(&self) -> &'a &'b str;
1381}
1382"#,
1383 r#"
1384trait Foo<'a, 'b> {
1385 fn foo(&self) -> &'a &'b str;
1386}
1387
1388impl<'a, 'b, T: ?Sized> Foo<'a, 'b> for $0T {
1389 fn foo(&self) -> &'a &'b str {
1390 todo!()
1391 }
1392}
1393"#,
1394 );
1395 }
1396
1397 #[test]
1398 fn test_gen_blanket_method_with_lifetime_bounds_at_where_clause() {
1399 check_assist(
1400 generate_blanket_trait_impl,
1401 r#"
1402trait $0Foo<'a>
1403where 'a: 'static,
1404{
1405 fn foo(&self) -> &'a str;
1406}
1407"#,
1408 r#"
1409trait Foo<'a>
1410where 'a: 'static,
1411{
1412 fn foo(&self) -> &'a str;
1413}
1414
1415impl<'a, T: ?Sized> Foo<'a> for $0T
1416where 'a: 'static,
1417{
1418 fn foo(&self) -> &'a str {
1419 todo!()
1420 }
1421}
1422"#,
1423 );
1424 }
1425
1426 #[test]
1427 fn test_gen_blanket_not_on_name() {
1428 check_assist_not_applicable(
1429 generate_blanket_trait_impl,
1430 r#"
1431trait Foo<T: Send>: $0ToOwned
1432where
1433 Self::Owned: Default,
1434{
1435 fn foo(&self) -> T;
1436
1437 fn print_foo(&self) {
1438 println!("{}", self.foo());
1439 }
1440}
1441"#,
1442 );
1443
1444 check_assist_not_applicable(
1445 generate_blanket_trait_impl,
1446 r#"
1447trait Foo<T: Send>: ToOwned
1448where
1449 Self::Owned: Default,
1450{
1451 $0fn foo(&self) -> T;
1452
1453 fn print_foo(&self) {
1454 println!("{}", self.foo());
1455 }
1456}
1457"#,
1458 );
1459
1460 check_assist_not_applicable(
1461 generate_blanket_trait_impl,
1462 r#"
1463trait Foo<T: Send>: ToOwned
1464where
1465 Self::Owned: Default,
1466{
1467 fn $0foo(&self) -> T;
1468
1469 fn print_foo(&self) {
1470 println!("{}", self.foo());
1471 }
1472}
1473"#,
1474 );
1475 }
1476
1477 #[test]
1478 fn test_gen_blanket_existing_impl() {
1479 cov_mark::check!(existing_any_impl);
1480 check_assist_not_applicable(
1481 generate_blanket_trait_impl,
1482 r#"
1483trait $0Foo: Default {
1484 fn foo(&self) -> Self;
1485}
1486impl Foo for () {}
1487"#,
1488 );
1489 }
1490
1491 #[test]
1492 fn test_gen_blanket_existing_other_impl() {
1493 check_assist(
1494 generate_blanket_trait_impl,
1495 r#"
1496trait $0Foo: Default {
1497 fn foo(&self) -> Self;
1498}
1499trait Bar: Default {
1500 fn bar(&self) -> Self;
1501}
1502impl Bar for () {}
1503"#,
1504 r#"
1505trait Foo: Default {
1506 fn foo(&self) -> Self;
1507}
1508
1509impl<T: Default> Foo for $0T {
1510 fn foo(&self) -> Self {
1511 todo!()
1512 }
1513}
1514trait Bar: Default {
1515 fn bar(&self) -> Self;
1516}
1517impl Bar for () {}
1518"#,
1519 );
1520 }
1521
1522 #[test]
1523 fn test_gen_blanket_apply_on_other_impl_block() {
1524 check_assist(
1525 generate_blanket_trait_impl,
1526 r#"
1527trait $0Foo {
1528 fn foo(&self) -> i32;
1529
1530 fn print_foo(&self) {
1531 println!("{}", self.foo());
1532 }
1533}
1534
1535trait Bar {}
1536impl Bar for i32 {}
1537"#,
1538 r#"
1539trait Foo {
1540 fn foo(&self) -> i32;
1541
1542 fn print_foo(&self) {
1543 println!("{}", self.foo());
1544 }
1545}
1546
1547impl<T: ?Sized> Foo for $0T {
1548 fn foo(&self) -> i32 {
1549 todo!()
1550 }
1551}
1552
1553trait Bar {}
1554impl Bar for i32 {}
1555"#,
1556 );
1557 }
1558
1559 #[test]
1560 fn test_gen_blanket_apply_on_other_blanket_impl_block() {
1561 check_assist(
1562 generate_blanket_trait_impl,
1563 r#"
1564trait $0Foo {
1565 fn foo(&self) -> i32;
1566
1567 fn print_foo(&self) {
1568 println!("{}", self.foo());
1569 }
1570}
1571
1572trait Bar {}
1573impl<T> Bar for T {}
1574"#,
1575 r#"
1576trait Foo {
1577 fn foo(&self) -> i32;
1578
1579 fn print_foo(&self) {
1580 println!("{}", self.foo());
1581 }
1582}
1583
1584impl<T: ?Sized> Foo for $0T {
1585 fn foo(&self) -> i32 {
1586 todo!()
1587 }
1588}
1589
1590trait Bar {}
1591impl<T> Bar for T {}
1592"#,
1593 );
1594 }
1595}
src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs+2-2
......@@ -57,7 +57,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
5757 };
5858
5959 let module = ctx.sema.to_def(&strukt)?.module(ctx.db());
60 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(module.krate()));
60 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate()));
6161 let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?;
6262 let trait_path = module.find_path(ctx.db(), ModuleDef::Trait(trait_), cfg)?;
6363
......@@ -99,7 +99,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()
9999 };
100100
101101 let module = ctx.sema.to_def(&strukt)?.module(ctx.db());
102 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(module.krate()));
102 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate()));
103103 let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?;
104104 let trait_path = module.find_path(ctx.db(), ModuleDef::Trait(trait_), cfg)?;
105105
src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs+1-1
......@@ -77,7 +77,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
7777
7878 let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?));
7979
80 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(current_module.krate()));
80 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(current_module.krate()));
8181 let type_path = current_module.find_path(
8282 ctx.sema.db,
8383 item_for_path_search(ctx.sema.db, item_in_ns)?,
src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs+1-1
......@@ -169,7 +169,7 @@ fn make_constructors(
169169 types: &[ast::Type],
170170) -> Vec<Option<ast::Expr>> {
171171 let (db, sema) = (ctx.db(), &ctx.sema);
172 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(module.krate()));
172 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate()));
173173 types
174174 .iter()
175175 .map(|ty| {
src/tools/rust-analyzer/crates/ide-assists/src/handlers/pull_assignment_up.rs+31-2
......@@ -1,3 +1,4 @@
1use either::Either;
12use syntax::{
23 AstNode,
34 algo::find_node_at_range,
......@@ -52,14 +53,15 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) ->
5253 assignments: Vec::new(),
5354 };
5455
55 let tgt: ast::Expr = if let Some(if_expr) = ctx.find_node_at_offset::<ast::IfExpr>() {
56 let node: Either<ast::IfExpr, ast::MatchExpr> = ctx.find_node_at_offset()?;
57 let tgt: ast::Expr = if let Either::Left(if_expr) = node {
5658 let if_expr = std::iter::successors(Some(if_expr), |it| {
5759 it.syntax().parent().and_then(ast::IfExpr::cast)
5860 })
5961 .last()?;
6062 collector.collect_if(&if_expr)?;
6163 if_expr.into()
62 } else if let Some(match_expr) = ctx.find_node_at_offset::<ast::MatchExpr>() {
64 } else if let Either::Right(match_expr) = node {
6365 collector.collect_match(&match_expr)?;
6466 match_expr.into()
6567 } else {
......@@ -311,6 +313,33 @@ fn foo() {
311313 );
312314 }
313315
316 #[test]
317 fn test_pull_assignment_up_match_in_if_expr() {
318 check_assist(
319 pull_assignment_up,
320 r#"
321fn foo() {
322 let x;
323 if true {
324 match true {
325 true => $0x = 2,
326 false => x = 3,
327 }
328 }
329}"#,
330 r#"
331fn foo() {
332 let x;
333 if true {
334 x = match true {
335 true => 2,
336 false => 3,
337 };
338 }
339}"#,
340 );
341 }
342
314343 #[test]
315344 fn test_pull_assignment_up_assignment_expressions() {
316345 check_assist(
src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs+1-1
......@@ -45,7 +45,7 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) ->
4545 let current_edition = current_module.krate().edition(ctx.db());
4646 let target_module_def = ModuleDef::from(resolved_call);
4747 let item_in_ns = ItemInNs::from(target_module_def);
48 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(current_module.krate()));
48 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(current_module.krate()));
4949 let receiver_path = current_module.find_path(
5050 ctx.sema.db,
5151 item_for_path_search(ctx.sema.db, item_in_ns)?,
src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs+133-44
......@@ -1,10 +1,12 @@
1use std::borrow::Cow;
2
3use syntax::{AstToken, TextRange, TextSize, ast, ast::IsString};
1use ide_db::source_change::SourceChangeBuilder;
2use syntax::{
3 AstToken,
4 ast::{self, IsString, make::tokens::literal},
5};
46
57use crate::{
68 AssistContext, AssistId, Assists,
7 utils::{required_hashes, string_suffix},
9 utils::{required_hashes, string_prefix, string_suffix},
810};
911
1012// Assist: make_raw_string
......@@ -23,8 +25,7 @@ use crate::{
2325// }
2426// ```
2527pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
26 // FIXME: This should support byte and c strings as well.
27 let token = ctx.find_token_at_offset::<ast::String>()?;
28 let token = ctx.find_token_at_offset::<ast::AnyString>()?;
2829 if token.is_raw() {
2930 return None;
3031 }
......@@ -36,16 +37,10 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
3637 target,
3738 |edit| {
3839 let hashes = "#".repeat(required_hashes(&value).max(1));
39 let range = token.syntax().text_range();
40 let raw_prefix = token.raw_prefix();
4041 let suffix = string_suffix(token.text()).unwrap_or_default();
41 let range = TextRange::new(range.start(), range.end() - TextSize::of(suffix));
42 if matches!(value, Cow::Borrowed(_)) {
43 // Avoid replacing the whole string to better position the cursor.
44 edit.insert(range.start(), format!("r{hashes}"));
45 edit.insert(range.end(), hashes);
46 } else {
47 edit.replace(range, format!("r{hashes}\"{value}\"{hashes}"));
48 }
42 let new_str = format!("{raw_prefix}{hashes}\"{value}\"{hashes}{suffix}");
43 replace_literal(&token, &new_str, edit, ctx);
4944 },
5045 )
5146}
......@@ -66,7 +61,7 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
6661// }
6762// ```
6863pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
69 let token = ctx.find_token_at_offset::<ast::String>()?;
64 let token = ctx.find_token_at_offset::<ast::AnyString>()?;
7065 if !token.is_raw() {
7166 return None;
7267 }
......@@ -80,18 +75,9 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
8075 // parse inside string to escape `"`
8176 let escaped = value.escape_default().to_string();
8277 let suffix = string_suffix(token.text()).unwrap_or_default();
83 if let Some(offsets) = token.quote_offsets()
84 && token.text()[offsets.contents - token.syntax().text_range().start()] == escaped
85 {
86 let end_quote = offsets.quotes.1;
87 let end_quote =
88 TextRange::new(end_quote.start(), end_quote.end() - TextSize::of(suffix));
89 edit.replace(offsets.quotes.0, "\"");
90 edit.replace(end_quote, "\"");
91 return;
92 }
93
94 edit.replace(token.syntax().text_range(), format!("\"{escaped}\"{suffix}"));
78 let prefix = string_prefix(token.text()).map_or("", |s| s.trim_end_matches('r'));
79 let new_str = format!("{prefix}\"{escaped}\"{suffix}");
80 replace_literal(&token, &new_str, edit, ctx);
9581 },
9682 )
9783}
......@@ -112,16 +98,18 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
11298// }
11399// ```
114100pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
115 let token = ctx.find_token_at_offset::<ast::String>()?;
101 let token = ctx.find_token_at_offset::<ast::AnyString>()?;
116102 if !token.is_raw() {
117103 return None;
118104 }
119 let text_range = token.syntax().text_range();
120 let target = text_range;
105 let target = token.syntax().text_range();
121106 acc.add(AssistId::refactor("add_hash"), "Add #", target, |edit| {
122 let suffix = string_suffix(token.text()).unwrap_or_default();
123 edit.insert(text_range.start() + TextSize::of('r'), "#");
124 edit.insert(text_range.end() - TextSize::of(suffix), "#");
107 let str = token.text();
108 let suffix = string_suffix(str).unwrap_or_default();
109 let raw_prefix = token.raw_prefix();
110 let wrap_range = raw_prefix.len()..str.len() - suffix.len();
111 let new_str = [raw_prefix, "#", &str[wrap_range], "#", suffix].concat();
112 replace_literal(&token, &new_str, edit, ctx);
125113 })
126114}
127115
......@@ -141,17 +129,15 @@ pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()>
141129// }
142130// ```
143131pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
144 let token = ctx.find_token_at_offset::<ast::String>()?;
132 let token = ctx.find_token_at_offset::<ast::AnyString>()?;
145133 if !token.is_raw() {
146134 return None;
147135 }
148136
149137 let text = token.text();
150 if !text.starts_with("r#") && text.ends_with('#') {
151 return None;
152 }
153138
154 let existing_hashes = text.chars().skip(1).take_while(|&it| it == '#').count();
139 let existing_hashes =
140 text.chars().skip(token.raw_prefix().len()).take_while(|&it| it == '#').count();
155141
156142 let text_range = token.syntax().text_range();
157143 let internal_text = &text[token.text_range_between_quotes()? - text_range.start()];
......@@ -163,14 +149,38 @@ pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
163149
164150 acc.add(AssistId::refactor_rewrite("remove_hash"), "Remove #", text_range, |edit| {
165151 let suffix = string_suffix(text).unwrap_or_default();
166 edit.delete(TextRange::at(text_range.start() + TextSize::of('r'), TextSize::of('#')));
167 edit.delete(
168 TextRange::new(text_range.end() - TextSize::of('#'), text_range.end())
169 - TextSize::of(suffix),
170 );
152 let prefix = token.raw_prefix();
153 let wrap_range = prefix.len() + 1..text.len() - suffix.len() - 1;
154 let new_str = [prefix, &text[wrap_range], suffix].concat();
155 replace_literal(&token, &new_str, edit, ctx);
171156 })
172157}
173158
159fn replace_literal(
160 token: &impl AstToken,
161 new: &str,
162 builder: &mut SourceChangeBuilder,
163 ctx: &AssistContext<'_>,
164) {
165 let token = token.syntax();
166 let node = token.parent().expect("no parent token");
167 let mut edit = builder.make_editor(&node);
168 let new_literal = literal(new);
169
170 edit.replace(token, mut_token(new_literal));
171
172 builder.add_file_edits(ctx.vfs_file_id(), edit);
173}
174
175fn mut_token(token: syntax::SyntaxToken) -> syntax::SyntaxToken {
176 let node = token.parent().expect("no parent token");
177 node.clone_for_update()
178 .children_with_tokens()
179 .filter_map(|it| it.into_token())
180 .find(|it| it.text_range() == token.text_range() && it.text() == token.text())
181 .unwrap()
182}
183
174184#[cfg(test)]
175185mod tests {
176186 use super::*;
......@@ -224,6 +234,42 @@ string"#;
224234 )
225235 }
226236
237 #[test]
238 fn make_raw_byte_string_works() {
239 check_assist(
240 make_raw_string,
241 r#"
242fn f() {
243 let s = $0b"random\nstring";
244}
245"#,
246 r##"
247fn f() {
248 let s = br#"random
249string"#;
250}
251"##,
252 )
253 }
254
255 #[test]
256 fn make_raw_c_string_works() {
257 check_assist(
258 make_raw_string,
259 r#"
260fn f() {
261 let s = $0c"random\nstring";
262}
263"#,
264 r##"
265fn f() {
266 let s = cr#"random
267string"#;
268}
269"##,
270 )
271 }
272
227273 #[test]
228274 fn make_raw_string_hashes_inside_works() {
229275 check_assist(
......@@ -348,6 +394,23 @@ string"###;
348394 )
349395 }
350396
397 #[test]
398 fn add_hash_works_for_c_str() {
399 check_assist(
400 add_hash,
401 r#"
402 fn f() {
403 let s = $0cr"random string";
404 }
405 "#,
406 r##"
407 fn f() {
408 let s = cr#"random string"#;
409 }
410 "##,
411 )
412 }
413
351414 #[test]
352415 fn add_hash_has_suffix_works() {
353416 check_assist(
......@@ -433,6 +496,15 @@ string"###;
433496 )
434497 }
435498
499 #[test]
500 fn remove_hash_works_for_c_str() {
501 check_assist(
502 remove_hash,
503 r##"fn f() { let s = $0cr#"random string"#; }"##,
504 r#"fn f() { let s = cr"random string"; }"#,
505 )
506 }
507
436508 #[test]
437509 fn remove_hash_has_suffix_works() {
438510 check_assist(
......@@ -529,6 +601,23 @@ string"###;
529601 )
530602 }
531603
604 #[test]
605 fn make_usual_string_for_c_str() {
606 check_assist(
607 make_usual_string,
608 r##"
609 fn f() {
610 let s = $0cr#"random string"#;
611 }
612 "##,
613 r#"
614 fn f() {
615 let s = c"random string";
616 }
617 "#,
618 )
619 }
620
532621 #[test]
533622 fn make_usual_string_has_suffix_works() {
534623 check_assist(
src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs+1-1
......@@ -71,7 +71,7 @@ pub(crate) fn replace_derive_with_manual_impl(
7171 let current_module = ctx.sema.scope(adt.syntax())?.module();
7272 let current_crate = current_module.krate();
7373 let current_edition = current_crate.edition(ctx.db());
74 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(current_crate));
74 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(current_crate));
7575
7676 let found_traits = items_locator::items_with_name(
7777 ctx.db(),
src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs+1-1
......@@ -64,7 +64,7 @@ pub(crate) fn replace_qualified_name_with_use(
6464 let path_to_qualifier = starts_with_name_ref
6565 .then(|| {
6666 let mod_ = ctx.sema.scope(original_path.syntax())?.module();
67 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(mod_.krate()));
67 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(mod_.krate()));
6868 mod_.find_use_path(ctx.sema.db, module, ctx.config.insert_use.prefix_kind, cfg)
6969 })
7070 .flatten();
src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs+1-1
......@@ -55,7 +55,7 @@ pub(crate) fn term_search(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
5555 path.gen_source_code(
5656 &scope,
5757 &mut formatter,
58 ctx.config.find_path_confg(ctx.sema.is_nightly(scope.module().krate())),
58 ctx.config.find_path_config(ctx.sema.is_nightly(scope.module().krate())),
5959 scope.krate().to_display_target(ctx.db()),
6060 )
6161 .ok()
src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs+1-1
......@@ -132,7 +132,7 @@ pub(crate) fn desugar_async_into_impl_future(
132132
133133 let scope = ctx.sema.scope(function.syntax())?;
134134 let module = scope.module();
135 let cfg = ctx.config.find_path_confg(ctx.sema.is_nightly(module.krate()));
135 let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate()));
136136 let future_trait = FamousDefs(&ctx.sema, scope.krate()).core_future_Future()?;
137137 let trait_path = module.find_path(ctx.db(), ModuleDef::Trait(future_trait), cfg)?;
138138 let edition = scope.krate().edition(ctx.db());
src/tools/rust-analyzer/crates/ide-assists/src/lib.rs+2
......@@ -153,6 +153,7 @@ mod handlers {
153153 mod flip_comma;
154154 mod flip_or_pattern;
155155 mod flip_trait_bound;
156 mod generate_blanket_trait_impl;
156157 mod generate_constant;
157158 mod generate_default_from_enum_variant;
158159 mod generate_default_from_new;
......@@ -308,6 +309,7 @@ mod handlers {
308309 generate_new::generate_new,
309310 generate_trait_from_impl::generate_trait_from_impl,
310311 generate_single_field_struct_from::generate_single_field_struct_from,
312 generate_blanket_trait_impl::generate_blanket_trait_impl,
311313 inline_call::inline_call,
312314 inline_call::inline_into_callers,
313315 inline_const_as_literal::inline_const_as_literal,
src/tools/rust-analyzer/crates/ide-assists/src/tests.rs+3-3
......@@ -5,7 +5,7 @@ use hir::{Semantics, db::HirDatabase, setup_tracing};
55use ide_db::{
66 EditionedFileId, FileRange, RootDatabase, SnippetCap,
77 assists::ExprFillDefaultMode,
8 base_db::{SourceDatabase, salsa},
8 base_db::SourceDatabase,
99 imports::insert_use::{ImportGranularity, InsertUseConfig},
1010 source_change::FileSystemEdit,
1111};
......@@ -109,7 +109,7 @@ fn assists(
109109 resolve: AssistResolveStrategy,
110110 range: ide_db::FileRange,
111111) -> Vec<Assist> {
112 salsa::attach(db, || {
112 hir::attach_db(db, || {
113113 HirDatabase::zalsa_register_downcaster(db);
114114 crate::assists(db, config, resolve, range)
115115 })
......@@ -332,7 +332,7 @@ fn check_with_config(
332332 _ => AssistResolveStrategy::All,
333333 };
334334 let mut acc = Assists::new(&ctx, resolve);
335 salsa::attach(&db, || {
335 hir::attach_db(&db, || {
336336 HirDatabase::zalsa_register_downcaster(&db);
337337 handler(&mut acc, &ctx);
338338 });
src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs+40
......@@ -1345,6 +1345,46 @@ fn foo<T: Copy + Clone>() { }
13451345 )
13461346}
13471347
1348#[test]
1349fn doctest_generate_blanket_trait_impl() {
1350 check_doc_test(
1351 "generate_blanket_trait_impl",
1352 r#####"
1353trait $0Foo<T: Send>: ToOwned
1354where
1355 Self::Owned: Default,
1356{
1357 fn foo(&self) -> T;
1358
1359 fn print_foo(&self) {
1360 println!("{}", self.foo());
1361 }
1362}
1363"#####,
1364 r#####"
1365trait Foo<T: Send>: ToOwned
1366where
1367 Self::Owned: Default,
1368{
1369 fn foo(&self) -> T;
1370
1371 fn print_foo(&self) {
1372 println!("{}", self.foo());
1373 }
1374}
1375
1376impl<T: Send, T1: ToOwned + ?Sized> Foo<T> for $0T1
1377where
1378 Self::Owned: Default,
1379{
1380 fn foo(&self) -> T {
1381 todo!()
1382 }
1383}
1384"#####,
1385 )
1386}
1387
13481388#[test]
13491389fn doctest_generate_constant() {
13501390 check_doc_test(
src/tools/rust-analyzer/crates/ide-assists/src/utils.rs+31
......@@ -1057,6 +1057,21 @@ fn test_string_suffix() {
10571057 assert_eq!(Some("i32"), string_suffix(r##"r#""#i32"##));
10581058}
10591059
1060/// Calculate the string literal prefix length
1061pub(crate) fn string_prefix(s: &str) -> Option<&str> {
1062 s.split_once(['"', '\'', '#']).map(|(prefix, _)| prefix)
1063}
1064#[test]
1065fn test_string_prefix() {
1066 assert_eq!(Some(""), string_prefix(r#""abc""#));
1067 assert_eq!(Some(""), string_prefix(r#""""#));
1068 assert_eq!(Some(""), string_prefix(r#"""suffix"#));
1069 assert_eq!(Some("c"), string_prefix(r#"c"""#));
1070 assert_eq!(Some("r"), string_prefix(r#"r"""#));
1071 assert_eq!(Some("cr"), string_prefix(r#"cr"""#));
1072 assert_eq!(Some("r"), string_prefix(r##"r#""#"##));
1073}
1074
10601075/// Replaces the record expression, handling field shorthands including inside macros.
10611076pub(crate) fn replace_record_field_expr(
10621077 ctx: &AssistContext<'_>,
......@@ -1150,3 +1165,19 @@ pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bo
11501165 });
11511166 is_const
11521167}
1168
1169// FIXME: #20460 When hir-ty can analyze the `never` statement at the end of block, remove it
1170pub(crate) fn is_never_block(
1171 sema: &Semantics<'_, RootDatabase>,
1172 block_expr: &ast::BlockExpr,
1173) -> bool {
1174 if let Some(tail_expr) = block_expr.tail_expr() {
1175 sema.type_of_expr(&tail_expr).is_some_and(|ty| ty.original.is_never())
1176 } else if let Some(ast::Stmt::ExprStmt(expr_stmt)) = block_expr.statements().last()
1177 && let Some(expr) = expr_stmt.expr()
1178 {
1179 sema.type_of_expr(&expr).is_some_and(|ty| ty.original.is_never())
1180 } else {
1181 false
1182 }
1183}
src/tools/rust-analyzer/crates/ide-completion/src/completions.rs+2-2
......@@ -630,7 +630,7 @@ fn enum_variants_with_paths(
630630 acc: &mut Completions,
631631 ctx: &CompletionContext<'_>,
632632 enum_: hir::Enum,
633 impl_: &Option<ast::Impl>,
633 impl_: Option<&ast::Impl>,
634634 cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath),
635635) {
636636 let mut process_variant = |variant: Variant| {
......@@ -644,7 +644,7 @@ fn enum_variants_with_paths(
644644
645645 let variants = enum_.variants(ctx.db);
646646
647 if let Some(impl_) = impl_.as_ref().and_then(|impl_| ctx.sema.to_def(impl_))
647 if let Some(impl_) = impl_.and_then(|impl_| ctx.sema.to_def(impl_))
648648 && impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_))
649649 {
650650 variants.iter().for_each(|variant| process_variant(*variant));
src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs+1-1
......@@ -39,7 +39,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
3939 "target_os" => KNOWN_OS.iter().copied().for_each(add_completion),
4040 "target_vendor" => KNOWN_VENDOR.iter().copied().for_each(add_completion),
4141 "target_endian" => ["little", "big"].into_iter().for_each(add_completion),
42 name => ctx.krate.potential_cfg(ctx.db).get_cfg_values(name).cloned().for_each(|s| {
42 name => ctx.krate.potential_cfg(ctx.db).get_cfg_values(name).for_each(|s| {
4343 let s = s.as_str();
4444 let insert_text = format!(r#""{s}""#);
4545 let mut item = CompletionItem::new(
src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs+1-2
......@@ -794,8 +794,7 @@ struct T(S);
794794
795795impl T {
796796 fn foo(&self) {
797 // FIXME: This doesn't work without the trailing `a` as `0.` is a float
798 self.0.a$0
797 self.0.$0
799798 }
800799}
801800"#,
src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs+13-6
......@@ -9,7 +9,7 @@ use syntax::ast;
99use crate::{
1010 CompletionContext, Completions,
1111 completions::record::add_default_update,
12 context::{BreakableKind, PathCompletionCtx, PathExprCtx, Qualified},
12 context::{PathCompletionCtx, PathExprCtx, Qualified},
1313};
1414
1515struct PathCallback<'a, F> {
......@@ -57,7 +57,6 @@ pub(crate) fn complete_expr_path(
5757
5858 let &PathExprCtx {
5959 in_block_expr,
60 in_breakable,
6160 after_if_expr,
6261 before_else_kw,
6362 in_condition,
......@@ -68,6 +67,7 @@ pub(crate) fn complete_expr_path(
6867 after_amp,
6968 ref is_func_update,
7069 ref innermost_ret_ty,
70 ref innermost_breakable_ty,
7171 ref impl_,
7272 in_match_guard,
7373 ..
......@@ -297,7 +297,7 @@ pub(crate) fn complete_expr_path(
297297 acc,
298298 ctx,
299299 e,
300 impl_,
300 impl_.as_ref(),
301301 |acc, ctx, variant, path| {
302302 acc.add_qualified_enum_variant(ctx, path_ctx, variant, path)
303303 },
......@@ -405,14 +405,21 @@ pub(crate) fn complete_expr_path(
405405 add_keyword("mut", "mut ");
406406 }
407407
408 if in_breakable != BreakableKind::None {
408 if let Some(loop_ty) = innermost_breakable_ty {
409409 if in_block_expr {
410410 add_keyword("continue", "continue;");
411 add_keyword("break", "break;");
412411 } else {
413412 add_keyword("continue", "continue");
414 add_keyword("break", "break");
415413 }
414 add_keyword(
415 "break",
416 match (loop_ty.is_unit(), in_block_expr) {
417 (true, true) => "break;",
418 (true, false) => "break",
419 (false, true) => "break $0;",
420 (false, false) => "break $0",
421 },
422 );
416423 }
417424
418425 if let Some(ret_ty) = innermost_ret_ty {
src/tools/rust-analyzer/crates/ide-completion/src/completions/fn_param.rs+8-7
......@@ -2,6 +2,7 @@
22
33use hir::HirDisplay;
44use ide_db::FxHashMap;
5use itertools::Either;
56use syntax::{
67 AstNode, Direction, SyntaxKind, TextRange, TextSize, algo,
78 ast::{self, HasModuleItem},
......@@ -24,8 +25,8 @@ pub(crate) fn complete_fn_param(
2425 ctx: &CompletionContext<'_>,
2526 pattern_ctx: &PatternContext,
2627) -> Option<()> {
27 let (ParamContext { param_list, kind, .. }, impl_) = match pattern_ctx {
28 PatternContext { param_ctx: Some(kind), impl_, .. } => (kind, impl_),
28 let (ParamContext { param_list, kind, .. }, impl_or_trait) = match pattern_ctx {
29 PatternContext { param_ctx: Some(kind), impl_or_trait, .. } => (kind, impl_or_trait),
2930 _ => return None,
3031 };
3132
......@@ -45,7 +46,7 @@ pub(crate) fn complete_fn_param(
4546
4647 match kind {
4748 ParamKind::Function(function) => {
48 fill_fn_params(ctx, function, param_list, impl_, add_new_item_to_acc);
49 fill_fn_params(ctx, function, param_list, impl_or_trait, add_new_item_to_acc);
4950 }
5051 ParamKind::Closure(closure) => {
5152 let stmt_list = closure.syntax().ancestors().find_map(ast::StmtList::cast)?;
......@@ -62,7 +63,7 @@ fn fill_fn_params(
6263 ctx: &CompletionContext<'_>,
6364 function: &ast::Fn,
6465 param_list: &ast::ParamList,
65 impl_: &Option<ast::Impl>,
66 impl_or_trait: &Option<Either<ast::Impl, ast::Trait>>,
6667 mut add_new_item_to_acc: impl FnMut(&str),
6768) {
6869 let mut file_params = FxHashMap::default();
......@@ -107,7 +108,7 @@ fn fill_fn_params(
107108 }
108109 remove_duplicated(&mut file_params, param_list.params());
109110 let self_completion_items = ["self", "&self", "mut self", "&mut self"];
110 if should_add_self_completions(ctx.token.text_range().start(), param_list, impl_) {
111 if should_add_self_completions(ctx.token.text_range().start(), param_list, impl_or_trait) {
111112 self_completion_items.into_iter().for_each(&mut add_new_item_to_acc);
112113 }
113114
......@@ -161,9 +162,9 @@ fn remove_duplicated(
161162fn should_add_self_completions(
162163 cursor: TextSize,
163164 param_list: &ast::ParamList,
164 impl_: &Option<ast::Impl>,
165 impl_or_trait: &Option<Either<ast::Impl, ast::Trait>>,
165166) -> bool {
166 if impl_.is_none() || param_list.self_param().is_some() {
167 if impl_or_trait.is_none() || param_list.self_param().is_some() {
167168 return false;
168169 }
169170 match param_list.params().next() {
src/tools/rust-analyzer/crates/ide-completion/src/completions/pattern.rs+1-1
......@@ -70,7 +70,7 @@ pub(crate) fn complete_pattern(
7070 acc,
7171 ctx,
7272 e,
73 &pattern_ctx.impl_,
73 pattern_ctx.impl_or_trait.as_ref().and_then(|it| it.as_ref().left()),
7474 |acc, ctx, variant, path| {
7575 acc.add_qualified_variant_pat(ctx, pattern_ctx, variant, path);
7676 },
src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs+54-10
......@@ -11,12 +11,12 @@ use ide_db::{
1111 text_edit::TextEdit,
1212 ty_filter::TryEnum,
1313};
14use itertools::Either;
1514use stdx::never;
1615use syntax::{
1716 SyntaxKind::{BLOCK_EXPR, EXPR_STMT, FOR_EXPR, IF_EXPR, LOOP_EXPR, STMT_LIST, WHILE_EXPR},
18 TextRange, TextSize,
17 T, TextRange, TextSize,
1918 ast::{self, AstNode, AstToken},
19 match_ast,
2020};
2121
2222use crate::{
......@@ -113,12 +113,8 @@ pub(crate) fn complete_postfix(
113113 if let Some(parent) = dot_receiver_including_refs.syntax().parent()
114114 && let Some(second_ancestor) = parent.parent()
115115 {
116 let sec_ancestor_kind = second_ancestor.kind();
117 if let Some(expr) = <Either<ast::IfExpr, ast::WhileExpr>>::cast(second_ancestor) {
118 is_in_cond = match expr {
119 Either::Left(it) => it.condition().is_some_and(|cond| *cond.syntax() == parent),
120 Either::Right(it) => it.condition().is_some_and(|cond| *cond.syntax() == parent),
121 }
116 if let Some(parent_expr) = ast::Expr::cast(parent) {
117 is_in_cond = is_in_condition(&parent_expr);
122118 }
123119 match &try_enum {
124120 Some(try_enum) if is_in_cond => match try_enum {
......@@ -147,7 +143,7 @@ pub(crate) fn complete_postfix(
147143 .add_to(acc, ctx.db);
148144 }
149145 },
150 _ if matches!(sec_ancestor_kind, STMT_LIST | EXPR_STMT) => {
146 _ if matches!(second_ancestor.kind(), STMT_LIST | EXPR_STMT) => {
151147 postfix_snippet("let", "let", &format!("let $0 = {receiver_text};"))
152148 .add_to(acc, ctx.db);
153149 postfix_snippet("letm", "let mut", &format!("let mut $0 = {receiver_text};"))
......@@ -295,7 +291,7 @@ pub(crate) fn complete_postfix(
295291 )
296292 .add_to(acc, ctx.db);
297293
298 if let BreakableKind::Block | BreakableKind::Loop = expr_ctx.in_breakable {
294 if let Some(BreakableKind::Block | BreakableKind::Loop) = expr_ctx.in_breakable {
299295 postfix_snippet(
300296 "break",
301297 "break expr",
......@@ -454,6 +450,22 @@ fn add_custom_postfix_completions(
454450 None
455451}
456452
453pub(crate) fn is_in_condition(it: &ast::Expr) -> bool {
454 it.syntax()
455 .parent()
456 .and_then(|parent| {
457 Some(match_ast! { match parent {
458 ast::IfExpr(expr) => expr.condition()? == *it,
459 ast::WhileExpr(expr) => expr.condition()? == *it,
460 ast::MatchGuard(guard) => guard.condition()? == *it,
461 ast::BinExpr(bin_expr) => (bin_expr.op_token()?.kind() == T![&&])
462 .then(|| is_in_condition(&bin_expr.into()))?,
463 _ => return None,
464 } })
465 })
466 .unwrap_or(false)
467}
468
457469#[cfg(test)]
458470mod tests {
459471 use expect_test::expect;
......@@ -648,6 +660,38 @@ fn main() {
648660 let bar = Some(true);
649661 if let Some($0) = bar
650662}
663"#,
664 );
665 check_edit(
666 "let",
667 r#"
668//- minicore: option
669fn main() {
670 let bar = Some(true);
671 if true && bar.$0
672}
673"#,
674 r#"
675fn main() {
676 let bar = Some(true);
677 if true && let Some($0) = bar
678}
679"#,
680 );
681 check_edit(
682 "let",
683 r#"
684//- minicore: option
685fn main() {
686 let bar = Some(true);
687 if true && true && bar.$0
688}
689"#,
690 r#"
691fn main() {
692 let bar = Some(true);
693 if true && true && let Some($0) = bar
694}
651695"#,
652696 );
653697 }
src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs+1-4
......@@ -135,10 +135,7 @@ fn complete_fields(
135135 receiver: None,
136136 receiver_ty: None,
137137 kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal: false },
138 ctx: DotAccessExprCtx {
139 in_block_expr: false,
140 in_breakable: crate::context::BreakableKind::None,
141 },
138 ctx: DotAccessExprCtx { in_block_expr: false, in_breakable: None },
142139 },
143140 None,
144141 field,
src/tools/rust-analyzer/crates/ide-completion/src/context.rs+5-4
......@@ -15,6 +15,7 @@ use ide_db::{
1515 FilePosition, FxHashMap, FxHashSet, RootDatabase, famous_defs::FamousDefs,
1616 helpers::is_editable_crate,
1717};
18use itertools::Either;
1819use syntax::{
1920 AstNode, Edition, SmolStr,
2021 SyntaxKind::{self, *},
......@@ -142,7 +143,7 @@ pub(crate) struct AttrCtx {
142143#[derive(Debug, PartialEq, Eq)]
143144pub(crate) struct PathExprCtx<'db> {
144145 pub(crate) in_block_expr: bool,
145 pub(crate) in_breakable: BreakableKind,
146 pub(crate) in_breakable: Option<BreakableKind>,
146147 pub(crate) after_if_expr: bool,
147148 pub(crate) before_else_kw: bool,
148149 /// Whether this expression is the direct condition of an if or while expression
......@@ -156,6 +157,7 @@ pub(crate) struct PathExprCtx<'db> {
156157 pub(crate) is_func_update: Option<ast::RecordExpr>,
157158 pub(crate) self_param: Option<hir::SelfParam>,
158159 pub(crate) innermost_ret_ty: Option<hir::Type<'db>>,
160 pub(crate) innermost_breakable_ty: Option<hir::Type<'db>>,
159161 pub(crate) impl_: Option<ast::Impl>,
160162 /// Whether this expression occurs in match arm guard position: before the
161163 /// fat arrow token
......@@ -282,7 +284,7 @@ pub(crate) struct PatternContext {
282284 pub(crate) mut_token: Option<SyntaxToken>,
283285 /// The record pattern this name or ref is a field of
284286 pub(crate) record_pat: Option<ast::RecordPat>,
285 pub(crate) impl_: Option<ast::Impl>,
287 pub(crate) impl_or_trait: Option<Either<ast::Impl, ast::Trait>>,
286288 /// List of missing variants in a match expr
287289 pub(crate) missing_variants: Vec<hir::Variant>,
288290}
......@@ -411,12 +413,11 @@ pub(crate) enum DotAccessKind {
411413#[derive(Debug, Clone, Copy, PartialEq, Eq)]
412414pub(crate) struct DotAccessExprCtx {
413415 pub(crate) in_block_expr: bool,
414 pub(crate) in_breakable: BreakableKind,
416 pub(crate) in_breakable: Option<BreakableKind>,
415417}
416418
417419#[derive(Copy, Clone, Debug, PartialEq, Eq)]
418420pub(crate) enum BreakableKind {
419 None,
420421 Loop,
421422 For,
422423 While,
src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs+47-47
......@@ -1,7 +1,6 @@
11//! Module responsible for analyzing the code surrounding the cursor for completion.
22use std::iter;
33
4use base_db::salsa;
54use hir::{ExpandResult, InFile, Semantics, Type, TypeInfo, Variant};
65use ide_db::{RootDatabase, active_parameter::ActiveParameter};
76use itertools::Either;
......@@ -20,12 +19,15 @@ use syntax::{
2019 match_ast,
2120};
2221
23use crate::context::{
24 AttrCtx, BreakableKind, COMPLETION_MARKER, CompletionAnalysis, DotAccess, DotAccessExprCtx,
25 DotAccessKind, ItemListKind, LifetimeContext, LifetimeKind, NameContext, NameKind,
26 NameRefContext, NameRefKind, ParamContext, ParamKind, PathCompletionCtx, PathExprCtx, PathKind,
27 PatternContext, PatternRefutability, Qualified, QualifierCtx, TypeAscriptionTarget,
28 TypeLocation,
22use crate::{
23 completions::postfix::is_in_condition,
24 context::{
25 AttrCtx, BreakableKind, COMPLETION_MARKER, CompletionAnalysis, DotAccess, DotAccessExprCtx,
26 DotAccessKind, ItemListKind, LifetimeContext, LifetimeKind, NameContext, NameKind,
27 NameRefContext, NameRefKind, ParamContext, ParamKind, PathCompletionCtx, PathExprCtx,
28 PathKind, PatternContext, PatternRefutability, Qualified, QualifierCtx,
29 TypeAscriptionTarget, TypeLocation,
30 },
2931};
3032
3133#[derive(Debug)]
......@@ -86,7 +88,7 @@ pub(super) fn expand_and_analyze<'db>(
8688 let original_offset = expansion.original_offset + relative_offset;
8789 let token = expansion.original_file.token_at_offset(original_offset).left_biased()?;
8890
89 salsa::attach(sema.db, || analyze(sema, expansion, original_token, &token)).map(
91 hir::attach_db(sema.db, || analyze(sema, expansion, original_token, &token)).map(
9092 |(analysis, expected, qualifier_ctx)| AnalysisResult {
9193 analysis,
9294 expected,
......@@ -563,10 +565,10 @@ fn analyze<'db>(
563565/// Calculate the expected type and name of the cursor position.
564566fn expected_type_and_name<'db>(
565567 sema: &Semantics<'db, RootDatabase>,
566 token: &SyntaxToken,
568 self_token: &SyntaxToken,
567569 name_like: &ast::NameLike,
568570) -> (Option<Type<'db>>, Option<NameOrNameRef>) {
569 let token = prev_special_biased_token_at_trivia(token.clone());
571 let token = prev_special_biased_token_at_trivia(self_token.clone());
570572 let mut node = match token.parent() {
571573 Some(it) => it,
572574 None => return (None, None),
......@@ -756,7 +758,15 @@ fn expected_type_and_name<'db>(
756758 .map(|c| (Some(c.return_type()), None))
757759 .unwrap_or((None, None))
758760 },
759 ast::ParamList(_) => (None, None),
761 ast::ParamList(it) => {
762 let closure = it.syntax().parent().and_then(ast::ClosureExpr::cast);
763 let ty = closure
764 .filter(|_| it.syntax().text_range().end() <= self_token.text_range().start())
765 .and_then(|it| sema.type_of_expr(&it.into()));
766 ty.and_then(|ty| ty.original.as_callable(sema.db))
767 .map(|c| (Some(c.return_type()), None))
768 .unwrap_or((None, None))
769 },
760770 ast::Stmt(_) => (None, None),
761771 ast::Item(_) => (None, None),
762772 _ => {
......@@ -916,7 +926,7 @@ fn classify_name_ref<'db>(
916926 receiver_ty,
917927 kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal },
918928 receiver,
919 ctx: DotAccessExprCtx { in_block_expr: is_in_block(field.syntax()), in_breakable: is_in_breakable(field.syntax()) }
929 ctx: DotAccessExprCtx { in_block_expr: is_in_block(field.syntax()), in_breakable: is_in_breakable(field.syntax()).unzip().0 }
920930 });
921931 return Some(make_res(kind));
922932 },
......@@ -931,7 +941,7 @@ fn classify_name_ref<'db>(
931941 receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)),
932942 kind: DotAccessKind::Method { has_parens },
933943 receiver,
934 ctx: DotAccessExprCtx { in_block_expr: is_in_block(method.syntax()), in_breakable: is_in_breakable(method.syntax()) }
944 ctx: DotAccessExprCtx { in_block_expr: is_in_block(method.syntax()), in_breakable: is_in_breakable(method.syntax()).unzip().0 }
935945 });
936946 return Some(make_res(kind));
937947 },
......@@ -1216,28 +1226,10 @@ fn classify_name_ref<'db>(
12161226 Some(res)
12171227 };
12181228
1219 fn is_in_condition(it: &ast::Expr) -> bool {
1220 (|| {
1221 let parent = it.syntax().parent()?;
1222 if let Some(expr) = ast::WhileExpr::cast(parent.clone()) {
1223 Some(expr.condition()? == *it)
1224 } else if let Some(expr) = ast::IfExpr::cast(parent.clone()) {
1225 Some(expr.condition()? == *it)
1226 } else if let Some(expr) = ast::BinExpr::cast(parent)
1227 && expr.op_token()?.kind() == T![&&]
1228 {
1229 Some(is_in_condition(&expr.into()))
1230 } else {
1231 None
1232 }
1233 })()
1234 .unwrap_or(false)
1235 }
1236
12371229 let make_path_kind_expr = |expr: ast::Expr| {
12381230 let it = expr.syntax();
12391231 let in_block_expr = is_in_block(it);
1240 let in_loop_body = is_in_breakable(it);
1232 let (in_loop_body, innermost_breakable) = is_in_breakable(it).unzip();
12411233 let after_if_expr = after_if_expr(it.clone());
12421234 let ref_expr_parent =
12431235 path.as_single_name_ref().and_then(|_| it.parent()).and_then(ast::RefExpr::cast);
......@@ -1291,6 +1283,11 @@ fn classify_name_ref<'db>(
12911283 None => (None, None),
12921284 }
12931285 };
1286 let innermost_breakable_ty = innermost_breakable
1287 .and_then(ast::Expr::cast)
1288 .and_then(|expr| find_node_in_file_compensated(sema, original_file, &expr))
1289 .and_then(|expr| sema.type_of_expr(&expr))
1290 .map(|ty| if ty.original.is_never() { ty.adjusted() } else { ty.original() });
12941291 let is_func_update = func_update_record(it);
12951292 let in_condition = is_in_condition(&expr);
12961293 let after_incomplete_let = after_incomplete_let(it.clone()).is_some();
......@@ -1303,7 +1300,8 @@ fn classify_name_ref<'db>(
13031300 .is_some_and(|it| it.semicolon_token().is_none())
13041301 || after_incomplete_let && incomplete_expr_stmt.unwrap_or(true) && !before_else_kw;
13051302 let in_value = it.parent().and_then(Either::<ast::LetStmt, ast::ArgList>::cast).is_some();
1306 let impl_ = fetch_immediate_impl(sema, original_file, expr.syntax());
1303 let impl_ = fetch_immediate_impl_or_trait(sema, original_file, expr.syntax())
1304 .and_then(Either::left);
13071305
13081306 let in_match_guard = match it.parent().and_then(ast::MatchArm::cast) {
13091307 Some(arm) => arm
......@@ -1323,6 +1321,7 @@ fn classify_name_ref<'db>(
13231321 after_amp,
13241322 is_func_update,
13251323 innermost_ret_ty,
1324 innermost_breakable_ty,
13261325 self_param,
13271326 in_value,
13281327 incomplete_let,
......@@ -1756,27 +1755,29 @@ fn pattern_context_for(
17561755 mut_token,
17571756 ref_token,
17581757 record_pat: None,
1759 impl_: fetch_immediate_impl(sema, original_file, pat.syntax()),
1758 impl_or_trait: fetch_immediate_impl_or_trait(sema, original_file, pat.syntax()),
17601759 missing_variants,
17611760 }
17621761}
17631762
1764fn fetch_immediate_impl(
1763fn fetch_immediate_impl_or_trait(
17651764 sema: &Semantics<'_, RootDatabase>,
17661765 original_file: &SyntaxNode,
17671766 node: &SyntaxNode,
1768) -> Option<ast::Impl> {
1767) -> Option<Either<ast::Impl, ast::Trait>> {
17691768 let mut ancestors = ancestors_in_file_compensated(sema, original_file, node)?
17701769 .filter_map(ast::Item::cast)
17711770 .filter(|it| !matches!(it, ast::Item::MacroCall(_)));
17721771
17731772 match ancestors.next()? {
17741773 ast::Item::Const(_) | ast::Item::Fn(_) | ast::Item::TypeAlias(_) => (),
1775 ast::Item::Impl(it) => return Some(it),
1774 ast::Item::Impl(it) => return Some(Either::Left(it)),
1775 ast::Item::Trait(it) => return Some(Either::Right(it)),
17761776 _ => return None,
17771777 }
17781778 match ancestors.next()? {
1779 ast::Item::Impl(it) => Some(it),
1779 ast::Item::Impl(it) => Some(Either::Left(it)),
1780 ast::Item::Trait(it) => Some(Either::Right(it)),
17801781 _ => None,
17811782 }
17821783}
......@@ -1870,24 +1871,22 @@ fn is_in_token_of_for_loop(path: &ast::Path) -> bool {
18701871 .unwrap_or(false)
18711872}
18721873
1873fn is_in_breakable(node: &SyntaxNode) -> BreakableKind {
1874fn is_in_breakable(node: &SyntaxNode) -> Option<(BreakableKind, SyntaxNode)> {
18741875 node.ancestors()
18751876 .take_while(|it| it.kind() != SyntaxKind::FN && it.kind() != SyntaxKind::CLOSURE_EXPR)
18761877 .find_map(|it| {
18771878 let (breakable, loop_body) = match_ast! {
18781879 match it {
1879 ast::ForExpr(it) => (BreakableKind::For, it.loop_body()),
1880 ast::WhileExpr(it) => (BreakableKind::While, it.loop_body()),
1881 ast::LoopExpr(it) => (BreakableKind::Loop, it.loop_body()),
1882 ast::BlockExpr(it) => return it.label().map(|_| BreakableKind::Block),
1880 ast::ForExpr(it) => (BreakableKind::For, it.loop_body()?),
1881 ast::WhileExpr(it) => (BreakableKind::While, it.loop_body()?),
1882 ast::LoopExpr(it) => (BreakableKind::Loop, it.loop_body()?),
1883 ast::BlockExpr(it) => return it.label().map(|_| (BreakableKind::Block, it.syntax().clone())),
18831884 _ => return None,
18841885 }
18851886 };
1886 loop_body
1887 .filter(|it| it.syntax().text_range().contains_range(node.text_range()))
1888 .map(|_| breakable)
1887 loop_body.syntax().text_range().contains_range(node.text_range())
1888 .then_some((breakable, it))
18891889 })
1890 .unwrap_or(BreakableKind::None)
18911890}
18921891
18931892fn is_in_block(node: &SyntaxNode) -> bool {
......@@ -1938,6 +1937,7 @@ fn prev_special_biased_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken {
19381937 | T![|=]
19391938 | T![&=]
19401939 | T![^=]
1940 | T![|]
19411941 | T![return]
19421942 | T![break]
19431943 | T![continue] = prev.kind()
src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs+14-4
......@@ -1,4 +1,3 @@
1use base_db::salsa;
21use expect_test::{Expect, expect};
32use hir::HirDisplay;
43
......@@ -11,12 +10,12 @@ fn check_expected_type_and_name(#[rust_analyzer::rust_fixture] ra_fixture: &str,
1110 let (db, pos) = position(ra_fixture);
1211 let config = TEST_CONFIG;
1312 let (completion_context, _analysis) =
14 salsa::attach(&db, || CompletionContext::new(&db, pos, &config).unwrap());
13 hir::attach_db(&db, || CompletionContext::new(&db, pos, &config).unwrap());
1514
1615 let ty = completion_context
1716 .expected_type
1817 .map(|t| {
19 salsa::attach(&db, || {
18 hir::attach_db(&db, || {
2019 t.display_test(&db, completion_context.krate.to_display_target(&db)).to_string()
2120 })
2221 })
......@@ -374,7 +373,6 @@ fn foo() -> u32 {
374373
375374#[test]
376375fn expected_type_closure_param_return() {
377 // FIXME: make this work with `|| $0`
378376 check_expected_type_and_name(
379377 r#"
380378//- minicore: fn
......@@ -382,6 +380,18 @@ fn foo() {
382380 bar(|| a$0);
383381}
384382
383fn bar(f: impl FnOnce() -> u32) {}
384"#,
385 expect![[r#"ty: u32, name: ?"#]],
386 );
387
388 check_expected_type_and_name(
389 r#"
390//- minicore: fn
391fn foo() {
392 bar(|| $0);
393}
394
385395fn bar(f: impl FnOnce() -> u32) {}
386396"#,
387397 expect![[r#"ty: u32, name: ?"#]],
src/tools/rust-analyzer/crates/ide-completion/src/render.rs+1-1
......@@ -2987,7 +2987,6 @@ fn main() {
29872987 &[CompletionItemKind::Snippet, CompletionItemKind::SymbolKind(SymbolKind::Method)],
29882988 expect![[r#"
29892989 sn not !expr [snippet]
2990 me not() fn(self) -> <Self as Not>::Output [type_could_unify+requires_import]
29912990 sn box Box::new(expr) []
29922991 sn call function(expr) []
29932992 sn const const {} []
......@@ -3001,6 +3000,7 @@ fn main() {
30013000 sn return return expr []
30023001 sn unsafe unsafe {} []
30033002 sn while while expr {} []
3003 me not() fn(self) -> <Self as Not>::Output [requires_import]
30043004 "#]],
30053005 );
30063006 }
src/tools/rust-analyzer/crates/ide-completion/src/tests.rs+3-3
......@@ -24,7 +24,7 @@ mod type_pos;
2424mod use_tree;
2525mod visibility;
2626
27use base_db::{SourceDatabase, salsa};
27use base_db::SourceDatabase;
2828use expect_test::Expect;
2929use hir::db::HirDatabase;
3030use hir::{PrefixKind, setup_tracing};
......@@ -244,7 +244,7 @@ pub(crate) fn check_edit_with_config(
244244 let ra_fixture_after = trim_indent(ra_fixture_after);
245245 let (db, position) = position(ra_fixture_before);
246246 let completions: Vec<CompletionItem> =
247 salsa::attach(&db, || crate::completions(&db, &config, position, None).unwrap());
247 hir::attach_db(&db, || crate::completions(&db, &config, position, None).unwrap());
248248 let (completion,) = completions
249249 .iter()
250250 .filter(|it| it.lookup() == what)
......@@ -307,7 +307,7 @@ pub(crate) fn get_all_items(
307307 trigger_character: Option<char>,
308308) -> Vec<CompletionItem> {
309309 let (db, position) = position(code);
310 let res = salsa::attach(&db, || {
310 let res = hir::attach_db(&db, || {
311311 HirDatabase::zalsa_register_downcaster(&db);
312312 crate::completions(&db, &config, position, trigger_character)
313313 })
src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs+39
......@@ -1090,6 +1090,45 @@ fn return_value_no_block() {
10901090 );
10911091}
10921092
1093#[test]
1094fn break_unit_block() {
1095 check_edit("break", r#"fn f() { loop { break; $0 } }"#, r#"fn f() { loop { break; break; } }"#);
1096 check_edit("break", r#"fn f() { loop { $0 } }"#, r#"fn f() { loop { break; } }"#);
1097}
1098
1099#[test]
1100fn break_unit_no_block() {
1101 check_edit(
1102 "break",
1103 r#"fn f() { loop { break; match () { () => $0 } } }"#,
1104 r#"fn f() { loop { break; match () { () => break } } }"#,
1105 );
1106
1107 check_edit(
1108 "break",
1109 r#"fn f() { loop { match () { () => $0 } } }"#,
1110 r#"fn f() { loop { match () { () => break } } }"#,
1111 );
1112}
1113
1114#[test]
1115fn break_value_block() {
1116 check_edit(
1117 "break",
1118 r#"fn f() -> i32 { loop { $0 } }"#,
1119 r#"fn f() -> i32 { loop { break $0; } }"#,
1120 );
1121}
1122
1123#[test]
1124fn break_value_no_block() {
1125 check_edit(
1126 "break",
1127 r#"fn f() -> i32 { loop { match () { () => $0 } } }"#,
1128 r#"fn f() -> i32 { loop { match () { () => break $0 } } }"#,
1129 );
1130}
1131
10931132#[test]
10941133fn else_completion_after_if() {
10951134 check(
src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs+1-2
......@@ -1,4 +1,3 @@
1use base_db::salsa;
21use expect_test::{Expect, expect};
32
43use crate::{
......@@ -20,7 +19,7 @@ fn check_with_config(
2019 let (ctx, analysis) = crate::context::CompletionContext::new(&db, position, &config).unwrap();
2120
2221 let mut acc = crate::completions::Completions::default();
23 salsa::attach(ctx.db, || {
22 hir::attach_db(ctx.db, || {
2423 if let CompletionAnalysis::Name(NameContext { kind: NameKind::IdentPat(pat_ctx), .. }) =
2524 &analysis
2625 {
src/tools/rust-analyzer/crates/ide-completion/src/tests/fn_param.rs+42
......@@ -85,7 +85,11 @@ pub(crate) trait SourceRoot {
8585}
8686"#,
8787 expect![[r#"
88 bn &mut self
89 bn &self
8890 bn file_id: usize
91 bn mut self
92 bn self
8993 kw mut
9094 kw ref
9195 "#]],
......@@ -183,6 +187,44 @@ impl A {
183187 )
184188}
185189
190#[test]
191fn in_trait_only_param() {
192 check(
193 r#"
194trait A {
195 fn foo(file_id: usize) {}
196 fn new($0) {}
197}
198"#,
199 expect![[r#"
200 bn &mut self
201 bn &self
202 bn file_id: usize
203 bn mut self
204 bn self
205 kw mut
206 kw ref
207 "#]],
208 )
209}
210
211#[test]
212fn in_trait_after_self() {
213 check(
214 r#"
215trait A {
216 fn foo(file_id: usize) {}
217 fn new(self, $0) {}
218}
219"#,
220 expect![[r#"
221 bn file_id: usize
222 kw mut
223 kw ref
224 "#]],
225 )
226}
227
186228// doesn't complete qux due to there being no expression after
187229// see source_analyzer::adjust comment
188230#[test]
src/tools/rust-analyzer/crates/ide-db/src/assists.rs+2-6
......@@ -170,14 +170,10 @@ impl AssistResolveStrategy {
170170#[derive(Clone, Debug)]
171171pub struct GroupLabel(pub String);
172172
173#[derive(Clone, Debug, PartialEq, Eq)]
173#[derive(Clone, Debug, PartialEq, Eq, Default)]
174174pub enum ExprFillDefaultMode {
175 #[default]
175176 Todo,
176177 Default,
177178 Underscore,
178179}
179impl Default for ExprFillDefaultMode {
180 fn default() -> Self {
181 Self::Todo
182 }
183}
src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs+12-6
......@@ -27,9 +27,6 @@ pub use hir::PrefixKind;
2727/// How imports should be grouped into use statements.
2828#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2929pub enum ImportGranularity {
30 /// Do not change the granularity of any imports and preserve the original structure written
31 /// by the developer.
32 Preserve,
3330 /// Merge imports from the same crate into a single use statement.
3431 Crate,
3532 /// Merge imports from the same module into a single use statement.
......@@ -174,7 +171,7 @@ fn insert_use_with_alias_option(
174171 ImportGranularity::Crate => Some(MergeBehavior::Crate),
175172 ImportGranularity::Module => Some(MergeBehavior::Module),
176173 ImportGranularity::One => Some(MergeBehavior::One),
177 ImportGranularity::Item | ImportGranularity::Preserve => None,
174 ImportGranularity::Item => None,
178175 };
179176 if !cfg.enforce_granularity {
180177 let file_granularity = guess_granularity_from_scope(scope);
......@@ -182,9 +179,18 @@ fn insert_use_with_alias_option(
182179 ImportGranularityGuess::Unknown => mb,
183180 ImportGranularityGuess::Item => None,
184181 ImportGranularityGuess::Module => Some(MergeBehavior::Module),
185 ImportGranularityGuess::ModuleOrItem => mb.and(Some(MergeBehavior::Module)),
182 // We use the user's setting to infer if this is module or item.
183 ImportGranularityGuess::ModuleOrItem => match mb {
184 Some(MergeBehavior::Module) | None => mb,
185 // There isn't really a way to decide between module or item here, so we just pick one.
186 // FIXME: Maybe it is possible to infer based on semantic analysis?
187 Some(MergeBehavior::One | MergeBehavior::Crate) => Some(MergeBehavior::Module),
188 },
186189 ImportGranularityGuess::Crate => Some(MergeBehavior::Crate),
187 ImportGranularityGuess::CrateOrModule => mb.or(Some(MergeBehavior::Crate)),
190 ImportGranularityGuess::CrateOrModule => match mb {
191 Some(MergeBehavior::Crate | MergeBehavior::Module) => mb,
192 Some(MergeBehavior::One) | None => Some(MergeBehavior::Crate),
193 },
188194 ImportGranularityGuess::One => Some(MergeBehavior::One),
189195 };
190196 }
src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs+2-2
......@@ -134,7 +134,7 @@ fn library_symbols(db: &dyn SymbolsDatabase, source_root_id: SourceRootId) -> Ar
134134 let _p = tracing::info_span!("library_symbols").entered();
135135
136136 // We call this without attaching because this runs in parallel, so we need to attach here.
137 salsa::attach(db, || {
137 hir::attach_db(db, || {
138138 let mut symbol_collector = SymbolCollector::new(db);
139139
140140 db.source_root_crates(source_root_id)
......@@ -153,7 +153,7 @@ fn module_symbols(db: &dyn SymbolsDatabase, module: Module) -> Arc<SymbolIndex>
153153 let _p = tracing::info_span!("module_symbols").entered();
154154
155155 // We call this without attaching because this runs in parallel, so we need to attach here.
156 salsa::attach(db, || Arc::new(SymbolIndex::new(SymbolCollector::new_module(db, module))))
156 hir::attach_db(db, || Arc::new(SymbolIndex::new(SymbolCollector::new_module(db, module))))
157157}
158158
159159pub fn crate_symbols(db: &dyn SymbolsDatabase, krate: Crate) -> Box<[Arc<SymbolIndex>]> {
src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs+1-1
......@@ -473,7 +473,7 @@ mod tests {
473473 frange.range,
474474 "selection is not an expression(yet contained in one)"
475475 );
476 let name = salsa::attach(sema.db, || NameGenerator::default().for_variable(&expr, &sema));
476 let name = hir::attach_db(sema.db, || NameGenerator::default().for_variable(&expr, &sema));
477477 assert_eq!(&name, expected);
478478 }
479479
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs+17
......@@ -203,6 +203,23 @@ impl WithSignals for Player {
203203 fn __signals_from_external(&self) -> Self::SignalCollection<'_, Self> {
204204 Self::SignalCollection { _v: self }
205205 }
206}
207 "#,
208 );
209 }
210
211 #[test]
212 fn enum_type_alias_default_param() {
213 check_diagnostics(
214 r#"
215//- minicore: result
216
217struct Error;
218
219type Result<T, E = Error> = core::result::Result<T, E>;
220
221fn main() {
222 let _ = Result::<()>::Ok(());
206223}
207224 "#,
208225 );
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs+38-1
......@@ -50,7 +50,12 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingUnsafe) -> Option<Vec<Ass
5050
5151 let node_to_add_unsafe_block = pick_best_node_to_add_unsafe_block(&expr)?;
5252
53 let replacement = format!("unsafe {{ {} }}", node_to_add_unsafe_block.text());
53 let mut replacement = format!("unsafe {{ {} }}", node_to_add_unsafe_block.text());
54 if let Some(expr) = ast::Expr::cast(node_to_add_unsafe_block.clone())
55 && needs_parentheses(&expr)
56 {
57 replacement = format!("({replacement})");
58 }
5459 let edit = TextEdit::replace(node_to_add_unsafe_block.text_range(), replacement);
5560 let source_change = SourceChange::from_text_edit(
5661 d.node.file_id.original_file(ctx.sema.db).file_id(ctx.sema.db),
......@@ -112,6 +117,17 @@ fn pick_best_node_to_add_unsafe_block(unsafe_expr: &ast::Expr) -> Option<SyntaxN
112117 None
113118}
114119
120fn needs_parentheses(expr: &ast::Expr) -> bool {
121 let node = expr.syntax();
122 node.ancestors()
123 .skip(1)
124 .take_while(|it| it.text_range().start() == node.text_range().start())
125 .map_while(ast::Expr::cast)
126 .last()
127 .and_then(|it| Some(it.syntax().parent()?.kind()))
128 .is_some_and(|kind| ast::ExprStmt::can_cast(kind) || ast::StmtList::can_cast(kind))
129}
130
115131#[cfg(test)]
116132mod tests {
117133 use crate::tests::{check_diagnostics, check_fix, check_no_fix};
......@@ -570,6 +586,27 @@ fn main() {
570586 )
571587 }
572588
589 #[test]
590 fn needs_parentheses_for_unambiguous() {
591 check_fix(
592 r#"
593//- minicore: copy
594static mut STATIC_MUT: u8 = 0;
595
596fn foo() -> u8 {
597 STATIC_MUT$0 * 2
598}
599"#,
600 r#"
601static mut STATIC_MUT: u8 = 0;
602
603fn foo() -> u8 {
604 (unsafe { STATIC_MUT }) * 2
605}
606"#,
607 )
608 }
609
573610 #[test]
574611 fn ref_to_unsafe_expr() {
575612 check_fix(
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs+16
......@@ -1302,6 +1302,22 @@ fn main() {
13021302 let mut var = 1;
13031303 let mut func = || (var,) = (2,);
13041304 func();
1305}
1306 "#,
1307 );
1308 }
1309
1310 #[test]
1311 fn regression_20662() {
1312 check_diagnostics(
1313 r#"
1314//- minicore: index
1315pub trait A: core::ops::IndexMut<usize> {
1316 type T: A;
1317}
1318
1319fn func(a: &mut impl A, b: &mut [i32]) {
1320 b[0] += 1;
13051321}
13061322 "#,
13071323 );
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_incorrect_safety.rs+9
......@@ -127,4 +127,13 @@ struct S;
127127"#,
128128 );
129129 }
130
131 #[test]
132 fn unsafe_unresolved_trait() {
133 check_diagnostics(
134 r#"
135unsafe impl TestTrait for u32 {}
136 "#,
137 );
138 }
130139}
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs+1-1
......@@ -1170,7 +1170,7 @@ trait B {}
11701170
11711171fn test(a: &dyn A) -> &dyn B {
11721172 a
1173 //^ error: expected &dyn B, found &dyn A
1173 //^ error: expected &(dyn B + 'static), found &(dyn A + 'static)
11741174}
11751175"#,
11761176 );
src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs+1-1
......@@ -253,7 +253,7 @@ impl DiagnosticsConfig {
253253 style_lints: true,
254254 snippet_cap: SnippetCap::new(true),
255255 insert_use: InsertUseConfig {
256 granularity: ImportGranularity::Preserve,
256 granularity: ImportGranularity::Item,
257257 enforce_granularity: false,
258258 prefix_kind: PrefixKind::Plain,
259259 group: false,
src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs+7-7
......@@ -6,7 +6,7 @@ use hir::setup_tracing;
66use ide_db::{
77 LineIndexDatabase, RootDatabase,
88 assists::{AssistResolveStrategy, ExprFillDefaultMode},
9 base_db::{SourceDatabase, salsa},
9 base_db::SourceDatabase,
1010};
1111use itertools::Itertools;
1212use stdx::trim_indent;
......@@ -74,7 +74,7 @@ fn check_nth_fix_with_config(
7474 let after = trim_indent(ra_fixture_after);
7575
7676 let (db, file_position) = RootDatabase::with_position(ra_fixture_before);
77 let diagnostic = salsa::attach(&db, || {
77 let diagnostic = hir::attach_db(&db, || {
7878 super::full_diagnostics(
7979 &db,
8080 &config,
......@@ -129,7 +129,7 @@ pub(crate) fn check_has_fix(
129129 let (db, file_position) = RootDatabase::with_position(ra_fixture_before);
130130 let mut conf = DiagnosticsConfig::test_sample();
131131 conf.expr_fill_default = ExprFillDefaultMode::Default;
132 let fix = salsa::attach(&db, || {
132 let fix = hir::attach_db(&db, || {
133133 super::full_diagnostics(
134134 &db,
135135 &conf,
......@@ -170,7 +170,7 @@ pub(crate) fn check_has_fix(
170170/// Checks that there's a diagnostic *without* fix at `$0`.
171171pub(crate) fn check_no_fix(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
172172 let (db, file_position) = RootDatabase::with_position(ra_fixture);
173 let diagnostic = salsa::attach(&db, || {
173 let diagnostic = hir::attach_db(&db, || {
174174 super::full_diagnostics(
175175 &db,
176176 &DiagnosticsConfig::test_sample(),
......@@ -212,7 +212,7 @@ pub(crate) fn check_diagnostics_with_config(
212212 .iter()
213213 .copied()
214214 .flat_map(|file_id| {
215 salsa::attach(&db, || {
215 hir::attach_db(&db, || {
216216 super::full_diagnostics(
217217 &db,
218218 &config,
......@@ -288,12 +288,12 @@ fn test_disabled_diagnostics() {
288288 let (db, file_id) = RootDatabase::with_single_file(r#"mod foo;"#);
289289 let file_id = file_id.file_id(&db);
290290
291 let diagnostics = salsa::attach(&db, || {
291 let diagnostics = hir::attach_db(&db, || {
292292 super::full_diagnostics(&db, &config, &AssistResolveStrategy::All, file_id)
293293 });
294294 assert!(diagnostics.is_empty());
295295
296 let diagnostics = salsa::attach(&db, || {
296 let diagnostics = hir::attach_db(&db, || {
297297 super::full_diagnostics(
298298 &db,
299299 &DiagnosticsConfig::test_sample(),
src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs+30-28
......@@ -799,33 +799,35 @@ mod tests {
799799 let input = "fn foo() {} fn bar() {} fn main() { foo(1+2); }";
800800
801801 let (db, position, selections) = crate::tests::single_file(input);
802 let position = ide_db::FilePosition {
803 file_id: position.file_id.file_id(&db),
804 offset: position.offset,
805 };
806 let mut match_finder = MatchFinder::in_context(
807 &db,
808 position,
809 selections
810 .into_iter()
811 .map(|frange| ide_db::FileRange {
812 file_id: frange.file_id.file_id(&db),
813 range: frange.range,
814 })
815 .collect(),
816 )
817 .unwrap();
818 match_finder.add_rule(rule).unwrap();
819 let matches = match_finder.matches();
820 assert_eq!(matches.matches.len(), 1);
821 assert_eq!(matches.matches[0].matched_node.text(), "foo(1+2)");
822 assert_eq!(matches.matches[0].placeholder_values.len(), 1);
823
824 let edits = match_finder.edits();
825 assert_eq!(edits.len(), 1);
826 let edit = &edits[&position.file_id];
827 let mut after = input.to_owned();
828 edit.apply(&mut after);
829 assert_eq!(after, "fn foo() {} fn bar() {} fn main() { bar(1+2); }");
802 hir::attach_db(&db, || {
803 let position = ide_db::FilePosition {
804 file_id: position.file_id.file_id(&db),
805 offset: position.offset,
806 };
807 let mut match_finder = MatchFinder::in_context(
808 &db,
809 position,
810 selections
811 .into_iter()
812 .map(|frange| ide_db::FileRange {
813 file_id: frange.file_id.file_id(&db),
814 range: frange.range,
815 })
816 .collect(),
817 )
818 .unwrap();
819 match_finder.add_rule(rule).unwrap();
820 let matches = match_finder.matches();
821 assert_eq!(matches.matches.len(), 1);
822 assert_eq!(matches.matches[0].matched_node.text(), "foo(1+2)");
823 assert_eq!(matches.matches[0].placeholder_values.len(), 1);
824
825 let edits = match_finder.edits();
826 assert_eq!(edits.len(), 1);
827 let edit = &edits[&position.file_id];
828 let mut after = input.to_owned();
829 edit.apply(&mut after);
830 assert_eq!(after, "fn foo() {} fn bar() {} fn main() { bar(1+2); }");
831 });
830832 }
831833}
src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs+2-2
......@@ -1,7 +1,7 @@
11//! This module is responsible for resolving paths within rules.
22
33use hir::AsAssocItem;
4use ide_db::{FxHashMap, base_db::salsa};
4use ide_db::FxHashMap;
55use parsing::Placeholder;
66use syntax::{
77 SmolStr, SyntaxKind, SyntaxNode, SyntaxToken,
......@@ -48,7 +48,7 @@ impl<'db> ResolvedRule<'db> {
4848 resolution_scope: &ResolutionScope<'db>,
4949 index: usize,
5050 ) -> Result<ResolvedRule<'db>, SsrError> {
51 salsa::attach(resolution_scope.scope.db, || {
51 hir::attach_db(resolution_scope.scope.db, || {
5252 let resolver = Resolver {
5353 resolution_scope,
5454 placeholders_by_stand_in: rule.placeholders_by_stand_in,
src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs+79-72
......@@ -2,10 +2,7 @@ use expect_test::{Expect, expect};
22use hir::{FilePosition, FileRange};
33use ide_db::{
44 EditionedFileId, FxHashSet,
5 base_db::{
6 SourceDatabase,
7 salsa::{self, Durability},
8 },
5 base_db::{SourceDatabase, salsa::Durability},
96};
107use test_utils::RangeOrOffset;
118use triomphe::Arc;
......@@ -101,33 +98,37 @@ fn assert_ssr_transform(rule: &str, input: &str, expected: Expect) {
10198
10299fn assert_ssr_transforms(rules: &[&str], input: &str, expected: Expect) {
103100 let (db, position, selections) = single_file(input);
104 let position =
105 ide_db::FilePosition { file_id: position.file_id.file_id(&db), offset: position.offset };
106 let mut match_finder = MatchFinder::in_context(
107 &db,
108 position,
109 selections
110 .into_iter()
111 .map(|selection| ide_db::FileRange {
112 file_id: selection.file_id.file_id(&db),
113 range: selection.range,
114 })
115 .collect(),
116 )
117 .unwrap();
118 for rule in rules {
119 let rule: SsrRule = rule.parse().unwrap();
120 match_finder.add_rule(rule).unwrap();
121 }
122 let edits = salsa::attach(&db, || match_finder.edits());
123 if edits.is_empty() {
124 panic!("No edits were made");
125 }
126 // Note, db.file_text is not necessarily the same as `input`, since fixture parsing alters
127 // stuff.
128 let mut actual = db.file_text(position.file_id).text(&db).to_string();
129 edits[&position.file_id].apply(&mut actual);
130 expected.assert_eq(&actual);
101 hir::attach_db(&db, || {
102 let position = ide_db::FilePosition {
103 file_id: position.file_id.file_id(&db),
104 offset: position.offset,
105 };
106 let mut match_finder = MatchFinder::in_context(
107 &db,
108 position,
109 selections
110 .into_iter()
111 .map(|selection| ide_db::FileRange {
112 file_id: selection.file_id.file_id(&db),
113 range: selection.range,
114 })
115 .collect(),
116 )
117 .unwrap();
118 for rule in rules {
119 let rule: SsrRule = rule.parse().unwrap();
120 match_finder.add_rule(rule).unwrap();
121 }
122 let edits = match_finder.edits();
123 if edits.is_empty() {
124 panic!("No edits were made");
125 }
126 // Note, db.file_text is not necessarily the same as `input`, since fixture parsing alters
127 // stuff.
128 let mut actual = db.file_text(position.file_id).text(&db).to_string();
129 edits[&position.file_id].apply(&mut actual);
130 expected.assert_eq(&actual);
131 })
131132}
132133
133134#[allow(clippy::print_stdout)]
......@@ -145,51 +146,57 @@ fn print_match_debug_info(match_finder: &MatchFinder<'_>, file_id: EditionedFile
145146
146147fn assert_matches(pattern: &str, code: &str, expected: &[&str]) {
147148 let (db, position, selections) = single_file(code);
148 let mut match_finder = MatchFinder::in_context(
149 &db,
150 ide_db::FilePosition { file_id: position.file_id.file_id(&db), offset: position.offset },
151 selections
152 .into_iter()
153 .map(|selection| ide_db::FileRange {
154 file_id: selection.file_id.file_id(&db),
155 range: selection.range,
156 })
157 .collect(),
158 )
159 .unwrap();
160 match_finder.add_search_pattern(pattern.parse().unwrap()).unwrap();
161 let matched_strings: Vec<String> = salsa::attach(&db, || match_finder.matches())
162 .flattened()
163 .matches
164 .iter()
165 .map(|m| m.matched_text())
166 .collect();
167 if matched_strings != expected && !expected.is_empty() {
168 print_match_debug_info(&match_finder, position.file_id, expected[0]);
169 }
170 assert_eq!(matched_strings, expected);
149 hir::attach_db(&db, || {
150 let mut match_finder = MatchFinder::in_context(
151 &db,
152 ide_db::FilePosition {
153 file_id: position.file_id.file_id(&db),
154 offset: position.offset,
155 },
156 selections
157 .into_iter()
158 .map(|selection| ide_db::FileRange {
159 file_id: selection.file_id.file_id(&db),
160 range: selection.range,
161 })
162 .collect(),
163 )
164 .unwrap();
165 match_finder.add_search_pattern(pattern.parse().unwrap()).unwrap();
166 let matched_strings: Vec<String> =
167 match_finder.matches().flattened().matches.iter().map(|m| m.matched_text()).collect();
168 if matched_strings != expected && !expected.is_empty() {
169 print_match_debug_info(&match_finder, position.file_id, expected[0]);
170 }
171 assert_eq!(matched_strings, expected);
172 })
171173}
172174
173175fn assert_no_match(pattern: &str, code: &str) {
174176 let (db, position, selections) = single_file(code);
175 let mut match_finder = MatchFinder::in_context(
176 &db,
177 ide_db::FilePosition { file_id: position.file_id.file_id(&db), offset: position.offset },
178 selections
179 .into_iter()
180 .map(|selection| ide_db::FileRange {
181 file_id: selection.file_id.file_id(&db),
182 range: selection.range,
183 })
184 .collect(),
185 )
186 .unwrap();
187 match_finder.add_search_pattern(pattern.parse().unwrap()).unwrap();
188 let matches = match_finder.matches().flattened().matches;
189 if !matches.is_empty() {
190 print_match_debug_info(&match_finder, position.file_id, &matches[0].matched_text());
191 panic!("Got {} matches when we expected none: {matches:#?}", matches.len());
192 }
177 hir::attach_db(&db, || {
178 let mut match_finder = MatchFinder::in_context(
179 &db,
180 ide_db::FilePosition {
181 file_id: position.file_id.file_id(&db),
182 offset: position.offset,
183 },
184 selections
185 .into_iter()
186 .map(|selection| ide_db::FileRange {
187 file_id: selection.file_id.file_id(&db),
188 range: selection.range,
189 })
190 .collect(),
191 )
192 .unwrap();
193 match_finder.add_search_pattern(pattern.parse().unwrap()).unwrap();
194 let matches = match_finder.matches().flattened().matches;
195 if !matches.is_empty() {
196 print_match_debug_info(&match_finder, position.file_id, &matches[0].matched_text());
197 panic!("Got {} matches when we expected none: {matches:#?}", matches.len());
198 }
199 });
193200}
194201
195202fn assert_match_failure_reason(pattern: &str, code: &str, snippet: &str, expected_reason: &str) {
src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs+2-3
......@@ -4,7 +4,6 @@ use expect_test::{Expect, expect};
44use hir::Semantics;
55use ide_db::{
66 FilePosition, FileRange, RootDatabase,
7 base_db::salsa,
87 defs::Definition,
98 documentation::{DocsRangeMap, Documentation, HasDocs},
109};
......@@ -48,7 +47,7 @@ fn check_rewrite(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect
4847 let sema = &Semantics::new(&analysis.db);
4948 let (cursor_def, docs, range) = def_under_cursor(sema, &position);
5049 let res =
51 salsa::attach(sema.db, || rewrite_links(sema.db, docs.as_str(), cursor_def, Some(range)));
50 hir::attach_db(sema.db, || rewrite_links(sema.db, docs.as_str(), cursor_def, Some(range)));
5251 expect.assert_eq(&res)
5352}
5453
......@@ -65,7 +64,7 @@ fn check_doc_links(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
6564 .flat_map(|(text_range, link, ns)| {
6665 let attr = range.map(text_range);
6766 let is_inner_attr = attr.map(|(_file, attr)| attr.is_inner_attr()).unwrap_or(false);
68 let def = salsa::attach(sema.db, || {
67 let def = hir::attach_db(sema.db, || {
6968 resolve_doc_path_for_def(sema.db, cursor_def, &link, ns, is_inner_attr)
7069 .unwrap_or_else(|| panic!("Failed to resolve {link}"))
7170 });
src/tools/rust-analyzer/crates/ide/src/hover/render.rs+4-4
......@@ -695,7 +695,7 @@ pub(super) fn definition(
695695 DropInfo { drop_glue: field.ty(db).to_type(db).drop_glue(db), has_dtor: None }
696696 }
697697 Definition::Adt(Adt::Struct(strukt)) => {
698 let struct_drop_glue = strukt.ty_placeholders(db).drop_glue(db);
698 let struct_drop_glue = strukt.ty_params(db).drop_glue(db);
699699 let mut fields_drop_glue = strukt
700700 .fields(db)
701701 .iter()
......@@ -716,10 +716,10 @@ pub(super) fn definition(
716716 // Unions cannot have fields with drop glue.
717717 Definition::Adt(Adt::Union(union)) => DropInfo {
718718 drop_glue: DropGlue::None,
719 has_dtor: Some(union.ty_placeholders(db).drop_glue(db) != DropGlue::None),
719 has_dtor: Some(union.ty_params(db).drop_glue(db) != DropGlue::None),
720720 },
721721 Definition::Adt(Adt::Enum(enum_)) => {
722 let enum_drop_glue = enum_.ty_placeholders(db).drop_glue(db);
722 let enum_drop_glue = enum_.ty_params(db).drop_glue(db);
723723 let fields_drop_glue = enum_
724724 .variants(db)
725725 .iter()
......@@ -748,7 +748,7 @@ pub(super) fn definition(
748748 DropInfo { drop_glue: fields_drop_glue, has_dtor: None }
749749 }
750750 Definition::TypeAlias(type_alias) => {
751 DropInfo { drop_glue: type_alias.ty_placeholders(db).drop_glue(db), has_dtor: None }
751 DropInfo { drop_glue: type_alias.ty_params(db).drop_glue(db), has_dtor: None }
752752 }
753753 Definition::Local(local) => {
754754 DropInfo { drop_glue: local.ty(db).drop_glue(db), has_dtor: None }
src/tools/rust-analyzer/crates/ide/src/hover/tests.rs+8-2
......@@ -6306,6 +6306,8 @@ const FOO$0: (&str, &str) = {
63066306 );
63076307}
63086308
6309// FIXME(next-solver): this fails to normalize the const, probably due to the solver
6310// refusing to give the impl because of the error type.
63096311#[test]
63106312fn hover_const_eval_in_generic_trait() {
63116313 // Doesn't compile, but we shouldn't crash.
......@@ -6327,12 +6329,16 @@ fn test() {
63276329 *FOO*
63286330
63296331 ```rust
6330 ra_test_fixture::S
6332 ra_test_fixture::Trait
63316333 ```
63326334
63336335 ```rust
6334 const FOO: bool = true
6336 const FOO: bool = false
63356337 ```
6338
6339 ---
6340
6341 `Self` = `S<{unknown}>`
63366342 "#]],
63376343 );
63386344}
src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs+3-5
......@@ -8,9 +8,7 @@ use hir::{
88 ClosureStyle, DisplayTarget, EditionedFileId, HasVisibility, HirDisplay, HirDisplayError,
99 HirWrite, InRealFile, ModuleDef, ModuleDefId, Semantics, sym,
1010};
11use ide_db::{
12 FileRange, RootDatabase, base_db::salsa, famous_defs::FamousDefs, text_edit::TextEditBuilder,
13};
11use ide_db::{FileRange, RootDatabase, famous_defs::FamousDefs, text_edit::TextEditBuilder};
1412use ide_db::{FxHashSet, text_edit::TextEdit};
1513use itertools::Itertools;
1614use smallvec::{SmallVec, smallvec};
......@@ -107,7 +105,7 @@ pub(crate) fn inlay_hints(
107105 }
108106 };
109107 let mut preorder = file.preorder();
110 salsa::attach(sema.db, || {
108 hir::attach_db(sema.db, || {
111109 while let Some(event) = preorder.next() {
112110 if matches!((&event, range_limit), (WalkEvent::Enter(node), Some(range)) if range.intersect(node.text_range()).is_none())
113111 {
......@@ -739,7 +737,7 @@ fn label_of_ty(
739737 config: &InlayHintsConfig,
740738 display_target: DisplayTarget,
741739 ) -> Result<(), HirDisplayError> {
742 salsa::attach(sema.db, || {
740 hir::attach_db(sema.db, || {
743741 let iter_item_type = hint_iterator(sema, famous_defs, ty);
744742 match iter_item_type {
745743 Some((iter_trait, item, ty)) => {
src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs+2-2
......@@ -10,7 +10,7 @@ use hir::{
1010 Adjust, Adjustment, AutoBorrow, DisplayTarget, HirDisplay, Mutability, OverloadedDeref,
1111 PointerCast, Safety,
1212};
13use ide_db::{base_db::salsa, famous_defs::FamousDefs};
13use ide_db::famous_defs::FamousDefs;
1414
1515use ide_db::text_edit::TextEditBuilder;
1616use syntax::ast::{self, AstNode, prec::ExprPrecedence};
......@@ -216,7 +216,7 @@ pub(super) fn hints(
216216 text: if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() },
217217 linked_location: None,
218218 tooltip: Some(config.lazy_tooltip(|| {
219 salsa::attach(sema.db, || {
219 hir::attach_db(sema.db, || {
220220 InlayTooltip::Markdown(format!(
221221 "`{}` → `{}`\n\n**{}**\n\n{}",
222222 source.display(sema.db, display_target),
src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs+2-2
......@@ -646,9 +646,9 @@ auto trait Sync {}
646646fn main() {
647647 // The block expression wrapping disables the constructor hint hiding logic
648648 let _v = { Vec::<Box<&(dyn Display + Sync)>>::new() };
649 //^^ Vec<Box<&(dyn Display + Sync)>>
649 //^^ Vec<Box<&(dyn Display + Sync + 'static)>>
650650 let _v = { Vec::<Box<*const (dyn Display + Sync)>>::new() };
651 //^^ Vec<Box<*const (dyn Display + Sync)>>
651 //^^ Vec<Box<*const (dyn Display + Sync + 'static)>>
652652 let _v = { Vec::<Box<dyn Display + Sync + 'static>>::new() };
653653 //^^ Vec<Box<dyn Display + Sync + 'static>>
654654}
src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs+2-2
......@@ -6,7 +6,7 @@
66//! }
77//! ```
88use hir::{
9 ChalkTyInterner, DefWithBody,
9 DefWithBody,
1010 db::{DefDatabase as _, HirDatabase as _},
1111 mir::{MirSpan, TerminatorKind},
1212};
......@@ -46,7 +46,7 @@ pub(super) fn hints(
4646 if !place.projection.is_empty() {
4747 continue; // Ignore complex cases for now
4848 }
49 if mir.locals[place.local].ty.adt_id(ChalkTyInterner).is_none() {
49 if mir.locals[place.local].ty.as_adt().is_none() {
5050 continue; // Arguably only ADTs have significant drop impls
5151 }
5252 let Some(&binding_idx) = local_to_binding.get(place.local) else {
src/tools/rust-analyzer/crates/ide/src/interpret.rs+1-1
......@@ -60,7 +60,7 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura
6060
6161pub(crate) fn render_const_eval_error(
6262 db: &RootDatabase,
63 e: ConstEvalError,
63 e: ConstEvalError<'_>,
6464 display_target: DisplayTarget,
6565) -> String {
6666 let span_formatter = |file_id, text_range: TextRange| {
src/tools/rust-analyzer/crates/ide/src/lib.rs+3-3
......@@ -67,7 +67,7 @@ use ide_db::{
6767 FxHashMap, FxIndexSet, LineIndexDatabase,
6868 base_db::{
6969 CrateOrigin, CrateWorkspaceData, Env, FileSet, RootQueryDb, SourceDatabase, VfsPath,
70 salsa::{self, Cancelled},
70 salsa::Cancelled,
7171 },
7272 prime_caches, symbol_index,
7373};
......@@ -480,7 +480,7 @@ impl Analysis {
480480 // if we were to attach it here.
481481 Cancelled::catch(|| {
482482 let symbols = symbol_index::world_symbols(&self.db, query);
483 salsa::attach(&self.db, || {
483 hir::attach_db(&self.db, || {
484484 symbols
485485 .into_iter()
486486 .filter_map(|s| s.try_to_nav(&Semantics::new(&self.db)))
......@@ -899,7 +899,7 @@ impl Analysis {
899899 where
900900 F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe,
901901 {
902 salsa::attach(&self.db, || {
902 hir::attach_db(&self.db, || {
903903 // the trait solver code may invoke `as_view<HirDatabase>` outside of queries,
904904 // so technically we might run into a panic in salsa if the downcaster has not yet been registered.
905905 HirDatabase::zalsa_register_downcaster(&self.db);
src/tools/rust-analyzer/crates/ide/src/navigation_target.rs+3-3
......@@ -10,7 +10,7 @@ use hir::{
1010};
1111use ide_db::{
1212 FileId, FileRange, RootDatabase, SymbolKind,
13 base_db::{CrateOrigin, LangCrateOrigin, RootQueryDb, salsa},
13 base_db::{CrateOrigin, LangCrateOrigin, RootQueryDb},
1414 defs::{Definition, find_std_module},
1515 documentation::{Documentation, HasDocs},
1616 famous_defs::FamousDefs,
......@@ -399,7 +399,7 @@ where
399399 )
400400 .map(|mut res| {
401401 res.docs = self.docs(db);
402 res.description = salsa::attach(db, || {
402 res.description = hir::attach_db(db, || {
403403 Some(self.display(db, self.krate(db).to_display_target(db)).to_string())
404404 });
405405 res.container_name = self.container_name(db);
......@@ -520,7 +520,7 @@ impl TryToNav for hir::Field {
520520 NavigationTarget::from_named(db, src.with_value(it), SymbolKind::Field).map(
521521 |mut res| {
522522 res.docs = self.docs(db);
523 res.description = salsa::attach(db, || {
523 res.description = hir::attach_db(db, || {
524524 Some(self.display(db, krate.to_display_target(db)).to_string())
525525 });
526526 res
src/tools/rust-analyzer/crates/ide/src/runnables.rs+3-3
......@@ -10,7 +10,7 @@ use hir::{
1010use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn};
1111use ide_db::{
1212 FilePosition, FxHashMap, FxIndexMap, FxIndexSet, RootDatabase, SymbolKind,
13 base_db::{RootQueryDb, salsa},
13 base_db::RootQueryDb,
1414 defs::Definition,
1515 documentation::docs_from_attrs,
1616 helpers::visit_file_defs,
......@@ -413,7 +413,7 @@ pub(crate) fn runnable_impl(
413413 let ty = def.self_ty(sema.db);
414414 let adt_name = ty.as_adt()?.name(sema.db);
415415 let mut ty_args = ty.generic_parameters(sema.db, display_target).peekable();
416 let params = salsa::attach(sema.db, || {
416 let params = hir::attach_db(sema.db, || {
417417 if ty_args.peek().is_some() {
418418 format!("<{}>", ty_args.format_with(",", |ty, cb| cb(&ty)))
419419 } else {
......@@ -522,7 +522,7 @@ fn module_def_doctest(sema: &Semantics<'_, RootDatabase>, def: Definition) -> Op
522522 let mut ty_args = ty.generic_parameters(db, display_target).peekable();
523523 format_to!(path, "{}", name.display(db, edition));
524524 if ty_args.peek().is_some() {
525 salsa::attach(db, || {
525 hir::attach_db(db, || {
526526 format_to!(path, "<{}>", ty_args.format_with(",", |ty, cb| cb(&ty)));
527527 });
528528 }
src/tools/rust-analyzer/crates/ide/src/signature_help.rs+3-4
......@@ -11,7 +11,6 @@ use hir::{
1111use ide_db::{
1212 FilePosition, FxIndexMap,
1313 active_parameter::{callable_for_arg_list, generic_def_for_node},
14 base_db::salsa,
1514 documentation::{Documentation, HasDocs},
1615};
1716use itertools::Itertools;
......@@ -267,7 +266,7 @@ fn signature_help_for_call(
267266 // In that case, fall back to render definitions of the respective parameters.
268267 // This is overly conservative: we do not substitute known type vars
269268 // (see FIXME in tests::impl_trait) and falling back on any unknowns.
270 salsa::attach(db, || match (p.ty().contains_unknown(), fn_params.as_deref()) {
269 hir::attach_db(db, || match (p.ty().contains_unknown(), fn_params.as_deref()) {
271270 (true, Some(fn_params)) => {
272271 format_to!(buf, "{}", fn_params[idx].ty().display(db, display_target))
273272 }
......@@ -730,7 +729,7 @@ fn signature_help_for_tuple_pat_ish<'db>(
730729mod tests {
731730
732731 use expect_test::{Expect, expect};
733 use ide_db::{FilePosition, base_db::salsa};
732 use ide_db::FilePosition;
734733 use stdx::format_to;
735734 use test_fixture::ChangeFixture;
736735
......@@ -759,7 +758,7 @@ mod tests {
759758 "#
760759 );
761760 let (db, position) = position(&fixture);
762 let sig_help = salsa::attach(&db, || crate::signature_help::signature_help(&db, position));
761 let sig_help = hir::attach_db(&db, || crate::signature_help::signature_help(&db, position));
763762 let actual = match sig_help {
764763 Some(sig_help) => {
765764 let mut rendered = String::new();
src/tools/rust-analyzer/crates/ide/src/static_index.rs+58-57
......@@ -5,7 +5,7 @@ use arrayvec::ArrayVec;
55use hir::{Crate, Module, Semantics, db::HirDatabase};
66use ide_db::{
77 FileId, FileRange, FxHashMap, FxHashSet, RootDatabase,
8 base_db::{RootQueryDb, SourceDatabase, VfsPath, salsa},
8 base_db::{RootQueryDb, SourceDatabase, VfsPath},
99 defs::{Definition, IdentClass},
1010 documentation::Documentation,
1111 famous_defs::FamousDefs,
......@@ -228,32 +228,30 @@ impl StaticIndex<'_> {
228228 let id = if let Some(it) = self.def_map.get(&def) {
229229 *it
230230 } else {
231 let it = salsa::attach(sema.db, || {
232 self.tokens.insert(TokenStaticData {
233 documentation: documentation_for_definition(&sema, def, scope_node),
234 hover: Some(hover_for_definition(
235 &sema,
236 file_id,
237 def,
238 None,
239 scope_node,
240 None,
241 false,
242 &hover_config,
243 edition,
244 display_target,
245 )),
246 definition: def.try_to_nav(&sema).map(UpmappingResult::call_site).map(
247 |it| FileRange { file_id: it.file_id, range: it.focus_or_full_range() },
248 ),
249 references: vec![],
250 moniker: current_crate.and_then(|cc| def_to_moniker(self.db, def, cc)),
251 display_name: def
252 .name(self.db)
253 .map(|name| name.display(self.db, edition).to_string()),
254 signature: Some(def.label(self.db, display_target)),
255 kind: def_to_kind(self.db, def),
256 })
231 let it = self.tokens.insert(TokenStaticData {
232 documentation: documentation_for_definition(&sema, def, scope_node),
233 hover: Some(hover_for_definition(
234 &sema,
235 file_id,
236 def,
237 None,
238 scope_node,
239 None,
240 false,
241 &hover_config,
242 edition,
243 display_target,
244 )),
245 definition: def.try_to_nav(&sema).map(UpmappingResult::call_site).map(|it| {
246 FileRange { file_id: it.file_id, range: it.focus_or_full_range() }
247 }),
248 references: vec![],
249 moniker: current_crate.and_then(|cc| def_to_moniker(self.db, def, cc)),
250 display_name: def
251 .name(self.db)
252 .map(|name| name.display(self.db, edition).to_string()),
253 signature: Some(def.label(self.db, display_target)),
254 kind: def_to_kind(self.db, def),
257255 });
258256 self.def_map.insert(def, it);
259257 it
......@@ -278,7 +276,7 @@ impl StaticIndex<'_> {
278276 for token in tokens {
279277 let range = token.text_range();
280278 let node = token.parent().unwrap();
281 match salsa::attach(self.db, || get_definitions(&sema, token.clone())) {
279 match hir::attach_db(self.db, || get_definitions(&sema, token.clone())) {
282280 Some(it) => {
283281 for i in it {
284282 add_token(i, range, &node);
......@@ -295,37 +293,40 @@ impl StaticIndex<'_> {
295293 vendored_libs_config: VendoredLibrariesConfig<'_>,
296294 ) -> StaticIndex<'a> {
297295 let db = &analysis.db;
298 let work = all_modules(db).into_iter().filter(|module| {
299 let file_id = module.definition_source_file_id(db).original_file(db);
300 let source_root = db.file_source_root(file_id.file_id(&analysis.db)).source_root_id(db);
301 let source_root = db.source_root(source_root).source_root(db);
302 let is_vendored = match vendored_libs_config {
303 VendoredLibrariesConfig::Included { workspace_root } => source_root
304 .path_for_file(&file_id.file_id(&analysis.db))
305 .is_some_and(|module_path| module_path.starts_with(workspace_root)),
306 VendoredLibrariesConfig::Excluded => false,
296 hir::attach_db(db, || {
297 let work = all_modules(db).into_iter().filter(|module| {
298 let file_id = module.definition_source_file_id(db).original_file(db);
299 let source_root =
300 db.file_source_root(file_id.file_id(&analysis.db)).source_root_id(db);
301 let source_root = db.source_root(source_root).source_root(db);
302 let is_vendored = match vendored_libs_config {
303 VendoredLibrariesConfig::Included { workspace_root } => source_root
304 .path_for_file(&file_id.file_id(&analysis.db))
305 .is_some_and(|module_path| module_path.starts_with(workspace_root)),
306 VendoredLibrariesConfig::Excluded => false,
307 };
308
309 !source_root.is_library || is_vendored
310 });
311 let mut this = StaticIndex {
312 files: vec![],
313 tokens: Default::default(),
314 analysis,
315 db,
316 def_map: Default::default(),
307317 };
308
309 !source_root.is_library || is_vendored
310 });
311 let mut this = StaticIndex {
312 files: vec![],
313 tokens: Default::default(),
314 analysis,
315 db,
316 def_map: Default::default(),
317 };
318 let mut visited_files = FxHashSet::default();
319 for module in work {
320 let file_id = module.definition_source_file_id(db).original_file(db);
321 if visited_files.contains(&file_id) {
322 continue;
318 let mut visited_files = FxHashSet::default();
319 for module in work {
320 let file_id = module.definition_source_file_id(db).original_file(db);
321 if visited_files.contains(&file_id) {
322 continue;
323 }
324 this.add_file(file_id.file_id(&analysis.db));
325 // mark the file
326 visited_files.insert(file_id);
323327 }
324 this.add_file(file_id.file_id(&analysis.db));
325 // mark the file
326 visited_files.insert(file_id);
327 }
328 this
328 this
329 })
329330 }
330331}
331332
src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs+10-7
......@@ -16,7 +16,7 @@ use std::ops::ControlFlow;
1616
1717use either::Either;
1818use hir::{DefWithBody, EditionedFileId, InFile, InRealFile, MacroKind, Name, Semantics};
19use ide_db::{FxHashMap, FxHashSet, Ranker, RootDatabase, SymbolKind, base_db::salsa};
19use ide_db::{FxHashMap, FxHashSet, Ranker, RootDatabase, SymbolKind};
2020use syntax::{
2121 AstNode, AstToken, NodeOrToken,
2222 SyntaxKind::*,
......@@ -116,7 +116,7 @@ pub struct HighlightConfig {
116116// |arithmetic| Emitted for the arithmetic operators `+`, `-`, `*`, `/`, `+=`, `-=`, `*=`, `/=`.|
117117// |bitwise| Emitted for the bitwise operators `|`, `&`, `!`, `^`, `|=`, `&=`, `^=`.|
118118// |comparison| Emitted for the comparison oerators `>`, `<`, `==`, `>=`, `<=`, `!=`.|
119// |logical| Emitted for the logical operatos `||`, `&&`, `!`.|
119// |logical| Emitted for the logical operators `||`, `&&`, `!`.|
120120//
121121// - For punctuation:
122122//
......@@ -426,9 +426,12 @@ fn traverse(
426426 let edition = descended_element.file_id.edition(sema.db);
427427 let (unsafe_ops, bindings_shadow_count) = match current_body {
428428 Some(current_body) => {
429 let (ops, bindings) = per_body_cache
430 .entry(current_body)
431 .or_insert_with(|| (sema.get_unsafe_ops(current_body), Default::default()));
429 let (ops, bindings) = per_body_cache.entry(current_body).or_insert_with(|| {
430 (
431 hir::attach_db(sema.db, || sema.get_unsafe_ops(current_body)),
432 Default::default(),
433 )
434 });
432435 (&*ops, Some(bindings))
433436 }
434437 None => (&empty, None),
......@@ -437,7 +440,7 @@ fn traverse(
437440 |node| unsafe_ops.contains(&InFile::new(descended_element.file_id, node));
438441 let element = match descended_element.value {
439442 NodeOrToken::Node(name_like) => {
440 let hl = salsa::attach(sema.db, || {
443 let hl = hir::attach_db(sema.db, || {
441444 highlight::name_like(
442445 sema,
443446 krate,
......@@ -455,7 +458,7 @@ fn traverse(
455458 }
456459 hl
457460 }
458 NodeOrToken::Token(token) => salsa::attach(sema.db, || {
461 NodeOrToken::Token(token) => hir::attach_db(sema.db, || {
459462 highlight::token(sema, token, edition, &is_unsafe_node, tt_level > 0)
460463 .zip(Some(None))
461464 }),
src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs+3-3
......@@ -5,7 +5,7 @@ use std::mem;
55use either::Either;
66use hir::{EditionedFileId, HirFileId, InFile, Semantics, sym};
77use ide_db::{
8 SymbolKind, active_parameter::ActiveParameter, base_db::salsa, defs::Definition,
8 SymbolKind, active_parameter::ActiveParameter, defs::Definition,
99 documentation::docs_with_rangemap, rust_doc::is_rust_fence,
1010};
1111use syntax::{
......@@ -27,7 +27,7 @@ pub(super) fn ra_fixture(
2727 expanded: &ast::String,
2828) -> Option<()> {
2929 let active_parameter =
30 salsa::attach(sema.db, || ActiveParameter::at_token(sema, expanded.syntax().clone()))?;
30 hir::attach_db(sema.db, || ActiveParameter::at_token(sema, expanded.syntax().clone()))?;
3131 let has_rust_fixture_attr = active_parameter.attrs().is_some_and(|attrs| {
3232 attrs.filter_map(|attr| attr.as_simple_path()).any(|path| {
3333 path.segments()
......@@ -128,7 +128,7 @@ pub(super) fn doc_comment(
128128
129129 // Extract intra-doc links and emit highlights for them.
130130 if let Some((docs, doc_mapping)) = docs_with_rangemap(sema.db, &attributes) {
131 salsa::attach(sema.db, || {
131 hir::attach_db(sema.db, || {
132132 extract_definitions_from_docs(&docs)
133133 .into_iter()
134134 .filter_map(|(range, link, ns)| {
src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs+11-14
......@@ -3,7 +3,6 @@ use std::fmt;
33use hir::{DisplayTarget, Field, HirDisplay, Layout, Semantics, Type};
44use ide_db::{
55 RootDatabase,
6 base_db::salsa,
76 defs::Definition,
87 helpers::{get_definition, pick_best_token},
98};
......@@ -94,14 +93,14 @@ pub(crate) fn view_memory_layout(
9493 let def = get_definition(&sema, token)?;
9594
9695 let ty = match def {
97 Definition::Adt(it) => salsa::attach(db, || it.ty(db)),
98 Definition::TypeAlias(it) => salsa::attach(db, || it.ty(db)),
96 Definition::Adt(it) => it.ty(db),
97 Definition::TypeAlias(it) => it.ty(db),
9998 Definition::BuiltinType(it) => it.ty(db),
10099 Definition::SelfType(it) => it.self_ty(db),
101100 Definition::Local(it) => it.ty(db),
102 Definition::Field(it) => salsa::attach(db, || it.ty(db).to_type(db)),
103 Definition::Const(it) => salsa::attach(db, || it.ty(db)),
104 Definition::Static(it) => salsa::attach(db, || it.ty(db)),
101 Definition::Field(it) => it.ty(db).to_type(db),
102 Definition::Const(it) => it.ty(db),
103 Definition::Static(it) => it.ty(db),
105104 _ => return None,
106105 };
107106
......@@ -139,12 +138,10 @@ pub(crate) fn view_memory_layout(
139138 nodes[parent_idx].children_len = fields.len() as u64;
140139
141140 for (field, child_ty) in fields.iter() {
142 if let Ok(child_layout) = salsa::attach(db, || child_ty.layout(db)) {
141 if let Ok(child_layout) = child_ty.layout(db) {
143142 nodes.push(MemoryLayoutNode {
144143 item_name: field.name(db),
145 typename: salsa::attach(db, || {
146 child_ty.display(db, display_target).to_string()
147 }),
144 typename: { child_ty.display(db, display_target).to_string() },
148145 size: child_layout.size(),
149146 alignment: child_layout.align(),
150147 offset: match *field {
......@@ -172,13 +169,13 @@ pub(crate) fn view_memory_layout(
172169 }
173170
174171 for (i, (_, child_ty)) in fields.iter().enumerate() {
175 if let Ok(child_layout) = salsa::attach(db, || child_ty.layout(db)) {
172 if let Ok(child_layout) = child_ty.layout(db) {
176173 read_layout(nodes, db, child_ty, &child_layout, children_start + i, display_target);
177174 }
178175 }
179176 }
180177
181 salsa::attach(db, || ty.layout(db))
178 ty.layout(db)
182179 .map(|layout| {
183180 let item_name = match def {
184181 // def is a datatype
......@@ -191,7 +188,7 @@ pub(crate) fn view_memory_layout(
191188 def => def.name(db).map(|n| n.as_str().to_owned()).unwrap_or("[ROOT]".to_owned()),
192189 };
193190
194 let typename = salsa::attach(db, || ty.display(db, display_target).to_string());
191 let typename = ty.display(db, display_target).to_string();
195192
196193 let mut nodes = vec![MemoryLayoutNode {
197194 item_name,
......@@ -222,7 +219,7 @@ mod tests {
222219 ) -> Option<RecursiveMemoryLayout> {
223220 let (analysis, position, _) = fixture::annotations(ra_fixture);
224221
225 view_memory_layout(&analysis.db, position)
222 hir::attach_db(&analysis.db, || view_memory_layout(&analysis.db, position))
226223 }
227224
228225 #[test]
src/tools/rust-analyzer/crates/macros/Cargo.toml created+19
......@@ -0,0 +1,19 @@
1[package]
2name = "macros"
3version = "0.0.0"
4repository.workspace = true
5description = "Proc macros for rust-analyzer."
6
7authors.workspace = true
8edition.workspace = true
9license.workspace = true
10rust-version.workspace = true
11
12[lib]
13proc-macro = true
14
15[dependencies]
16proc-macro2 = "1"
17quote = "1"
18syn = "2.0.9"
19synstructure = "0.13.0"
src/tools/rust-analyzer/crates/macros/src/lib.rs created+164
......@@ -0,0 +1,164 @@
1//! Proc macros for rust-analyzer.
2
3use quote::{ToTokens, quote};
4use syn::parse_quote;
5use synstructure::decl_derive;
6
7decl_derive!(
8 [TypeFoldable, attributes(type_foldable)] =>
9 /// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported).
10 ///
11 /// The fold will produce a value of the same struct or enum variant as the input, with
12 /// each field respectively folded using the `TypeFoldable` implementation for its type.
13 /// However, if a field of a struct or an enum variant is annotated with
14 /// `#[type_foldable(identity)]` then that field will retain its incumbent value (and its
15 /// type is not required to implement `TypeFoldable`).
16 type_foldable_derive
17);
18decl_derive!(
19 [TypeVisitable, attributes(type_visitable)] =>
20 /// Derives `TypeVisitable` for the annotated `struct` or `enum` (`union` is not supported).
21 ///
22 /// Each field of the struct or enum variant will be visited in definition order, using the
23 /// `TypeVisitable` implementation for its type. However, if a field of a struct or an enum
24 /// variant is annotated with `#[type_visitable(ignore)]` then that field will not be
25 /// visited (and its type is not required to implement `TypeVisitable`).
26 type_visitable_derive
27);
28
29fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
30 if let syn::Data::Union(_) = s.ast().data {
31 panic!("cannot derive on union")
32 }
33
34 // ignore fields with #[type_visitable(ignore)]
35 s.filter(|bi| {
36 let mut ignored = false;
37
38 bi.ast().attrs.iter().for_each(|attr| {
39 if !attr.path().is_ident("type_visitable") {
40 return;
41 }
42 let _ = attr.parse_nested_meta(|nested| {
43 if nested.path.is_ident("ignore") {
44 ignored = true;
45 }
46 Ok(())
47 });
48 });
49
50 !ignored
51 });
52
53 if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "db") {
54 s.add_impl_generic(parse_quote! { 'db });
55 }
56
57 s.add_bounds(synstructure::AddBounds::Generics);
58 let body_visit = s.each(|bind| {
59 quote! {
60 match ::rustc_type_ir::VisitorResult::branch(
61 ::rustc_type_ir::TypeVisitable::visit_with(#bind, __visitor)
62 ) {
63 ::core::ops::ControlFlow::Continue(()) => {},
64 ::core::ops::ControlFlow::Break(r) => {
65 return ::rustc_type_ir::VisitorResult::from_residual(r);
66 },
67 }
68 }
69 });
70 s.bind_with(|_| synstructure::BindStyle::Move);
71
72 s.bound_impl(
73 quote!(::rustc_type_ir::TypeVisitable<::hir_ty::next_solver::DbInterner<'db>>),
74 quote! {
75 fn visit_with<__V: ::rustc_type_ir::TypeVisitor<::hir_ty::next_solver::DbInterner<'db>>>(
76 &self,
77 __visitor: &mut __V
78 ) -> __V::Result {
79 match *self { #body_visit }
80 <__V::Result as ::rustc_type_ir::VisitorResult>::output()
81 }
82 },
83 )
84}
85
86fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
87 if let syn::Data::Union(_) = s.ast().data {
88 panic!("cannot derive on union")
89 }
90
91 if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "db") {
92 s.add_impl_generic(parse_quote! { 'db });
93 }
94
95 s.add_bounds(synstructure::AddBounds::Generics);
96 s.bind_with(|_| synstructure::BindStyle::Move);
97 let try_body_fold = s.each_variant(|vi| {
98 let bindings = vi.bindings();
99 vi.construct(|_, index| {
100 let bind = &bindings[index];
101
102 // retain value of fields with #[type_foldable(identity)]
103 if has_ignore_attr(&bind.ast().attrs, "type_foldable", "identity") {
104 bind.to_token_stream()
105 } else {
106 quote! {
107 ::rustc_type_ir::TypeFoldable::try_fold_with(#bind, __folder)?
108 }
109 }
110 })
111 });
112
113 let body_fold = s.each_variant(|vi| {
114 let bindings = vi.bindings();
115 vi.construct(|_, index| {
116 let bind = &bindings[index];
117
118 // retain value of fields with #[type_foldable(identity)]
119 if has_ignore_attr(&bind.ast().attrs, "type_foldable", "identity") {
120 bind.to_token_stream()
121 } else {
122 quote! {
123 ::rustc_type_ir::TypeFoldable::fold_with(#bind, __folder)
124 }
125 }
126 })
127 });
128
129 s.bound_impl(
130 quote!(::rustc_type_ir::TypeFoldable<::hir_ty::next_solver::DbInterner<'db>>),
131 quote! {
132 fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<::hir_ty::next_solver::DbInterner<'db>>>(
133 self,
134 __folder: &mut __F
135 ) -> Result<Self, __F::Error> {
136 Ok(match self { #try_body_fold })
137 }
138
139 fn fold_with<__F: ::rustc_type_ir::TypeFolder<::hir_ty::next_solver::DbInterner<'db>>>(
140 self,
141 __folder: &mut __F
142 ) -> Self {
143 match self { #body_fold }
144 }
145 },
146 )
147}
148
149fn has_ignore_attr(attrs: &[syn::Attribute], name: &'static str, meta: &'static str) -> bool {
150 let mut ignored = false;
151 attrs.iter().for_each(|attr| {
152 if !attr.path().is_ident(name) {
153 return;
154 }
155 let _ = attr.parse_nested_meta(|nested| {
156 if nested.path.is_ident(meta) {
157 ignored = true;
158 }
159 Ok(())
160 });
161 });
162
163 ignored
164}
src/tools/rust-analyzer/crates/parser/src/grammar/items/consts.rs+17-10
......@@ -25,21 +25,28 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) {
2525 }
2626
2727 // FIXME: Recover on statics with generic params/where clause.
28 if is_const {
29 // test generic_const
30 // const C<i32>: u32 = 0;
31 // impl Foo {
32 // const C<'a>: &'a () = &();
33 // }
34 generic_params::opt_generic_param_list(p);
28 if !is_const && p.at(T![<]) {
29 // test_err generic_static
30 // static C<i32>: u32 = 0;
31 p.error("`static` may not have generic parameters");
3532 }
36 // test_err generic_static
37 // static C<i32>: u32 = 0;
33 // test generic_const
34 // const C<i32>: u32 = 0;
35 // impl Foo {
36 // const C<'a>: &'a () = &();
37 // }
38 generic_params::opt_generic_param_list(p);
3839
3940 if p.at(T![:]) {
4041 types::ascription(p);
42 } else if is_const {
43 // test_err missing_const_type
44 // const C = 0;
45 p.error("missing type for `const`");
4146 } else {
42 p.error("missing type for `const` or `static`");
47 // test_err missing_static_type
48 // static C = 0;
49 p.error("missing type for `static`");
4350 }
4451 if p.eat(T![=]) {
4552 expressions::expr(p);
src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs+8
......@@ -824,10 +824,18 @@ mod err {
824824 run_and_expect_errors("test_data/parser/inline/err/misplaced_label_err.rs");
825825 }
826826 #[test]
827 fn missing_const_type() {
828 run_and_expect_errors("test_data/parser/inline/err/missing_const_type.rs");
829 }
830 #[test]
827831 fn missing_fn_param_type() {
828832 run_and_expect_errors("test_data/parser/inline/err/missing_fn_param_type.rs");
829833 }
830834 #[test]
835 fn missing_static_type() {
836 run_and_expect_errors("test_data/parser/inline/err/missing_static_type.rs");
837 }
838 #[test]
831839 fn path_item_without_excl() {
832840 run_and_expect_errors("test_data/parser/inline/err/path_item_without_excl.rs");
833841 }
src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast+1-1
......@@ -42,7 +42,7 @@ SOURCE_FILE
4242 WHITESPACE "\n"
4343error 6: expected fn, trait or impl
4444error 38: expected a name
45error 40: missing type for `const` or `static`
45error 40: missing type for `const`
4646error 40: expected SEMICOLON
4747error 44: expected an item
4848error 44: expected an item
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast+16-31
......@@ -4,39 +4,24 @@ SOURCE_FILE
44 WHITESPACE " "
55 NAME
66 IDENT "C"
7 ERROR
8 L_ANGLE "<"
9 ERROR
10 PATH
11 PATH_SEGMENT
12 NAME_REF
7 GENERIC_PARAM_LIST
8 L_ANGLE "<"
9 TYPE_PARAM
10 NAME
1311 IDENT "i32"
14 ERROR
15 R_ANGLE ">"
16 ERROR
12 R_ANGLE ">"
1713 COLON ":"
18 WHITESPACE " "
19 ERROR
20 PATH
21 PATH_SEGMENT
22 NAME_REF
23 IDENT "u32"
24 WHITESPACE " "
25 ERROR
14 WHITESPACE " "
15 PATH_TYPE
16 PATH
17 PATH_SEGMENT
18 NAME_REF
19 IDENT "u32"
20 WHITESPACE " "
2621 EQ "="
27 WHITESPACE " "
28 ERROR
29 INT_NUMBER "0"
30 ERROR
22 WHITESPACE " "
23 LITERAL
24 INT_NUMBER "0"
3125 SEMICOLON ";"
3226 WHITESPACE "\n"
33error 8: missing type for `const` or `static`
34error 8: expected SEMICOLON
35error 8: expected an item
36error 12: expected an item
37error 12: expected an item
38error 13: expected an item
39error 18: expected an item
40error 19: expected an item
41error 21: expected an item
42error 22: expected an item
27error 8: `static` may not have generic parameters
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rast created+14
......@@ -0,0 +1,14 @@
1SOURCE_FILE
2 CONST
3 CONST_KW "const"
4 WHITESPACE " "
5 NAME
6 IDENT "C"
7 WHITESPACE " "
8 EQ "="
9 WHITESPACE " "
10 LITERAL
11 INT_NUMBER "0"
12 SEMICOLON ";"
13 WHITESPACE "\n"
14error 7: missing type for `const`
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rs created+1
......@@ -0,0 +1 @@
1const C = 0;
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rast created+14
......@@ -0,0 +1,14 @@
1SOURCE_FILE
2 STATIC
3 STATIC_KW "static"
4 WHITESPACE " "
5 NAME
6 IDENT "C"
7 WHITESPACE " "
8 EQ "="
9 WHITESPACE " "
10 LITERAL
11 INT_NUMBER "0"
12 SEMICOLON ";"
13 WHITESPACE "\n"
14error 8: missing type for `static`
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rs created+1
......@@ -0,0 +1 @@
1static C = 0;
src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs+5-4
......@@ -13,12 +13,12 @@ use serde_derive::Deserialize;
1313use serde_json::from_value;
1414use span::Edition;
1515use stdx::process::spawn_with_streaming_output;
16use toolchain::Tool;
16use toolchain::{NO_RUSTUP_AUTO_INSTALL_ENV, Tool};
1717use triomphe::Arc;
1818
19use crate::cargo_config_file::make_lockfile_copy;
20use crate::{CfgOverrides, InvocationStrategy};
21use crate::{ManifestPath, Sysroot};
19use crate::{
20 CfgOverrides, InvocationStrategy, ManifestPath, Sysroot, cargo_config_file::make_lockfile_copy,
21};
2222
2323pub(crate) const MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH: semver::Version =
2424 semver::Version {
......@@ -632,6 +632,7 @@ impl FetchMetadata {
632632 ) -> Self {
633633 let cargo = sysroot.tool(Tool::Cargo, current_dir, &config.extra_env);
634634 let mut command = MetadataCommand::new();
635 command.env(NO_RUSTUP_AUTO_INSTALL_ENV.0, NO_RUSTUP_AUTO_INSTALL_ENV.1);
635636 command.cargo_path(cargo.get_program());
636637 cargo.get_envs().for_each(|(var, val)| _ = command.env(var, val.unwrap_or_default()));
637638 command.manifest_path(cargo_toml.to_path_buf());
src/tools/rust-analyzer/crates/project-model/src/workspace.rs+3-2
......@@ -16,8 +16,9 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
1616use rustc_hash::{FxHashMap, FxHashSet};
1717use semver::Version;
1818use span::{Edition, FileId};
19use toolchain::Tool;
19use toolchain::{NO_RUSTUP_AUTO_INSTALL_ENV, Tool};
2020use tracing::instrument;
21use tracing::{debug, error, info};
2122use triomphe::Arc;
2223
2324use crate::{
......@@ -33,7 +34,6 @@ use crate::{
3334 toolchain_info::{QueryConfig, rustc_cfg, target_data, target_tuple, version},
3435 utf8_stdout,
3536};
36use tracing::{debug, error, info};
3737
3838pub type FileLoader<'a> = &'a mut dyn for<'b> FnMut(&'b AbsPath) -> Option<FileId>;
3939
......@@ -1907,6 +1907,7 @@ fn cargo_target_dir(
19071907) -> Option<Utf8PathBuf> {
19081908 let cargo = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env);
19091909 let mut meta = cargo_metadata::MetadataCommand::new();
1910 meta.env(NO_RUSTUP_AUTO_INSTALL_ENV.0, NO_RUSTUP_AUTO_INSTALL_ENV.1);
19101911 meta.cargo_path(cargo.get_program());
19111912 meta.manifest_path(manifest);
19121913 // `--no-deps` doesn't (over)write lockfiles as it doesn't do any package resolve.
src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs+2-1
......@@ -327,7 +327,8 @@ impl ToTokens for Lookup {
327327 let wrapper_struct = self.interned_struct_path.to_token_stream();
328328 let method = quote! {
329329 #sig {
330 #wrapper_struct::ingredient(self).data(self.as_dyn_database(), id.as_id()).0.clone()
330 let zalsa = self.zalsa();
331 #wrapper_struct::ingredient(zalsa).data(zalsa, id.as_id()).0.clone()
331332 }
332333 };
333334
src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml+2
......@@ -75,6 +75,8 @@ vfs-notify.workspace = true
7575vfs.workspace = true
7676paths.workspace = true
7777
78ra-ap-rustc_type_ir.workspace = true
79
7880[target.'cfg(windows)'.dependencies]
7981windows-sys = { version = "0.60", features = [
8082 "Win32_System_Diagnostics_Debug",
src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs+35-35
......@@ -20,7 +20,6 @@ use hir_def::{
2020 expr_store::BodySourceMap,
2121 hir::{ExprId, PatId},
2222};
23use hir_ty::{Interner, TyExt, TypeFlags};
2423use ide::{
2524 Analysis, AnalysisHost, AnnotationConfig, DiagnosticsConfig, Edition, InlayFieldsToResolve,
2625 InlayHintsConfig, LineCol, RootDatabase,
......@@ -36,6 +35,7 @@ use profile::StopWatch;
3635use project_model::{CargoConfig, CfgOverrides, ProjectManifest, ProjectWorkspace, RustLibSource};
3736use rayon::prelude::*;
3837use rustc_hash::{FxHashMap, FxHashSet};
38use rustc_type_ir::inherent::Ty as _;
3939use syntax::AstNode;
4040use vfs::{AbsPathBuf, Vfs, VfsPath};
4141
......@@ -312,32 +312,37 @@ impl flags::AnalysisStats {
312312 shuffle(&mut rng, &mut bodies);
313313 }
314314
315 if !self.skip_lowering {
316 self.run_body_lowering(db, &vfs, &bodies, verbosity);
317 }
315 hir::attach_db(db, || {
316 if !self.skip_lowering {
317 self.run_body_lowering(db, &vfs, &bodies, verbosity);
318 }
318319
319 if !self.skip_inference {
320 self.run_inference(db, &vfs, &bodies, verbosity);
321 }
320 if !self.skip_inference {
321 self.run_inference(db, &vfs, &bodies, verbosity);
322 }
322323
323 if !self.skip_mir_stats {
324 self.run_mir_lowering(db, &bodies, verbosity);
325 }
324 if !self.skip_mir_stats {
325 self.run_mir_lowering(db, &bodies, verbosity);
326 }
326327
327 if !self.skip_data_layout {
328 self.run_data_layout(db, &adts, verbosity);
329 }
328 if !self.skip_data_layout {
329 self.run_data_layout(db, &adts, verbosity);
330 }
330331
331 if !self.skip_const_eval {
332 self.run_const_eval(db, &bodies, verbosity);
333 }
332 if !self.skip_const_eval {
333 self.run_const_eval(db, &bodies, verbosity);
334 }
335 });
336
337 file_ids.sort();
338 file_ids.dedup();
334339
335340 if self.run_all_ide_things {
336 self.run_ide_things(host.analysis(), file_ids.clone(), db, &vfs, verbosity);
341 self.run_ide_things(host.analysis(), &file_ids, db, &vfs, verbosity);
337342 }
338343
339344 if self.run_term_search {
340 self.run_term_search(&workspace, db, &vfs, file_ids, verbosity);
345 self.run_term_search(&workspace, db, &vfs, &file_ids, verbosity);
341346 }
342347
343348 let db = host.raw_database_mut();
......@@ -433,12 +438,13 @@ impl flags::AnalysisStats {
433438 report_metric("const eval time", const_eval_time.time.as_millis() as u64, "ms");
434439 }
435440
441 /// Invariant: `file_ids` must be sorted and deduped before passing into here
436442 fn run_term_search(
437443 &self,
438444 ws: &ProjectWorkspace,
439445 db: &RootDatabase,
440446 vfs: &Vfs,
441 mut file_ids: Vec<EditionedFileId>,
447 file_ids: &[EditionedFileId],
442448 verbosity: Verbosity,
443449 ) {
444450 let cargo_config = CargoConfig {
......@@ -456,9 +462,6 @@ impl flags::AnalysisStats {
456462 _ => ProgressReport::new(file_ids.len()),
457463 };
458464
459 file_ids.sort();
460 file_ids.dedup();
461
462465 #[derive(Debug, Default)]
463466 struct Acc {
464467 tail_expr_syntax_hits: u64,
......@@ -472,7 +475,7 @@ impl flags::AnalysisStats {
472475 bar.tick();
473476 let mut sw = self.stop_watch();
474477
475 for &file_id in &file_ids {
478 for &file_id in file_ids {
476479 let file_id = file_id.editioned_file_id(db);
477480 let sema = hir::Semantics::new(db);
478481 let display_target = match sema.first_crate(file_id.file_id()) {
......@@ -814,7 +817,7 @@ impl flags::AnalysisStats {
814817 for (expr_id, _) in body.exprs() {
815818 let ty = &inference_result[expr_id];
816819 num_exprs += 1;
817 let unknown_or_partial = if ty.is_unknown() {
820 let unknown_or_partial = if ty.is_ty_error() {
818821 num_exprs_unknown += 1;
819822 if verbosity.is_spammy() {
820823 if let Some((path, start, end)) = expr_syntax_range(db, vfs, &sm(), expr_id)
......@@ -836,8 +839,7 @@ impl flags::AnalysisStats {
836839 }
837840 true
838841 } else {
839 let is_partially_unknown =
840 ty.data(Interner).flags.contains(TypeFlags::HAS_ERROR);
842 let is_partially_unknown = ty.references_non_lt_error();
841843 if is_partially_unknown {
842844 num_exprs_partially_unknown += 1;
843845 }
......@@ -919,7 +921,7 @@ impl flags::AnalysisStats {
919921 for (pat_id, _) in body.pats() {
920922 let ty = &inference_result[pat_id];
921923 num_pats += 1;
922 let unknown_or_partial = if ty.is_unknown() {
924 let unknown_or_partial = if ty.is_ty_error() {
923925 num_pats_unknown += 1;
924926 if verbosity.is_spammy() {
925927 if let Some((path, start, end)) = pat_syntax_range(db, vfs, &sm(), pat_id) {
......@@ -940,8 +942,7 @@ impl flags::AnalysisStats {
940942 }
941943 true
942944 } else {
943 let is_partially_unknown =
944 ty.data(Interner).flags.contains(TypeFlags::HAS_ERROR);
945 let is_partially_unknown = ty.references_non_lt_error();
945946 if is_partially_unknown {
946947 num_pats_partially_unknown += 1;
947948 }
......@@ -1106,10 +1107,11 @@ impl flags::AnalysisStats {
11061107 report_metric("body lowering time", body_lowering_time.time.as_millis() as u64, "ms");
11071108 }
11081109
1110 /// Invariant: `file_ids` must be sorted and deduped before passing into here
11091111 fn run_ide_things(
11101112 &self,
11111113 analysis: Analysis,
1112 mut file_ids: Vec<EditionedFileId>,
1114 file_ids: &[EditionedFileId],
11131115 db: &RootDatabase,
11141116 vfs: &Vfs,
11151117 verbosity: Verbosity,
......@@ -1121,12 +1123,10 @@ impl flags::AnalysisStats {
11211123 _ => ProgressReport::new(len),
11221124 };
11231125
1124 file_ids.sort();
1125 file_ids.dedup();
11261126 let mut sw = self.stop_watch();
11271127
11281128 let mut bar = create_bar();
1129 for &file_id in &file_ids {
1129 for &file_id in file_ids {
11301130 let msg = format!("diagnostics: {}", vfs.file_path(file_id.file_id(db)));
11311131 bar.set_message(move || msg.clone());
11321132 _ = analysis.full_diagnostics(
......@@ -1160,7 +1160,7 @@ impl flags::AnalysisStats {
11601160 bar.finish_and_clear();
11611161
11621162 let mut bar = create_bar();
1163 for &file_id in &file_ids {
1163 for &file_id in file_ids {
11641164 let msg = format!("inlay hints: {}", vfs.file_path(file_id.file_id(db)));
11651165 bar.set_message(move || msg.clone());
11661166 _ = analysis.inlay_hints(
......@@ -1203,7 +1203,7 @@ impl flags::AnalysisStats {
12031203 bar.finish_and_clear();
12041204
12051205 let mut bar = create_bar();
1206 for &file_id in &file_ids {
1206 for &file_id in file_ids {
12071207 let msg = format!("annotations: {}", vfs.file_path(file_id.file_id(db)));
12081208 bar.set_message(move || msg.clone());
12091209 analysis
src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs+23-3
......@@ -3,13 +3,15 @@
33
44use std::{
55 ffi::OsString,
6 fmt, io,
6 fmt,
7 io::{self, BufWriter, Write},
78 marker::PhantomData,
89 path::PathBuf,
910 process::{ChildStderr, ChildStdout, Command, Stdio},
1011};
1112
1213use crossbeam_channel::Sender;
14use paths::Utf8PathBuf;
1315use process_wrap::std::{StdChildWrapper, StdCommandWrap};
1416use stdx::process::streaming_output;
1517
......@@ -40,7 +42,7 @@ impl<T: Sized + Send + 'static> CargoActor<T> {
4042}
4143
4244impl<T: Sized + Send + 'static> CargoActor<T> {
43 fn run(self) -> io::Result<(bool, String)> {
45 fn run(self, outfile: Option<Utf8PathBuf>) -> io::Result<(bool, String)> {
4446 // We manually read a line at a time, instead of using serde's
4547 // stream deserializers, because the deserializer cannot recover
4648 // from an error, resulting in it getting stuck, because we try to
......@@ -50,6 +52,15 @@ impl<T: Sized + Send + 'static> CargoActor<T> {
5052 // simply skip a line if it doesn't parse, which just ignores any
5153 // erroneous output.
5254
55 let mut stdout = outfile.as_ref().and_then(|path| {
56 _ = std::fs::create_dir_all(path);
57 Some(BufWriter::new(std::fs::File::create(path.join("stdout")).ok()?))
58 });
59 let mut stderr = outfile.as_ref().and_then(|path| {
60 _ = std::fs::create_dir_all(path);
61 Some(BufWriter::new(std::fs::File::create(path.join("stderr")).ok()?))
62 });
63
5364 let mut stdout_errors = String::new();
5465 let mut stderr_errors = String::new();
5566 let mut read_at_least_one_stdout_message = false;
......@@ -67,11 +78,19 @@ impl<T: Sized + Send + 'static> CargoActor<T> {
6778 self.stdout,
6879 self.stderr,
6980 &mut |line| {
81 if let Some(stdout) = &mut stdout {
82 _ = stdout.write_all(line.as_bytes());
83 _ = stdout.write_all(b"\n");
84 }
7085 if process_line(line, &mut stdout_errors) {
7186 read_at_least_one_stdout_message = true;
7287 }
7388 },
7489 &mut |line| {
90 if let Some(stderr) = &mut stderr {
91 _ = stderr.write_all(line.as_bytes());
92 _ = stderr.write_all(b"\n");
93 }
7594 if process_line(line, &mut stderr_errors) {
7695 read_at_least_one_stderr_message = true;
7796 }
......@@ -130,6 +149,7 @@ impl<T: Sized + Send + 'static> CommandHandle<T> {
130149 mut command: Command,
131150 parser: impl CargoParser<T>,
132151 sender: Sender<T>,
152 out_file: Option<Utf8PathBuf>,
133153 ) -> std::io::Result<Self> {
134154 command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null());
135155
......@@ -150,7 +170,7 @@ impl<T: Sized + Send + 'static> CommandHandle<T> {
150170 let actor = CargoActor::<T>::new(parser, sender, stdout, stderr);
151171 let thread =
152172 stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "CommandHandle")
153 .spawn(move || actor.run())
173 .spawn(move || actor.run(out_file))
154174 .expect("failed to spawn thread");
155175 Ok(CommandHandle { program, arguments, current_dir, child, thread, _phantom: PhantomData })
156176 }
src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs+21-10
......@@ -895,7 +895,7 @@ config_data! {
895895 /// [custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field),
896896 /// they will end up being interpreted as options to
897897 /// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
898 runnables_extraTestBinaryArgs: Vec<String> = vec!["--show-output".to_owned()],
898 runnables_extraTestBinaryArgs: Vec<String> = vec!["--nocapture".to_owned()],
899899
900900 /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
901901 /// projects, or "discover" to try to automatically find it if the `rustc-dev` component
......@@ -1944,8 +1944,9 @@ impl Config {
19441944 fn insert_use_config(&self, source_root: Option<SourceRootId>) -> InsertUseConfig {
19451945 InsertUseConfig {
19461946 granularity: match self.imports_granularity_group(source_root) {
1947 ImportGranularityDef::Preserve => ImportGranularity::Preserve,
1948 ImportGranularityDef::Item => ImportGranularity::Item,
1947 ImportGranularityDef::Item | ImportGranularityDef::Preserve => {
1948 ImportGranularity::Item
1949 }
19491950 ImportGranularityDef::Crate => ImportGranularity::Crate,
19501951 ImportGranularityDef::Module => ImportGranularity::Module,
19511952 ImportGranularityDef::One => ImportGranularity::One,
......@@ -3504,13 +3505,23 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
35043505 },
35053506 "ImportGranularityDef" => set! {
35063507 "type": "string",
3507 "enum": ["preserve", "crate", "module", "item", "one"],
3508 "enumDescriptions": [
3509 "Do not change the granularity of any imports and preserve the original structure written by the developer.",
3510 "Merge imports from the same crate into a single use statement. Conversely, imports from different crates are split into separate statements.",
3511 "Merge imports from the same module into a single use statement. Conversely, imports from different modules are split into separate statements.",
3512 "Flatten imports so that each has its own use statement.",
3513 "Merge all imports into a single use statement as long as they have the same visibility and attributes."
3508 "anyOf": [
3509 {
3510 "enum": ["crate", "module", "item", "one"],
3511 "enumDescriptions": [
3512 "Merge imports from the same crate into a single use statement. Conversely, imports from different crates are split into separate statements.",
3513 "Merge imports from the same module into a single use statement. Conversely, imports from different modules are split into separate statements.",
3514 "Flatten imports so that each has its own use statement.",
3515 "Merge all imports into a single use statement as long as they have the same visibility and attributes."
3516 ],
3517 },
3518 {
3519 "enum": ["preserve"],
3520 "enumDescriptions": [
3521 "Deprecated - unless `enforceGranularity` is `true`, the style of the current file is preferred over this setting. Behaves like `item`.",
3522 ],
3523 "deprecated": true,
3524 }
35143525 ],
35153526 },
35163527 "ImportPrefixDef" => set! {
src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs+1-1
......@@ -67,7 +67,7 @@ impl DiscoverCommand {
6767 cmd.args(args);
6868
6969 Ok(DiscoverHandle {
70 _handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone())?,
70 _handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone(), None)?,
7171 span: info_span!("discover_command").entered(),
7272 })
7373 }
src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs+16-1
......@@ -423,7 +423,21 @@ impl FlycheckActor {
423423
424424 tracing::debug!(?command, "will restart flycheck");
425425 let (sender, receiver) = unbounded();
426 match CommandHandle::spawn(command, CargoCheckParser, sender) {
426 match CommandHandle::spawn(
427 command,
428 CargoCheckParser,
429 sender,
430 match &self.config {
431 FlycheckConfig::CargoCommand { options, .. } => Some(
432 options
433 .target_dir
434 .as_deref()
435 .unwrap_or("target".as_ref())
436 .join(format!("rust-analyzer/flycheck{}", self.id)),
437 ),
438 _ => None,
439 },
440 ) {
427441 Ok(command_handle) => {
428442 tracing::debug!(command = formatted_command, "did restart flycheck");
429443 self.command_handle = Some(command_handle);
......@@ -622,6 +636,7 @@ impl FlycheckActor {
622636 {
623637 cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(sysroot_root));
624638 }
639 cmd.env("CARGO_LOG", "cargo::core::compiler::fingerprint=info");
625640 cmd.arg(command);
626641
627642 match scope {
src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs+2
......@@ -9,6 +9,8 @@
99//! The `cli` submodule implements some batch-processing analysis, primarily as
1010//! a debugging aid.
1111
12extern crate ra_ap_rustc_type_ir as rustc_type_ir;
13
1214/// Any toolchain less than this version will likely not work with rust-analyzer built from this revision.
1315pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version {
1416 major: 1,
src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs+6-1
......@@ -136,7 +136,12 @@ impl CargoTestHandle {
136136 }
137137
138138 Ok(Self {
139 _handle: CommandHandle::spawn(cmd, CargoTestOutputParser::new(&test_target), sender)?,
139 _handle: CommandHandle::spawn(
140 cmd,
141 CargoTestOutputParser::new(&test_target),
142 sender,
143 None,
144 )?,
140145 })
141146 }
142147}
src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs+2-2
......@@ -256,7 +256,7 @@ fn main() {}
256256 {
257257 "args": {
258258 "cargoArgs": ["test", "--package", "foo", "--test", "spam"],
259 "executableArgs": ["test_eggs", "--exact", "--show-output"],
259 "executableArgs": ["test_eggs", "--exact", "--nocapture"],
260260 "overrideCargo": null,
261261 "cwd": server.path().join("foo"),
262262 "workspaceRoot": server.path().join("foo")
......@@ -289,7 +289,7 @@ fn main() {}
289289 ],
290290 "executableArgs": [
291291 "",
292 "--show-output"
292 "--nocapture"
293293 ]
294294 },
295295 "kind": "cargo",
src/tools/rust-analyzer/crates/span/src/hygiene.rs+73-24
......@@ -67,6 +67,16 @@ const _: () = {
6767 self.parent.hash(state);
6868 }
6969 }
70
71 impl zalsa_::HasJar for SyntaxContext {
72 type Jar = zalsa_struct_::JarImpl<SyntaxContext>;
73 const KIND: zalsa_::JarKind = zalsa_::JarKind::Struct;
74 }
75
76 zalsa_::register_jar! {
77 zalsa_::ErasedJar::erase::<SyntaxContext>()
78 }
79
7080 /// Key to use during hash lookups. Each field is some type that implements `Lookup<T>`
7181 /// for the owned type. This permits interning with an `&str` when a `String` is required and so forth.
7282 #[derive(Hash)]
......@@ -98,21 +108,38 @@ const _: () = {
98108 salsa::plumbing::Location { file: file!(), line: line!() };
99109 const DEBUG_NAME: &'static str = "SyntaxContextData";
100110 const REVISIONS: std::num::NonZeroUsize = std::num::NonZeroUsize::MAX;
111 const PERSIST: bool = false;
112
101113 type Fields<'a> = SyntaxContextData;
102114 type Struct<'a> = SyntaxContext;
103 }
104 impl SyntaxContext {
105 pub fn ingredient<Db>(db: &Db) -> &zalsa_struct_::IngredientImpl<Self>
115
116 fn serialize<S>(_: &Self::Fields<'_>, _: S) -> Result<S::Ok, S::Error>
106117 where
107 Db: ?Sized + zalsa_::Database,
118 S: zalsa_::serde::Serializer,
119 {
120 unimplemented!("attempted to serialize value that set `PERSIST` to false")
121 }
122
123 fn deserialize<'de, D>(_: D) -> Result<Self::Fields<'static>, D::Error>
124 where
125 D: zalsa_::serde::Deserializer<'de>,
108126 {
127 unimplemented!("attempted to deserialize value that cannot set `PERSIST` to false");
128 }
129 }
130
131 impl SyntaxContext {
132 pub fn ingredient(zalsa: &zalsa_::Zalsa) -> &zalsa_struct_::IngredientImpl<Self> {
109133 static CACHE: zalsa_::IngredientCache<zalsa_struct_::IngredientImpl<SyntaxContext>> =
110134 zalsa_::IngredientCache::new();
111 CACHE.get_or_create(db.zalsa(), || {
112 db.zalsa()
113 .lookup_jar_by_type::<zalsa_struct_::JarImpl<SyntaxContext>>()
114 .get_or_create()
115 })
135
136 // SAFETY: `lookup_jar_by_type` returns a valid ingredient index, and the only
137 // ingredient created by our jar is the struct ingredient.
138 unsafe {
139 CACHE.get_or_create(zalsa, || {
140 zalsa.lookup_jar_by_type::<zalsa_struct_::JarImpl<SyntaxContext>>()
141 })
142 }
116143 }
117144 }
118145 impl zalsa_::AsId for SyntaxContext {
......@@ -132,13 +159,14 @@ const _: () = {
132159 impl zalsa_::SalsaStructInDb for SyntaxContext {
133160 type MemoIngredientMap = salsa::plumbing::MemoIngredientSingletonIndex;
134161
135 fn lookup_or_create_ingredient_index(
136 zalsa: &salsa::plumbing::Zalsa,
137 ) -> salsa::plumbing::IngredientIndices {
138 zalsa
139 .lookup_jar_by_type::<zalsa_struct_::JarImpl<SyntaxContext>>()
140 .get_or_create()
141 .into()
162 fn lookup_ingredient_index(aux: &zalsa_::Zalsa) -> salsa::plumbing::IngredientIndices {
163 aux.lookup_jar_by_type::<zalsa_struct_::JarImpl<SyntaxContext>>().into()
164 }
165
166 fn entries(zalsa: &zalsa_::Zalsa) -> impl Iterator<Item = zalsa_::DatabaseKeyIndex> + '_ {
167 let _ingredient_index =
168 zalsa.lookup_jar_by_type::<zalsa_struct_::JarImpl<SyntaxContext>>();
169 <SyntaxContext>::ingredient(zalsa).entries(zalsa).map(|entry| entry.key())
142170 }
143171
144172 #[inline]
......@@ -149,6 +177,18 @@ const _: () = {
149177 None
150178 }
151179 }
180
181 #[inline]
182 unsafe fn memo_table(
183 zalsa: &zalsa_::Zalsa,
184 id: zalsa_::Id,
185 current_revision: zalsa_::Revision,
186 ) -> zalsa_::MemoTableWithTypes<'_> {
187 // SAFETY: Guaranteed by caller.
188 unsafe {
189 zalsa.table().memos::<zalsa_struct_::Value<SyntaxContext>>(id, current_revision)
190 }
191 }
152192 }
153193
154194 unsafe impl salsa::plumbing::Update for SyntaxContext {
......@@ -184,8 +224,11 @@ const _: () = {
184224 Edition: zalsa_::interned::HashEqLike<T2>,
185225 SyntaxContext: zalsa_::interned::HashEqLike<T3>,
186226 {
187 SyntaxContext::ingredient(db).intern(
188 db.as_dyn_database(),
227 let (zalsa, zalsa_local) = db.zalsas();
228
229 SyntaxContext::ingredient(zalsa).intern(
230 zalsa,
231 zalsa_local,
189232 StructKey::<'db>(
190233 outer_expn,
191234 outer_transparency,
......@@ -216,7 +259,8 @@ const _: () = {
216259 Db: ?Sized + zalsa_::Database,
217260 {
218261 let id = self.as_salsa_id()?;
219 let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id);
262 let zalsa = db.zalsa();
263 let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id);
220264 fields.outer_expn
221265 }
222266
......@@ -225,7 +269,8 @@ const _: () = {
225269 Db: ?Sized + zalsa_::Database,
226270 {
227271 let Some(id) = self.as_salsa_id() else { return Transparency::Opaque };
228 let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id);
272 let zalsa = db.zalsa();
273 let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id);
229274 fields.outer_transparency
230275 }
231276
......@@ -235,7 +280,8 @@ const _: () = {
235280 {
236281 match self.as_salsa_id() {
237282 Some(id) => {
238 let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id);
283 let zalsa = db.zalsa();
284 let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id);
239285 fields.edition
240286 }
241287 None => Edition::from_u32(SyntaxContext::MAX_ID - self.into_u32()),
......@@ -248,7 +294,8 @@ const _: () = {
248294 {
249295 match self.as_salsa_id() {
250296 Some(id) => {
251 let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id);
297 let zalsa = db.zalsa();
298 let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id);
252299 fields.parent
253300 }
254301 None => self,
......@@ -262,7 +309,8 @@ const _: () = {
262309 {
263310 match self.as_salsa_id() {
264311 Some(id) => {
265 let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id);
312 let zalsa = db.zalsa();
313 let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id);
266314 fields.opaque
267315 }
268316 None => self,
......@@ -276,7 +324,8 @@ const _: () = {
276324 {
277325 match self.as_salsa_id() {
278326 Some(id) => {
279 let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id);
327 let zalsa = db.zalsa();
328 let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id);
280329 fields.opaque_and_semitransparent
281330 }
282331 None => self,
src/tools/rust-analyzer/crates/stdx/src/thread.rs-1
......@@ -101,7 +101,6 @@ impl<T> Drop for JoinHandle<T> {
101101 }
102102}
103103
104#[expect(clippy::min_ident_chars, reason = "trait impl")]
105104impl<T> fmt::Debug for JoinHandle<T> {
106105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107106 f.pad("JoinHandle { .. }")
src/tools/rust-analyzer/crates/syntax/src/ast.rs+3-1
......@@ -29,7 +29,9 @@ pub use self::{
2929 SlicePatComponents, StructKind, TypeBoundKind, TypeOrConstParam, VisibilityKind,
3030 },
3131 operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp},
32 token_ext::{CommentKind, CommentPlacement, CommentShape, IsString, QuoteOffsets, Radix},
32 token_ext::{
33 AnyString, CommentKind, CommentPlacement, CommentShape, IsString, QuoteOffsets, Radix,
34 },
3335 traits::{
3436 AttrDocCommentIter, DocCommentIter, HasArgList, HasAttrs, HasDocComments, HasGenericArgs,
3537 HasGenericParams, HasLoopBody, HasModuleItem, HasName, HasTypeBounds, HasVisibility,
src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs+84-10
......@@ -151,10 +151,10 @@ impl QuoteOffsets {
151151}
152152
153153pub trait IsString: AstToken {
154 const RAW_PREFIX: &'static str;
155 fn unescape(s: &str, callback: impl FnMut(Range<usize>, Result<char, EscapeError>));
154 fn raw_prefix(&self) -> &'static str;
155 fn unescape(&self, s: &str, callback: impl FnMut(Range<usize>, Result<char, EscapeError>));
156156 fn is_raw(&self) -> bool {
157 self.text().starts_with(Self::RAW_PREFIX)
157 self.text().starts_with(self.raw_prefix())
158158 }
159159 fn quote_offsets(&self) -> Option<QuoteOffsets> {
160160 let text = self.text();
......@@ -187,7 +187,7 @@ pub trait IsString: AstToken {
187187 let text = &self.text()[text_range_no_quotes - start];
188188 let offset = text_range_no_quotes.start() - start;
189189
190 Self::unescape(text, &mut |range: Range<usize>, unescaped_char| {
190 self.unescape(text, &mut |range: Range<usize>, unescaped_char| {
191191 if let Some((s, e)) = range.start.try_into().ok().zip(range.end.try_into().ok()) {
192192 cb(TextRange::new(s, e) + offset, unescaped_char);
193193 }
......@@ -204,8 +204,10 @@ pub trait IsString: AstToken {
204204}
205205
206206impl IsString for ast::String {
207 const RAW_PREFIX: &'static str = "r";
208 fn unescape(s: &str, cb: impl FnMut(Range<usize>, Result<char, EscapeError>)) {
207 fn raw_prefix(&self) -> &'static str {
208 "r"
209 }
210 fn unescape(&self, s: &str, cb: impl FnMut(Range<usize>, Result<char, EscapeError>)) {
209211 unescape_str(s, cb)
210212 }
211213}
......@@ -246,8 +248,10 @@ impl ast::String {
246248}
247249
248250impl IsString for ast::ByteString {
249 const RAW_PREFIX: &'static str = "br";
250 fn unescape(s: &str, mut callback: impl FnMut(Range<usize>, Result<char, EscapeError>)) {
251 fn raw_prefix(&self) -> &'static str {
252 "br"
253 }
254 fn unescape(&self, s: &str, mut callback: impl FnMut(Range<usize>, Result<char, EscapeError>)) {
251255 unescape_byte_str(s, |range, res| callback(range, res.map(char::from)))
252256 }
253257}
......@@ -288,10 +292,12 @@ impl ast::ByteString {
288292}
289293
290294impl IsString for ast::CString {
291 const RAW_PREFIX: &'static str = "cr";
295 fn raw_prefix(&self) -> &'static str {
296 "cr"
297 }
292298 // NOTE: This method should only be used for highlighting ranges. The unescaped
293299 // char/byte is not used. For simplicity, we return an arbitrary placeholder char.
294 fn unescape(s: &str, mut callback: impl FnMut(Range<usize>, Result<char, EscapeError>)) {
300 fn unescape(&self, s: &str, mut callback: impl FnMut(Range<usize>, Result<char, EscapeError>)) {
295301 unescape_c_str(s, |range, _res| callback(range, Ok('_')))
296302 }
297303}
......@@ -465,6 +471,74 @@ impl ast::Byte {
465471 }
466472}
467473
474pub enum AnyString {
475 ByteString(ast::ByteString),
476 CString(ast::CString),
477 String(ast::String),
478}
479
480impl AnyString {
481 pub fn value(&self) -> Result<Cow<'_, str>, EscapeError> {
482 fn from_utf8(s: Cow<'_, [u8]>) -> Result<Cow<'_, str>, EscapeError> {
483 match s {
484 Cow::Borrowed(s) => str::from_utf8(s)
485 .map_err(|_| EscapeError::NonAsciiCharInByte)
486 .map(Cow::Borrowed),
487 Cow::Owned(s) => String::from_utf8(s)
488 .map_err(|_| EscapeError::NonAsciiCharInByte)
489 .map(Cow::Owned),
490 }
491 }
492
493 match self {
494 AnyString::String(s) => s.value(),
495 AnyString::ByteString(s) => s.value().and_then(from_utf8),
496 AnyString::CString(s) => s.value().and_then(from_utf8),
497 }
498 }
499}
500
501impl ast::AstToken for AnyString {
502 fn can_cast(kind: crate::SyntaxKind) -> bool {
503 ast::String::can_cast(kind)
504 || ast::ByteString::can_cast(kind)
505 || ast::CString::can_cast(kind)
506 }
507
508 fn cast(syntax: crate::SyntaxToken) -> Option<Self> {
509 ast::String::cast(syntax.clone())
510 .map(Self::String)
511 .or_else(|| ast::ByteString::cast(syntax.clone()).map(Self::ByteString))
512 .or_else(|| ast::CString::cast(syntax).map(Self::CString))
513 }
514
515 fn syntax(&self) -> &crate::SyntaxToken {
516 match self {
517 Self::ByteString(it) => it.syntax(),
518 Self::CString(it) => it.syntax(),
519 Self::String(it) => it.syntax(),
520 }
521 }
522}
523
524impl IsString for AnyString {
525 fn raw_prefix(&self) -> &'static str {
526 match self {
527 AnyString::ByteString(s) => s.raw_prefix(),
528 AnyString::CString(s) => s.raw_prefix(),
529 AnyString::String(s) => s.raw_prefix(),
530 }
531 }
532
533 fn unescape(&self, s: &str, callback: impl FnMut(Range<usize>, Result<char, EscapeError>)) {
534 match self {
535 AnyString::ByteString(it) => it.unescape(s, callback),
536 AnyString::CString(it) => it.unescape(s, callback),
537 AnyString::String(it) => it.unescape(s, callback),
538 }
539 }
540}
541
468542#[cfg(test)]
469543mod tests {
470544 use rustc_apfloat::ieee::Quad as f128;
src/tools/rust-analyzer/crates/toolchain/src/lib.rs+4
......@@ -71,6 +71,9 @@ impl Tool {
7171 }
7272}
7373
74// Prevent rustup from automatically installing toolchains, see https://github.com/rust-lang/rust-analyzer/issues/20719.
75pub const NO_RUSTUP_AUTO_INSTALL_ENV: (&str, &str) = ("RUSTUP_AUTO_INSTALL", "0");
76
7477#[allow(clippy::disallowed_types)] /* generic parameter allows for FxHashMap */
7578pub fn command<H>(
7679 cmd: impl AsRef<OsStr>,
......@@ -81,6 +84,7 @@ pub fn command<H>(
8184 #[allow(clippy::disallowed_methods)]
8285 let mut cmd = Command::new(cmd);
8386 cmd.current_dir(working_directory);
87 cmd.env(NO_RUSTUP_AUTO_INSTALL_ENV.0, NO_RUSTUP_AUTO_INSTALL_ENV.1);
8488 for env in extra_env {
8589 match env {
8690 (key, Some(val)) => cmd.env(key, val),
src/tools/rust-analyzer/docs/book/src/configuration.md+6-1
......@@ -13,7 +13,7 @@ Vim](./other_editors.md#coc-rust-analyzer) provide `rust-analyzer` specific conf
1313UIs. Others may require you to know a bit more about the interaction
1414with `rust-analyzer`.
1515
16For the later category, it might help to know that the initial
16For the latter category, it might help to know that the initial
1717configuration is specified as a value of the `initializationOptions`
1818field of the [`InitializeParams` message, in the LSP
1919protocol](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#initialize).
......@@ -46,6 +46,11 @@ To verify which configuration is actually used by `rust-analyzer`, set
4646config-related messages. Logs should show both the JSON that
4747`rust-analyzer` sees as well as the updated config.
4848
49(Work in progress:) It is also possible to place configuration in a
50`rust-analyzer.toml` file. It should be located in the project root or in your
51user configuration directory (e.g. `~/.config/rust-analyzer/`). This is a work in
52progress, many configuration options aren't supported yet.
53
4954This is the list of config options `rust-analyzer` supports:
5055
5156{{#include configuration_generated.md}}
src/tools/rust-analyzer/docs/book/src/configuration_generated.md+1-1
......@@ -1323,7 +1323,7 @@ tests or binaries. For example, it may be `--release`.
13231323Default:
13241324```json
13251325[
1326 "--show-output"
1326 "--nocapture"
13271327]
13281328```
13291329
src/tools/rust-analyzer/docs/book/src/contributing/guide.md+1-1
......@@ -235,7 +235,7 @@ of type `V`. Queries come in two basic varieties:
235235 intelligently) when we can re-use these memoized values and when we have to
236236 recompute them.
237237
238For further discussion, its important to understand one bit of "fairly
238For further discussion, it's important to understand one bit of "fairly
239239intelligently". Suppose we have two functions, `f1` and `f2`, and one input,
240240`z`. We call `f1(X)` which in turn calls `f2(Y)` which inspects `i(Z)`. `i(Z)`
241241returns some value `V1`, `f2` uses that and returns `R1`, `f1` uses that and
src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md+11-11
......@@ -455,7 +455,7 @@ interface TestItem {
455455 // A human readable name for this test
456456 label: string;
457457 // The kind of this test item. Based on the kind,
458 // an icon is chosen by the editor.
458 // an icon is chosen by the editor.
459459 kind: "package" | "module" | "test";
460460 // True if this test may have children not available eagerly
461461 canResolveChildren: boolean;
......@@ -467,7 +467,7 @@ interface TestItem {
467467 // like debugging, this field is useful.
468468 // Note that this field includes some information about label and location as well, but
469469 // those exist just for keeping things in sync with other methods of running runnables
470 // (for example using one consistent name in the vscode's launch.json) so for any propose
470 // (for example using one consistent name in the vscode's launch.json) so for any purpose
471471 // other than running tests this field should not be used.
472472 runnable?: Runnable | undefined;
473473};
......@@ -475,11 +475,11 @@ interface TestItem {
475475interface DiscoverTestResults {
476476 // The discovered tests.
477477 tests: TestItem[];
478 // For each test which its id is in this list, the response
478 // For each test whose id is in this list, the response
479479 // contains all tests that are children of this test, and
480480 // client should remove old tests not included in the response.
481481 scope: string[] | undefined;
482 // For each file which its uri is in this list, the response
482 // For each file whose uri is in this list, the response
483483 // contains all tests that are located in this file, and
484484 // client should remove old tests not included in the response.
485485 scopeFile: lc.TextDocumentIdentifier[] | undefined;
......@@ -491,7 +491,7 @@ interface DiscoverTestResults {
491491**Notification:** `DiscoverTestResults`
492492
493493This notification is sent from the server to the client when the
494server detect changes in the existing tests. The `DiscoverTestResults` is
494server detects changes in the existing tests. The `DiscoverTestResults` is
495495the same as the one in `experimental/discoverTest` response.
496496
497497**Method:** `experimental/runTest`
......@@ -527,7 +527,7 @@ after this.
527527
528528This notification is sent from the client to the server when the user is no longer
529529interested in the test results. The server should clean up its resources and send
530a `experimental/endRunTest` when is done.
530a `experimental/endRunTest` when it is done.
531531
532532**Method:** `experimental/changeTestState`
533533
......@@ -648,8 +648,8 @@ interface ServerStatusParams {
648648```
649649
650650This notification is sent from server to client.
651The client can use it to display *persistent* status to the user (in modline).
652It is similar to the `showMessage`, but is intended for stares rather than point-in-time events.
651The client can use it to display *persistent* status to the user (in the mode line).
652It is similar to the `showMessage`, but is intended for status rather than point-in-time events.
653653
654654Note that this functionality is intended primarily to inform the end user about the state of the server.
655655In particular, it's valid for the client to completely ignore this extension.
......@@ -1070,13 +1070,13 @@ export interface RecursiveMemoryLayoutNode = {
10701070 size: number;
10711071 /// Alignment of the type in bytes
10721072 alignment: number;
1073 /// Offset of the type relative to its parent (or 0 if its the root)
1073 /// Offset of the type relative to its parent (or 0 if it's the root)
10741074 offset: number;
1075 /// Index of the node's parent (or -1 if its the root)
1075 /// Index of the node's parent (or -1 if it's the root)
10761076 parent_idx: number;
10771077 /// Index of the node's children (or -1 if it does not have children)
10781078 children_start: number;
1079 /// Number of child nodes (unspecified it does not have children)
1079 /// Number of child nodes (unspecified if it does not have children)
10801080 children_len: number;
10811081};
10821082
src/tools/rust-analyzer/docs/book/src/contributing/syntax.md+1-1
......@@ -192,7 +192,7 @@ Modeling this with immutable trees is possible, but annoying.
192192
193193A function green tree is not super-convenient to use.
194194The biggest problem is accessing parents (there are no parent pointers!).
195But there are also "identify" issues.
195But there are also "identity" issues.
196196Let's say you want to write a code which builds a list of expressions in a file: `fn collect_expressions(file: GreenNode) -> HashSet<GreenNode>`.
197197For the input like
198198
src/tools/rust-analyzer/editors/code/package.json+25-14
......@@ -2009,19 +2009,30 @@
20092009 "markdownDescription": "How imports should be grouped into use statements.",
20102010 "default": "crate",
20112011 "type": "string",
2012 "enum": [
2013 "preserve",
2014 "crate",
2015 "module",
2016 "item",
2017 "one"
2018 ],
2019 "enumDescriptions": [
2020 "Do not change the granularity of any imports and preserve the original structure written by the developer.",
2021 "Merge imports from the same crate into a single use statement. Conversely, imports from different crates are split into separate statements.",
2022 "Merge imports from the same module into a single use statement. Conversely, imports from different modules are split into separate statements.",
2023 "Flatten imports so that each has its own use statement.",
2024 "Merge all imports into a single use statement as long as they have the same visibility and attributes."
2012 "anyOf": [
2013 {
2014 "enum": [
2015 "crate",
2016 "module",
2017 "item",
2018 "one"
2019 ],
2020 "enumDescriptions": [
2021 "Merge imports from the same crate into a single use statement. Conversely, imports from different crates are split into separate statements.",
2022 "Merge imports from the same module into a single use statement. Conversely, imports from different modules are split into separate statements.",
2023 "Flatten imports so that each has its own use statement.",
2024 "Merge all imports into a single use statement as long as they have the same visibility and attributes."
2025 ]
2026 },
2027 {
2028 "enum": [
2029 "preserve"
2030 ],
2031 "enumDescriptions": [
2032 "Deprecated - unless `enforceGranularity` is `true`, the style of the current file is preferred over this setting. Behaves like `item`."
2033 ],
2034 "deprecated": true
2035 }
20252036 ]
20262037 }
20272038 }
......@@ -2789,7 +2800,7 @@
27892800 "rust-analyzer.runnables.extraTestBinaryArgs": {
27902801 "markdownDescription": "Additional arguments to be passed through Cargo to launched tests, benchmarks, or\ndoc-tests.\n\nUnless the launched target uses a\n[custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field),\nthey will end up being interpreted as options to\n[`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).",
27912802 "default": [
2792 "--show-output"
2803 "--nocapture"
27932804 ],
27942805 "type": "array",
27952806 "items": {
src/tools/rust-analyzer/josh-sync.toml+4
......@@ -1,2 +1,6 @@
11repo = "rust-analyzer"
22filter = ":rev(55d9a533b309119c8acd13061581b43ae8840823:prefix=src/tools/rust-analyzer):/src/tools/rust-analyzer"
3
4[[post-pull]]
5cmd = ["cargo", "fmt"]
6commit-message = "Format code"
src/tools/rust-analyzer/rust-version+1-1
......@@ -1 +1 @@
1f957826bff7a68b267ce75b1ea56352aed0cca0a
1fb24b04b096a980bffd80154f6aba22fd07cb3d9
src/tools/rust-analyzer/xtask/src/install.rs+2-2
......@@ -145,12 +145,12 @@ fn install_server(sh: &Shell, opts: ServerOpt) -> anyhow::Result<()> {
145145 );
146146
147147 if let Some(train_crate) = opts.pgo {
148 let target = detect_target(sh);
148149 let build_cmd = cmd!(
149150 sh,
150 "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --profile={profile} --locked --features force-always-assert {features...}"
151 "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target} --profile={profile} --locked --features force-always-assert {features...}"
151152 );
152153
153 let target = detect_target(sh);
154154 let profile = crate::pgo::gather_pgo_profile(sh, build_cmd, &target, train_crate)?;
155155 install_cmd = crate::pgo::apply_pgo_to_cmd(install_cmd, &profile);
156156 }
src/tools/rust-analyzer/xtask/src/pgo.rs+17-8
......@@ -53,14 +53,23 @@ pub(crate) fn gather_pgo_profile<'a>(
5353
5454 // Merge profiles into a single file
5555 let merged_profile = pgo_dir.join("merged.profdata");
56 let profile_files = std::fs::read_dir(pgo_dir)?.filter_map(|entry| {
57 let entry = entry.ok()?;
58 if entry.path().extension() == Some(OsStr::new("profraw")) {
59 Some(entry.path().to_str().unwrap().to_owned())
60 } else {
61 None
62 }
63 });
56 let profile_files = std::fs::read_dir(pgo_dir)?
57 .filter_map(|entry| {
58 let entry = entry.ok()?;
59 if entry.path().extension() == Some(OsStr::new("profraw")) {
60 Some(entry.path().to_str().unwrap().to_owned())
61 } else {
62 None
63 }
64 })
65 .collect::<Vec<_>>();
66
67 if profile_files.is_empty() {
68 anyhow::bail!(
69 "rust-analyzer analysis-stats produced no pgo files. This is a bug in rust-analyzer; please file an issue."
70 );
71 }
72
6473 cmd!(sh, "{llvm_profdata} merge {profile_files...} -o {merged_profile}").run().context(
6574 "cannot merge PGO profiles. Do you have the rustup `llvm-tools` component installed?",
6675 )?;