aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock72
-rw-r--r--crates/base_db/src/input.rs16
-rw-r--r--crates/cfg/src/dnf.rs8
-rw-r--r--crates/hir/src/display.rs2
-rw-r--r--crates/hir/src/lib.rs225
-rw-r--r--crates/hir/src/semantics.rs4
-rw-r--r--crates/hir_def/src/attr.rs2
-rw-r--r--crates/hir_def/src/body/scope.rs57
-rw-r--r--crates/hir_def/src/find_path.rs56
-rw-r--r--crates/hir_def/src/nameres.rs17
-rw-r--r--crates/hir_def/src/nameres/collector.rs178
-rw-r--r--crates/hir_def/src/nameres/mod_resolution.rs13
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs2
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs21
-rw-r--r--crates/hir_def/src/resolver.rs24
-rw-r--r--crates/hir_expand/src/builtin_macro.rs66
-rw-r--r--crates/hir_expand/src/db.rs2
-rw-r--r--crates/hir_expand/src/eager.rs13
-rw-r--r--crates/hir_expand/src/lib.rs23
-rw-r--r--crates/hir_expand/src/name.rs5
-rw-r--r--crates/hir_ty/src/autoderef.rs51
-rw-r--r--crates/hir_ty/src/db.rs11
-rw-r--r--crates/hir_ty/src/display.rs65
-rw-r--r--crates/hir_ty/src/infer.rs2
-rw-r--r--crates/hir_ty/src/infer/coerce.rs6
-rw-r--r--crates/hir_ty/src/infer/expr.rs27
-rw-r--r--crates/hir_ty/src/infer/pat.rs34
-rw-r--r--crates/hir_ty/src/infer/unify.rs66
-rw-r--r--crates/hir_ty/src/lib.rs138
-rw-r--r--crates/hir_ty/src/lower.rs109
-rw-r--r--crates/hir_ty/src/method_resolution.rs53
-rw-r--r--crates/hir_ty/src/tests.rs69
-rw-r--r--crates/hir_ty/src/tests/macros.rs23
-rw-r--r--crates/hir_ty/src/tests/patterns.rs22
-rw-r--r--crates/hir_ty/src/tests/regression.rs13
-rw-r--r--crates/hir_ty/src/tests/traits.rs96
-rw-r--r--crates/hir_ty/src/traits.rs17
-rw-r--r--crates/hir_ty/src/traits/chalk.rs20
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs124
-rw-r--r--crates/hir_ty/src/utils.rs10
-rw-r--r--crates/ide/src/annotations.rs46
-rw-r--r--crates/ide/src/call_hierarchy.rs11
-rw-r--r--crates/ide/src/diagnostics/unlinked_file.rs4
-rw-r--r--crates/ide/src/doc_links.rs260
-rw-r--r--crates/ide/src/extend_selection.rs7
-rw-r--r--crates/ide/src/goto_definition.rs66
-rw-r--r--crates/ide/src/hover.rs63
-rw-r--r--crates/ide/src/lib.rs10
-rw-r--r--crates/ide/src/move_item.rs620
-rw-r--r--crates/ide/src/references.rs30
-rw-r--r--crates/ide/src/references/rename.rs152
-rw-r--r--crates/ide/src/runnables.rs28
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs8
-rw-r--r--crates/ide_assists/src/assist_context.rs44
-rw-r--r--crates/ide_assists/src/handlers/add_explicit_type.rs90
-rw-r--r--crates/ide_assists/src/handlers/add_lifetime_to_type.rs70
-rw-r--r--crates/ide_assists/src/handlers/add_missing_impl_members.rs6
-rw-r--r--crates/ide_assists/src/handlers/convert_comment_block.rs51
-rw-r--r--crates/ide_assists/src/handlers/early_return.rs89
-rw-r--r--crates/ide_assists/src/handlers/expand_glob_import.rs19
-rw-r--r--crates/ide_assists/src/handlers/merge_imports.rs43
-rw-r--r--crates/ide_assists/src/handlers/move_bounds.rs8
-rw-r--r--crates/ide_assists/src/handlers/qualify_path.rs1
-rw-r--r--crates/ide_assists/src/handlers/reorder_fields.rs112
-rw-r--r--crates/ide_assists/src/handlers/reorder_impl.rs2
-rw-r--r--crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs34
-rw-r--r--crates/ide_assists/src/handlers/unmerge_use.rs30
-rw-r--r--crates/ide_assists/src/handlers/unwrap_block.rs76
-rw-r--r--crates/ide_completion/src/completions.rs42
-rw-r--r--crates/ide_completion/src/completions/attribute.rs3
-rw-r--r--crates/ide_completion/src/completions/dot.rs2
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs93
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs316
-rw-r--r--crates/ide_completion/src/completions/pattern.rs2
-rw-r--r--crates/ide_completion/src/context.rs90
-rw-r--r--crates/ide_completion/src/lib.rs29
-rw-r--r--crates/ide_completion/src/patterns.rs2
-rw-r--r--crates/ide_completion/src/render.rs50
-rw-r--r--crates/ide_completion/src/render/function.rs23
-rw-r--r--crates/ide_db/src/apply_change.rs1
-rw-r--r--crates/ide_db/src/call_info.rs14
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs212
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs8
-rw-r--r--crates/ide_db/src/items_locator.rs178
-rw-r--r--crates/ide_db/src/search.rs170
-rw-r--r--crates/ide_db/src/symbol_index.rs16
-rw-r--r--crates/ide_ssr/src/parsing.rs2
-rw-r--r--crates/mbe/src/expander/matcher.rs13
-rw-r--r--crates/mbe/src/lib.rs2
-rw-r--r--crates/mbe/src/parser.rs14
-rw-r--r--crates/mbe/src/subtree_source.rs1
-rw-r--r--crates/mbe/src/syntax_bridge.rs9
-rw-r--r--crates/mbe/src/tests/expand.rs9
-rw-r--r--crates/mbe/src/tests/rule.rs4
-rw-r--r--crates/mbe/src/tt_iter.rs7
-rw-r--r--crates/proc_macro_api/src/msg.rs35
-rw-r--r--crates/proc_macro_api/src/process.rs7
-rw-r--r--crates/proc_macro_api/src/rpc.rs30
-rw-r--r--crates/proc_macro_srv/src/cli.rs7
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs9
-rw-r--r--crates/project_model/src/build_data.rs91
-rw-r--r--crates/rust-analyzer/src/caps.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs7
-rw-r--r--crates/rust-analyzer/src/handlers.rs19
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs22
-rw-r--r--crates/rust-analyzer/src/main_loop.rs8
-rw-r--r--crates/rust-analyzer/src/reload.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs18
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/main.rs4
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/support.rs2
-rw-r--r--crates/syntax/Cargo.toml2
-rw-r--r--crates/syntax/src/algo.rs4
-rw-r--r--crates/syntax/src/ast/edit.rs52
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs44
-rw-r--r--crates/syntax/src/ast/expr_ext.rs44
-rw-r--r--crates/syntax/src/ast/make.rs4
-rw-r--r--crates/syntax/src/ast/node_ext.rs28
-rw-r--r--crates/syntax/src/ast/token_ext.rs10
-rw-r--r--crates/syntax/src/fuzz.rs2
-rw-r--r--crates/syntax/src/ted.rs28
-rw-r--r--crates/syntax/src/validation.rs4
-rw-r--r--crates/tt/src/lib.rs3
-rw-r--r--docs/dev/README.md3
-rw-r--r--docs/dev/lsp-extensions.md28
-rw-r--r--docs/user/generated_config.adoc4
-rw-r--r--docs/user/manual.adoc14
-rw-r--r--editors/code/package.json14
-rw-r--r--editors/code/src/commands.ts45
-rw-r--r--editors/code/src/lsp_ext.ts13
-rw-r--r--editors/code/src/main.ts2
-rw-r--r--xtask/src/codegen/gen_assists_docs.rs4
-rw-r--r--xtask/src/codegen/gen_parser_tests.rs10
-rw-r--r--xtask/src/codegen/gen_syntax.rs2
-rw-r--r--xtask/src/main.rs2
-rw-r--r--xtask/src/metrics.rs2
-rw-r--r--xtask/src/tidy.rs2
136 files changed, 3953 insertions, 1734 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 9f013c275..7f666ca61 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -35,9 +35,9 @@ dependencies = [
35 35
36[[package]] 36[[package]]
37name = "anyhow" 37name = "anyhow"
38version = "1.0.38" 38version = "1.0.39"
39source = "registry+https://github.com/rust-lang/crates.io-index" 39source = "registry+https://github.com/rust-lang/crates.io-index"
40checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" 40checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767"
41 41
42[[package]] 42[[package]]
43name = "anymap" 43name = "anymap"
@@ -111,9 +111,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
111 111
112[[package]] 112[[package]]
113name = "camino" 113name = "camino"
114version = "1.0.2" 114version = "1.0.4"
115source = "registry+https://github.com/rust-lang/crates.io-index" 115source = "registry+https://github.com/rust-lang/crates.io-index"
116checksum = "cd065703998b183ed0b348a22555691373a9345a1431141e5778b48bb17e4703" 116checksum = "d4648c6d00a709aa069a236adcaae4f605a6241c72bf5bee79331a4b625921a9"
117dependencies = [ 117dependencies = [
118 "serde", 118 "serde",
119] 119]
@@ -794,9 +794,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
794 794
795[[package]] 795[[package]]
796name = "libc" 796name = "libc"
797version = "0.2.88" 797version = "0.2.91"
798source = "registry+https://github.com/rust-lang/crates.io-index" 798source = "registry+https://github.com/rust-lang/crates.io-index"
799checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" 799checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
800 800
801[[package]] 801[[package]]
802name = "libloading" 802name = "libloading"
@@ -946,9 +946,9 @@ dependencies = [
946 946
947[[package]] 947[[package]]
948name = "mio" 948name = "mio"
949version = "0.7.9" 949version = "0.7.11"
950source = "registry+https://github.com/rust-lang/crates.io-index" 950source = "registry+https://github.com/rust-lang/crates.io-index"
951checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a" 951checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
952dependencies = [ 952dependencies = [
953 "libc", 953 "libc",
954 "log", 954 "log",
@@ -959,11 +959,10 @@ dependencies = [
959 959
960[[package]] 960[[package]]
961name = "miow" 961name = "miow"
962version = "0.3.6" 962version = "0.3.7"
963source = "registry+https://github.com/rust-lang/crates.io-index" 963source = "registry+https://github.com/rust-lang/crates.io-index"
964checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" 964checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
965dependencies = [ 965dependencies = [
966 "socket2",
967 "winapi", 966 "winapi",
968] 967]
969 968
@@ -1299,9 +1298,9 @@ dependencies = [
1299 1298
1300[[package]] 1299[[package]]
1301name = "regex" 1300name = "regex"
1302version = "1.4.3" 1301version = "1.4.5"
1303source = "registry+https://github.com/rust-lang/crates.io-index" 1302source = "registry+https://github.com/rust-lang/crates.io-index"
1304checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" 1303checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
1305dependencies = [ 1304dependencies = [
1306 "regex-syntax", 1305 "regex-syntax",
1307] 1306]
@@ -1318,15 +1317,15 @@ dependencies = [
1318 1317
1319[[package]] 1318[[package]]
1320name = "regex-syntax" 1319name = "regex-syntax"
1321version = "0.6.22" 1320version = "0.6.23"
1322source = "registry+https://github.com/rust-lang/crates.io-index" 1321source = "registry+https://github.com/rust-lang/crates.io-index"
1323checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" 1322checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
1324 1323
1325[[package]] 1324[[package]]
1326name = "rowan" 1325name = "rowan"
1327version = "0.13.0-pre.2" 1326version = "0.13.0-pre.3"
1328source = "registry+https://github.com/rust-lang/crates.io-index" 1327source = "registry+https://github.com/rust-lang/crates.io-index"
1329checksum = "8f300be7fa17c3fa563d2bc6ab5b1a8d5163162f9111599eda4f86a563714724" 1328checksum = "77d315d6f2e33f294412faa47f41b56bdb3fce72c999d384b5e78c8d21551b13"
1330dependencies = [ 1329dependencies = [
1331 "countme", 1330 "countme",
1332 "hashbrown", 1331 "hashbrown",
@@ -1485,18 +1484,18 @@ dependencies = [
1485 1484
1486[[package]] 1485[[package]]
1487name = "serde" 1486name = "serde"
1488version = "1.0.124" 1487version = "1.0.125"
1489source = "registry+https://github.com/rust-lang/crates.io-index" 1488source = "registry+https://github.com/rust-lang/crates.io-index"
1490checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" 1489checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
1491dependencies = [ 1490dependencies = [
1492 "serde_derive", 1491 "serde_derive",
1493] 1492]
1494 1493
1495[[package]] 1494[[package]]
1496name = "serde_derive" 1495name = "serde_derive"
1497version = "1.0.124" 1496version = "1.0.125"
1498source = "registry+https://github.com/rust-lang/crates.io-index" 1497source = "registry+https://github.com/rust-lang/crates.io-index"
1499checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" 1498checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
1500dependencies = [ 1499dependencies = [
1501 "proc-macro2", 1500 "proc-macro2",
1502 "quote", 1501 "quote",
@@ -1566,17 +1565,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1566checksum = "dc725476a1398f0480d56cd0ad381f6f32acf2642704456f8f59a35df464b59a" 1565checksum = "dc725476a1398f0480d56cd0ad381f6f32acf2642704456f8f59a35df464b59a"
1567 1566
1568[[package]] 1567[[package]]
1569name = "socket2"
1570version = "0.3.19"
1571source = "registry+https://github.com/rust-lang/crates.io-index"
1572checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
1573dependencies = [
1574 "cfg-if",
1575 "libc",
1576 "winapi",
1577]
1578
1579[[package]]
1580name = "stdx" 1568name = "stdx"
1581version = "0.0.0" 1569version = "0.0.0"
1582dependencies = [ 1570dependencies = [
@@ -1586,9 +1574,9 @@ dependencies = [
1586 1574
1587[[package]] 1575[[package]]
1588name = "syn" 1576name = "syn"
1589version = "1.0.63" 1577version = "1.0.64"
1590source = "registry+https://github.com/rust-lang/crates.io-index" 1578source = "registry+https://github.com/rust-lang/crates.io-index"
1591checksum = "8fd9bc7ccc2688b3344c2f48b9b546648b25ce0b20fc717ee7fa7981a8ca9717" 1579checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f"
1592dependencies = [ 1580dependencies = [
1593 "proc-macro2", 1581 "proc-macro2",
1594 "quote", 1582 "quote",
@@ -1718,9 +1706,9 @@ dependencies = [
1718 1706
1719[[package]] 1707[[package]]
1720name = "tracing-attributes" 1708name = "tracing-attributes"
1721version = "0.1.13" 1709version = "0.1.15"
1722source = "registry+https://github.com/rust-lang/crates.io-index" 1710source = "registry+https://github.com/rust-lang/crates.io-index"
1723checksum = "a8a9bd1db7706f2373a190b0d067146caa39350c486f3d455b0e33b431f94c07" 1711checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2"
1724dependencies = [ 1712dependencies = [
1725 "proc-macro2", 1713 "proc-macro2",
1726 "quote", 1714 "quote",
@@ -1759,9 +1747,9 @@ dependencies = [
1759 1747
1760[[package]] 1748[[package]]
1761name = "tracing-subscriber" 1749name = "tracing-subscriber"
1762version = "0.2.16" 1750version = "0.2.17"
1763source = "registry+https://github.com/rust-lang/crates.io-index" 1751source = "registry+https://github.com/rust-lang/crates.io-index"
1764checksum = "8ab8966ac3ca27126141f7999361cc97dd6fb4b71da04c02044fa9045d98bb96" 1752checksum = "705096c6f83bf68ea5d357a6aa01829ddbdac531b357b45abeca842938085baa"
1765dependencies = [ 1753dependencies = [
1766 "ansi_term", 1754 "ansi_term",
1767 "chrono", 1755 "chrono",
@@ -1867,9 +1855,9 @@ dependencies = [
1867 1855
1868[[package]] 1856[[package]]
1869name = "version_check" 1857name = "version_check"
1870version = "0.9.2" 1858version = "0.9.3"
1871source = "registry+https://github.com/rust-lang/crates.io-index" 1859source = "registry+https://github.com/rust-lang/crates.io-index"
1872checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 1860checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
1873 1861
1874[[package]] 1862[[package]]
1875name = "vfs" 1863name = "vfs"
@@ -1896,9 +1884,9 @@ dependencies = [
1896 1884
1897[[package]] 1885[[package]]
1898name = "walkdir" 1886name = "walkdir"
1899version = "2.3.1" 1887version = "2.3.2"
1900source = "registry+https://github.com/rust-lang/crates.io-index" 1888source = "registry+https://github.com/rust-lang/crates.io-index"
1901checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 1889checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
1902dependencies = [ 1890dependencies = [
1903 "same-file", 1891 "same-file",
1904 "winapi", 1892 "winapi",
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index d0def2181..07628935f 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -257,7 +257,8 @@ impl CrateGraph {
257 self.arena.keys().copied() 257 self.arena.keys().copied()
258 } 258 }
259 259
260 /// Returns an iterator over all transitive dependencies of the given crate. 260 /// Returns an iterator over all transitive dependencies of the given crate,
261 /// including the crate itself.
261 pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> + '_ { 262 pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> + '_ {
262 let mut worklist = vec![of]; 263 let mut worklist = vec![of];
263 let mut deps = FxHashSet::default(); 264 let mut deps = FxHashSet::default();
@@ -270,17 +271,16 @@ impl CrateGraph {
270 worklist.extend(self[krate].dependencies.iter().map(|dep| dep.crate_id)); 271 worklist.extend(self[krate].dependencies.iter().map(|dep| dep.crate_id));
271 } 272 }
272 273
273 deps.remove(&of);
274 deps.into_iter() 274 deps.into_iter()
275 } 275 }
276 276
277 /// Returns an iterator over all transitive reverse dependencies of the given crate. 277 /// Returns all transitive reverse dependencies of the given crate,
278 pub fn transitive_reverse_dependencies( 278 /// including the crate itself.
279 &self, 279 pub fn transitive_rev_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> + '_ {
280 of: CrateId,
281 ) -> impl Iterator<Item = CrateId> + '_ {
282 let mut worklist = vec![of]; 280 let mut worklist = vec![of];
283 let mut rev_deps = FxHashSet::default(); 281 let mut rev_deps = FxHashSet::default();
282 rev_deps.insert(of);
283
284 let mut inverted_graph = FxHashMap::<_, Vec<_>>::default(); 284 let mut inverted_graph = FxHashMap::<_, Vec<_>>::default();
285 self.arena.iter().for_each(|(&krate, data)| { 285 self.arena.iter().for_each(|(&krate, data)| {
286 data.dependencies 286 data.dependencies
@@ -410,7 +410,7 @@ impl CrateId {
410 410
411impl CrateData { 411impl CrateData {
412 fn add_dep(&mut self, name: CrateName, crate_id: CrateId) { 412 fn add_dep(&mut self, name: CrateName, crate_id: CrateId) {
413 self.dependencies.push(Dependency { name, crate_id }) 413 self.dependencies.push(Dependency { crate_id, name })
414 } 414 }
415} 415}
416 416
diff --git a/crates/cfg/src/dnf.rs b/crates/cfg/src/dnf.rs
index 30f4bcdf7..75ded9aa1 100644
--- a/crates/cfg/src/dnf.rs
+++ b/crates/cfg/src/dnf.rs
@@ -255,9 +255,9 @@ impl Builder {
255fn make_dnf(expr: CfgExpr) -> CfgExpr { 255fn make_dnf(expr: CfgExpr) -> CfgExpr {
256 match expr { 256 match expr {
257 CfgExpr::Invalid | CfgExpr::Atom(_) | CfgExpr::Not(_) => expr, 257 CfgExpr::Invalid | CfgExpr::Atom(_) | CfgExpr::Not(_) => expr,
258 CfgExpr::Any(e) => CfgExpr::Any(e.into_iter().map(|expr| make_dnf(expr)).collect()), 258 CfgExpr::Any(e) => CfgExpr::Any(e.into_iter().map(make_dnf).collect()),
259 CfgExpr::All(e) => { 259 CfgExpr::All(e) => {
260 let e = e.into_iter().map(|expr| make_nnf(expr)).collect::<Vec<_>>(); 260 let e = e.into_iter().map(make_nnf).collect::<Vec<_>>();
261 261
262 CfgExpr::Any(distribute_conj(&e)) 262 CfgExpr::Any(distribute_conj(&e))
263 } 263 }
@@ -300,8 +300,8 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
300fn make_nnf(expr: CfgExpr) -> CfgExpr { 300fn make_nnf(expr: CfgExpr) -> CfgExpr {
301 match expr { 301 match expr {
302 CfgExpr::Invalid | CfgExpr::Atom(_) => expr, 302 CfgExpr::Invalid | CfgExpr::Atom(_) => expr,
303 CfgExpr::Any(expr) => CfgExpr::Any(expr.into_iter().map(|expr| make_nnf(expr)).collect()), 303 CfgExpr::Any(expr) => CfgExpr::Any(expr.into_iter().map(make_nnf).collect()),
304 CfgExpr::All(expr) => CfgExpr::All(expr.into_iter().map(|expr| make_nnf(expr)).collect()), 304 CfgExpr::All(expr) => CfgExpr::All(expr.into_iter().map(make_nnf).collect()),
305 CfgExpr::Not(operand) => match *operand { 305 CfgExpr::Not(operand) => match *operand {
306 CfgExpr::Invalid | CfgExpr::Atom(_) => CfgExpr::Not(operand.clone()), // Original negated expr 306 CfgExpr::Invalid | CfgExpr::Atom(_) => CfgExpr::Not(operand.clone()), // Original negated expr
307 CfgExpr::Not(expr) => { 307 CfgExpr::Not(expr) => {
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 9f6d7be48..97a78ca25 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -217,7 +217,7 @@ impl HirDisplay for Variant {
217 217
218impl HirDisplay for Type { 218impl HirDisplay for Type {
219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
220 self.ty.value.hir_fmt(f) 220 self.ty.hir_fmt(f)
221 } 221 }
222} 222}
223 223
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 746b4c942..6fa676c4d 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -56,9 +56,9 @@ use hir_ty::{
56 primitive::UintTy, 56 primitive::UintTy,
57 to_assoc_type_id, 57 to_assoc_type_id,
58 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, Cast, DebruijnIndex, 59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
60 InEnvironment, Interner, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind, 60 DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar,
61 TyVariableKind, WhereClause, 61 Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause,
62}; 62};
63use itertools::Itertools; 63use itertools::Itertools;
64use rustc_hash::FxHashSet; 64use rustc_hash::FxHashSet;
@@ -154,11 +154,7 @@ impl Crate {
154 } 154 }
155 155
156 pub fn transitive_reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> { 156 pub fn transitive_reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> {
157 db.crate_graph() 157 db.crate_graph().transitive_rev_deps(self.id).into_iter().map(|id| Crate { id }).collect()
158 .transitive_reverse_dependencies(self.id)
159 .into_iter()
160 .map(|id| Crate { id })
161 .collect()
162 } 158 }
163 159
164 pub fn root_module(self, db: &dyn HirDatabase) -> Module { 160 pub fn root_module(self, db: &dyn HirDatabase) -> Module {
@@ -213,7 +209,7 @@ impl Crate {
213 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text), 209 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text),
214 _ => None 210 _ => None
215 } 211 }
216 }).flat_map(|t| t).next(); 212 }).flatten().next();
217 213
218 doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") 214 doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
219 } 215 }
@@ -851,17 +847,12 @@ impl Function {
851 .iter() 847 .iter()
852 .enumerate() 848 .enumerate()
853 .map(|(idx, type_ref)| { 849 .map(|(idx, type_ref)| {
854 let ty = Type { 850 let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) };
855 krate,
856 ty: InEnvironment {
857 value: ctx.lower_ty(type_ref),
858 environment: environment.clone(),
859 },
860 };
861 Param { func: self, ty, idx } 851 Param { func: self, ty, idx }
862 }) 852 })
863 .collect() 853 .collect()
864 } 854 }
855
865 pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> { 856 pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> {
866 if self.self_param(db).is_none() { 857 if self.self_param(db).is_none() {
867 return None; 858 return None;
@@ -919,7 +910,7 @@ impl From<hir_ty::Mutability> for Access {
919 } 910 }
920} 911}
921 912
922#[derive(Debug)] 913#[derive(Clone, Debug)]
923pub struct Param { 914pub struct Param {
924 func: Function, 915 func: Function,
925 /// The index in parameter list, including self parameter. 916 /// The index in parameter list, including self parameter.
@@ -932,13 +923,25 @@ impl Param {
932 &self.ty 923 &self.ty
933 } 924 }
934 925
926 pub fn as_local(&self, db: &dyn HirDatabase) -> Local {
927 let parent = DefWithBodyId::FunctionId(self.func.into());
928 let body = db.body(parent);
929 Local { parent, pat_id: body.params[self.idx] }
930 }
931
935 pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> { 932 pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {
936 let params = self.func.source(db)?.value.param_list()?; 933 self.source(db).and_then(|p| p.value.pat())
934 }
935
936 pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::Param>> {
937 let InFile { file_id, value } = self.func.source(db)?;
938 let params = value.param_list()?;
937 if params.self_param().is_some() { 939 if params.self_param().is_some() {
938 params.params().nth(self.idx.checked_sub(1)?)?.pat() 940 params.params().nth(self.idx.checked_sub(1)?)
939 } else { 941 } else {
940 params.params().nth(self.idx)?.pat() 942 params.params().nth(self.idx)
941 } 943 }
944 .map(|value| InFile { file_id, value })
942 } 945 }
943} 946}
944 947
@@ -970,6 +973,14 @@ impl SelfParam {
970 Access::Owned => "self", 973 Access::Owned => "self",
971 } 974 }
972 } 975 }
976
977 pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::SelfParam>> {
978 let InFile { file_id, value } = Function::from(self.func).source(db)?;
979 value
980 .param_list()
981 .and_then(|params| params.self_param())
982 .map(|value| InFile { file_id, value })
983 }
973} 984}
974 985
975impl HasVisibility for Function { 986impl HasVisibility for Function {
@@ -1127,6 +1138,14 @@ impl BuiltinType {
1127} 1138}
1128 1139
1129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1141pub enum MacroKind {
1142 Declarative,
1143 ProcMacro,
1144 Derive,
1145 BuiltIn,
1146}
1147
1148#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1130pub struct MacroDef { 1149pub struct MacroDef {
1131 pub(crate) id: MacroDefId, 1150 pub(crate) id: MacroDefId,
1132} 1151}
@@ -1150,15 +1169,15 @@ impl MacroDef {
1150 } 1169 }
1151 } 1170 }
1152 1171
1153 /// Indicate it is a proc-macro 1172 pub fn kind(&self) -> MacroKind {
1154 pub fn is_proc_macro(&self) -> bool { 1173 match self.id.kind {
1155 matches!(self.id.kind, MacroDefKind::ProcMacro(..)) 1174 MacroDefKind::Declarative(_) => MacroKind::Declarative,
1156 } 1175 MacroDefKind::BuiltIn(_, _) => MacroKind::BuiltIn,
1157 1176 MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive,
1158 /// Indicate it is a derive macro 1177 MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn,
1159 pub fn is_derive_macro(&self) -> bool { 1178 // FIXME might be a derive
1160 // FIXME: wrong for `ProcMacro` 1179 MacroDefKind::ProcMacro(_, _) => MacroKind::ProcMacro,
1161 matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..)) 1180 }
1162 } 1181 }
1163} 1182}
1164 1183
@@ -1337,6 +1356,13 @@ impl Local {
1337 } 1356 }
1338 } 1357 }
1339 1358
1359 pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
1360 match self.parent {
1361 DefWithBodyId::FunctionId(func) if self.is_self(db) => Some(SelfParam { func }),
1362 _ => None,
1363 }
1364 }
1365
1340 // FIXME: why is this an option? It shouldn't be? 1366 // FIXME: why is this an option? It shouldn't be?
1341 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 1367 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1342 let body = db.body(self.parent); 1368 let body = db.body(self.parent);
@@ -1460,7 +1486,7 @@ impl TypeParam {
1460 pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { 1486 pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
1461 db.generic_predicates_for_param(self.id) 1487 db.generic_predicates_for_param(self.id)
1462 .into_iter() 1488 .into_iter()
1463 .filter_map(|pred| match &pred.value { 1489 .filter_map(|pred| match &pred.skip_binders().skip_binders() {
1464 hir_ty::WhereClause::Implemented(trait_ref) => { 1490 hir_ty::WhereClause::Implemented(trait_ref) => {
1465 Some(Trait::from(trait_ref.hir_trait_id())) 1491 Some(Trait::from(trait_ref.hir_trait_id()))
1466 } 1492 }
@@ -1540,8 +1566,8 @@ impl Impl {
1540 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1566 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1541 } 1567 }
1542 1568
1543 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> { 1569 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
1544 let def_crates = match ty.value.def_crates(db, krate) { 1570 let def_crates = match ty.def_crates(db, krate) {
1545 Some(def_crates) => def_crates, 1571 Some(def_crates) => def_crates,
1546 None => return Vec::new(), 1572 None => return Vec::new(),
1547 }; 1573 };
@@ -1549,14 +1575,14 @@ impl Impl {
1549 let filter = |impl_def: &Impl| { 1575 let filter = |impl_def: &Impl| {
1550 let target_ty = impl_def.target_ty(db); 1576 let target_ty = impl_def.target_ty(db);
1551 let rref = target_ty.remove_ref(); 1577 let rref = target_ty.remove_ref();
1552 ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) 1578 ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty))
1553 }; 1579 };
1554 1580
1555 let mut all = Vec::new(); 1581 let mut all = Vec::new();
1556 def_crates.iter().for_each(|&id| { 1582 def_crates.iter().for_each(|&id| {
1557 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) 1583 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1558 }); 1584 });
1559 let fp = TyFingerprint::for_impl(&ty.value); 1585 let fp = TyFingerprint::for_impl(&ty);
1560 for id in def_crates 1586 for id in def_crates
1561 .iter() 1587 .iter()
1562 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) 1588 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
@@ -1578,8 +1604,7 @@ impl Impl {
1578 pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { 1604 pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
1579 let krate = trait_.module(db).krate(); 1605 let krate = trait_.module(db).krate();
1580 let mut all = Vec::new(); 1606 let mut all = Vec::new();
1581 for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter().chain(Some(krate)) 1607 for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter() {
1582 {
1583 let impls = db.trait_impls_in_crate(id); 1608 let impls = db.trait_impls_in_crate(id);
1584 all.extend(impls.for_trait(trait_.id).map(Self::from)) 1609 all.extend(impls.for_trait(trait_.id).map(Self::from))
1585 } 1610 }
@@ -1643,7 +1668,8 @@ impl Impl {
1643#[derive(Clone, PartialEq, Eq, Debug)] 1668#[derive(Clone, PartialEq, Eq, Debug)]
1644pub struct Type { 1669pub struct Type {
1645 krate: CrateId, 1670 krate: CrateId,
1646 ty: InEnvironment<Ty>, 1671 env: Arc<TraitEnvironment>,
1672 ty: Ty,
1647} 1673}
1648 1674
1649impl Type { 1675impl Type {
@@ -1663,14 +1689,14 @@ impl Type {
1663 ) -> Type { 1689 ) -> Type {
1664 let environment = 1690 let environment =
1665 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); 1691 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1666 Type { krate, ty: InEnvironment { value: ty, environment } } 1692 Type { krate, env: environment, ty }
1667 } 1693 }
1668 1694
1669 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { 1695 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
1670 let resolver = lexical_env.resolver(db.upcast()); 1696 let resolver = lexical_env.resolver(db.upcast());
1671 let environment = 1697 let environment =
1672 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); 1698 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1673 Type { krate, ty: InEnvironment { value: ty, environment } } 1699 Type { krate, env: environment, ty }
1674 } 1700 }
1675 1701
1676 fn from_def( 1702 fn from_def(
@@ -1684,29 +1710,29 @@ impl Type {
1684 } 1710 }
1685 1711
1686 pub fn is_unit(&self) -> bool { 1712 pub fn is_unit(&self) -> bool {
1687 matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..)) 1713 matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..))
1688 } 1714 }
1689 pub fn is_bool(&self) -> bool { 1715 pub fn is_bool(&self) -> bool {
1690 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool)) 1716 matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool))
1691 } 1717 }
1692 1718
1693 pub fn is_mutable_reference(&self) -> bool { 1719 pub fn is_mutable_reference(&self) -> bool {
1694 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) 1720 matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1695 } 1721 }
1696 1722
1697 pub fn is_usize(&self) -> bool { 1723 pub fn is_usize(&self) -> bool {
1698 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) 1724 matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
1699 } 1725 }
1700 1726
1701 pub fn remove_ref(&self) -> Option<Type> { 1727 pub fn remove_ref(&self) -> Option<Type> {
1702 match &self.ty.value.interned(&Interner) { 1728 match &self.ty.interned(&Interner) {
1703 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), 1729 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
1704 _ => None, 1730 _ => None,
1705 } 1731 }
1706 } 1732 }
1707 1733
1708 pub fn is_unknown(&self) -> bool { 1734 pub fn is_unknown(&self) -> bool {
1709 self.ty.value.is_unknown() 1735 self.ty.is_unknown()
1710 } 1736 }
1711 1737
1712 /// Checks that particular type `ty` implements `std::future::Future`. 1738 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -1723,11 +1749,12 @@ impl Type {
1723 None => return false, 1749 None => return false,
1724 }; 1750 };
1725 1751
1726 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1752 let canonical_ty =
1753 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1727 method_resolution::implements_trait( 1754 method_resolution::implements_trait(
1728 &canonical_ty, 1755 &canonical_ty,
1729 db, 1756 db,
1730 self.ty.environment.clone(), 1757 self.env.clone(),
1731 krate, 1758 krate,
1732 std_future_trait, 1759 std_future_trait,
1733 ) 1760 )
@@ -1745,11 +1772,12 @@ impl Type {
1745 None => return false, 1772 None => return false,
1746 }; 1773 };
1747 1774
1748 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1775 let canonical_ty =
1776 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1749 method_resolution::implements_trait_unique( 1777 method_resolution::implements_trait_unique(
1750 &canonical_ty, 1778 &canonical_ty,
1751 db, 1779 db,
1752 self.ty.environment.clone(), 1780 self.env.clone(),
1753 krate, 1781 krate,
1754 fnonce_trait, 1782 fnonce_trait,
1755 ) 1783 )
@@ -1759,17 +1787,14 @@ impl Type {
1759 let trait_ref = hir_ty::TraitRef { 1787 let trait_ref = hir_ty::TraitRef {
1760 trait_id: hir_ty::to_chalk_trait_id(trait_.id), 1788 trait_id: hir_ty::to_chalk_trait_id(trait_.id),
1761 substitution: Substitution::build_for_def(db, trait_.id) 1789 substitution: Substitution::build_for_def(db, trait_.id)
1762 .push(self.ty.value.clone()) 1790 .push(self.ty.clone())
1763 .fill(args.iter().map(|t| t.ty.value.clone())) 1791 .fill(args.iter().map(|t| t.ty.clone()))
1764 .build(), 1792 .build(),
1765 }; 1793 };
1766 1794
1767 let goal = Canonical { 1795 let goal = Canonical {
1768 value: hir_ty::InEnvironment::new( 1796 value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)),
1769 self.ty.environment.clone(), 1797 binders: CanonicalVarKinds::empty(&Interner),
1770 trait_ref.cast(&Interner),
1771 ),
1772 kinds: Arc::new([]),
1773 }; 1798 };
1774 1799
1775 db.trait_solve(self.krate, goal).is_some() 1800 db.trait_solve(self.krate, goal).is_some()
@@ -1783,12 +1808,12 @@ impl Type {
1783 alias: TypeAlias, 1808 alias: TypeAlias,
1784 ) -> Option<Type> { 1809 ) -> Option<Type> {
1785 let subst = Substitution::build_for_def(db, trait_.id) 1810 let subst = Substitution::build_for_def(db, trait_.id)
1786 .push(self.ty.value.clone()) 1811 .push(self.ty.clone())
1787 .fill(args.iter().map(|t| t.ty.value.clone())) 1812 .fill(args.iter().map(|t| t.ty.clone()))
1788 .build(); 1813 .build();
1789 let goal = Canonical { 1814 let goal = Canonical::new(
1790 value: InEnvironment::new( 1815 InEnvironment::new(
1791 self.ty.environment.clone(), 1816 self.env.env.clone(),
1792 AliasEq { 1817 AliasEq {
1793 alias: AliasTy::Projection(ProjectionTy { 1818 alias: AliasTy::Projection(ProjectionTy {
1794 associated_ty_id: to_assoc_type_id(alias.id), 1819 associated_ty_id: to_assoc_type_id(alias.id),
@@ -1799,8 +1824,8 @@ impl Type {
1799 } 1824 }
1800 .cast(&Interner), 1825 .cast(&Interner),
1801 ), 1826 ),
1802 kinds: Arc::new([TyVariableKind::General]), 1827 [TyVariableKind::General].iter().copied(),
1803 }; 1828 );
1804 1829
1805 match db.trait_solve(self.krate, goal)? { 1830 match db.trait_solve(self.krate, goal)? {
1806 Solution::Unique(SolutionVariables(subst)) => { 1831 Solution::Unique(SolutionVariables(subst)) => {
@@ -1820,22 +1845,22 @@ impl Type {
1820 } 1845 }
1821 1846
1822 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1847 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1823 let def = self.ty.value.callable_def(db); 1848 let def = self.ty.callable_def(db);
1824 1849
1825 let sig = self.ty.value.callable_sig(db)?; 1850 let sig = self.ty.callable_sig(db)?;
1826 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) 1851 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1827 } 1852 }
1828 1853
1829 pub fn is_closure(&self) -> bool { 1854 pub fn is_closure(&self) -> bool {
1830 matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. }) 1855 matches!(&self.ty.interned(&Interner), TyKind::Closure { .. })
1831 } 1856 }
1832 1857
1833 pub fn is_fn(&self) -> bool { 1858 pub fn is_fn(&self) -> bool {
1834 matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) 1859 matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
1835 } 1860 }
1836 1861
1837 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1862 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1838 let adt_id = match self.ty.value.interned(&Interner) { 1863 let adt_id = match self.ty.interned(&Interner) {
1839 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, 1864 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
1840 _ => return false, 1865 _ => return false,
1841 }; 1866 };
@@ -1848,11 +1873,11 @@ impl Type {
1848 } 1873 }
1849 1874
1850 pub fn is_raw_ptr(&self) -> bool { 1875 pub fn is_raw_ptr(&self) -> bool {
1851 matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..)) 1876 matches!(&self.ty.interned(&Interner), TyKind::Raw(..))
1852 } 1877 }
1853 1878
1854 pub fn contains_unknown(&self) -> bool { 1879 pub fn contains_unknown(&self) -> bool {
1855 return go(&self.ty.value); 1880 return go(&self.ty);
1856 1881
1857 fn go(ty: &Ty) -> bool { 1882 fn go(ty: &Ty) -> bool {
1858 match ty.interned(&Interner) { 1883 match ty.interned(&Interner) {
@@ -1884,7 +1909,7 @@ impl Type {
1884 } 1909 }
1885 1910
1886 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1911 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1887 let (variant_id, substs) = match self.ty.value.interned(&Interner) { 1912 let (variant_id, substs) = match self.ty.interned(&Interner) {
1888 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), 1913 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
1889 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), 1914 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
1890 _ => return Vec::new(), 1915 _ => return Vec::new(),
@@ -1901,7 +1926,7 @@ impl Type {
1901 } 1926 }
1902 1927
1903 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1928 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1904 if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) { 1929 if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) {
1905 substs.iter().map(|ty| self.derived(ty.clone())).collect() 1930 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1906 } else { 1931 } else {
1907 Vec::new() 1932 Vec::new()
@@ -1911,9 +1936,10 @@ impl Type {
1911 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { 1936 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
1912 // There should be no inference vars in types passed here 1937 // There should be no inference vars in types passed here
1913 // FIXME check that? 1938 // FIXME check that?
1914 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1939 let canonical =
1915 let environment = self.ty.environment.clone(); 1940 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1916 let ty = InEnvironment { value: canonical, environment }; 1941 let environment = self.env.env.clone();
1942 let ty = InEnvironment { goal: canonical, environment };
1917 autoderef(db, Some(self.krate), ty) 1943 autoderef(db, Some(self.krate), ty)
1918 .map(|canonical| canonical.value) 1944 .map(|canonical| canonical.value)
1919 .map(move |ty| self.derived(ty)) 1945 .map(move |ty| self.derived(ty))
@@ -1927,10 +1953,10 @@ impl Type {
1927 krate: Crate, 1953 krate: Crate,
1928 mut callback: impl FnMut(AssocItem) -> Option<T>, 1954 mut callback: impl FnMut(AssocItem) -> Option<T>,
1929 ) -> Option<T> { 1955 ) -> Option<T> {
1930 for krate in self.ty.value.def_crates(db, krate.id)? { 1956 for krate in self.ty.def_crates(db, krate.id)? {
1931 let impls = db.inherent_impls_in_crate(krate); 1957 let impls = db.inherent_impls_in_crate(krate);
1932 1958
1933 for impl_def in impls.for_self_ty(&self.ty.value) { 1959 for impl_def in impls.for_self_ty(&self.ty) {
1934 for &item in db.impl_data(*impl_def).items.iter() { 1960 for &item in db.impl_data(*impl_def).items.iter() {
1935 if let Some(result) = callback(item.into()) { 1961 if let Some(result) = callback(item.into()) {
1936 return Some(result); 1962 return Some(result);
@@ -1943,7 +1969,6 @@ impl Type {
1943 1969
1944 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { 1970 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1945 self.ty 1971 self.ty
1946 .value
1947 .strip_references() 1972 .strip_references()
1948 .substs() 1973 .substs()
1949 .into_iter() 1974 .into_iter()
@@ -1962,9 +1987,10 @@ impl Type {
1962 // There should be no inference vars in types passed here 1987 // There should be no inference vars in types passed here
1963 // FIXME check that? 1988 // FIXME check that?
1964 // FIXME replace Unknown by bound vars here 1989 // FIXME replace Unknown by bound vars here
1965 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1990 let canonical =
1991 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1966 1992
1967 let env = self.ty.environment.clone(); 1993 let env = self.env.clone();
1968 let krate = krate.id; 1994 let krate = krate.id;
1969 1995
1970 method_resolution::iterate_method_candidates( 1996 method_resolution::iterate_method_candidates(
@@ -1994,9 +2020,10 @@ impl Type {
1994 // There should be no inference vars in types passed here 2020 // There should be no inference vars in types passed here
1995 // FIXME check that? 2021 // FIXME check that?
1996 // FIXME replace Unknown by bound vars here 2022 // FIXME replace Unknown by bound vars here
1997 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 2023 let canonical =
2024 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1998 2025
1999 let env = self.ty.environment.clone(); 2026 let env = self.env.clone();
2000 let krate = krate.id; 2027 let krate = krate.id;
2001 2028
2002 method_resolution::iterate_method_candidates( 2029 method_resolution::iterate_method_candidates(
@@ -2013,18 +2040,18 @@ impl Type {
2013 } 2040 }
2014 2041
2015 pub fn as_adt(&self) -> Option<Adt> { 2042 pub fn as_adt(&self) -> Option<Adt> {
2016 let (adt, _subst) = self.ty.value.as_adt()?; 2043 let (adt, _subst) = self.ty.as_adt()?;
2017 Some(adt.into()) 2044 Some(adt.into())
2018 } 2045 }
2019 2046
2020 pub fn as_dyn_trait(&self) -> Option<Trait> { 2047 pub fn as_dyn_trait(&self) -> Option<Trait> {
2021 self.ty.value.dyn_trait().map(Into::into) 2048 self.ty.dyn_trait().map(Into::into)
2022 } 2049 }
2023 2050
2024 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { 2051 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
2025 self.ty.value.impl_trait_bounds(db).map(|it| { 2052 self.ty.impl_trait_bounds(db).map(|it| {
2026 it.into_iter() 2053 it.into_iter()
2027 .filter_map(|pred| match pred { 2054 .filter_map(|pred| match pred.skip_binders() {
2028 hir_ty::WhereClause::Implemented(trait_ref) => { 2055 hir_ty::WhereClause::Implemented(trait_ref) => {
2029 Some(Trait::from(trait_ref.hir_trait_id())) 2056 Some(Trait::from(trait_ref.hir_trait_id()))
2030 } 2057 }
@@ -2035,14 +2062,11 @@ impl Type {
2035 } 2062 }
2036 2063
2037 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> { 2064 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
2038 self.ty.value.associated_type_parent_trait(db).map(Into::into) 2065 self.ty.associated_type_parent_trait(db).map(Into::into)
2039 } 2066 }
2040 2067
2041 fn derived(&self, ty: Ty) -> Type { 2068 fn derived(&self, ty: Ty) -> Type {
2042 Type { 2069 Type { krate: self.krate, env: self.env.clone(), ty }
2043 krate: self.krate,
2044 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
2045 }
2046 } 2070 }
2047 2071
2048 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) { 2072 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
@@ -2063,14 +2087,17 @@ impl Type {
2063 fn walk_bounds( 2087 fn walk_bounds(
2064 db: &dyn HirDatabase, 2088 db: &dyn HirDatabase,
2065 type_: &Type, 2089 type_: &Type,
2066 bounds: &[WhereClause], 2090 bounds: &[QuantifiedWhereClause],
2067 cb: &mut impl FnMut(Type), 2091 cb: &mut impl FnMut(Type),
2068 ) { 2092 ) {
2069 for pred in bounds { 2093 for pred in bounds {
2070 match pred { 2094 match pred.skip_binders() {
2071 WhereClause::Implemented(trait_ref) => { 2095 WhereClause::Implemented(trait_ref) => {
2072 cb(type_.clone()); 2096 cb(type_.clone());
2073 walk_substs(db, type_, &trait_ref.substitution, cb); 2097 // skip the self type. it's likely the type we just got the bounds from
2098 for ty in trait_ref.substitution.iter().skip(1) {
2099 walk_type(db, &type_.derived(ty.clone()), cb);
2100 }
2074 } 2101 }
2075 _ => (), 2102 _ => (),
2076 } 2103 }
@@ -2078,7 +2105,7 @@ impl Type {
2078 } 2105 }
2079 2106
2080 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 2107 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
2081 let ty = type_.ty.value.strip_references(); 2108 let ty = type_.ty.strip_references();
2082 match ty.interned(&Interner) { 2109 match ty.interned(&Interner) {
2083 TyKind::Adt(..) => { 2110 TyKind::Adt(..) => {
2084 cb(type_.derived(ty.clone())); 2111 cb(type_.derived(ty.clone()));
@@ -2106,7 +2133,12 @@ impl Type {
2106 } 2133 }
2107 } 2134 }
2108 TyKind::Dyn(bounds) => { 2135 TyKind::Dyn(bounds) => {
2109 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 2136 walk_bounds(
2137 db,
2138 &type_.derived(ty.clone()),
2139 bounds.bounds.skip_binders().interned(),
2140 cb,
2141 );
2110 } 2142 }
2111 2143
2112 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { 2144 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
@@ -2201,6 +2233,7 @@ pub enum ScopeDef {
2201 ImplSelfType(Impl), 2233 ImplSelfType(Impl),
2202 AdtSelfType(Adt), 2234 AdtSelfType(Adt),
2203 Local(Local), 2235 Local(Local),
2236 Label(Label),
2204 Unknown, 2237 Unknown,
2205} 2238}
2206 2239
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 15651bb22..1198e3f0b 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -839,6 +839,10 @@ impl<'a> SemanticsScope<'a> {
839 let parent = resolver.body_owner().unwrap(); 839 let parent = resolver.body_owner().unwrap();
840 ScopeDef::Local(Local { parent, pat_id }) 840 ScopeDef::Local(Local { parent, pat_id })
841 } 841 }
842 resolver::ScopeDef::Label(label_id) => {
843 let parent = resolver.body_owner().unwrap();
844 ScopeDef::Label(Label { parent, label_id })
845 }
842 }; 846 };
843 f(name, def) 847 f(name, def)
844 }) 848 })
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index 2c10f46d8..52a2bce9b 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -638,7 +638,7 @@ fn collect_attrs(
638 owner: &dyn ast::AttrsOwner, 638 owner: &dyn ast::AttrsOwner,
639) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> { 639) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> {
640 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) 640 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
641 .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); 641 .map_or((None, None), |(attrs, docs)| (Some(attrs), Some(docs)));
642 642
643 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none()); 643 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
644 let attrs = outer_attrs 644 let attrs = outer_attrs
diff --git a/crates/hir_def/src/body/scope.rs b/crates/hir_def/src/body/scope.rs
index 1bbb54fc6..bd7005ca6 100644
--- a/crates/hir_def/src/body/scope.rs
+++ b/crates/hir_def/src/body/scope.rs
@@ -8,7 +8,7 @@ use rustc_hash::FxHashMap;
8use crate::{ 8use crate::{
9 body::Body, 9 body::Body,
10 db::DefDatabase, 10 db::DefDatabase,
11 expr::{Expr, ExprId, Pat, PatId, Statement}, 11 expr::{Expr, ExprId, LabelId, Pat, PatId, Statement},
12 BlockId, DefWithBodyId, 12 BlockId, DefWithBodyId,
13}; 13};
14 14
@@ -40,6 +40,7 @@ impl ScopeEntry {
40pub struct ScopeData { 40pub struct ScopeData {
41 parent: Option<ScopeId>, 41 parent: Option<ScopeId>,
42 block: Option<BlockId>, 42 block: Option<BlockId>,
43 label: Option<(LabelId, Name)>,
43 entries: Vec<ScopeEntry>, 44 entries: Vec<ScopeEntry>,
44} 45}
45 46
@@ -67,6 +68,11 @@ impl ExprScopes {
67 self.scopes[scope].block 68 self.scopes[scope].block
68 } 69 }
69 70
71 /// If `scope` refers to a labeled expression scope, returns the corresponding `Label`.
72 pub fn label(&self, scope: ScopeId) -> Option<(LabelId, Name)> {
73 self.scopes[scope].label.clone()
74 }
75
70 pub fn scope_chain(&self, scope: Option<ScopeId>) -> impl Iterator<Item = ScopeId> + '_ { 76 pub fn scope_chain(&self, scope: Option<ScopeId>) -> impl Iterator<Item = ScopeId> + '_ {
71 std::iter::successors(scope, move |&scope| self.scopes[scope].parent) 77 std::iter::successors(scope, move |&scope| self.scopes[scope].parent)
72 } 78 }
@@ -85,15 +91,34 @@ impl ExprScopes {
85 } 91 }
86 92
87 fn root_scope(&mut self) -> ScopeId { 93 fn root_scope(&mut self) -> ScopeId {
88 self.scopes.alloc(ScopeData { parent: None, block: None, entries: vec![] }) 94 self.scopes.alloc(ScopeData { parent: None, block: None, label: None, entries: vec![] })
89 } 95 }
90 96
91 fn new_scope(&mut self, parent: ScopeId) -> ScopeId { 97 fn new_scope(&mut self, parent: ScopeId) -> ScopeId {
92 self.scopes.alloc(ScopeData { parent: Some(parent), block: None, entries: vec![] }) 98 self.scopes.alloc(ScopeData {
99 parent: Some(parent),
100 block: None,
101 label: None,
102 entries: vec![],
103 })
93 } 104 }
94 105
95 fn new_block_scope(&mut self, parent: ScopeId, block: BlockId) -> ScopeId { 106 fn new_labeled_scope(&mut self, parent: ScopeId, label: Option<(LabelId, Name)>) -> ScopeId {
96 self.scopes.alloc(ScopeData { parent: Some(parent), block: Some(block), entries: vec![] }) 107 self.scopes.alloc(ScopeData { parent: Some(parent), block: None, label, entries: vec![] })
108 }
109
110 fn new_block_scope(
111 &mut self,
112 parent: ScopeId,
113 block: BlockId,
114 label: Option<(LabelId, Name)>,
115 ) -> ScopeId {
116 self.scopes.alloc(ScopeData {
117 parent: Some(parent),
118 block: Some(block),
119 label,
120 entries: vec![],
121 })
97 } 122 }
98 123
99 fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { 124 fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) {
@@ -144,21 +169,33 @@ fn compute_block_scopes(
144} 169}
145 170
146fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) { 171fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) {
172 let make_label =
173 |label: &Option<_>| label.map(|label| (label, body.labels[label].name.clone()));
174
147 scopes.set_scope(expr, scope); 175 scopes.set_scope(expr, scope);
148 match &body[expr] { 176 match &body[expr] {
149 Expr::Block { statements, tail, id, .. } => { 177 Expr::Block { statements, tail, id, label } => {
150 let scope = scopes.new_block_scope(scope, *id); 178 let scope = scopes.new_block_scope(scope, *id, make_label(label));
151 // Overwrite the old scope for the block expr, so that every block scope can be found 179 // Overwrite the old scope for the block expr, so that every block scope can be found
152 // via the block itself (important for blocks that only contain items, no expressions). 180 // via the block itself (important for blocks that only contain items, no expressions).
153 scopes.set_scope(expr, scope); 181 scopes.set_scope(expr, scope);
154 compute_block_scopes(&statements, *tail, body, scopes, scope); 182 compute_block_scopes(statements, *tail, body, scopes, scope);
155 } 183 }
156 Expr::For { iterable, pat, body: body_expr, .. } => { 184 Expr::For { iterable, pat, body: body_expr, label } => {
157 compute_expr_scopes(*iterable, body, scopes, scope); 185 compute_expr_scopes(*iterable, body, scopes, scope);
158 let scope = scopes.new_scope(scope); 186 let scope = scopes.new_labeled_scope(scope, make_label(label));
159 scopes.add_bindings(body, scope, *pat); 187 scopes.add_bindings(body, scope, *pat);
160 compute_expr_scopes(*body_expr, body, scopes, scope); 188 compute_expr_scopes(*body_expr, body, scopes, scope);
161 } 189 }
190 Expr::While { condition, body: body_expr, label } => {
191 let scope = scopes.new_labeled_scope(scope, make_label(label));
192 compute_expr_scopes(*condition, body, scopes, scope);
193 compute_expr_scopes(*body_expr, body, scopes, scope);
194 }
195 Expr::Loop { body: body_expr, label } => {
196 let scope = scopes.new_labeled_scope(scope, make_label(label));
197 compute_expr_scopes(*body_expr, body, scopes, scope);
198 }
162 Expr::Lambda { args, body: body_expr, .. } => { 199 Expr::Lambda { args, body: body_expr, .. } => {
163 let scope = scopes.new_scope(scope); 200 let scope = scopes.new_scope(scope);
164 scopes.add_params_bindings(body, scope, &args); 201 scopes.add_params_bindings(body, scope, &args);
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index de08e2737..109d3552f 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -18,7 +18,8 @@ use crate::{
18/// *from where* you're referring to the item, hence the `from` parameter. 18/// *from where* you're referring to the item, hence the `from` parameter.
19pub fn find_path(db: &dyn DefDatabase, item: ItemInNs, from: ModuleId) -> Option<ModPath> { 19pub fn find_path(db: &dyn DefDatabase, item: ItemInNs, from: ModuleId) -> Option<ModPath> {
20 let _p = profile::span("find_path"); 20 let _p = profile::span("find_path");
21 find_path_inner(db, item, from, MAX_PATH_LEN, None) 21 let mut visited_modules = FxHashSet::default();
22 find_path_inner(db, item, from, MAX_PATH_LEN, None, &mut visited_modules)
22} 23}
23 24
24pub fn find_path_prefixed( 25pub fn find_path_prefixed(
@@ -28,7 +29,8 @@ pub fn find_path_prefixed(
28 prefix_kind: PrefixKind, 29 prefix_kind: PrefixKind,
29) -> Option<ModPath> { 30) -> Option<ModPath> {
30 let _p = profile::span("find_path_prefixed"); 31 let _p = profile::span("find_path_prefixed");
31 find_path_inner(db, item, from, MAX_PATH_LEN, Some(prefix_kind)) 32 let mut visited_modules = FxHashSet::default();
33 find_path_inner(db, item, from, MAX_PATH_LEN, Some(prefix_kind), &mut visited_modules)
32} 34}
33 35
34const MAX_PATH_LEN: usize = 15; 36const MAX_PATH_LEN: usize = 15;
@@ -97,6 +99,7 @@ fn find_path_inner(
97 from: ModuleId, 99 from: ModuleId,
98 max_len: usize, 100 max_len: usize,
99 mut prefixed: Option<PrefixKind>, 101 mut prefixed: Option<PrefixKind>,
102 visited_modules: &mut FxHashSet<ModuleId>,
100) -> Option<ModPath> { 103) -> Option<ModPath> {
101 if max_len == 0 { 104 if max_len == 0 {
102 return None; 105 return None;
@@ -176,15 +179,18 @@ fn find_path_inner(
176 if item.krate(db) == Some(from.krate) { 179 if item.krate(db) == Some(from.krate) {
177 // Item was defined in the same crate that wants to import it. It cannot be found in any 180 // Item was defined in the same crate that wants to import it. It cannot be found in any
178 // dependency in this case. 181 // dependency in this case.
179 182 for (module_id, name) in find_local_import_locations(db, item, from) {
180 let local_imports = find_local_import_locations(db, item, from); 183 if !visited_modules.insert(module_id) {
181 for (module_id, name) in local_imports { 184 cov_mark::hit!(recursive_imports);
185 continue;
186 }
182 if let Some(mut path) = find_path_inner( 187 if let Some(mut path) = find_path_inner(
183 db, 188 db,
184 ItemInNs::Types(ModuleDefId::ModuleId(module_id)), 189 ItemInNs::Types(ModuleDefId::ModuleId(module_id)),
185 from, 190 from,
186 best_path_len - 1, 191 best_path_len - 1,
187 prefixed, 192 prefixed,
193 visited_modules,
188 ) { 194 ) {
189 path.push_segment(name); 195 path.push_segment(name);
190 196
@@ -213,6 +219,7 @@ fn find_path_inner(
213 from, 219 from,
214 best_path_len - 1, 220 best_path_len - 1,
215 prefixed, 221 prefixed,
222 visited_modules,
216 )?; 223 )?;
217 cov_mark::hit!(partially_imported); 224 cov_mark::hit!(partially_imported);
218 path.push_segment(info.path.segments.last().unwrap().clone()); 225 path.push_segment(info.path.segments.last().unwrap().clone());
@@ -391,8 +398,15 @@ mod tests {
391 .take_types() 398 .take_types()
392 .unwrap(); 399 .unwrap();
393 400
394 let found_path = 401 let mut visited_modules = FxHashSet::default();
395 find_path_inner(&db, ItemInNs::Types(resolved), module, MAX_PATH_LEN, prefix_kind); 402 let found_path = find_path_inner(
403 &db,
404 ItemInNs::Types(resolved),
405 module,
406 MAX_PATH_LEN,
407 prefix_kind,
408 &mut visited_modules,
409 );
396 assert_eq!(found_path, Some(mod_path), "{:?}", prefix_kind); 410 assert_eq!(found_path, Some(mod_path), "{:?}", prefix_kind);
397 } 411 }
398 412
@@ -878,4 +892,32 @@ mod tests {
878 "self::module::CompleteMe", 892 "self::module::CompleteMe",
879 ) 893 )
880 } 894 }
895
896 #[test]
897 fn recursive_pub_mod_reexport() {
898 cov_mark::check!(recursive_imports);
899 check_found_path(
900 r#"
901fn main() {
902 let _ = 22_i32.as_name$0();
903}
904
905pub mod name {
906 pub trait AsName {
907 fn as_name(&self) -> String;
908 }
909 impl AsName for i32 {
910 fn as_name(&self) -> String {
911 format!("Name: {}", self)
912 }
913 }
914 pub use crate::name;
915}
916"#,
917 "name::AsName",
918 "name::AsName",
919 "crate::name::AsName",
920 "self::name::AsName",
921 );
922 }
881} 923}
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 0d3a0b54f..9e8e4e9ec 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -322,6 +322,23 @@ impl DefMap {
322 (res.resolved_def, res.segment_index) 322 (res.resolved_def, res.segment_index)
323 } 323 }
324 324
325 pub(crate) fn resolve_path_locally(
326 &self,
327 db: &dyn DefDatabase,
328 original_module: LocalModuleId,
329 path: &ModPath,
330 shadow: BuiltinShadowMode,
331 ) -> (PerNs, Option<usize>) {
332 let res = self.resolve_path_fp_with_macro_single(
333 db,
334 ResolveMode::Other,
335 original_module,
336 path,
337 shadow,
338 );
339 (res.resolved_def, res.segment_index)
340 }
341
325 /// Ascends the `DefMap` hierarchy and calls `f` with every `DefMap` and containing module. 342 /// Ascends the `DefMap` hierarchy and calls `f` with every `DefMap` and containing module.
326 /// 343 ///
327 /// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns 344 /// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 46a3c60cd..d8fabe49b 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -91,7 +91,6 @@ pub(super) fn collect_defs(
91 resolved_imports: Vec::new(), 91 resolved_imports: Vec::new(),
92 92
93 unexpanded_macros: Vec::new(), 93 unexpanded_macros: Vec::new(),
94 unexpanded_attribute_macros: Vec::new(),
95 mod_dirs: FxHashMap::default(), 94 mod_dirs: FxHashMap::default(),
96 cfg_options, 95 cfg_options,
97 proc_macros, 96 proc_macros,
@@ -202,15 +201,14 @@ struct ImportDirective {
202#[derive(Clone, Debug, Eq, PartialEq)] 201#[derive(Clone, Debug, Eq, PartialEq)]
203struct MacroDirective { 202struct MacroDirective {
204 module_id: LocalModuleId, 203 module_id: LocalModuleId,
205 ast_id: AstIdWithPath<ast::MacroCall>,
206 legacy: Option<MacroCallId>,
207 depth: usize, 204 depth: usize,
205 kind: MacroDirectiveKind,
208} 206}
209 207
210#[derive(Clone, Debug, Eq, PartialEq)] 208#[derive(Clone, Debug, Eq, PartialEq)]
211struct DeriveDirective { 209enum MacroDirectiveKind {
212 module_id: LocalModuleId, 210 FnLike { ast_id: AstIdWithPath<ast::MacroCall>, legacy: Option<MacroCallId> },
213 ast_id: AstIdWithPath<ast::Item>, 211 Derive { ast_id: AstIdWithPath<ast::Item> },
214} 212}
215 213
216struct DefData<'a> { 214struct DefData<'a> {
@@ -228,7 +226,6 @@ struct DefCollector<'a> {
228 unresolved_imports: Vec<ImportDirective>, 226 unresolved_imports: Vec<ImportDirective>,
229 resolved_imports: Vec<ImportDirective>, 227 resolved_imports: Vec<ImportDirective>,
230 unexpanded_macros: Vec<MacroDirective>, 228 unexpanded_macros: Vec<MacroDirective>,
231 unexpanded_attribute_macros: Vec<DeriveDirective>,
232 mod_dirs: FxHashMap<LocalModuleId, ModDir>, 229 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
233 cfg_options: &'a CfgOptions, 230 cfg_options: &'a CfgOptions,
234 /// List of procedural macros defined by this crate. This is read from the dynamic library 231 /// List of procedural macros defined by this crate. This is read from the dynamic library
@@ -782,60 +779,58 @@ impl DefCollector<'_> {
782 779
783 fn resolve_macros(&mut self) -> ReachedFixedPoint { 780 fn resolve_macros(&mut self) -> ReachedFixedPoint {
784 let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); 781 let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new());
785 let mut attribute_macros =
786 std::mem::replace(&mut self.unexpanded_attribute_macros, Vec::new());
787 let mut resolved = Vec::new(); 782 let mut resolved = Vec::new();
788 let mut res = ReachedFixedPoint::Yes; 783 let mut res = ReachedFixedPoint::Yes;
789 macros.retain(|directive| { 784 macros.retain(|directive| {
790 if let Some(call_id) = directive.legacy { 785 match &directive.kind {
791 res = ReachedFixedPoint::No; 786 MacroDirectiveKind::FnLike { ast_id, legacy } => {
792 resolved.push((directive.module_id, call_id, directive.depth)); 787 if let Some(call_id) = legacy {
793 return false; 788 res = ReachedFixedPoint::No;
794 } 789 resolved.push((directive.module_id, *call_id, directive.depth));
790 return false;
791 }
795 792
796 match macro_call_as_call_id( 793 match macro_call_as_call_id(
797 &directive.ast_id, 794 ast_id,
798 self.db,
799 self.def_map.krate,
800 |path| {
801 let resolved_res = self.def_map.resolve_path_fp_with_macro(
802 self.db, 795 self.db,
803 ResolveMode::Other, 796 self.def_map.krate,
804 directive.module_id, 797 |path| {
805 &path, 798 let resolved_res = self.def_map.resolve_path_fp_with_macro(
806 BuiltinShadowMode::Module, 799 self.db,
807 ); 800 ResolveMode::Other,
808 resolved_res.resolved_def.take_macros() 801 directive.module_id,
809 }, 802 &path,
810 &mut |_err| (), 803 BuiltinShadowMode::Module,
811 ) { 804 );
812 Ok(Ok(call_id)) => { 805 resolved_res.resolved_def.take_macros()
813 resolved.push((directive.module_id, call_id, directive.depth)); 806 },
814 res = ReachedFixedPoint::No; 807 &mut |_err| (),
815 return false; 808 ) {
809 Ok(Ok(call_id)) => {
810 resolved.push((directive.module_id, call_id, directive.depth));
811 res = ReachedFixedPoint::No;
812 return false;
813 }
814 Err(UnresolvedMacro) | Ok(Err(_)) => {}
815 }
816 } 816 }
817 Err(UnresolvedMacro) | Ok(Err(_)) => {} 817 MacroDirectiveKind::Derive { ast_id } => {
818 } 818 match derive_macro_as_call_id(ast_id, self.db, self.def_map.krate, |path| {
819 819 self.resolve_derive_macro(directive.module_id, &path)
820 true 820 }) {
821 }); 821 Ok(call_id) => {
822 attribute_macros.retain(|directive| { 822 resolved.push((directive.module_id, call_id, 0));
823 match derive_macro_as_call_id(&directive.ast_id, self.db, self.def_map.krate, |path| { 823 res = ReachedFixedPoint::No;
824 self.resolve_derive_macro(&directive, &path) 824 return false;
825 }) { 825 }
826 Ok(call_id) => { 826 Err(UnresolvedMacro) => (),
827 resolved.push((directive.module_id, call_id, 0)); 827 }
828 res = ReachedFixedPoint::No;
829 return false;
830 } 828 }
831 Err(UnresolvedMacro) => (),
832 } 829 }
833 830
834 true 831 true
835 }); 832 });
836
837 self.unexpanded_macros = macros; 833 self.unexpanded_macros = macros;
838 self.unexpanded_attribute_macros = attribute_macros;
839 834
840 for (module_id, macro_call_id, depth) in resolved { 835 for (module_id, macro_call_id, depth) in resolved {
841 self.collect_macro_expansion(module_id, macro_call_id, depth); 836 self.collect_macro_expansion(module_id, macro_call_id, depth);
@@ -844,15 +839,11 @@ impl DefCollector<'_> {
844 res 839 res
845 } 840 }
846 841
847 fn resolve_derive_macro( 842 fn resolve_derive_macro(&self, module: LocalModuleId, path: &ModPath) -> Option<MacroDefId> {
848 &self,
849 directive: &DeriveDirective,
850 path: &ModPath,
851 ) -> Option<MacroDefId> {
852 let resolved_res = self.def_map.resolve_path_fp_with_macro( 843 let resolved_res = self.def_map.resolve_path_fp_with_macro(
853 self.db, 844 self.db,
854 ResolveMode::Other, 845 ResolveMode::Other,
855 directive.module_id, 846 module,
856 &path, 847 &path,
857 BuiltinShadowMode::Module, 848 BuiltinShadowMode::Module,
858 ); 849 );
@@ -912,33 +903,35 @@ impl DefCollector<'_> {
912 // Emit diagnostics for all remaining unexpanded macros. 903 // Emit diagnostics for all remaining unexpanded macros.
913 904
914 for directive in &self.unexpanded_macros { 905 for directive in &self.unexpanded_macros {
915 let mut error = None; 906 match &directive.kind {
916 match macro_call_as_call_id( 907 MacroDirectiveKind::FnLike { ast_id, .. } => match macro_call_as_call_id(
917 &directive.ast_id, 908 ast_id,
918 self.db, 909 self.db,
919 self.def_map.krate, 910 self.def_map.krate,
920 |path| { 911 |path| {
921 let resolved_res = self.def_map.resolve_path_fp_with_macro( 912 let resolved_res = self.def_map.resolve_path_fp_with_macro(
922 self.db, 913 self.db,
923 ResolveMode::Other, 914 ResolveMode::Other,
924 directive.module_id, 915 directive.module_id,
925 &path, 916 &path,
926 BuiltinShadowMode::Module, 917 BuiltinShadowMode::Module,
927 ); 918 );
928 resolved_res.resolved_def.take_macros() 919 resolved_res.resolved_def.take_macros()
929 }, 920 },
930 &mut |e| { 921 &mut |_| (),
931 error.get_or_insert(e); 922 ) {
923 Ok(_) => (),
924 Err(UnresolvedMacro) => {
925 self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
926 directive.module_id,
927 ast_id.ast_id,
928 ));
929 }
932 }, 930 },
933 ) { 931 MacroDirectiveKind::Derive { .. } => {
934 Ok(_) => (), 932 // FIXME: we might want to diagnose this too
935 Err(UnresolvedMacro) => {
936 self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
937 directive.module_id,
938 directive.ast_id.ast_id,
939 ));
940 } 933 }
941 }; 934 }
942 } 935 }
943 936
944 // Emit diagnostics for all remaining unresolved imports. 937 // Emit diagnostics for all remaining unresolved imports.
@@ -1380,9 +1373,11 @@ impl ModCollector<'_, '_> {
1380 Some(derive_macros) => { 1373 Some(derive_macros) => {
1381 for path in derive_macros { 1374 for path in derive_macros {
1382 let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); 1375 let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
1383 self.def_collector 1376 self.def_collector.unexpanded_macros.push(MacroDirective {
1384 .unexpanded_attribute_macros 1377 module_id: self.module_id,
1385 .push(DeriveDirective { module_id: self.module_id, ast_id }); 1378 depth: self.macro_depth + 1,
1379 kind: MacroDirectiveKind::Derive { ast_id },
1380 });
1386 } 1381 }
1387 } 1382 }
1388 None => { 1383 None => {
@@ -1467,12 +1462,13 @@ impl ModCollector<'_, '_> {
1467 }, 1462 },
1468 ) { 1463 ) {
1469 Ok(Ok(macro_call_id)) => { 1464 Ok(Ok(macro_call_id)) => {
1470 self.def_collector.unexpanded_macros.push(MacroDirective { 1465 // Legacy macros need to be expanded immediately, so that any macros they produce
1471 module_id: self.module_id, 1466 // are in scope.
1472 ast_id, 1467 self.def_collector.collect_macro_expansion(
1473 legacy: Some(macro_call_id), 1468 self.module_id,
1474 depth: self.macro_depth + 1, 1469 macro_call_id,
1475 }); 1470 self.macro_depth + 1,
1471 );
1476 1472
1477 return; 1473 return;
1478 } 1474 }
@@ -1496,9 +1492,8 @@ impl ModCollector<'_, '_> {
1496 1492
1497 self.def_collector.unexpanded_macros.push(MacroDirective { 1493 self.def_collector.unexpanded_macros.push(MacroDirective {
1498 module_id: self.module_id, 1494 module_id: self.module_id,
1499 ast_id,
1500 legacy: None,
1501 depth: self.macro_depth + 1, 1495 depth: self.macro_depth + 1,
1496 kind: MacroDirectiveKind::FnLike { ast_id, legacy: None },
1502 }); 1497 });
1503 } 1498 }
1504 1499
@@ -1541,7 +1536,6 @@ mod tests {
1541 unresolved_imports: Vec::new(), 1536 unresolved_imports: Vec::new(),
1542 resolved_imports: Vec::new(), 1537 resolved_imports: Vec::new(),
1543 unexpanded_macros: Vec::new(), 1538 unexpanded_macros: Vec::new(),
1544 unexpanded_attribute_macros: Vec::new(),
1545 mod_dirs: FxHashMap::default(), 1539 mod_dirs: FxHashMap::default(),
1546 cfg_options: &CfgOptions::default(), 1540 cfg_options: &CfgOptions::default(),
1547 proc_macros: Default::default(), 1541 proc_macros: Default::default(),
diff --git a/crates/hir_def/src/nameres/mod_resolution.rs b/crates/hir_def/src/nameres/mod_resolution.rs
index d5de9899c..d9cec0e27 100644
--- a/crates/hir_def/src/nameres/mod_resolution.rs
+++ b/crates/hir_def/src/nameres/mod_resolution.rs
@@ -62,7 +62,7 @@ impl ModDir {
62 name: &Name, 62 name: &Name,
63 attr_path: Option<&SmolStr>, 63 attr_path: Option<&SmolStr>,
64 ) -> Result<(FileId, bool, ModDir), String> { 64 ) -> Result<(FileId, bool, ModDir), String> {
65 let file_id = file_id.original_file(db.upcast()); 65 let orig_file_id = file_id.original_file(db.upcast());
66 66
67 let mut candidate_files = Vec::new(); 67 let mut candidate_files = Vec::new();
68 match attr_path { 68 match attr_path {
@@ -70,13 +70,18 @@ impl ModDir {
70 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner)) 70 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
71 } 71 }
72 None => { 72 None => {
73 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name)); 73 if file_id.is_include_macro(db.upcast()) {
74 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name)); 74 candidate_files.push(format!("{}.rs", name));
75 candidate_files.push(format!("{}/mod.rs", name));
76 } else {
77 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
78 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
79 }
75 } 80 }
76 }; 81 };
77 82
78 for candidate in candidate_files.iter() { 83 for candidate in candidate_files.iter() {
79 let path = AnchoredPath { anchor: file_id, path: candidate.as_str() }; 84 let path = AnchoredPath { anchor: orig_file_id, path: candidate.as_str() };
80 if let Some(file_id) = db.resolve_path(path) { 85 if let Some(file_id) = db.resolve_path(path) {
81 let is_mod_rs = candidate.ends_with("/mod.rs"); 86 let is_mod_rs = candidate.ends_with("/mod.rs");
82 87
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index db459b1ed..60471937c 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -156,7 +156,7 @@ impl DefMap {
156 } 156 }
157 } 157 }
158 158
159 fn resolve_path_fp_with_macro_single( 159 pub(super) fn resolve_path_fp_with_macro_single(
160 &self, 160 &self,
161 db: &dyn DefDatabase, 161 db: &dyn DefDatabase,
162 mode: ResolveMode, 162 mode: ResolveMode,
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index d59d3c0db..6d3cb8d7a 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -713,6 +713,27 @@ b! { static = #[] ();}
713} 713}
714 714
715#[test] 715#[test]
716fn macros_defining_macros() {
717 check(
718 r#"
719macro_rules! item {
720 ($item:item) => { $item }
721}
722
723item! {
724 macro_rules! indirect_macro { () => { struct S {} } }
725}
726
727indirect_macro!();
728 "#,
729 expect![[r#"
730 crate
731 S: t
732 "#]],
733 );
734}
735
736#[test]
716fn resolves_proc_macros() { 737fn resolves_proc_macros() {
717 check( 738 check(
718 r" 739 r"
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index 42736171e..a73585ee7 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -12,7 +12,7 @@ use crate::{
12 body::scope::{ExprScopes, ScopeId}, 12 body::scope::{ExprScopes, ScopeId},
13 builtin_type::BuiltinType, 13 builtin_type::BuiltinType,
14 db::DefDatabase, 14 db::DefDatabase,
15 expr::{ExprId, PatId}, 15 expr::{ExprId, LabelId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 item_scope::{BuiltinShadowMode, BUILTIN_SCOPE}, 17 item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
18 nameres::DefMap, 18 nameres::DefMap,
@@ -409,6 +409,7 @@ pub enum ScopeDef {
409 AdtSelfType(AdtId), 409 AdtSelfType(AdtId),
410 GenericParam(GenericParamId), 410 GenericParam(GenericParamId),
411 Local(PatId), 411 Local(PatId),
412 Label(LabelId),
412} 413}
413 414
414impl Scope { 415impl Scope {
@@ -470,6 +471,9 @@ impl Scope {
470 f(name![Self], ScopeDef::AdtSelfType(*i)); 471 f(name![Self], ScopeDef::AdtSelfType(*i));
471 } 472 }
472 Scope::ExprScope(scope) => { 473 Scope::ExprScope(scope) => {
474 if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) {
475 f(name, ScopeDef::Label(label))
476 }
473 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { 477 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
474 f(e.name().clone(), ScopeDef::Local(e.pat())); 478 f(e.name().clone(), ScopeDef::Local(e.pat()));
475 }); 479 });
@@ -544,7 +548,7 @@ impl ModuleItemMap {
544 path: &ModPath, 548 path: &ModPath,
545 ) -> Option<ResolveValueResult> { 549 ) -> Option<ResolveValueResult> {
546 let (module_def, idx) = 550 let (module_def, idx) =
547 self.def_map.resolve_path(db, self.module_id, &path, BuiltinShadowMode::Other); 551 self.def_map.resolve_path_locally(db, self.module_id, &path, BuiltinShadowMode::Other);
548 match idx { 552 match idx {
549 None => { 553 None => {
550 let value = to_value_ns(module_def)?; 554 let value = to_value_ns(module_def)?;
@@ -574,7 +578,7 @@ impl ModuleItemMap {
574 path: &ModPath, 578 path: &ModPath,
575 ) -> Option<(TypeNs, Option<usize>)> { 579 ) -> Option<(TypeNs, Option<usize>)> {
576 let (module_def, idx) = 580 let (module_def, idx) =
577 self.def_map.resolve_path(db, self.module_id, &path, BuiltinShadowMode::Other); 581 self.def_map.resolve_path_locally(db, self.module_id, &path, BuiltinShadowMode::Other);
578 let res = to_type_ns(module_def)?; 582 let res = to_type_ns(module_def)?;
579 Some((res, idx)) 583 Some((res, idx))
580 } 584 }
@@ -623,8 +627,18 @@ pub trait HasResolver: Copy {
623 627
624impl HasResolver for ModuleId { 628impl HasResolver for ModuleId {
625 fn resolver(self, db: &dyn DefDatabase) -> Resolver { 629 fn resolver(self, db: &dyn DefDatabase) -> Resolver {
626 let def_map = self.def_map(db); 630 let mut def_map = self.def_map(db);
627 Resolver::default().push_module_scope(def_map, self.local_id) 631 let mut modules = Vec::new();
632 modules.push((def_map.clone(), self.local_id));
633 while let Some(parent) = def_map.parent() {
634 def_map = parent.def_map(db);
635 modules.push((def_map.clone(), parent.local_id));
636 }
637 let mut resolver = Resolver::default();
638 for (def_map, module) in modules.into_iter().rev() {
639 resolver = resolver.push_module_scope(def_map, module);
640 }
641 resolver
628 } 642 }
629} 643}
630 644
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 8529b43b6..4d52904b9 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -43,7 +43,7 @@ macro_rules! register_builtin {
43 db: &dyn AstDatabase, 43 db: &dyn AstDatabase,
44 arg_id: EagerMacroId, 44 arg_id: EagerMacroId,
45 tt: &tt::Subtree, 45 tt: &tt::Subtree,
46 ) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 46 ) -> ExpandResult<Option<ExpandedEager>> {
47 let expander = match *self { 47 let expander = match *self {
48 $( EagerExpander::$e_kind => $e_expand, )* 48 $( EagerExpander::$e_kind => $e_expand, )*
49 }; 49 };
@@ -61,6 +61,20 @@ macro_rules! register_builtin {
61 }; 61 };
62} 62}
63 63
64#[derive(Debug)]
65pub struct ExpandedEager {
66 pub(crate) subtree: tt::Subtree,
67 pub(crate) fragment: FragmentKind,
68 /// The included file ID of the include macro.
69 pub(crate) included_file: Option<FileId>,
70}
71
72impl ExpandedEager {
73 fn new(subtree: tt::Subtree, fragment: FragmentKind) -> Self {
74 ExpandedEager { subtree, fragment, included_file: None }
75 }
76}
77
64pub fn find_builtin_macro( 78pub fn find_builtin_macro(
65 ident: &name::Name, 79 ident: &name::Name,
66 krate: CrateId, 80 krate: CrateId,
@@ -280,7 +294,7 @@ fn compile_error_expand(
280 _db: &dyn AstDatabase, 294 _db: &dyn AstDatabase,
281 _id: EagerMacroId, 295 _id: EagerMacroId,
282 tt: &tt::Subtree, 296 tt: &tt::Subtree,
283) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 297) -> ExpandResult<Option<ExpandedEager>> {
284 let err = match &*tt.token_trees { 298 let err = match &*tt.token_trees {
285 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => { 299 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => {
286 let text = it.text.as_str(); 300 let text = it.text.as_str();
@@ -294,14 +308,14 @@ fn compile_error_expand(
294 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()), 308 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()),
295 }; 309 };
296 310
297 ExpandResult { value: Some((quote! {}, FragmentKind::Items)), err: Some(err) } 311 ExpandResult { value: Some(ExpandedEager::new(quote! {}, FragmentKind::Items)), err: Some(err) }
298} 312}
299 313
300fn concat_expand( 314fn concat_expand(
301 _db: &dyn AstDatabase, 315 _db: &dyn AstDatabase,
302 _arg_id: EagerMacroId, 316 _arg_id: EagerMacroId,
303 tt: &tt::Subtree, 317 tt: &tt::Subtree,
304) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 318) -> ExpandResult<Option<ExpandedEager>> {
305 let mut err = None; 319 let mut err = None;
306 let mut text = String::new(); 320 let mut text = String::new();
307 for (i, t) in tt.token_trees.iter().enumerate() { 321 for (i, t) in tt.token_trees.iter().enumerate() {
@@ -325,7 +339,7 @@ fn concat_expand(
325 } 339 }
326 } 340 }
327 } 341 }
328 ExpandResult { value: Some((quote!(#text), FragmentKind::Expr)), err } 342 ExpandResult { value: Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)), err }
329} 343}
330 344
331fn relative_file( 345fn relative_file(
@@ -361,21 +375,27 @@ fn include_expand(
361 db: &dyn AstDatabase, 375 db: &dyn AstDatabase,
362 arg_id: EagerMacroId, 376 arg_id: EagerMacroId,
363 tt: &tt::Subtree, 377 tt: &tt::Subtree,
364) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 378) -> ExpandResult<Option<ExpandedEager>> {
365 let res = (|| { 379 let res = (|| {
366 let path = parse_string(tt)?; 380 let path = parse_string(tt)?;
367 let file_id = relative_file(db, arg_id.into(), &path, false)?; 381 let file_id = relative_file(db, arg_id.into(), &path, false)?;
368 382
369 Ok(parse_to_token_tree(&db.file_text(file_id)) 383 let subtree = parse_to_token_tree(&db.file_text(file_id))
370 .ok_or_else(|| mbe::ExpandError::ConversionError)? 384 .ok_or_else(|| mbe::ExpandError::ConversionError)?
371 .0) 385 .0;
386 Ok((subtree, file_id))
372 })(); 387 })();
373 388
374 match res { 389 match res {
375 Ok(res) => { 390 Ok((subtree, file_id)) => {
376 // FIXME: 391 // FIXME:
377 // Handle include as expression 392 // Handle include as expression
378 ExpandResult::ok(Some((res, FragmentKind::Items))) 393
394 ExpandResult::ok(Some(ExpandedEager {
395 subtree,
396 fragment: FragmentKind::Items,
397 included_file: Some(file_id),
398 }))
379 } 399 }
380 Err(e) => ExpandResult::only_err(e), 400 Err(e) => ExpandResult::only_err(e),
381 } 401 }
@@ -385,7 +405,7 @@ fn include_bytes_expand(
385 _db: &dyn AstDatabase, 405 _db: &dyn AstDatabase,
386 _arg_id: EagerMacroId, 406 _arg_id: EagerMacroId,
387 tt: &tt::Subtree, 407 tt: &tt::Subtree,
388) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 408) -> ExpandResult<Option<ExpandedEager>> {
389 if let Err(e) = parse_string(tt) { 409 if let Err(e) = parse_string(tt) {
390 return ExpandResult::only_err(e); 410 return ExpandResult::only_err(e);
391 } 411 }
@@ -398,14 +418,14 @@ fn include_bytes_expand(
398 id: tt::TokenId::unspecified(), 418 id: tt::TokenId::unspecified(),
399 }))], 419 }))],
400 }; 420 };
401 ExpandResult::ok(Some((res, FragmentKind::Expr))) 421 ExpandResult::ok(Some(ExpandedEager::new(res, FragmentKind::Expr)))
402} 422}
403 423
404fn include_str_expand( 424fn include_str_expand(
405 db: &dyn AstDatabase, 425 db: &dyn AstDatabase,
406 arg_id: EagerMacroId, 426 arg_id: EagerMacroId,
407 tt: &tt::Subtree, 427 tt: &tt::Subtree,
408) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 428) -> ExpandResult<Option<ExpandedEager>> {
409 let path = match parse_string(tt) { 429 let path = match parse_string(tt) {
410 Ok(it) => it, 430 Ok(it) => it,
411 Err(e) => return ExpandResult::only_err(e), 431 Err(e) => return ExpandResult::only_err(e),
@@ -418,14 +438,14 @@ fn include_str_expand(
418 let file_id = match relative_file(db, arg_id.into(), &path, true) { 438 let file_id = match relative_file(db, arg_id.into(), &path, true) {
419 Ok(file_id) => file_id, 439 Ok(file_id) => file_id,
420 Err(_) => { 440 Err(_) => {
421 return ExpandResult::ok(Some((quote!(""), FragmentKind::Expr))); 441 return ExpandResult::ok(Some(ExpandedEager::new(quote!(""), FragmentKind::Expr)));
422 } 442 }
423 }; 443 };
424 444
425 let text = db.file_text(file_id); 445 let text = db.file_text(file_id);
426 let text = &*text; 446 let text = &*text;
427 447
428 ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr))) 448 ExpandResult::ok(Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)))
429} 449}
430 450
431fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { 451fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
@@ -437,7 +457,7 @@ fn env_expand(
437 db: &dyn AstDatabase, 457 db: &dyn AstDatabase,
438 arg_id: EagerMacroId, 458 arg_id: EagerMacroId,
439 tt: &tt::Subtree, 459 tt: &tt::Subtree,
440) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 460) -> ExpandResult<Option<ExpandedEager>> {
441 let key = match parse_string(tt) { 461 let key = match parse_string(tt) {
442 Ok(it) => it, 462 Ok(it) => it,
443 Err(e) => return ExpandResult::only_err(e), 463 Err(e) => return ExpandResult::only_err(e),
@@ -461,14 +481,14 @@ fn env_expand(
461 }); 481 });
462 let expanded = quote! { #s }; 482 let expanded = quote! { #s };
463 483
464 ExpandResult { value: Some((expanded, FragmentKind::Expr)), err } 484 ExpandResult { value: Some(ExpandedEager::new(expanded, FragmentKind::Expr)), err }
465} 485}
466 486
467fn option_env_expand( 487fn option_env_expand(
468 db: &dyn AstDatabase, 488 db: &dyn AstDatabase,
469 arg_id: EagerMacroId, 489 arg_id: EagerMacroId,
470 tt: &tt::Subtree, 490 tt: &tt::Subtree,
471) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 491) -> ExpandResult<Option<ExpandedEager>> {
472 let key = match parse_string(tt) { 492 let key = match parse_string(tt) {
473 Ok(it) => it, 493 Ok(it) => it,
474 Err(e) => return ExpandResult::only_err(e), 494 Err(e) => return ExpandResult::only_err(e),
@@ -479,7 +499,7 @@ fn option_env_expand(
479 Some(s) => quote! { std::option::Some(#s) }, 499 Some(s) => quote! { std::option::Some(#s) },
480 }; 500 };
481 501
482 ExpandResult::ok(Some((expanded, FragmentKind::Expr))) 502 ExpandResult::ok(Some(ExpandedEager::new(expanded, FragmentKind::Expr)))
483} 503}
484 504
485#[cfg(test)] 505#[cfg(test)]
@@ -553,16 +573,18 @@ mod tests {
553 subtree: Arc::new(parsed_args.clone()), 573 subtree: Arc::new(parsed_args.clone()),
554 krate, 574 krate,
555 call: call_id, 575 call: call_id,
576 included_file: None,
556 } 577 }
557 }); 578 });
558 579
559 let (subtree, fragment) = expander.expand(&db, arg_id, &parsed_args).value.unwrap(); 580 let expanded = expander.expand(&db, arg_id, &parsed_args).value.unwrap();
560 let eager = EagerCallLoc { 581 let eager = EagerCallLoc {
561 def, 582 def,
562 fragment, 583 fragment: expanded.fragment,
563 subtree: Arc::new(subtree), 584 subtree: Arc::new(expanded.subtree),
564 krate, 585 krate,
565 call: call_id, 586 call: call_id,
587 included_file: expanded.included_file,
566 }; 588 };
567 589
568 let id: MacroCallId = db.intern_eager_expansion(eager).into(); 590 let id: MacroCallId = db.intern_eager_expansion(eager).into();
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index 2748e25cf..fc73e435b 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -173,7 +173,7 @@ fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> {
173 }; 173 };
174 let loc = db.lookup_intern_macro(id); 174 let loc = db.lookup_intern_macro(id);
175 let arg = loc.kind.arg(db)?; 175 let arg = loc.kind.arg(db)?;
176 Some(arg.green().to_owned()) 176 Some(arg.green())
177} 177}
178 178
179fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { 179fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> {
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index 04f374a29..9eedc8461 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -124,6 +124,7 @@ pub fn expand_eager_macro(
124 subtree: Arc::new(parsed_args.clone()), 124 subtree: Arc::new(parsed_args.clone()),
125 krate, 125 krate,
126 call: call_id, 126 call: call_id,
127 included_file: None,
127 } 128 }
128 }); 129 });
129 let arg_file_id: MacroCallId = arg_id.into(); 130 let arg_file_id: MacroCallId = arg_id.into();
@@ -143,9 +144,15 @@ pub fn expand_eager_macro(
143 if let MacroDefKind::BuiltInEager(eager, _) = def.kind { 144 if let MacroDefKind::BuiltInEager(eager, _) = def.kind {
144 let res = eager.expand(db, arg_id, &subtree); 145 let res = eager.expand(db, arg_id, &subtree);
145 146
146 let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?; 147 let expanded = diagnostic_sink.expand_result_option(res)?;
147 let eager = 148 let eager = EagerCallLoc {
148 EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id }; 149 def,
150 fragment: expanded.fragment,
151 subtree: Arc::new(expanded.subtree),
152 krate,
153 call: call_id,
154 included_file: expanded.included_file,
155 };
149 156
150 Ok(db.intern_eager_expansion(eager)) 157 Ok(db.intern_eager_expansion(eager))
151 } else { 158 } else {
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index f49fd4fda..b8045fda9 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -84,7 +84,11 @@ impl HirFileId {
84 } 84 }
85 MacroCallId::EagerMacro(id) => { 85 MacroCallId::EagerMacro(id) => {
86 let loc = db.lookup_intern_eager_expansion(id); 86 let loc = db.lookup_intern_eager_expansion(id);
87 loc.call.file_id 87 if let Some(included_file) = loc.included_file {
88 return included_file;
89 } else {
90 loc.call.file_id
91 }
88 } 92 }
89 }; 93 };
90 file_id.original_file(db) 94 file_id.original_file(db)
@@ -188,6 +192,21 @@ impl HirFileId {
188 } 192 }
189 } 193 }
190 } 194 }
195
196 /// Return whether this file is an include macro
197 pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool {
198 match self.0 {
199 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
200 MacroCallId::EagerMacro(id) => {
201 let loc = db.lookup_intern_eager_expansion(id);
202 return loc.included_file.is_some();
203 }
204 _ => {}
205 },
206 _ => {}
207 }
208 false
209 }
191} 210}
192 211
193#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 212#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -315,6 +334,8 @@ pub struct EagerCallLoc {
315 pub(crate) subtree: Arc<tt::Subtree>, 334 pub(crate) subtree: Arc<tt::Subtree>,
316 pub(crate) krate: CrateId, 335 pub(crate) krate: CrateId,
317 pub(crate) call: AstId<ast::MacroCall>, 336 pub(crate) call: AstId<ast::MacroCall>,
337 // The included file ID of the include macro.
338 pub(crate) included_file: Option<FileId>,
318} 339}
319 340
320/// ExpansionInfo mainly describes how to map text range between src and expanded macro 341/// ExpansionInfo mainly describes how to map text range between src and expanded macro
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 43de9edd6..0aeea48d5 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -48,9 +48,8 @@ impl Name {
48 48
49 /// Resolve a name from the text of token. 49 /// Resolve a name from the text of token.
50 fn resolve(raw_text: &str) -> Name { 50 fn resolve(raw_text: &str) -> Name {
51 let raw_start = "r#"; 51 if let Some(text) = raw_text.strip_prefix("r#") {
52 if raw_text.starts_with(raw_start) { 52 Name::new_text(SmolStr::new(text))
53 Name::new_text(SmolStr::new(&raw_text[raw_start.len()..]))
54 } else { 53 } else {
55 Name::new_text(raw_text.into()) 54 Name::new_text(raw_text.into())
56 } 55 }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index 23ab042c1..dc5fc759a 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -16,8 +16,8 @@ use crate::{
16 to_assoc_type_id, to_chalk_trait_id, 16 to_assoc_type_id, to_chalk_trait_id,
17 traits::{InEnvironment, Solution}, 17 traits::{InEnvironment, Solution},
18 utils::generics, 18 utils::generics,
19 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, ProjectionTy, Substitution, 19 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner,
20 TraitRef, Ty, TyKind, 20 ProjectionTy, Substitution, TraitRef, Ty, TyKind,
21}; 21};
22 22
23const AUTODEREF_RECURSION_LIMIT: usize = 10; 23const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -27,9 +27,9 @@ pub fn autoderef<'a>(
27 krate: Option<CrateId>, 27 krate: Option<CrateId>,
28 ty: InEnvironment<Canonical<Ty>>, 28 ty: InEnvironment<Canonical<Ty>>,
29) -> impl Iterator<Item = Canonical<Ty>> + 'a { 29) -> impl Iterator<Item = Canonical<Ty>> + 'a {
30 let InEnvironment { value: ty, environment } = ty; 30 let InEnvironment { goal: ty, environment } = ty;
31 successors(Some(ty), move |ty| { 31 successors(Some(ty), move |ty| {
32 deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() }) 32 deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() })
33 }) 33 })
34 .take(AUTODEREF_RECURSION_LIMIT) 34 .take(AUTODEREF_RECURSION_LIMIT)
35} 35}
@@ -39,8 +39,8 @@ pub(crate) fn deref(
39 krate: CrateId, 39 krate: CrateId,
40 ty: InEnvironment<&Canonical<Ty>>, 40 ty: InEnvironment<&Canonical<Ty>>,
41) -> Option<Canonical<Ty>> { 41) -> Option<Canonical<Ty>> {
42 if let Some(derefed) = ty.value.value.builtin_deref() { 42 if let Some(derefed) = ty.goal.value.builtin_deref() {
43 Some(Canonical { value: derefed, kinds: ty.value.kinds.clone() }) 43 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
44 } else { 44 } else {
45 deref_by_trait(db, krate, ty) 45 deref_by_trait(db, krate, ty)
46 } 46 }
@@ -67,15 +67,15 @@ fn deref_by_trait(
67 // FIXME make the Canonical / bound var handling nicer 67 // FIXME make the Canonical / bound var handling nicer
68 68
69 let parameters = 69 let parameters =
70 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 70 Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
71 71
72 // Check that the type implements Deref at all 72 // Check that the type implements Deref at all
73 let trait_ref = 73 let trait_ref =
74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() }; 74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
75 let implements_goal = Canonical { 75 let implements_goal = Canonical {
76 kinds: ty.value.kinds.clone(), 76 binders: ty.goal.binders.clone(),
77 value: InEnvironment { 77 value: InEnvironment {
78 value: trait_ref.cast(&Interner), 78 goal: trait_ref.cast(&Interner),
79 environment: ty.environment.clone(), 79 environment: ty.environment.clone(),
80 }, 80 },
81 }; 81 };
@@ -89,18 +89,27 @@ fn deref_by_trait(
89 associated_ty_id: to_assoc_type_id(target), 89 associated_ty_id: to_assoc_type_id(target),
90 substitution: parameters, 90 substitution: parameters,
91 }), 91 }),
92 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) 92 ty: TyKind::BoundVar(BoundVar::new(
93 .intern(&Interner), 93 DebruijnIndex::INNERMOST,
94 ty.goal.binders.len(&Interner),
95 ))
96 .intern(&Interner),
94 }; 97 };
95 98
96 let obligation = projection.cast(&Interner); 99 let obligation = projection.cast(&Interner);
97 100
98 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
99 102
100 let canonical = Canonical::new( 103 let canonical = Canonical {
101 in_env, 104 value: in_env,
102 ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)), 105 binders: CanonicalVarKinds::from_iter(
103 ); 106 &Interner,
107 ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
108 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
109 chalk_ir::UniverseIndex::ROOT,
110 ))),
111 ),
112 };
104 113
105 let solution = db.trait_solve(krate, canonical)?; 114 let solution = db.trait_solve(krate, canonical)?;
106 115
@@ -121,21 +130,21 @@ fn deref_by_trait(
121 // assumptions will be broken. We would need to properly introduce 130 // assumptions will be broken. We would need to properly introduce
122 // new variables in that case 131 // new variables in that case
123 132
124 for i in 1..vars.0.kinds.len() { 133 for i in 1..vars.0.binders.len(&Interner) {
125 if vars.0.value[i - 1].interned(&Interner) 134 if vars.0.value[i - 1].interned(&Interner)
126 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
127 { 136 {
128 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
129 return None; 138 return None;
130 } 139 }
131 } 140 }
132 Some(Canonical { 141 Some(Canonical {
133 value: vars.0.value[vars.0.value.len() - 1].clone(), 142 value: vars.0.value[vars.0.value.len() - 1].clone(),
134 kinds: vars.0.kinds.clone(), 143 binders: vars.0.binders.clone(),
135 }) 144 })
136 } 145 }
137 Solution::Ambig(_) => { 146 Solution::Ambig(_) => {
138 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); 147 info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution);
139 None 148 None
140 } 149 }
141 } 150 }
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 91a2e0b5b..58e4247c6 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -12,8 +12,8 @@ use la_arena::ArenaMap;
12use crate::{ 12use crate::{
13 method_resolution::{InherentImpls, TraitImpls}, 13 method_resolution::{InherentImpls, TraitImpls},
14 traits::chalk, 14 traits::chalk,
15 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig, ReturnTypeImplTraits, 15 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig,
16 TraitRef, Ty, TyDefId, ValueTyDefId, WhereClause, 16 QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
17}; 17};
18use hir_expand::name::Name; 18use hir_expand::name::Name;
19 19
@@ -57,10 +57,13 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
57 57
58 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] 58 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
59 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] 59 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
60 fn generic_predicates_for_param(&self, param_id: TypeParamId) -> Arc<[Binders<WhereClause>]>; 60 fn generic_predicates_for_param(
61 &self,
62 param_id: TypeParamId,
63 ) -> Arc<[Binders<QuantifiedWhereClause>]>;
61 64
62 #[salsa::invoke(crate::lower::generic_predicates_query)] 65 #[salsa::invoke(crate::lower::generic_predicates_query)]
63 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<WhereClause>]>; 66 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<QuantifiedWhereClause>]>;
64 67
65 #[salsa::invoke(crate::lower::trait_environment_query)] 68 #[salsa::invoke(crate::lower::trait_environment_query)]
66 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>; 69 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 3845009ae..6149067c7 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{borrow::Cow, fmt}; 3use std::fmt;
4 4
5use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability; 6use chalk_ir::Mutability;
@@ -20,7 +20,7 @@ use crate::{
20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, 20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, 21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, 22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
23 ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, 23 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
24}; 24};
25 25
26pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -190,6 +190,7 @@ impl DisplayTarget {
190pub enum DisplaySourceCodeError { 190pub enum DisplaySourceCodeError {
191 PathNotFound, 191 PathNotFound,
192 UnknownType, 192 UnknownType,
193 Closure,
193} 194}
194 195
195pub enum HirDisplayError { 196pub enum HirDisplayError {
@@ -328,9 +329,9 @@ impl HirDisplay for Ty {
328 329
329 // FIXME: all this just to decide whether to use parentheses... 330 // FIXME: all this just to decide whether to use parentheses...
330 let datas; 331 let datas;
331 let predicates = match t.interned(&Interner) { 332 let predicates: Vec<_> = match t.interned(&Interner) {
332 TyKind::Dyn(predicates) if predicates.len() > 1 => { 333 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
333 Cow::Borrowed(predicates.as_ref()) 334 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect()
334 } 335 }
335 &TyKind::Alias(AliasTy::Opaque(OpaqueTy { 336 &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
336 opaque_ty_id, 337 opaque_ty_id,
@@ -345,17 +346,21 @@ impl HirDisplay for Ty {
345 .as_ref() 346 .as_ref()
346 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 347 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
347 let bounds = data.subst(parameters); 348 let bounds = data.subst(parameters);
348 Cow::Owned(bounds.value) 349 bounds.value
349 } else { 350 } else {
350 Cow::Borrowed(&[][..]) 351 Vec::new()
351 } 352 }
352 } 353 }
353 _ => Cow::Borrowed(&[][..]), 354 _ => Vec::new(),
354 }; 355 };
355 356
356 if let [WhereClause::Implemented(trait_ref), _] = predicates.as_ref() { 357 if let Some(WhereClause::Implemented(trait_ref)) =
358 predicates.get(0).map(|b| b.skip_binders())
359 {
357 let trait_ = trait_ref.hir_trait_id(); 360 let trait_ = trait_ref.hir_trait_id();
358 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) { 361 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
362 && predicates.len() <= 2
363 {
359 return write!(f, "{}", ty_display); 364 return write!(f, "{}", ty_display);
360 } 365 }
361 } 366 }
@@ -539,6 +544,11 @@ impl HirDisplay for Ty {
539 } 544 }
540 } 545 }
541 TyKind::Closure(.., substs) => { 546 TyKind::Closure(.., substs) => {
547 if f.display_target.is_source_code() {
548 return Err(HirDisplayError::DisplaySourceCodeError(
549 DisplaySourceCodeError::Closure,
550 ));
551 }
542 let sig = substs[0].callable_sig(f.db); 552 let sig = substs[0].callable_sig(f.db);
543 if let Some(sig) = sig { 553 if let Some(sig) = sig {
544 if sig.params().is_empty() { 554 if sig.params().is_empty() {
@@ -571,19 +581,32 @@ impl HirDisplay for Ty {
571 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 581 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
572 } 582 }
573 TypeParamProvenance::ArgumentImplTrait => { 583 TypeParamProvenance::ArgumentImplTrait => {
574 let bounds = f.db.generic_predicates_for_param(id);
575 let substs = Substitution::type_params_for_generics(f.db, &generics); 584 let substs = Substitution::type_params_for_generics(f.db, &generics);
576 write_bounds_like_dyn_trait_with_prefix( 585 let bounds = f
577 "impl", 586 .db
578 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 587 .generic_predicates(id.parent)
579 f, 588 .into_iter()
580 )?; 589 .map(|pred| pred.clone().subst(&substs))
590 .filter(|wc| match &wc.skip_binders() {
591 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
592 WhereClause::AliasEq(AliasEq {
593 alias: AliasTy::Projection(proj),
594 ty: _,
595 }) => proj.self_type_parameter() == self,
596 _ => false,
597 })
598 .collect::<Vec<_>>();
599 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
581 } 600 }
582 } 601 }
583 } 602 }
584 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 603 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
585 TyKind::Dyn(predicates) => { 604 TyKind::Dyn(dyn_ty) => {
586 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 605 write_bounds_like_dyn_trait_with_prefix(
606 "dyn",
607 dyn_ty.bounds.skip_binders().interned(),
608 f,
609 )?;
587 } 610 }
588 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, 611 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
589 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { 612 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
@@ -652,7 +675,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
652 675
653pub fn write_bounds_like_dyn_trait_with_prefix( 676pub fn write_bounds_like_dyn_trait_with_prefix(
654 prefix: &str, 677 prefix: &str,
655 predicates: &[WhereClause], 678 predicates: &[QuantifiedWhereClause],
656 f: &mut HirFormatter, 679 f: &mut HirFormatter,
657) -> Result<(), HirDisplayError> { 680) -> Result<(), HirDisplayError> {
658 write!(f, "{}", prefix)?; 681 write!(f, "{}", prefix)?;
@@ -665,7 +688,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
665} 688}
666 689
667fn write_bounds_like_dyn_trait( 690fn write_bounds_like_dyn_trait(
668 predicates: &[WhereClause], 691 predicates: &[QuantifiedWhereClause],
669 f: &mut HirFormatter, 692 f: &mut HirFormatter,
670) -> Result<(), HirDisplayError> { 693) -> Result<(), HirDisplayError> {
671 // Note: This code is written to produce nice results (i.e. 694 // Note: This code is written to produce nice results (i.e.
@@ -678,7 +701,7 @@ fn write_bounds_like_dyn_trait(
678 let mut angle_open = false; 701 let mut angle_open = false;
679 let mut is_fn_trait = false; 702 let mut is_fn_trait = false;
680 for p in predicates.iter() { 703 for p in predicates.iter() {
681 match p { 704 match p.skip_binders() {
682 WhereClause::Implemented(trait_ref) => { 705 WhereClause::Implemented(trait_ref) => {
683 let trait_ = trait_ref.hir_trait_id(); 706 let trait_ = trait_ref.hir_trait_id();
684 if !is_fn_trait { 707 if !is_fn_trait {
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index b9e434c78..8f9cf7480 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -331,7 +331,7 @@ impl<'a> InferenceContext<'a> {
331 fn resolve_obligations_as_possible(&mut self) { 331 fn resolve_obligations_as_possible(&mut self) {
332 let obligations = mem::replace(&mut self.obligations, Vec::new()); 332 let obligations = mem::replace(&mut self.obligations, Vec::new());
333 for obligation in obligations { 333 for obligation in obligations {
334 let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); 334 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone());
335 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); 335 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
336 let solution = 336 let solution =
337 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); 337 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 07eb96573..9c62932b1 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -142,7 +142,7 @@ impl<'a> InferenceContext<'a> {
142 .build(); 142 .build();
143 let trait_ref = 143 let trait_ref =
144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs }; 144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
145 let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner)); 145 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner));
146 146
147 let canonicalizer = self.canonicalizer(); 147 let canonicalizer = self.canonicalizer();
148 let canonicalized = canonicalizer.canonicalize_obligation(goal); 148 let canonicalized = canonicalizer.canonicalize_obligation(goal);
@@ -170,8 +170,8 @@ impl<'a> InferenceContext<'a> {
170 self.db, 170 self.db,
171 self.resolver.krate(), 171 self.resolver.krate(),
172 InEnvironment { 172 InEnvironment {
173 value: canonicalized.value.clone(), 173 goal: canonicalized.value.clone(),
174 environment: self.trait_env.clone(), 174 environment: self.trait_env.env.clone(),
175 }, 175 },
176 ) { 176 ) {
177 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 177 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 46d713a7b..3f3187ea2 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -11,6 +11,7 @@ use hir_def::{
11 AssocContainerId, FieldId, Lookup, 11 AssocContainerId, FieldId, Lookup,
12}; 12};
13use hir_expand::name::{name, Name}; 13use hir_expand::name::{name, Name};
14use stdx::always;
14use syntax::ast::RangeOp; 15use syntax::ast::RangeOp;
15 16
16use crate::{ 17use crate::{
@@ -89,12 +90,12 @@ impl<'a> InferenceContext<'a> {
89 let substs = 90 let substs =
90 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 92
92 let trait_env = Arc::clone(&self.trait_env); 93 let trait_env = self.trait_env.env.clone();
93 let implements_fn_trait: DomainGoal = 94 let implements_fn_trait: DomainGoal =
94 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
95 .cast(&Interner); 96 .cast(&Interner);
96 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { 97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
97 value: implements_fn_trait.clone(), 98 goal: implements_fn_trait.clone(),
98 environment: trait_env, 99 environment: trait_env,
99 }); 100 });
100 if self.db.trait_solve(krate, goal.value).is_some() { 101 if self.db.trait_solve(krate, goal.value).is_some() {
@@ -298,8 +299,8 @@ impl<'a> InferenceContext<'a> {
298 self.db, 299 self.db,
299 self.resolver.krate(), 300 self.resolver.krate(),
300 InEnvironment { 301 InEnvironment {
301 value: canonicalized.value.clone(), 302 goal: canonicalized.value.clone(),
302 environment: self.trait_env.clone(), 303 environment: self.trait_env.env.clone(),
303 }, 304 },
304 ); 305 );
305 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs 306 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs
@@ -437,8 +438,8 @@ impl<'a> InferenceContext<'a> {
437 self.db, 438 self.db,
438 self.resolver.krate(), 439 self.resolver.krate(),
439 InEnvironment { 440 InEnvironment {
440 value: canonicalized.value.clone(), 441 goal: canonicalized.value.clone(),
441 environment: self.trait_env.clone(), 442 environment: self.trait_env.env.clone(),
442 }, 443 },
443 ) 444 )
444 .find_map(|derefed_ty| { 445 .find_map(|derefed_ty| {
@@ -533,10 +534,10 @@ impl<'a> InferenceContext<'a> {
533 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 534 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
534 if let Some(box_) = self.resolve_boxed_box() { 535 if let Some(box_) = self.resolve_boxed_box() {
535 let mut sb = 536 let mut sb =
536 Substitution::builder(generics(self.db.upcast(), box_.into()).len()); 537 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into()));
537 sb = sb.push(inner_ty); 538 sb = sb.push(inner_ty);
538 match self.db.generic_defaults(box_.into()).as_ref() { 539 match self.db.generic_defaults(box_.into()).get(1) {
539 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { 540 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
540 sb = sb.push(alloc_ty.value.clone()); 541 sb = sb.push(alloc_ty.value.clone());
541 } 542 }
542 _ => (), 543 _ => (),
@@ -557,8 +558,8 @@ impl<'a> InferenceContext<'a> {
557 self.db, 558 self.db,
558 krate, 559 krate,
559 InEnvironment { 560 InEnvironment {
560 value: &canonicalized.value, 561 goal: &canonicalized.value,
561 environment: self.trait_env.clone(), 562 environment: self.trait_env.env.clone(),
562 }, 563 },
563 ) { 564 ) {
564 Some(derefed_ty) => { 565 Some(derefed_ty) => {
@@ -957,7 +958,9 @@ impl<'a> InferenceContext<'a> {
957 let def: CallableDefId = from_chalk(self.db, *fn_def); 958 let def: CallableDefId = from_chalk(self.db, *fn_def);
958 let generic_predicates = self.db.generic_predicates(def.into()); 959 let generic_predicates = self.db.generic_predicates(def.into());
959 for predicate in generic_predicates.iter() { 960 for predicate in generic_predicates.iter() {
960 let predicate = predicate.clone().subst(parameters); 961 let (predicate, binders) =
962 predicate.clone().subst(parameters).into_value_and_skipped_binders();
963 always!(binders == 0); // quantified where clauses not yet handled
961 self.obligations.push(predicate.cast(&Interner)); 964 self.obligations.push(predicate.cast(&Interner));
962 } 965 }
963 // add obligation for trait implementation, if this is a trait method 966 // add obligation for trait implementation, if this is a trait method
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index befa0d69b..474363709 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,7 +13,9 @@ use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 15use crate::{
16 lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyKind, 16 lower::lower_to_chalk_mutability,
17 utils::{generics, variant_data},
18 Interner, Substitution, Ty, TyKind,
17}; 19};
18 20
19impl<'a> InferenceContext<'a> { 21impl<'a> InferenceContext<'a> {
@@ -38,7 +40,7 @@ impl<'a> InferenceContext<'a> {
38 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
39 let (pre, post) = match ellipsis { 41 let (pre, post) = match ellipsis {
40 Some(idx) => subpats.split_at(idx), 42 Some(idx) => subpats.split_at(idx),
41 None => (&subpats[..], &[][..]), 43 None => (subpats, &[][..]),
42 }; 44 };
43 let post_idx_offset = field_tys.iter().count() - post.len(); 45 let post_idx_offset = field_tys.iter().count() - post.len();
44 46
@@ -233,13 +235,31 @@ impl<'a> InferenceContext<'a> {
233 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), 235 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
234 Pat::Box { inner } => match self.resolve_boxed_box() { 236 Pat::Box { inner } => match self.resolve_boxed_box() {
235 Some(box_adt) => { 237 Some(box_adt) => {
236 let inner_expected = match expected.as_adt() { 238 let (inner_ty, alloc_ty) = match expected.as_adt() {
237 Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), 239 Some((adt, subst)) if adt == box_adt => {
238 _ => self.result.standard_types.unknown.clone(), 240 (subst[0].clone(), subst.get(1).cloned())
241 }
242 _ => (self.result.standard_types.unknown.clone(), None),
239 }; 243 };
240 244
241 let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); 245 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
242 Ty::adt_ty(box_adt, Substitution::single(inner_ty)) 246 let mut sb = Substitution::build_for_generics(&generics(
247 self.db.upcast(),
248 box_adt.into(),
249 ));
250 sb = sb.push(inner_ty);
251 if sb.remaining() == 1 {
252 sb = sb.push(match alloc_ty {
253 Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
254 _ => match self.db.generic_defaults(box_adt.into()).get(1) {
255 Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
256 alloc_ty.value.clone()
257 }
258 _ => self.table.new_type_var(),
259 },
260 });
261 }
262 Ty::adt_ty(box_adt, sb.build())
243 } 263 }
244 None => self.err_ty(), 264 None => self.err_ty(),
245 }, 265 },
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 1fc03c8f4..75250a369 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,13 +2,13 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind}; 5use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind};
6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 7
8use super::{DomainGoal, InferenceContext}; 8use super::{DomainGoal, InferenceContext};
9use crate::{ 9use crate::{
10 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar, 10 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer,
11 Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, 11 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
12}; 12};
13 13
14impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
@@ -76,8 +76,17 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
76 } 76 }
77 77
78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> {
79 let kinds = self.free_vars.iter().map(|&(_, k)| k).collect(); 79 let kinds = self
80 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } 80 .free_vars
81 .iter()
82 .map(|&(_, k)| chalk_ir::WithKind::new(VariableKind::Ty(k), UniverseIndex::ROOT));
83 Canonicalized {
84 value: Canonical {
85 value: result,
86 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
87 },
88 free_vars: self.free_vars,
89 }
81 } 90 }
82 91
83 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { 92 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> {
@@ -89,15 +98,12 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
89 mut self, 98 mut self,
90 obligation: InEnvironment<DomainGoal>, 99 obligation: InEnvironment<DomainGoal>,
91 ) -> Canonicalized<InEnvironment<DomainGoal>> { 100 ) -> Canonicalized<InEnvironment<DomainGoal>> {
92 let result = match obligation.value { 101 let result = match obligation.goal {
93 DomainGoal::Holds(wc) => { 102 DomainGoal::Holds(wc) => {
94 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) 103 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
95 } 104 }
96 }; 105 };
97 self.into_canonicalized(InEnvironment { 106 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment })
98 value: result,
99 environment: obligation.environment,
100 })
101 } 107 }
102} 108}
103 109
@@ -125,12 +131,19 @@ impl<T> Canonicalized<T> {
125 // the solution may contain new variables, which we need to convert to new inference vars 131 // the solution may contain new variables, which we need to convert to new inference vars
126 let new_vars = Substitution( 132 let new_vars = Substitution(
127 solution 133 solution
128 .kinds 134 .binders
129 .iter() 135 .iter(&Interner)
130 .map(|k| match k { 136 .map(|k| match k.kind {
131 TyVariableKind::General => ctx.table.new_type_var(), 137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
132 TyVariableKind::Integer => ctx.table.new_integer_var(), 138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
133 TyVariableKind::Float => ctx.table.new_float_var(), 139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
140 // HACK: Chalk can sometimes return new lifetime variables. We
141 // want to just skip them, but to not mess up the indices of
142 // other variables, we'll just create a new type variable in
143 // their place instead. This should not matter (we never see the
144 // actual *uses* of the lifetime variable).
145 VariableKind::Lifetime => ctx.table.new_type_var(),
146 _ => panic!("const variable in solution"),
134 }) 147 })
135 .collect(), 148 .collect(),
136 ); 149 );
@@ -147,8 +160,8 @@ impl<T> Canonicalized<T> {
147pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 160pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
148 let mut table = InferenceTable::new(); 161 let mut table = InferenceTable::new();
149 let vars = Substitution( 162 let vars = Substitution(
150 tys.kinds 163 tys.binders
151 .iter() 164 .iter(&Interner)
152 // we always use type vars here because we want everything to 165 // we always use type vars here because we want everything to
153 // fallback to Unknown in the end (kind of hacky, as below) 166 // fallback to Unknown in the end (kind of hacky, as below)
154 .map(|_| table.new_type_var()) 167 .map(|_| table.new_type_var())
@@ -170,7 +183,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
170 } 183 }
171 } 184 }
172 Some( 185 Some(
173 Substitution::builder(tys.kinds.len()) 186 Substitution::builder(tys.binders.len(&Interner))
174 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 187 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone())))
175 .build(), 188 .build(),
176 ) 189 )
@@ -310,9 +323,18 @@ impl InferenceTable {
310 323
311 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 324 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
312 325
313 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { 326 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2))
314 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { 327 if dyn1.bounds.skip_binders().interned().len()
315 if !self.unify_preds(pred1, pred2, depth + 1) { 328 == dyn2.bounds.skip_binders().interned().len() =>
329 {
330 for (pred1, pred2) in dyn1
331 .bounds
332 .skip_binders()
333 .interned()
334 .iter()
335 .zip(dyn2.bounds.skip_binders().interned().iter())
336 {
337 if !self.unify_preds(pred1.skip_binders(), pred2.skip_binders(), depth + 1) {
316 return false; 338 return false;
317 } 339 }
318 } 340 }
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index c46529879..69265286f 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -61,6 +61,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
63 63
64pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
65
64pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 66pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
65 67
66#[derive(Clone, PartialEq, Eq, Debug, Hash)] 68#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -106,6 +108,10 @@ impl ProjectionTy {
106 } 108 }
107 } 109 }
108 110
111 pub fn self_type_parameter(&self) -> &Ty {
112 &self.substitution[0]
113 }
114
109 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 115 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
110 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { 116 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
111 AssocContainerId::TraitId(it) => it, 117 AssocContainerId::TraitId(it) => it,
@@ -128,6 +134,12 @@ impl TypeWalk for ProjectionTy {
128 } 134 }
129} 135}
130 136
137#[derive(Clone, PartialEq, Eq, Debug, Hash)]
138