| author | bors <bors@rust-lang.org> 2024-12-23 12:18:14 UTC |
| committer | bors <bors@rust-lang.org> 2024-12-23 12:18:14 UTC |
| log | 904d8f6b39ce98fb890ac3381a710f071ddae44d |
| tree | 0301bf9e4b4dbc841acadc026db5621d9f6e7de7 |
| parent | 85c39893a761fe4c050523278da4e7e45ab42b6e |
| parent | 8dbdcc03ebfd5d3c21671d8a021669dc79d93038 |
Subtree update of `rust-analyzer`
r? `@ghost`113 files changed, 3082 insertions(+), 2151 deletions(-)
src/tools/rust-analyzer/Cargo.lock+30-39| ... | ... | @@ -1011,24 +1011,25 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" |
| 1011 | 1011 | [[package]] |
| 1012 | 1012 | name = "lsp-server" |
| 1013 | 1013 | version = "0.7.7" |
| 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1015 | checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9" | |
| 1014 | 1016 | dependencies = [ |
| 1015 | 1017 | "crossbeam-channel", |
| 1016 | "ctrlc", | |
| 1017 | 1018 | "log", |
| 1018 | "lsp-types", | |
| 1019 | 1019 | "serde", |
| 1020 | 1020 | "serde_json", |
| 1021 | 1021 | ] |
| 1022 | 1022 | |
| 1023 | 1023 | [[package]] |
| 1024 | 1024 | name = "lsp-server" |
| 1025 | version = "0.7.7" | |
| 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1027 | checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9" | |
| 1025 | version = "0.7.8" | |
| 1028 | 1026 | dependencies = [ |
| 1029 | 1027 | "crossbeam-channel", |
| 1028 | "ctrlc", | |
| 1030 | 1029 | "log", |
| 1030 | "lsp-types", | |
| 1031 | 1031 | "serde", |
| 1032 | "serde_derive", | |
| 1032 | 1033 | "serde_json", |
| 1033 | 1034 | ] |
| 1034 | 1035 | |
| ... | ... | @@ -1289,7 +1290,6 @@ name = "paths" |
| 1289 | 1290 | version = "0.0.0" |
| 1290 | 1291 | dependencies = [ |
| 1291 | 1292 | "camino", |
| 1292 | "serde", | |
| 1293 | 1293 | ] |
| 1294 | 1294 | |
| 1295 | 1295 | [[package]] |
| ... | ... | @@ -1352,12 +1352,12 @@ dependencies = [ |
| 1352 | 1352 | name = "proc-macro-api" |
| 1353 | 1353 | version = "0.0.0" |
| 1354 | 1354 | dependencies = [ |
| 1355 | "base-db", | |
| 1356 | 1355 | "indexmap", |
| 1357 | 1356 | "intern", |
| 1358 | 1357 | "paths", |
| 1359 | 1358 | "rustc-hash 2.0.0", |
| 1360 | 1359 | "serde", |
| 1360 | "serde_derive", | |
| 1361 | 1361 | "serde_json", |
| 1362 | 1362 | "span", |
| 1363 | 1363 | "stdx", |
| ... | ... | @@ -1369,7 +1369,6 @@ dependencies = [ |
| 1369 | 1369 | name = "proc-macro-srv" |
| 1370 | 1370 | version = "0.0.0" |
| 1371 | 1371 | dependencies = [ |
| 1372 | "base-db", | |
| 1373 | 1372 | "expect-test", |
| 1374 | 1373 | "intern", |
| 1375 | 1374 | "libloading", |
| ... | ... | @@ -1448,6 +1447,7 @@ dependencies = [ |
| 1448 | 1447 | "rustc-hash 2.0.0", |
| 1449 | 1448 | "semver", |
| 1450 | 1449 | "serde", |
| 1450 | "serde_derive", | |
| 1451 | 1451 | "serde_json", |
| 1452 | 1452 | "span", |
| 1453 | 1453 | "stdx", |
| ... | ... | @@ -1507,9 +1507,9 @@ dependencies = [ |
| 1507 | 1507 | |
| 1508 | 1508 | [[package]] |
| 1509 | 1509 | name = "ra-ap-rustc_abi" |
| 1510 | version = "0.85.0" | |
| 1510 | version = "0.87.0" | |
| 1511 | 1511 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1512 | checksum = "af462c3a2d524b84a51b6848b439787f01b35c6c1086d3e3086a5f5eea92ed9a" | |
| 1512 | checksum = "28b782af0a7a8df16ddf43cd70da9f17bc3b1ce712c9e4992b6edb16f5f53632" | |
| 1513 | 1513 | dependencies = [ |
| 1514 | 1514 | "bitflags 2.6.0", |
| 1515 | 1515 | "ra-ap-rustc_index", |
| ... | ... | @@ -1518,9 +1518,9 @@ dependencies = [ |
| 1518 | 1518 | |
| 1519 | 1519 | [[package]] |
| 1520 | 1520 | name = "ra-ap-rustc_index" |
| 1521 | version = "0.85.0" | |
| 1521 | version = "0.87.0" | |
| 1522 | 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1523 | checksum = "be6bb8cb0ab78d94a222f1ffd3e87254cdfb57413382b8d6ebe26a85482f99d1" | |
| 1523 | checksum = "ce5742f134960482f543b35ecebec3cacc6d79a9a685713518b4d8d70c5f9aa8" | |
| 1524 | 1524 | dependencies = [ |
| 1525 | 1525 | "ra-ap-rustc_index_macros", |
| 1526 | 1526 | "smallvec", |
| ... | ... | @@ -1528,9 +1528,9 @@ dependencies = [ |
| 1528 | 1528 | |
| 1529 | 1529 | [[package]] |
| 1530 | 1530 | name = "ra-ap-rustc_index_macros" |
| 1531 | version = "0.85.0" | |
| 1531 | version = "0.87.0" | |
| 1532 | 1532 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1533 | checksum = "c24b1641455b46e87435b7321219672077066e678963d239a4a2904732979b16" | |
| 1533 | checksum = "d7ea011fcf68309a8835ad01d91c032cb18444617b00e2cab21d45b208164441" | |
| 1534 | 1534 | dependencies = [ |
| 1535 | 1535 | "proc-macro2", |
| 1536 | 1536 | "quote", |
| ... | ... | @@ -1539,9 +1539,9 @@ dependencies = [ |
| 1539 | 1539 | |
| 1540 | 1540 | [[package]] |
| 1541 | 1541 | name = "ra-ap-rustc_lexer" |
| 1542 | version = "0.85.0" | |
| 1542 | version = "0.87.0" | |
| 1543 | 1543 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1544 | checksum = "94daa86974417981fed2f12bd8fb00158dfa6fee561152bed689278c846d0272" | |
| 1544 | checksum = "eb76f0a4d4c20859e41f0a23bff0f37ab9ca9171c214a6c7dd72ea69434865dc" | |
| 1545 | 1545 | dependencies = [ |
| 1546 | 1546 | "unicode-properties", |
| 1547 | 1547 | "unicode-xid", |
| ... | ... | @@ -1549,9 +1549,9 @@ dependencies = [ |
| 1549 | 1549 | |
| 1550 | 1550 | [[package]] |
| 1551 | 1551 | name = "ra-ap-rustc_parse_format" |
| 1552 | version = "0.85.0" | |
| 1552 | version = "0.87.0" | |
| 1553 | 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1554 | checksum = "fc07f6bd581746f358e39c4b6bfe8d455b3d6ad1a857821016d0d42eeb5e1e3e" | |
| 1554 | checksum = "06080bd35078305421a62da77f3c128482d8d44441b6da8ce9d146d1cd9cdb5b" | |
| 1555 | 1555 | dependencies = [ |
| 1556 | 1556 | "ra-ap-rustc_index", |
| 1557 | 1557 | "ra-ap-rustc_lexer", |
| ... | ... | @@ -1559,9 +1559,9 @@ dependencies = [ |
| 1559 | 1559 | |
| 1560 | 1560 | [[package]] |
| 1561 | 1561 | name = "ra-ap-rustc_pattern_analysis" |
| 1562 | version = "0.85.0" | |
| 1562 | version = "0.87.0" | |
| 1563 | 1563 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1564 | checksum = "2f49b86e1276c1c3c72898410def29b699415f4e7d1dfb3531daf79794694372" | |
| 1564 | checksum = "68a3154fe4c20c177d7b3c678a2d3a97aba0cca156ddef88959915041889daf0" | |
| 1565 | 1565 | dependencies = [ |
| 1566 | 1566 | "ra-ap-rustc_index", |
| 1567 | 1567 | "rustc-hash 2.0.0", |
| ... | ... | @@ -1676,7 +1676,7 @@ dependencies = [ |
| 1676 | 1676 | "intern", |
| 1677 | 1677 | "itertools", |
| 1678 | 1678 | "load-cargo", |
| 1679 | "lsp-server 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 1679 | "lsp-server 0.7.7", | |
| 1680 | 1680 | "lsp-types", |
| 1681 | 1681 | "memchr", |
| 1682 | 1682 | "mimalloc", |
| ... | ... | @@ -1695,6 +1695,7 @@ dependencies = [ |
| 1695 | 1695 | "scip", |
| 1696 | 1696 | "semver", |
| 1697 | 1697 | "serde", |
| 1698 | "serde_derive", | |
| 1698 | 1699 | "serde_json", |
| 1699 | 1700 | "stdx", |
| 1700 | 1701 | "syntax", |
| ... | ... | @@ -1822,18 +1823,18 @@ dependencies = [ |
| 1822 | 1823 | |
| 1823 | 1824 | [[package]] |
| 1824 | 1825 | name = "serde" |
| 1825 | version = "1.0.206" | |
| 1826 | version = "1.0.216" | |
| 1826 | 1827 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1827 | checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284" | |
| 1828 | checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" | |
| 1828 | 1829 | dependencies = [ |
| 1829 | 1830 | "serde_derive", |
| 1830 | 1831 | ] |
| 1831 | 1832 | |
| 1832 | 1833 | [[package]] |
| 1833 | 1834 | name = "serde_derive" |
| 1834 | version = "1.0.206" | |
| 1835 | version = "1.0.216" | |
| 1835 | 1836 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1836 | checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97" | |
| 1837 | checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" | |
| 1837 | 1838 | dependencies = [ |
| 1838 | 1839 | "proc-macro2", |
| 1839 | 1840 | "quote", |
| ... | ... | @@ -1924,12 +1925,6 @@ version = "0.3.2" |
| 1924 | 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1925 | 1926 | checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" |
| 1926 | 1927 | |
| 1927 | [[package]] | |
| 1928 | name = "stable_deref_trait" | |
| 1929 | version = "1.2.0" | |
| 1930 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1931 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" | |
| 1932 | ||
| 1933 | 1928 | [[package]] |
| 1934 | 1929 | name = "stdx" |
| 1935 | 1930 | version = "0.0.0" |
| ... | ... | @@ -1946,9 +1941,9 @@ dependencies = [ |
| 1946 | 1941 | |
| 1947 | 1942 | [[package]] |
| 1948 | 1943 | name = "syn" |
| 1949 | version = "2.0.74" | |
| 1944 | version = "2.0.87" | |
| 1950 | 1945 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1951 | checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" | |
| 1946 | checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" | |
| 1952 | 1947 | dependencies = [ |
| 1953 | 1948 | "proc-macro2", |
| 1954 | 1949 | "quote", |
| ... | ... | @@ -2264,13 +2259,9 @@ dependencies = [ |
| 2264 | 2259 | |
| 2265 | 2260 | [[package]] |
| 2266 | 2261 | name = "triomphe" |
| 2267 | version = "0.1.13" | |
| 2262 | version = "0.1.14" | |
| 2268 | 2263 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2269 | checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" | |
| 2270 | dependencies = [ | |
| 2271 | "serde", | |
| 2272 | "stable_deref_trait", | |
| 2273 | ] | |
| 2264 | checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" | |
| 2274 | 2265 | |
| 2275 | 2266 | [[package]] |
| 2276 | 2267 | name = "tt" |
src/tools/rust-analyzer/Cargo.toml+8-7| ... | ... | @@ -85,11 +85,11 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } |
| 85 | 85 | vfs = { path = "./crates/vfs", version = "0.0.0" } |
| 86 | 86 | edition = { path = "./crates/edition", version = "0.0.0" } |
| 87 | 87 | |
| 88 | ra-ap-rustc_lexer = { version = "0.85", default-features = false } | |
| 89 | ra-ap-rustc_parse_format = { version = "0.85", default-features = false } | |
| 90 | ra-ap-rustc_index = { version = "0.85", default-features = false } | |
| 91 | ra-ap-rustc_abi = { version = "0.85", default-features = false } | |
| 92 | ra-ap-rustc_pattern_analysis = { version = "0.85", default-features = false } | |
| 88 | ra-ap-rustc_lexer = { version = "0.87", default-features = false } | |
| 89 | ra-ap-rustc_parse_format = { version = "0.87", default-features = false } | |
| 90 | ra-ap-rustc_index = { version = "0.87", default-features = false } | |
| 91 | ra-ap-rustc_abi = { version = "0.87", default-features = false } | |
| 92 | ra-ap-rustc_pattern_analysis = { version = "0.87", default-features = false } | |
| 93 | 93 | |
| 94 | 94 | # local crates that aren't published to crates.io. These should not have versions. |
| 95 | 95 | test-fixture = { path = "./crates/test-fixture" } |
| ... | ... | @@ -138,7 +138,8 @@ pulldown-cmark = { version = "0.9.0", default-features = false } |
| 138 | 138 | rayon = "1.8.0" |
| 139 | 139 | rustc-hash = "2.0.0" |
| 140 | 140 | semver = "1.0.14" |
| 141 | serde = { version = "1.0.192", features = ["derive"] } | |
| 141 | serde = { version = "1.0.192" } | |
| 142 | serde_derive = { version = "1.0.192" } | |
| 142 | 143 | serde_json = "1.0.108" |
| 143 | 144 | smallvec = { version = "1.10.0", features = [ |
| 144 | 145 | "const_new", |
| ... | ... | @@ -157,7 +158,7 @@ tracing-subscriber = { version = "0.3.18", default-features = false, features = |
| 157 | 158 | "time", |
| 158 | 159 | "tracing-log", |
| 159 | 160 | ] } |
| 160 | triomphe = { version = "0.1.10", default-features = false, features = ["std"] } | |
| 161 | triomphe = { version = "0.1.14", default-features = false, features = ["std"] } | |
| 161 | 162 | url = "2.3.1" |
| 162 | 163 | xshell = "0.2.5" |
| 163 | 164 |
src/tools/rust-analyzer/crates/hir-def/src/body.rs+38-14| ... | ... | @@ -18,6 +18,7 @@ use smallvec::SmallVec; |
| 18 | 18 | use span::{Edition, MacroFileId}; |
| 19 | 19 | use syntax::{ast, AstPtr, SyntaxNodePtr}; |
| 20 | 20 | use triomphe::Arc; |
| 21 | use tt::TextRange; | |
| 21 | 22 | |
| 22 | 23 | use crate::{ |
| 23 | 24 | db::DefDatabase, |
| ... | ... | @@ -143,15 +144,7 @@ pub struct BodySourceMap { |
| 143 | 144 | |
| 144 | 145 | pub types: TypesSourceMap, |
| 145 | 146 | |
| 146 | // FIXME: Make this a sane struct. | |
| 147 | template_map: Option< | |
| 148 | Box<( | |
| 149 | // format_args! | |
| 150 | FxHashMap<ExprId, (HygieneId, Vec<(syntax::TextRange, Name)>)>, | |
| 151 | // asm! | |
| 152 | FxHashMap<ExprId, Vec<Vec<(syntax::TextRange, usize)>>>, | |
| 153 | )>, | |
| 154 | >, | |
| 147 | template_map: Option<Box<FormatTemplate>>, | |
| 155 | 148 | |
| 156 | 149 | expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, MacroFileId>, |
| 157 | 150 | |
| ... | ... | @@ -160,6 +153,20 @@ pub struct BodySourceMap { |
| 160 | 153 | diagnostics: Vec<BodyDiagnostic>, |
| 161 | 154 | } |
| 162 | 155 | |
| 156 | #[derive(Default, Debug, Eq, PartialEq)] | |
| 157 | struct FormatTemplate { | |
| 158 | /// A map from `format_args!()` expressions to their captures. | |
| 159 | format_args_to_captures: FxHashMap<ExprId, (HygieneId, Vec<(syntax::TextRange, Name)>)>, | |
| 160 | /// A map from `asm!()` expressions to their captures. | |
| 161 | asm_to_captures: FxHashMap<ExprId, Vec<Vec<(syntax::TextRange, usize)>>>, | |
| 162 | /// A map from desugared expressions of implicit captures to their source. | |
| 163 | /// | |
| 164 | /// The value stored for each capture is its template literal and offset inside it. The template literal | |
| 165 | /// is from the `format_args[_nl]!()` macro and so needs to be mapped up once to go to the user-written | |
| 166 | /// template. | |
| 167 | implicit_capture_to_source: FxHashMap<ExprId, InFile<(AstPtr<ast::Expr>, TextRange)>>, | |
| 168 | } | |
| 169 | ||
| 163 | 170 | #[derive(Debug, Eq, PartialEq)] |
| 164 | 171 | pub enum BodyDiagnostic { |
| 165 | 172 | InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions }, |
| ... | ... | @@ -798,18 +805,29 @@ impl BodySourceMap { |
| 798 | 805 | node: InFile<&ast::FormatArgsExpr>, |
| 799 | 806 | ) -> Option<(HygieneId, &[(syntax::TextRange, Name)])> { |
| 800 | 807 | let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>); |
| 801 | let (hygiene, names) = | |
| 802 | self.template_map.as_ref()?.0.get(&self.expr_map.get(&src)?.as_expr()?)?; | |
| 808 | let (hygiene, names) = self | |
| 809 | .template_map | |
| 810 | .as_ref()? | |
| 811 | .format_args_to_captures | |
| 812 | .get(&self.expr_map.get(&src)?.as_expr()?)?; | |
| 803 | 813 | Some((*hygiene, &**names)) |
| 804 | 814 | } |
| 805 | 815 | |
| 816 | pub fn format_args_implicit_capture( | |
| 817 | &self, | |
| 818 | capture_expr: ExprId, | |
| 819 | ) -> Option<InFile<(AstPtr<ast::Expr>, TextRange)>> { | |
| 820 | self.template_map.as_ref()?.implicit_capture_to_source.get(&capture_expr).copied() | |
| 821 | } | |
| 822 | ||
| 806 | 823 | pub fn asm_template_args( |
| 807 | 824 | &self, |
| 808 | 825 | node: InFile<&ast::AsmExpr>, |
| 809 | 826 | ) -> Option<(ExprId, &[Vec<(syntax::TextRange, usize)>])> { |
| 810 | 827 | let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>); |
| 811 | 828 | let expr = self.expr_map.get(&src)?.as_expr()?; |
| 812 | Some(expr).zip(self.template_map.as_ref()?.1.get(&expr).map(std::ops::Deref::deref)) | |
| 829 | Some(expr) | |
| 830 | .zip(self.template_map.as_ref()?.asm_to_captures.get(&expr).map(std::ops::Deref::deref)) | |
| 813 | 831 | } |
| 814 | 832 | |
| 815 | 833 | /// Get a reference to the body source map's diagnostics. |
| ... | ... | @@ -835,8 +853,14 @@ impl BodySourceMap { |
| 835 | 853 | types, |
| 836 | 854 | } = self; |
| 837 | 855 | if let Some(template_map) = template_map { |
| 838 | template_map.0.shrink_to_fit(); | |
| 839 | template_map.1.shrink_to_fit(); | |
| 856 | let FormatTemplate { | |
| 857 | format_args_to_captures, | |
| 858 | asm_to_captures, | |
| 859 | implicit_capture_to_source, | |
| 860 | } = &mut **template_map; | |
| 861 | format_args_to_captures.shrink_to_fit(); | |
| 862 | asm_to_captures.shrink_to_fit(); | |
| 863 | implicit_capture_to_source.shrink_to_fit(); | |
| 840 | 864 | } |
| 841 | 865 | expr_map.shrink_to_fit(); |
| 842 | 866 | expr_map_back.shrink_to_fit(); |
src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs+16-4| ... | ... | @@ -1957,8 +1957,10 @@ impl ExprCollector<'_> { |
| 1957 | 1957 | _ => None, |
| 1958 | 1958 | }); |
| 1959 | 1959 | let mut mappings = vec![]; |
| 1960 | let (fmt, hygiene) = match template.and_then(|it| self.expand_macros_to_string(it)) { | |
| 1961 | Some((s, is_direct_literal)) => { | |
| 1960 | let (fmt, hygiene) = match template.and_then(|template| { | |
| 1961 | self.expand_macros_to_string(template.clone()).map(|it| (it, template)) | |
| 1962 | }) { | |
| 1963 | Some(((s, is_direct_literal), template)) => { | |
| 1962 | 1964 | let call_ctx = self.expander.syntax_context(); |
| 1963 | 1965 | let hygiene = self.hygiene_id_for(s.syntax().text_range().start()); |
| 1964 | 1966 | let fmt = format_args::parse( |
| ... | ... | @@ -1966,8 +1968,18 @@ impl ExprCollector<'_> { |
| 1966 | 1968 | fmt_snippet, |
| 1967 | 1969 | args, |
| 1968 | 1970 | is_direct_literal, |
| 1969 | |name| { | |
| 1971 | |name, range| { | |
| 1970 | 1972 | let expr_id = self.alloc_expr_desugared(Expr::Path(Path::from(name))); |
| 1973 | if let Some(range) = range { | |
| 1974 | self.source_map | |
| 1975 | .template_map | |
| 1976 | .get_or_insert_with(Default::default) | |
| 1977 | .implicit_capture_to_source | |
| 1978 | .insert( | |
| 1979 | expr_id, | |
| 1980 | self.expander.in_file((AstPtr::new(&template), range)), | |
| 1981 | ); | |
| 1982 | } | |
| 1971 | 1983 | if !hygiene.is_root() { |
| 1972 | 1984 | self.body.expr_hygiene.insert(expr_id, hygiene); |
| 1973 | 1985 | } |
| ... | ... | @@ -2139,7 +2151,7 @@ impl ExprCollector<'_> { |
| 2139 | 2151 | self.source_map |
| 2140 | 2152 | .template_map |
| 2141 | 2153 | .get_or_insert_with(Default::default) |
| 2142 | .0 | |
| 2154 | .format_args_to_captures | |
| 2143 | 2155 | .insert(idx, (hygiene, mappings)); |
| 2144 | 2156 | idx |
| 2145 | 2157 | } |
src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs+7-3| ... | ... | @@ -6,7 +6,7 @@ use syntax::{ |
| 6 | 6 | ast::{self, HasName, IsString}, |
| 7 | 7 | AstNode, AstPtr, AstToken, T, |
| 8 | 8 | }; |
| 9 | use tt::{TextRange, TextSize}; | |
| 9 | use tt::TextRange; | |
| 10 | 10 | |
| 11 | 11 | use crate::{ |
| 12 | 12 | body::lower::{ExprCollector, FxIndexSet}, |
| ... | ... | @@ -224,7 +224,7 @@ impl ExprCollector<'_> { |
| 224 | 224 | TextRange::new( |
| 225 | 225 | inner_span.start.try_into().unwrap(), |
| 226 | 226 | inner_span.end.try_into().unwrap(), |
| 227 | ) - TextSize::from(str_style.map(|it| it + 1).unwrap_or(0) as u32 + 1) | |
| 227 | ) | |
| 228 | 228 | }) |
| 229 | 229 | }; |
| 230 | 230 | for piece in unverified_pieces { |
| ... | ... | @@ -268,7 +268,11 @@ impl ExprCollector<'_> { |
| 268 | 268 | Expr::InlineAsm(InlineAsm { operands: operands.into_boxed_slice(), options }), |
| 269 | 269 | syntax_ptr, |
| 270 | 270 | ); |
| 271 | self.source_map.template_map.get_or_insert_with(Default::default).1.insert(idx, mappings); | |
| 271 | self.source_map | |
| 272 | .template_map | |
| 273 | .get_or_insert_with(Default::default) | |
| 274 | .asm_to_captures | |
| 275 | .insert(idx, mappings); | |
| 272 | 276 | idx |
| 273 | 277 | } |
| 274 | 278 | } |
src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs+1| ... | ... | @@ -685,6 +685,7 @@ impl Printer<'_> { |
| 685 | 685 | self.print_binding(*id); |
| 686 | 686 | if let Some(pat) = subpat { |
| 687 | 687 | self.whitespace(); |
| 688 | w!(self, "@ "); | |
| 688 | 689 | self.print_pat(*pat); |
| 689 | 690 | } |
| 690 | 691 | } |
src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs+18| ... | ... | @@ -426,3 +426,21 @@ fn f() { |
| 426 | 426 | "should have a binding for `B`", |
| 427 | 427 | ); |
| 428 | 428 | } |
| 429 | ||
| 430 | #[test] | |
| 431 | fn regression_pretty_print_bind_pat() { | |
| 432 | let (db, body, owner) = lower( | |
| 433 | r#" | |
| 434 | fn foo() { | |
| 435 | let v @ u = 123; | |
| 436 | } | |
| 437 | "#, | |
| 438 | ); | |
| 439 | let printed = body.pretty_print(&db, owner, Edition::CURRENT); | |
| 440 | assert_eq!( | |
| 441 | printed, | |
| 442 | r#"fn foo() -> () { | |
| 443 | let v @ u = 123; | |
| 444 | }"# | |
| 445 | ); | |
| 446 | } |
src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs+20-18| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | //! Parses `format_args` input. |
| 2 | 2 | |
| 3 | use either::Either; | |
| 3 | 4 | use hir_expand::name::Name; |
| 4 | 5 | use intern::Symbol; |
| 5 | 6 | use rustc_parse_format as parse; |
| ... | ... | @@ -7,7 +8,7 @@ use span::SyntaxContextId; |
| 7 | 8 | use stdx::TupleExt; |
| 8 | 9 | use syntax::{ |
| 9 | 10 | ast::{self, IsString}, |
| 10 | TextRange, TextSize, | |
| 11 | TextRange, | |
| 11 | 12 | }; |
| 12 | 13 | |
| 13 | 14 | use crate::hir::ExprId; |
| ... | ... | @@ -33,7 +34,7 @@ pub enum FormatArgsPiece { |
| 33 | 34 | Placeholder(FormatPlaceholder), |
| 34 | 35 | } |
| 35 | 36 | |
| 36 | #[derive(Copy, Debug, Clone, PartialEq, Eq)] | |
| 37 | #[derive(Debug, Clone, PartialEq, Eq)] | |
| 37 | 38 | pub struct FormatPlaceholder { |
| 38 | 39 | /// Index into [`FormatArgs::arguments`]. |
| 39 | 40 | pub argument: FormatArgPosition, |
| ... | ... | @@ -45,11 +46,11 @@ pub struct FormatPlaceholder { |
| 45 | 46 | pub format_options: FormatOptions, |
| 46 | 47 | } |
| 47 | 48 | |
| 48 | #[derive(Copy, Debug, Clone, PartialEq, Eq)] | |
| 49 | #[derive(Debug, Clone, PartialEq, Eq)] | |
| 49 | 50 | pub struct FormatArgPosition { |
| 50 | 51 | /// Which argument this position refers to (Ok), |
| 51 | 52 | /// or would've referred to if it existed (Err). |
| 52 | pub index: Result<usize, usize>, | |
| 53 | pub index: Result<usize, Either<usize, Name>>, | |
| 53 | 54 | /// What kind of position this is. See [`FormatArgPositionKind`]. |
| 54 | 55 | pub kind: FormatArgPositionKind, |
| 55 | 56 | /// The span of the name or number. |
| ... | ... | @@ -88,7 +89,7 @@ pub enum FormatTrait { |
| 88 | 89 | UpperHex, |
| 89 | 90 | } |
| 90 | 91 | |
| 91 | #[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] | |
| 92 | #[derive(Clone, Default, Debug, PartialEq, Eq)] | |
| 92 | 93 | pub struct FormatOptions { |
| 93 | 94 | /// The width. E.g. `{:5}` or `{:width$}`. |
| 94 | 95 | pub width: Option<FormatCount>, |
| ... | ... | @@ -133,7 +134,7 @@ pub enum FormatAlignment { |
| 133 | 134 | Center, |
| 134 | 135 | } |
| 135 | 136 | |
| 136 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | |
| 137 | #[derive(Clone, Debug, PartialEq, Eq)] | |
| 137 | 138 | pub enum FormatCount { |
| 138 | 139 | /// `{:5}` or `{:.5}` |
| 139 | 140 | Literal(usize), |
| ... | ... | @@ -173,7 +174,7 @@ pub(crate) fn parse( |
| 173 | 174 | fmt_snippet: Option<String>, |
| 174 | 175 | mut args: FormatArgumentsCollector, |
| 175 | 176 | is_direct_literal: bool, |
| 176 | mut synth: impl FnMut(Name) -> ExprId, | |
| 177 | mut synth: impl FnMut(Name, Option<TextRange>) -> ExprId, | |
| 177 | 178 | mut record_usage: impl FnMut(Name, Option<TextRange>), |
| 178 | 179 | call_ctx: SyntaxContextId, |
| 179 | 180 | ) -> FormatArgs { |
| ... | ... | @@ -192,7 +193,6 @@ pub(crate) fn parse( |
| 192 | 193 | } |
| 193 | 194 | None => None, |
| 194 | 195 | }; |
| 195 | ||
| 196 | 196 | let mut parser = |
| 197 | 197 | parse::Parser::new(&text, str_style, fmt_snippet, false, parse::ParseMode::Format); |
| 198 | 198 | |
| ... | ... | @@ -217,7 +217,6 @@ pub(crate) fn parse( |
| 217 | 217 | let to_span = |inner_span: parse::InnerSpan| { |
| 218 | 218 | is_source_literal.then(|| { |
| 219 | 219 | TextRange::new(inner_span.start.try_into().unwrap(), inner_span.end.try_into().unwrap()) |
| 220 | - TextSize::from(str_style.map(|it| it + 1).unwrap_or(0) as u32 + 1) | |
| 221 | 220 | }) |
| 222 | 221 | }; |
| 223 | 222 | |
| ... | ... | @@ -245,8 +244,8 @@ pub(crate) fn parse( |
| 245 | 244 | Ok(index) |
| 246 | 245 | } else { |
| 247 | 246 | // Doesn't exist as an explicit argument. |
| 248 | invalid_refs.push((index, span, used_as, kind)); | |
| 249 | Err(index) | |
| 247 | invalid_refs.push((Either::Left(index), span, used_as, kind)); | |
| 248 | Err(Either::Left(index)) | |
| 250 | 249 | } |
| 251 | 250 | } |
| 252 | 251 | ArgRef::Name(name, span) => { |
| ... | ... | @@ -265,14 +264,17 @@ pub(crate) fn parse( |
| 265 | 264 | // For the moment capturing variables from format strings expanded from macros is |
| 266 | 265 | // disabled (see RFC #2795) |
| 267 | 266 | // FIXME: Diagnose |
| 267 | invalid_refs.push((Either::Right(name.clone()), span, used_as, kind)); | |
| 268 | Err(Either::Right(name)) | |
| 269 | } else { | |
| 270 | record_usage(name.clone(), span); | |
| 271 | Ok(args.add(FormatArgument { | |
| 272 | kind: FormatArgumentKind::Captured(name.clone()), | |
| 273 | // FIXME: This is problematic, we might want to synthesize a dummy | |
| 274 | // expression proper and/or desugar these. | |
| 275 | expr: synth(name, span), | |
| 276 | })) | |
| 268 | 277 | } |
| 269 | record_usage(name.clone(), span); | |
| 270 | Ok(args.add(FormatArgument { | |
| 271 | kind: FormatArgumentKind::Captured(name.clone()), | |
| 272 | // FIXME: This is problematic, we might want to synthesize a dummy | |
| 273 | // expression proper and/or desugar these. | |
| 274 | expr: synth(name), | |
| 275 | })) | |
| 276 | 278 | } |
| 277 | 279 | } |
| 278 | 280 | }; |
src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs+68-56| ... | ... | @@ -16,7 +16,7 @@ use syntax::ast; |
| 16 | 16 | |
| 17 | 17 | use crate::{ |
| 18 | 18 | db::DefDatabase, |
| 19 | per_ns::PerNs, | |
| 19 | per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem}, | |
| 20 | 20 | visibility::{Visibility, VisibilityExplicitness}, |
| 21 | 21 | AdtId, BuiltinType, ConstId, ExternCrateId, FxIndexMap, HasModule, ImplId, LocalModuleId, |
| 22 | 22 | Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId, |
| ... | ... | @@ -80,9 +80,9 @@ pub struct ItemScope { |
| 80 | 80 | /// Defs visible in this scope. This includes `declarations`, but also |
| 81 | 81 | /// imports. The imports belong to this module and can be resolved by using them on |
| 82 | 82 | /// the `use_imports_*` fields. |
| 83 | types: FxIndexMap<Name, (ModuleDefId, Visibility, Option<ImportOrExternCrate>)>, | |
| 84 | values: FxIndexMap<Name, (ModuleDefId, Visibility, Option<ImportId>)>, | |
| 85 | macros: FxIndexMap<Name, (MacroId, Visibility, Option<ImportId>)>, | |
| 83 | types: FxIndexMap<Name, TypesItem>, | |
| 84 | values: FxIndexMap<Name, ValuesItem>, | |
| 85 | macros: FxIndexMap<Name, MacrosItem>, | |
| 86 | 86 | unresolved: FxHashSet<Name>, |
| 87 | 87 | |
| 88 | 88 | /// The defs declared in this scope. Each def has a single scope where it is |
| ... | ... | @@ -92,7 +92,7 @@ pub struct ItemScope { |
| 92 | 92 | impls: Vec<ImplId>, |
| 93 | 93 | unnamed_consts: Vec<ConstId>, |
| 94 | 94 | /// Traits imported via `use Trait as _;`. |
| 95 | unnamed_trait_imports: FxHashMap<TraitId, (Visibility, Option<ImportId>)>, | |
| 95 | unnamed_trait_imports: FxHashMap<TraitId, Item<()>>, | |
| 96 | 96 | |
| 97 | 97 | // the resolutions of the imports of this scope |
| 98 | 98 | use_imports_types: FxHashMap<ImportOrExternCrate, ImportOrDef>, |
| ... | ... | @@ -187,7 +187,7 @@ impl ItemScope { |
| 187 | 187 | import = i; |
| 188 | 188 | } |
| 189 | 189 | ImportOrDef::Def(ModuleDefId::MacroId(def)) => { |
| 190 | res.macros = Some((def, Visibility::Public, None)); | |
| 190 | res.macros = Some(Item { def, vis: Visibility::Public, import: None }); | |
| 191 | 191 | break; |
| 192 | 192 | } |
| 193 | 193 | _ => break, |
| ... | ... | @@ -203,7 +203,7 @@ impl ItemScope { |
| 203 | 203 | import = i; |
| 204 | 204 | } |
| 205 | 205 | ImportOrDef::Def(def) => { |
| 206 | res.types = Some((def, Visibility::Public, None)); | |
| 206 | res.types = Some(Item { def, vis: Visibility::Public, import: None }); | |
| 207 | 207 | break; |
| 208 | 208 | } |
| 209 | 209 | _ => break, |
| ... | ... | @@ -219,7 +219,7 @@ impl ItemScope { |
| 219 | 219 | import = i; |
| 220 | 220 | } |
| 221 | 221 | ImportOrDef::Def(def) => { |
| 222 | res.values = Some((def, Visibility::Public, None)); | |
| 222 | res.values = Some(Item { def, vis: Visibility::Public, import: None }); | |
| 223 | 223 | break; |
| 224 | 224 | } |
| 225 | 225 | _ => break, |
| ... | ... | @@ -253,8 +253,8 @@ impl ItemScope { |
| 253 | 253 | } |
| 254 | 254 | |
| 255 | 255 | pub(crate) fn modules_in_scope(&self) -> impl Iterator<Item = (ModuleId, Visibility)> + '_ { |
| 256 | self.types.values().copied().filter_map(|(def, vis, _)| match def { | |
| 257 | ModuleDefId::ModuleId(module) => Some((module, vis)), | |
| 256 | self.types.values().filter_map(|ns| match ns.def { | |
| 257 | ModuleDefId::ModuleId(module) => Some((module, ns.vis)), | |
| 258 | 258 | _ => None, |
| 259 | 259 | }) |
| 260 | 260 | } |
| ... | ... | @@ -283,20 +283,20 @@ impl ItemScope { |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | pub(crate) fn type_(&self, name: &Name) -> Option<(ModuleDefId, Visibility)> { |
| 286 | self.types.get(name).copied().map(|(a, b, _)| (a, b)) | |
| 286 | self.types.get(name).map(|item| (item.def, item.vis)) | |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | 289 | /// XXX: this is O(N) rather than O(1), try to not introduce new usages. |
| 290 | 290 | pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility, /*declared*/ bool)> { |
| 291 | 291 | match item { |
| 292 | ItemInNs::Macros(def) => self.macros.iter().find_map(|(name, &(other_def, vis, i))| { | |
| 293 | (other_def == def).then_some((name, vis, i.is_none())) | |
| 292 | ItemInNs::Macros(def) => self.macros.iter().find_map(|(name, other_def)| { | |
| 293 | (other_def.def == def).then_some((name, other_def.vis, other_def.import.is_none())) | |
| 294 | 294 | }), |
| 295 | ItemInNs::Types(def) => self.types.iter().find_map(|(name, &(other_def, vis, i))| { | |
| 296 | (other_def == def).then_some((name, vis, i.is_none())) | |
| 295 | ItemInNs::Types(def) => self.types.iter().find_map(|(name, other_def)| { | |
| 296 | (other_def.def == def).then_some((name, other_def.vis, other_def.import.is_none())) | |
| 297 | 297 | }), |
| 298 | ItemInNs::Values(def) => self.values.iter().find_map(|(name, &(other_def, vis, i))| { | |
| 299 | (other_def == def).then_some((name, vis, i.is_none())) | |
| 298 | ItemInNs::Values(def) => self.values.iter().find_map(|(name, other_def)| { | |
| 299 | (other_def.def == def).then_some((name, other_def.vis, other_def.import.is_none())) | |
| 300 | 300 | }), |
| 301 | 301 | } |
| 302 | 302 | } |
| ... | ... | @@ -311,22 +311,34 @@ impl ItemScope { |
| 311 | 311 | ItemInNs::Macros(def) => self |
| 312 | 312 | .macros |
| 313 | 313 | .iter() |
| 314 | .filter_map(|(name, &(other_def, vis, i))| { | |
| 315 | (other_def == def).then_some((name, vis, i.is_none())) | |
| 314 | .filter_map(|(name, other_def)| { | |
| 315 | (other_def.def == def).then_some(( | |
| 316 | name, | |
| 317 | other_def.vis, | |
| 318 | other_def.import.is_none(), | |
| 319 | )) | |
| 316 | 320 | }) |
| 317 | 321 | .find_map(|(a, b, c)| cb(a, b, c)), |
| 318 | 322 | ItemInNs::Types(def) => self |
| 319 | 323 | .types |
| 320 | 324 | .iter() |
| 321 | .filter_map(|(name, &(other_def, vis, i))| { | |
| 322 | (other_def == def).then_some((name, vis, i.is_none())) | |
| 325 | .filter_map(|(name, other_def)| { | |
| 326 | (other_def.def == def).then_some(( | |
| 327 | name, | |
| 328 | other_def.vis, | |
| 329 | other_def.import.is_none(), | |
| 330 | )) | |
| 323 | 331 | }) |
| 324 | 332 | .find_map(|(a, b, c)| cb(a, b, c)), |
| 325 | 333 | ItemInNs::Values(def) => self |
| 326 | 334 | .values |
| 327 | 335 | .iter() |
| 328 | .filter_map(|(name, &(other_def, vis, i))| { | |
| 329 | (other_def == def).then_some((name, vis, i.is_none())) | |
| 336 | .filter_map(|(name, other_def)| { | |
| 337 | (other_def.def == def).then_some(( | |
| 338 | name, | |
| 339 | other_def.vis, | |
| 340 | other_def.import.is_none(), | |
| 341 | )) | |
| 330 | 342 | }) |
| 331 | 343 | .find_map(|(a, b, c)| cb(a, b, c)), |
| 332 | 344 | } |
| ... | ... | @@ -335,7 +347,7 @@ impl ItemScope { |
| 335 | 347 | pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ { |
| 336 | 348 | self.types |
| 337 | 349 | .values() |
| 338 | .filter_map(|&(def, _, _)| match def { | |
| 350 | .filter_map(|def| match def.def { | |
| 339 | 351 | ModuleDefId::TraitId(t) => Some(t), |
| 340 | 352 | _ => None, |
| 341 | 353 | }) |
| ... | ... | @@ -344,13 +356,13 @@ impl ItemScope { |
| 344 | 356 | |
| 345 | 357 | pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ { |
| 346 | 358 | self.entries().map(|(name, res)| (Some(name.clone()), res)).chain( |
| 347 | self.unnamed_trait_imports.iter().map(|(tr, (vis, i))| { | |
| 359 | self.unnamed_trait_imports.iter().map(|(tr, trait_)| { | |
| 348 | 360 | ( |
| 349 | 361 | None, |
| 350 | 362 | PerNs::types( |
| 351 | 363 | ModuleDefId::TraitId(*tr), |
| 352 | *vis, | |
| 353 | i.map(ImportOrExternCrate::Import), | |
| 364 | trait_.vis, | |
| 365 | trait_.import.map(ImportOrExternCrate::Import), | |
| 354 | 366 | ), |
| 355 | 367 | ) |
| 356 | 368 | }), |
| ... | ... | @@ -464,12 +476,12 @@ impl ItemScope { |
| 464 | 476 | |
| 465 | 477 | // FIXME: This is only used in collection, we should move the relevant parts of it out of ItemScope |
| 466 | 478 | pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> { |
| 467 | self.unnamed_trait_imports.get(&tr).copied().map(|(a, _)| a) | |
| 479 | self.unnamed_trait_imports.get(&tr).map(|trait_| trait_.vis) | |
| 468 | 480 | } |
| 469 | 481 | |
| 470 | 482 | pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) { |
| 471 | 483 | // FIXME: import |
| 472 | self.unnamed_trait_imports.insert(tr, (vis, None)); | |
| 484 | self.unnamed_trait_imports.insert(tr, Item { def: (), vis, import: None }); | |
| 473 | 485 | } |
| 474 | 486 | |
| 475 | 487 | pub(crate) fn push_res_with_import( |
| ... | ... | @@ -502,7 +514,7 @@ impl ItemScope { |
| 502 | 514 | } |
| 503 | 515 | None | Some(ImportType::Glob(_)) => None, |
| 504 | 516 | }; |
| 505 | let prev = std::mem::replace(&mut fld.2, import); | |
| 517 | let prev = std::mem::replace(&mut fld.import, import); | |
| 506 | 518 | if let Some(import) = import { |
| 507 | 519 | self.use_imports_types.insert( |
| 508 | 520 | import, |
| ... | ... | @@ -513,7 +525,7 @@ impl ItemScope { |
| 513 | 525 | Some(ImportOrExternCrate::ExternCrate(import)) => { |
| 514 | 526 | ImportOrDef::ExternCrate(import) |
| 515 | 527 | } |
| 516 | None => ImportOrDef::Def(fld.0), | |
| 528 | None => ImportOrDef::Def(fld.def), | |
| 517 | 529 | }, |
| 518 | 530 | ); |
| 519 | 531 | } |
| ... | ... | @@ -540,7 +552,7 @@ impl ItemScope { |
| 540 | 552 | } |
| 541 | 553 | None | Some(ImportType::Glob(_)) => None, |
| 542 | 554 | }; |
| 543 | let prev = std::mem::replace(&mut fld.2, import); | |
| 555 | let prev = std::mem::replace(&mut fld.import, import); | |
| 544 | 556 | if let Some(import) = import { |
| 545 | 557 | self.use_imports_types.insert( |
| 546 | 558 | import, |
| ... | ... | @@ -551,7 +563,7 @@ impl ItemScope { |
| 551 | 563 | Some(ImportOrExternCrate::ExternCrate(import)) => { |
| 552 | 564 | ImportOrDef::ExternCrate(import) |
| 553 | 565 | } |
| 554 | None => ImportOrDef::Def(fld.0), | |
| 566 | None => ImportOrDef::Def(fld.def), | |
| 555 | 567 | }, |
| 556 | 568 | ); |
| 557 | 569 | } |
| ... | ... | @@ -579,13 +591,13 @@ impl ItemScope { |
| 579 | 591 | Some(ImportType::Import(import)) => Some(import), |
| 580 | 592 | _ => None, |
| 581 | 593 | }; |
| 582 | let prev = std::mem::replace(&mut fld.2, import); | |
| 594 | let prev = std::mem::replace(&mut fld.import, import); | |
| 583 | 595 | if let Some(import) = import { |
| 584 | 596 | self.use_imports_values.insert( |
| 585 | 597 | import, |
| 586 | 598 | match prev { |
| 587 | 599 | Some(import) => ImportOrDef::Import(import), |
| 588 | None => ImportOrDef::Def(fld.0), | |
| 600 | None => ImportOrDef::Def(fld.def), | |
| 589 | 601 | }, |
| 590 | 602 | ); |
| 591 | 603 | } |
| ... | ... | @@ -599,13 +611,13 @@ impl ItemScope { |
| 599 | 611 | Some(ImportType::Import(import)) => Some(import), |
| 600 | 612 | _ => None, |
| 601 | 613 | }; |
| 602 | let prev = std::mem::replace(&mut fld.2, import); | |
| 614 | let prev = std::mem::replace(&mut fld.import, import); | |
| 603 | 615 | if let Some(import) = import { |
| 604 | 616 | self.use_imports_values.insert( |
| 605 | 617 | import, |
| 606 | 618 | match prev { |
| 607 | 619 | Some(import) => ImportOrDef::Import(import), |
| 608 | None => ImportOrDef::Def(fld.0), | |
| 620 | None => ImportOrDef::Def(fld.def), | |
| 609 | 621 | }, |
| 610 | 622 | ); |
| 611 | 623 | } |
| ... | ... | @@ -631,13 +643,13 @@ impl ItemScope { |
| 631 | 643 | Some(ImportType::Import(import)) => Some(import), |
| 632 | 644 | _ => None, |
| 633 | 645 | }; |
| 634 | let prev = std::mem::replace(&mut fld.2, import); | |
| 646 | let prev = std::mem::replace(&mut fld.import, import); | |
| 635 | 647 | if let Some(import) = import { |
| 636 | 648 | self.use_imports_macros.insert( |
| 637 | 649 | import, |
| 638 | 650 | match prev { |
| 639 | 651 | Some(import) => ImportOrDef::Import(import), |
| 640 | None => ImportOrDef::Def(fld.0.into()), | |
| 652 | None => ImportOrDef::Def(fld.def.into()), | |
| 641 | 653 | }, |
| 642 | 654 | ); |
| 643 | 655 | } |
| ... | ... | @@ -651,13 +663,13 @@ impl ItemScope { |
| 651 | 663 | Some(ImportType::Import(import)) => Some(import), |
| 652 | 664 | _ => None, |
| 653 | 665 | }; |
| 654 | let prev = std::mem::replace(&mut fld.2, import); | |
| 666 | let prev = std::mem::replace(&mut fld.import, import); | |
| 655 | 667 | if let Some(import) = import { |
| 656 | 668 | self.use_imports_macros.insert( |
| 657 | 669 | import, |
| 658 | 670 | match prev { |
| 659 | 671 | Some(import) => ImportOrDef::Import(import), |
| 660 | None => ImportOrDef::Def(fld.0.into()), | |
| 672 | None => ImportOrDef::Def(fld.def.into()), | |
| 661 | 673 | }, |
| 662 | 674 | ); |
| 663 | 675 | } |
| ... | ... | @@ -680,19 +692,19 @@ impl ItemScope { |
| 680 | 692 | pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) { |
| 681 | 693 | self.types |
| 682 | 694 | .values_mut() |
| 683 | .map(|(_, vis, _)| vis) | |
| 684 | .chain(self.values.values_mut().map(|(_, vis, _)| vis)) | |
| 685 | .chain(self.unnamed_trait_imports.values_mut().map(|(vis, _)| vis)) | |
| 695 | .map(|def| &mut def.vis) | |
| 696 | .chain(self.values.values_mut().map(|def| &mut def.vis)) | |
| 697 | .chain(self.unnamed_trait_imports.values_mut().map(|def| &mut def.vis)) | |
| 686 | 698 | .for_each(|vis| { |
| 687 | 699 | *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit) |
| 688 | 700 | }); |
| 689 | 701 | |
| 690 | for (mac, vis, import) in self.macros.values_mut() { | |
| 691 | if matches!(mac, MacroId::ProcMacroId(_) if import.is_none()) { | |
| 702 | for mac in self.macros.values_mut() { | |
| 703 | if matches!(mac.def, MacroId::ProcMacroId(_) if mac.import.is_none()) { | |
| 692 | 704 | continue; |
| 693 | 705 | } |
| 694 | 706 | |
| 695 | *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit); | |
| 707 | mac.vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit); | |
| 696 | 708 | } |
| 697 | 709 | } |
| 698 | 710 | |
| ... | ... | @@ -707,23 +719,23 @@ impl ItemScope { |
| 707 | 719 | name.map_or("_".to_owned(), |name| name.display(db, Edition::LATEST).to_string()) |
| 708 | 720 | ); |
| 709 | 721 | |
| 710 | if let Some((.., i)) = def.types { | |
| 722 | if let Some(Item { import, .. }) = def.types { | |
| 711 | 723 | buf.push_str(" t"); |
| 712 | match i { | |
| 724 | match import { | |
| 713 | 725 | Some(ImportOrExternCrate::Import(_)) => buf.push('i'), |
| 714 | 726 | Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'), |
| 715 | 727 | None => (), |
| 716 | 728 | } |
| 717 | 729 | } |
| 718 | if let Some((.., i)) = def.values { | |
| 730 | if let Some(Item { import, .. }) = def.values { | |
| 719 | 731 | buf.push_str(" v"); |
| 720 | if i.is_some() { | |
| 732 | if import.is_some() { | |
| 721 | 733 | buf.push('i'); |
| 722 | 734 | } |
| 723 | 735 | } |
| 724 | if let Some((.., i)) = def.macros { | |
| 736 | if let Some(Item { import, .. }) = def.macros { | |
| 725 | 737 | buf.push_str(" m"); |
| 726 | if i.is_some() { | |
| 738 | if import.is_some() { | |
| 727 | 739 | buf.push('i'); |
| 728 | 740 | } |
| 729 | 741 | } |
| ... | ... | @@ -781,19 +793,19 @@ impl ItemScope { |
| 781 | 793 | pub(crate) fn update_visibility_types(&mut self, name: &Name, vis: Visibility) { |
| 782 | 794 | let res = |
| 783 | 795 | self.types.get_mut(name).expect("tried to update visibility of non-existent type"); |
| 784 | res.1 = vis; | |
| 796 | res.vis = vis; | |
| 785 | 797 | } |
| 786 | 798 | |
| 787 | 799 | pub(crate) fn update_visibility_values(&mut self, name: &Name, vis: Visibility) { |
| 788 | 800 | let res = |
| 789 | 801 | self.values.get_mut(name).expect("tried to update visibility of non-existent value"); |
| 790 | res.1 = vis; | |
| 802 | res.vis = vis; | |
| 791 | 803 | } |
| 792 | 804 | |
| 793 | 805 | pub(crate) fn update_visibility_macros(&mut self, name: &Name, vis: Visibility) { |
| 794 | 806 | let res = |
| 795 | 807 | self.macros.get_mut(name).expect("tried to update visibility of non-existent macro"); |
| 796 | res.1 = vis; | |
| 808 | res.vis = vis; | |
| 797 | 809 | } |
| 798 | 810 | } |
| 799 | 811 |
src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs+28-28| ... | ... | @@ -44,7 +44,7 @@ use crate::{ |
| 44 | 44 | ResolveMode, |
| 45 | 45 | }, |
| 46 | 46 | path::{ImportAlias, ModPath, PathKind}, |
| 47 | per_ns::PerNs, | |
| 47 | per_ns::{Item, PerNs}, | |
| 48 | 48 | tt, |
| 49 | 49 | visibility::{RawVisibility, Visibility}, |
| 50 | 50 | AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantLoc, |
| ... | ... | @@ -523,7 +523,7 @@ impl DefCollector<'_> { |
| 523 | 523 | self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None); |
| 524 | 524 | |
| 525 | 525 | match per_ns.types { |
| 526 | Some((ModuleDefId::ModuleId(m), _, import)) => { | |
| 526 | Some(Item { def: ModuleDefId::ModuleId(m), import, .. }) => { | |
| 527 | 527 | // FIXME: This should specifically look for a glob import somehow and record that here |
| 528 | 528 | self.def_map.prelude = Some(( |
| 529 | 529 | m, |
| ... | ... | @@ -1069,9 +1069,9 @@ impl DefCollector<'_> { |
| 1069 | 1069 | // |
| 1070 | 1070 | // This has been historically allowed, but may be not allowed in future |
| 1071 | 1071 | // https://github.com/rust-lang/rust/issues/127909 |
| 1072 | if let Some((_, v, it)) = defs.types.as_mut() { | |
| 1072 | if let Some(def) = defs.types.as_mut() { | |
| 1073 | 1073 | let is_extern_crate_reimport_without_prefix = || { |
| 1074 | let Some(ImportOrExternCrate::ExternCrate(_)) = it else { | |
| 1074 | let Some(ImportOrExternCrate::ExternCrate(_)) = def.import else { | |
| 1075 | 1075 | return false; |
| 1076 | 1076 | }; |
| 1077 | 1077 | let Some(ImportType::Import(id)) = def_import_type else { |
| ... | ... | @@ -1086,16 +1086,16 @@ impl DefCollector<'_> { |
| 1086 | 1086 | path.segments().len() < 2 |
| 1087 | 1087 | }; |
| 1088 | 1088 | if is_extern_crate_reimport_without_prefix() { |
| 1089 | *v = vis; | |
| 1089 | def.vis = vis; | |
| 1090 | 1090 | } else { |
| 1091 | *v = v.min(vis, &self.def_map).unwrap_or(vis); | |
| 1091 | def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); | |
| 1092 | 1092 | } |
| 1093 | 1093 | } |
| 1094 | if let Some((_, v, _)) = defs.values.as_mut() { | |
| 1095 | *v = v.min(vis, &self.def_map).unwrap_or(vis); | |
| 1094 | if let Some(def) = defs.values.as_mut() { | |
| 1095 | def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); | |
| 1096 | 1096 | } |
| 1097 | if let Some((_, v, _)) = defs.macros.as_mut() { | |
| 1098 | *v = v.min(vis, &self.def_map).unwrap_or(vis); | |
| 1097 | if let Some(def) = defs.macros.as_mut() { | |
| 1098 | def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); | |
| 1099 | 1099 | } |
| 1100 | 1100 | |
| 1101 | 1101 | let mut changed = false; |
| ... | ... | @@ -1106,12 +1106,12 @@ impl DefCollector<'_> { |
| 1106 | 1106 | // Multiple globs may import the same item and they may override visibility from |
| 1107 | 1107 | // previously resolved globs. Handle overrides here and leave the rest to |
| 1108 | 1108 | // `ItemScope::push_res_with_import()`. |
| 1109 | if let Some((def, def_vis, _)) = defs.types { | |
| 1110 | if let Some((prev_def, prev_vis, _)) = prev_defs.types { | |
| 1111 | if def == prev_def | |
| 1109 | if let Some(def) = defs.types { | |
| 1110 | if let Some(prev_def) = prev_defs.types { | |
| 1111 | if def.def == prev_def.def | |
| 1112 | 1112 | && self.from_glob_import.contains_type(module_id, name.clone()) |
| 1113 | && def_vis != prev_vis | |
| 1114 | && def_vis.max(prev_vis, &self.def_map) == Some(def_vis) | |
| 1113 | && def.vis != prev_def.vis | |
| 1114 | && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) | |
| 1115 | 1115 | { |
| 1116 | 1116 | changed = true; |
| 1117 | 1117 | // This import is being handled here, don't pass it down to |
| ... | ... | @@ -1119,41 +1119,41 @@ impl DefCollector<'_> { |
| 1119 | 1119 | defs.types = None; |
| 1120 | 1120 | self.def_map.modules[module_id] |
| 1121 | 1121 | .scope |
| 1122 | .update_visibility_types(name, def_vis); | |
| 1122 | .update_visibility_types(name, def.vis); | |
| 1123 | 1123 | } |
| 1124 | 1124 | } |
| 1125 | 1125 | } |
| 1126 | 1126 | |
| 1127 | if let Some((def, def_vis, _)) = defs.values { | |
| 1128 | if let Some((prev_def, prev_vis, _)) = prev_defs.values { | |
| 1129 | if def == prev_def | |
| 1127 | if let Some(def) = defs.values { | |
| 1128 | if let Some(prev_def) = prev_defs.values { | |
| 1129 | if def.def == prev_def.def | |
| 1130 | 1130 | && self.from_glob_import.contains_value(module_id, name.clone()) |
| 1131 | && def_vis != prev_vis | |
| 1132 | && def_vis.max(prev_vis, &self.def_map) == Some(def_vis) | |
| 1131 | && def.vis != prev_def.vis | |
| 1132 | && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) | |
| 1133 | 1133 | { |
| 1134 | 1134 | changed = true; |
| 1135 | 1135 | // See comment above. |
| 1136 | 1136 | defs.values = None; |
| 1137 | 1137 | self.def_map.modules[module_id] |
| 1138 | 1138 | .scope |
| 1139 | .update_visibility_values(name, def_vis); | |
| 1139 | .update_visibility_values(name, def.vis); | |
| 1140 | 1140 | } |
| 1141 | 1141 | } |
| 1142 | 1142 | } |
| 1143 | 1143 | |
| 1144 | if let Some((def, def_vis, _)) = defs.macros { | |
| 1145 | if let Some((prev_def, prev_vis, _)) = prev_defs.macros { | |
| 1146 | if def == prev_def | |
| 1144 | if let Some(def) = defs.macros { | |
| 1145 | if let Some(prev_def) = prev_defs.macros { | |
| 1146 | if def.def == prev_def.def | |
| 1147 | 1147 | && self.from_glob_import.contains_macro(module_id, name.clone()) |
| 1148 | && def_vis != prev_vis | |
| 1149 | && def_vis.max(prev_vis, &self.def_map) == Some(def_vis) | |
| 1148 | && def.vis != prev_def.vis | |
| 1149 | && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) | |
| 1150 | 1150 | { |
| 1151 | 1151 | changed = true; |
| 1152 | 1152 | // See comment above. |
| 1153 | 1153 | defs.macros = None; |
| 1154 | 1154 | self.def_map.modules[module_id] |
| 1155 | 1155 | .scope |
| 1156 | .update_visibility_macros(name, def_vis); | |
| 1156 | .update_visibility_macros(name, def.vis); | |
| 1157 | 1157 | } |
| 1158 | 1158 | } |
| 1159 | 1159 | } |
src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs+6-6| ... | ... | @@ -67,8 +67,8 @@ impl PerNs { |
| 67 | 67 | db: &dyn DefDatabase, |
| 68 | 68 | expected: Option<MacroSubNs>, |
| 69 | 69 | ) -> Self { |
| 70 | self.macros = self.macros.filter(|&(id, _, _)| { | |
| 71 | let this = MacroSubNs::from_id(db, id); | |
| 70 | self.macros = self.macros.filter(|def| { | |
| 71 | let this = MacroSubNs::from_id(db, def.def); | |
| 72 | 72 | sub_namespace_match(Some(this), expected) |
| 73 | 73 | }); |
| 74 | 74 | |
| ... | ... | @@ -411,7 +411,7 @@ impl DefMap { |
| 411 | 411 | original_module: LocalModuleId, |
| 412 | 412 | ) -> ResolvePathResult { |
| 413 | 413 | for (i, segment) in segments { |
| 414 | let (curr, vis, imp) = match curr_per_ns.take_types_full() { | |
| 414 | let curr = match curr_per_ns.take_types_full() { | |
| 415 | 415 | Some(r) => r, |
| 416 | 416 | None => { |
| 417 | 417 | // we still have path segments left, but the path so far |
| ... | ... | @@ -424,7 +424,7 @@ impl DefMap { |
| 424 | 424 | }; |
| 425 | 425 | // resolve segment in curr |
| 426 | 426 | |
| 427 | curr_per_ns = match curr { | |
| 427 | curr_per_ns = match curr.def { | |
| 428 | 428 | ModuleDefId::ModuleId(module) => { |
| 429 | 429 | if module.krate != self.krate { |
| 430 | 430 | let path = ModPath::from_segments( |
| ... | ... | @@ -492,7 +492,7 @@ impl DefMap { |
| 492 | 492 | Some(res) => res, |
| 493 | 493 | None => { |
| 494 | 494 | return ResolvePathResult::new( |
| 495 | PerNs::types(e.into(), vis, imp), | |
| 495 | PerNs::types(e.into(), curr.vis, curr.import), | |
| 496 | 496 | ReachedFixedPoint::Yes, |
| 497 | 497 | Some(i), |
| 498 | 498 | false, |
| ... | ... | @@ -510,7 +510,7 @@ impl DefMap { |
| 510 | 510 | ); |
| 511 | 511 | |
| 512 | 512 | return ResolvePathResult::new( |
| 513 | PerNs::types(s, vis, imp), | |
| 513 | PerNs::types(s, curr.vis, curr.import), | |
| 514 | 514 | ReachedFixedPoint::Yes, |
| 515 | 515 | Some(i), |
| 516 | 516 | false, |
src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs+1-1| ... | ... | @@ -331,7 +331,7 @@ pub type Ty = (); |
| 331 | 331 | } |
| 332 | 332 | |
| 333 | 333 | for (_, res) in module_data.scope.resolutions() { |
| 334 | match res.values.map(|(a, _, _)| a).or(res.types.map(|(a, _, _)| a)).unwrap() { | |
| 334 | match res.values.map(|it| it.def).or(res.types.map(|it| it.def)).unwrap() { | |
| 335 | 335 | ModuleDefId::FunctionId(f) => _ = db.function_data(f), |
| 336 | 336 | ModuleDefId::AdtId(adt) => match adt { |
| 337 | 337 | AdtId::StructId(it) => _ = db.struct_data(it), |
src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs+47-30| ... | ... | @@ -28,11 +28,22 @@ bitflags! { |
| 28 | 28 | } |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | |
| 32 | pub struct Item<Def, Import = ImportId> { | |
| 33 | pub def: Def, | |
| 34 | pub vis: Visibility, | |
| 35 | pub import: Option<Import>, | |
| 36 | } | |
| 37 | ||
| 38 | pub type TypesItem = Item<ModuleDefId, ImportOrExternCrate>; | |
| 39 | pub type ValuesItem = Item<ModuleDefId>; | |
| 40 | pub type MacrosItem = Item<MacroId>; | |
| 41 | ||
| 31 | 42 | #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] |
| 32 | 43 | pub struct PerNs { |
| 33 | pub types: Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)>, | |
| 34 | pub values: Option<(ModuleDefId, Visibility, Option<ImportId>)>, | |
| 35 | pub macros: Option<(MacroId, Visibility, Option<ImportId>)>, | |
| 44 | pub types: Option<TypesItem>, | |
| 45 | pub values: Option<ValuesItem>, | |
| 46 | pub macros: Option<MacrosItem>, | |
| 36 | 47 | } |
| 37 | 48 | |
| 38 | 49 | impl PerNs { |
| ... | ... | @@ -48,29 +59,33 @@ impl PerNs { |
| 48 | 59 | PerNs { types: None, values: None, macros: None } |
| 49 | 60 | } |
| 50 | 61 | |
| 51 | pub fn values(t: ModuleDefId, v: Visibility, i: Option<ImportId>) -> PerNs { | |
| 52 | PerNs { types: None, values: Some((t, v, i)), macros: None } | |
| 62 | pub fn values(def: ModuleDefId, vis: Visibility, import: Option<ImportId>) -> PerNs { | |
| 63 | PerNs { types: None, values: Some(Item { def, vis, import }), macros: None } | |
| 53 | 64 | } |
| 54 | 65 | |
| 55 | pub fn types(t: ModuleDefId, v: Visibility, i: Option<ImportOrExternCrate>) -> PerNs { | |
| 56 | PerNs { types: Some((t, v, i)), values: None, macros: None } | |
| 66 | pub fn types(def: ModuleDefId, vis: Visibility, import: Option<ImportOrExternCrate>) -> PerNs { | |
| 67 | PerNs { types: Some(Item { def, vis, import }), values: None, macros: None } | |
| 57 | 68 | } |
| 58 | 69 | |
| 59 | 70 | pub fn both( |
| 60 | 71 | types: ModuleDefId, |
| 61 | 72 | values: ModuleDefId, |
| 62 | v: Visibility, | |
| 63 | i: Option<ImportOrExternCrate>, | |
| 73 | vis: Visibility, | |
| 74 | import: Option<ImportOrExternCrate>, | |
| 64 | 75 | ) -> PerNs { |
| 65 | 76 | PerNs { |
| 66 | types: Some((types, v, i)), | |
| 67 | values: Some((values, v, i.and_then(ImportOrExternCrate::into_import))), | |
| 77 | types: Some(Item { def: types, vis, import }), | |
| 78 | values: Some(Item { | |
| 79 | def: values, | |
| 80 | vis, | |
| 81 | import: import.and_then(ImportOrExternCrate::into_import), | |
| 82 | }), | |
| 68 | 83 | macros: None, |
| 69 | 84 | } |
| 70 | 85 | } |
| 71 | 86 | |
| 72 | pub fn macros(macro_: MacroId, v: Visibility, i: Option<ImportId>) -> PerNs { | |
| 73 | PerNs { types: None, values: None, macros: Some((macro_, v, i)) } | |
| 87 | pub fn macros(def: MacroId, vis: Visibility, import: Option<ImportId>) -> PerNs { | |
| 88 | PerNs { types: None, values: None, macros: Some(Item { def, vis, import }) } | |
| 74 | 89 | } |
| 75 | 90 | |
| 76 | 91 | pub fn is_none(&self) -> bool { |
| ... | ... | @@ -82,43 +97,43 @@ impl PerNs { |
| 82 | 97 | } |
| 83 | 98 | |
| 84 | 99 | pub fn take_types(self) -> Option<ModuleDefId> { |
| 85 | self.types.map(|it| it.0) | |
| 100 | self.types.map(|it| it.def) | |
| 86 | 101 | } |
| 87 | 102 | |
| 88 | pub fn take_types_full(self) -> Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)> { | |
| 103 | pub fn take_types_full(self) -> Option<TypesItem> { | |
| 89 | 104 | self.types |
| 90 | 105 | } |
| 91 | 106 | |
| 92 | 107 | pub fn take_values(self) -> Option<ModuleDefId> { |
| 93 | self.values.map(|it| it.0) | |
| 108 | self.values.map(|it| it.def) | |
| 94 | 109 | } |
| 95 | 110 | |
| 96 | 111 | pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportId>)> { |
| 97 | self.values.map(|it| (it.0, it.2)) | |
| 112 | self.values.map(|it| (it.def, it.import)) | |
| 98 | 113 | } |
| 99 | 114 | |
| 100 | 115 | pub fn take_macros(self) -> Option<MacroId> { |
| 101 | self.macros.map(|it| it.0) | |
| 116 | self.macros.map(|it| it.def) | |
| 102 | 117 | } |
| 103 | 118 | |
| 104 | 119 | pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportId>)> { |
| 105 | self.macros.map(|it| (it.0, it.2)) | |
| 120 | self.macros.map(|it| (it.def, it.import)) | |
| 106 | 121 | } |
| 107 | 122 | |
| 108 | 123 | pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs { |
| 109 | 124 | let _p = tracing::info_span!("PerNs::filter_visibility").entered(); |
| 110 | 125 | PerNs { |
| 111 | types: self.types.filter(|&(_, v, _)| f(v)), | |
| 112 | values: self.values.filter(|&(_, v, _)| f(v)), | |
| 113 | macros: self.macros.filter(|&(_, v, _)| f(v)), | |
| 126 | types: self.types.filter(|def| f(def.vis)), | |
| 127 | values: self.values.filter(|def| f(def.vis)), | |
| 128 | macros: self.macros.filter(|def| f(def.vis)), | |
| 114 | 129 | } |
| 115 | 130 | } |
| 116 | 131 | |
| 117 | 132 | pub fn with_visibility(self, vis: Visibility) -> PerNs { |
| 118 | 133 | PerNs { |
| 119 | types: self.types.map(|(it, _, c)| (it, vis, c)), | |
| 120 | values: self.values.map(|(it, _, c)| (it, vis, c)), | |
| 121 | macros: self.macros.map(|(it, _, import)| (it, vis, import)), | |
| 134 | types: self.types.map(|def| Item { vis, ..def }), | |
| 135 | values: self.values.map(|def| Item { vis, ..def }), | |
| 136 | macros: self.macros.map(|def| Item { vis, ..def }), | |
| 122 | 137 | } |
| 123 | 138 | } |
| 124 | 139 | |
| ... | ... | @@ -141,15 +156,17 @@ impl PerNs { |
| 141 | 156 | pub fn iter_items(self) -> impl Iterator<Item = (ItemInNs, Option<ImportOrExternCrate>)> { |
| 142 | 157 | let _p = tracing::info_span!("PerNs::iter_items").entered(); |
| 143 | 158 | self.types |
| 144 | .map(|it| (ItemInNs::Types(it.0), it.2)) | |
| 159 | .map(|it| (ItemInNs::Types(it.def), it.import)) | |
| 145 | 160 | .into_iter() |
| 146 | 161 | .chain( |
| 147 | self.values | |
| 148 | .map(|it| (ItemInNs::Values(it.0), it.2.map(ImportOrExternCrate::Import))), | |
| 162 | self.values.map(|it| { | |
| 163 | (ItemInNs::Values(it.def), it.import.map(ImportOrExternCrate::Import)) | |
| 164 | }), | |
| 149 | 165 | ) |
| 150 | 166 | .chain( |
| 151 | self.macros | |
| 152 | .map(|it| (ItemInNs::Macros(it.0), it.2.map(ImportOrExternCrate::Import))), | |
| 167 | self.macros.map(|it| { | |
| 168 | (ItemInNs::Macros(it.def), it.import.map(ImportOrExternCrate::Import)) | |
| 169 | }), | |
| 153 | 170 | ) |
| 154 | 171 | } |
| 155 | 172 | } |
src/tools/rust-analyzer/crates/hir-def/src/resolver.rs+12-12| ... | ... | @@ -933,8 +933,8 @@ impl ModuleItemMap { |
| 933 | 933 | Some(ResolveValueResult::ValueNs(value, import)) |
| 934 | 934 | } |
| 935 | 935 | Some(idx) => { |
| 936 | let (def, _, import) = module_def.take_types_full()?; | |
| 937 | let ty = match def { | |
| 936 | let def = module_def.take_types_full()?; | |
| 937 | let ty = match def.def { | |
| 938 | 938 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), |
| 939 | 939 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), |
| 940 | 940 | ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it), |
| ... | ... | @@ -948,7 +948,7 @@ impl ModuleItemMap { |
| 948 | 948 | | ModuleDefId::MacroId(_) |
| 949 | 949 | | ModuleDefId::StaticId(_) => return None, |
| 950 | 950 | }; |
| 951 | Some(ResolveValueResult::Partial(ty, idx, import)) | |
| 951 | Some(ResolveValueResult::Partial(ty, idx, def.import)) | |
| 952 | 952 | } |
| 953 | 953 | } |
| 954 | 954 | } |
| ... | ... | @@ -986,8 +986,8 @@ fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> { |
| 986 | 986 | } |
| 987 | 987 | |
| 988 | 988 | fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> { |
| 989 | let (def, _, import) = per_ns.take_types_full()?; | |
| 990 | let res = match def { | |
| 989 | let def = per_ns.take_types_full()?; | |
| 990 | let res = match def.def { | |
| 991 | 991 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), |
| 992 | 992 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), |
| 993 | 993 | |
| ... | ... | @@ -1003,7 +1003,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> { |
| 1003 | 1003 | | ModuleDefId::StaticId(_) |
| 1004 | 1004 | | ModuleDefId::ModuleId(_) => return None, |
| 1005 | 1005 | }; |
| 1006 | Some((res, import)) | |
| 1006 | Some((res, def.import)) | |
| 1007 | 1007 | } |
| 1008 | 1008 | |
| 1009 | 1009 | #[derive(Default)] |
| ... | ... | @@ -1019,14 +1019,14 @@ impl ScopeNames { |
| 1019 | 1019 | } |
| 1020 | 1020 | } |
| 1021 | 1021 | fn add_per_ns(&mut self, name: &Name, def: PerNs) { |
| 1022 | if let &Some((ty, _, _)) = &def.types { | |
| 1023 | self.add(name, ScopeDef::ModuleDef(ty)) | |
| 1022 | if let Some(ty) = &def.types { | |
| 1023 | self.add(name, ScopeDef::ModuleDef(ty.def)) | |
| 1024 | 1024 | } |
| 1025 | if let &Some((def, _, _)) = &def.values { | |
| 1026 | self.add(name, ScopeDef::ModuleDef(def)) | |
| 1025 | if let Some(def) = &def.values { | |
| 1026 | self.add(name, ScopeDef::ModuleDef(def.def)) | |
| 1027 | 1027 | } |
| 1028 | if let &Some((mac, _, _)) = &def.macros { | |
| 1029 | self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac))) | |
| 1028 | if let Some(mac) = &def.macros { | |
| 1029 | self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac.def))) | |
| 1030 | 1030 | } |
| 1031 | 1031 | if def.is_none() { |
| 1032 | 1032 | self.add(name, ScopeDef::Unknown) |
src/tools/rust-analyzer/crates/hir-expand/src/db.rs+9-7| ... | ... | @@ -153,13 +153,13 @@ fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId) -> SyntaxContextId { |
| 153 | 153 | /// This expands the given macro call, but with different arguments. This is |
| 154 | 154 | /// used for completion, where we want to see what 'would happen' if we insert a |
| 155 | 155 | /// token. The `token_to_map` mapped down into the expansion, with the mapped |
| 156 | /// token returned. | |
| 156 | /// token(s) returned with their priority. | |
| 157 | 157 | pub fn expand_speculative( |
| 158 | 158 | db: &dyn ExpandDatabase, |
| 159 | 159 | actual_macro_call: MacroCallId, |
| 160 | 160 | speculative_args: &SyntaxNode, |
| 161 | 161 | token_to_map: SyntaxToken, |
| 162 | ) -> Option<(SyntaxNode, SyntaxToken)> { | |
| 162 | ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> { | |
| 163 | 163 | let loc = db.lookup_intern_macro_call(actual_macro_call); |
| 164 | 164 | let (_, _, span) = db.macro_arg_considering_derives(actual_macro_call, &loc.kind); |
| 165 | 165 | |
| ... | ... | @@ -303,17 +303,19 @@ pub fn expand_speculative( |
| 303 | 303 | token_tree_to_syntax_node(&speculative_expansion.value, expand_to, loc.def.edition); |
| 304 | 304 | |
| 305 | 305 | let syntax_node = node.syntax_node(); |
| 306 | let (token, _) = rev_tmap | |
| 306 | let token = rev_tmap | |
| 307 | 307 | .ranges_with_span(span_map.span_for_range(token_to_map.text_range())) |
| 308 | 308 | .filter_map(|(range, ctx)| syntax_node.covering_element(range).into_token().zip(Some(ctx))) |
| 309 | .min_by_key(|(t, ctx)| { | |
| 309 | .map(|(t, ctx)| { | |
| 310 | 310 | // prefer tokens of the same kind and text, as well as non opaque marked ones |
| 311 | 311 | // Note the inversion of the score here, as we want to prefer the first token in case |
| 312 | 312 | // of all tokens having the same score |
| 313 | ctx.is_opaque(db) as u8 | |
| 313 | let ranking = ctx.is_opaque(db) as u8 | |
| 314 | 314 | + 2 * (t.kind() != token_to_map.kind()) as u8 |
| 315 | + 4 * ((t.text() != token_to_map.text()) as u8) | |
| 316 | })?; | |
| 315 | + 4 * ((t.text() != token_to_map.text()) as u8); | |
| 316 | (t, ranking) | |
| 317 | }) | |
| 318 | .collect(); | |
| 317 | 319 | Some((node.syntax_node(), token)) |
| 318 | 320 | } |
| 319 | 321 |
src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs+1-10| ... | ... | @@ -22,7 +22,6 @@ use hir_def::{ |
| 22 | 22 | |
| 23 | 23 | use crate::{ |
| 24 | 24 | db::{HirDatabase, InternedCoroutine}, |
| 25 | display::HirDisplay, | |
| 26 | 25 | from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, |
| 27 | 26 | generics::generics, |
| 28 | 27 | make_binders, make_single_type_binders, |
| ... | ... | @@ -823,13 +822,12 @@ pub(crate) fn impl_datum_query( |
| 823 | 822 | let _p = tracing::info_span!("impl_datum_query").entered(); |
| 824 | 823 | debug!("impl_datum {:?}", impl_id); |
| 825 | 824 | let impl_: hir_def::ImplId = from_chalk(db, impl_id); |
| 826 | impl_def_datum(db, krate, impl_id, impl_) | |
| 825 | impl_def_datum(db, krate, impl_) | |
| 827 | 826 | } |
| 828 | 827 | |
| 829 | 828 | fn impl_def_datum( |
| 830 | 829 | db: &dyn HirDatabase, |
| 831 | 830 | krate: CrateId, |
| 832 | chalk_id: ImplId, | |
| 833 | 831 | impl_id: hir_def::ImplId, |
| 834 | 832 | ) -> Arc<ImplDatum> { |
| 835 | 833 | let trait_ref = db |
| ... | ... | @@ -850,13 +848,6 @@ fn impl_def_datum( |
| 850 | 848 | }; |
| 851 | 849 | let where_clauses = convert_where_clauses(db, impl_id.into(), &bound_vars); |
| 852 | 850 | let negative = impl_data.is_negative; |
| 853 | debug!( | |
| 854 | "impl {:?}: {}{} where {:?}", | |
| 855 | chalk_id, | |
| 856 | if negative { "!" } else { "" }, | |
| 857 | trait_ref.display(db, db.crate_graph()[krate].edition), | |
| 858 | where_clauses | |
| 859 | ); | |
| 860 | 851 | |
| 861 | 852 | let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive }; |
| 862 | 853 |
src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs+11-2| ... | ... | @@ -193,10 +193,19 @@ impl<'a> UnsafeVisitor<'a> { |
| 193 | 193 | self.resolver.reset_to_guard(guard); |
| 194 | 194 | } |
| 195 | 195 | Expr::Ref { expr, rawness: Rawness::RawPtr, mutability: _ } => { |
| 196 | if let Expr::Path(_) = self.body.exprs[*expr] { | |
| 196 | match self.body.exprs[*expr] { | |
| 197 | 197 | // Do not report unsafe for `addr_of[_mut]!(EXTERN_OR_MUT_STATIC)`, |
| 198 | 198 | // see https://github.com/rust-lang/rust/pull/125834. |
| 199 | return; | |
| 199 | Expr::Path(_) => return, | |
| 200 | // https://github.com/rust-lang/rust/pull/129248 | |
| 201 | // Taking a raw ref to a deref place expr is always safe. | |
| 202 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { | |
| 203 | self.body | |
| 204 | .walk_child_exprs_without_pats(expr, |child| self.walk_expr(child)); | |
| 205 | ||
| 206 | return; | |
| 207 | } | |
| 208 | _ => (), | |
| 200 | 209 | } |
| 201 | 210 | } |
| 202 | 211 | Expr::MethodCall { .. } => { |
src/tools/rust-analyzer/crates/hir/src/diagnostics.rs+14-7| ... | ... | @@ -262,7 +262,7 @@ pub struct UnresolvedAssocItem { |
| 262 | 262 | |
| 263 | 263 | #[derive(Debug)] |
| 264 | 264 | pub struct UnresolvedIdent { |
| 265 | pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>, | |
| 265 | pub node: InFile<(AstPtr<Either<ast::Expr, ast::Pat>>, Option<TextRange>)>, | |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | 268 | #[derive(Debug)] |
| ... | ... | @@ -550,11 +550,10 @@ impl AnyDiagnostic { |
| 550 | 550 | source_map: &hir_def::body::BodySourceMap, |
| 551 | 551 | ) -> Option<AnyDiagnostic> { |
| 552 | 552 | let expr_syntax = |expr| { |
| 553 | source_map.expr_syntax(expr).inspect_err(|_| tracing::error!("synthetic syntax")).ok() | |
| 554 | }; | |
| 555 | let pat_syntax = |pat| { | |
| 556 | source_map.pat_syntax(pat).inspect_err(|_| tracing::error!("synthetic syntax")).ok() | |
| 553 | source_map.expr_syntax(expr).inspect_err(|_| stdx::never!("synthetic syntax")).ok() | |
| 557 | 554 | }; |
| 555 | let pat_syntax = | |
| 556 | |pat| source_map.pat_syntax(pat).inspect_err(|_| stdx::never!("synthetic syntax")).ok(); | |
| 558 | 557 | let expr_or_pat_syntax = |id| match id { |
| 559 | 558 | ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(|it| it.map(AstPtr::wrap_left)), |
| 560 | 559 | ExprOrPatId::PatId(pat) => pat_syntax(pat), |
| ... | ... | @@ -626,8 +625,16 @@ impl AnyDiagnostic { |
| 626 | 625 | UnresolvedAssocItem { expr_or_pat }.into() |
| 627 | 626 | } |
| 628 | 627 | &InferenceDiagnostic::UnresolvedIdent { id } => { |
| 629 | let expr_or_pat = expr_or_pat_syntax(id)?; | |
| 630 | UnresolvedIdent { expr_or_pat }.into() | |
| 628 | let node = match id { | |
| 629 | ExprOrPatId::ExprId(id) => match source_map.expr_syntax(id) { | |
| 630 | Ok(syntax) => syntax.map(|it| (it.wrap_left(), None)), | |
| 631 | Err(SyntheticSyntax) => source_map | |
| 632 | .format_args_implicit_capture(id)? | |
| 633 | .map(|(node, range)| (node.wrap_left(), Some(range))), | |
| 634 | }, | |
| 635 | ExprOrPatId::PatId(id) => pat_syntax(id)?.map(|it| (it, None)), | |
| 636 | }; | |
| 637 | UnresolvedIdent { node }.into() | |
| 631 | 638 | } |
| 632 | 639 | &InferenceDiagnostic::BreakOutsideOfLoop { expr, is_break, bad_value_break } => { |
| 633 | 640 | let expr = expr_syntax(expr)?; |
src/tools/rust-analyzer/crates/hir/src/lib.rs+3-3| ... | ... | @@ -3105,10 +3105,10 @@ impl From<ModuleDef> for ItemInNs { |
| 3105 | 3105 | } |
| 3106 | 3106 | |
| 3107 | 3107 | impl ItemInNs { |
| 3108 | pub fn as_module_def(self) -> Option<ModuleDef> { | |
| 3108 | pub fn into_module_def(self) -> ModuleDef { | |
| 3109 | 3109 | match self { |
| 3110 | ItemInNs::Types(id) | ItemInNs::Values(id) => Some(id), | |
| 3111 | ItemInNs::Macros(_) => None, | |
| 3110 | ItemInNs::Types(id) | ItemInNs::Values(id) => id, | |
| 3111 | ItemInNs::Macros(id) => ModuleDef::Macro(id), | |
| 3112 | 3112 | } |
| 3113 | 3113 | } |
| 3114 | 3114 |
src/tools/rust-analyzer/crates/hir/src/semantics.rs+28-15| ... | ... | @@ -38,9 +38,9 @@ use span::{AstIdMap, EditionedFileId, FileId, HirFileIdRepr, SyntaxContextId}; |
| 38 | 38 | use stdx::TupleExt; |
| 39 | 39 | use syntax::{ |
| 40 | 40 | algo::skip_trivia_token, |
| 41 | ast::{self, HasAttrs as _, HasGenericParams, IsString as _}, | |
| 42 | AstNode, AstToken, Direction, SyntaxKind, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, | |
| 43 | TextSize, | |
| 41 | ast::{self, HasAttrs as _, HasGenericParams}, | |
| 42 | AstNode, AstToken, Direction, SmolStr, SyntaxKind, SyntaxNode, SyntaxNodePtr, SyntaxToken, | |
| 43 | TextRange, TextSize, | |
| 44 | 44 | }; |
| 45 | 45 | use triomphe::Arc; |
| 46 | 46 | |
| ... | ... | @@ -571,7 +571,7 @@ impl<'db> SemanticsImpl<'db> { |
| 571 | 571 | actual_macro_call: &ast::MacroCall, |
| 572 | 572 | speculative_args: &ast::TokenTree, |
| 573 | 573 | token_to_map: SyntaxToken, |
| 574 | ) -> Option<(SyntaxNode, SyntaxToken)> { | |
| 574 | ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> { | |
| 575 | 575 | let SourceAnalyzer { file_id, resolver, .. } = |
| 576 | 576 | self.analyze_no_infer(actual_macro_call.syntax())?; |
| 577 | 577 | let macro_call = InFile::new(file_id, actual_macro_call); |
| ... | ... | @@ -592,7 +592,7 @@ impl<'db> SemanticsImpl<'db> { |
| 592 | 592 | macro_file: MacroFileId, |
| 593 | 593 | speculative_args: &SyntaxNode, |
| 594 | 594 | token_to_map: SyntaxToken, |
| 595 | ) -> Option<(SyntaxNode, SyntaxToken)> { | |
| 595 | ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> { | |
| 596 | 596 | hir_expand::db::expand_speculative( |
| 597 | 597 | self.db.upcast(), |
| 598 | 598 | macro_file.macro_call_id, |
| ... | ... | @@ -608,7 +608,7 @@ impl<'db> SemanticsImpl<'db> { |
| 608 | 608 | actual_macro_call: &ast::Item, |
| 609 | 609 | speculative_args: &ast::Item, |
| 610 | 610 | token_to_map: SyntaxToken, |
| 611 | ) -> Option<(SyntaxNode, SyntaxToken)> { | |
| 611 | ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> { | |
| 612 | 612 | let macro_call = self.wrap_node_infile(actual_macro_call.clone()); |
| 613 | 613 | let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(macro_call.as_ref()))?; |
| 614 | 614 | hir_expand::db::expand_speculative( |
| ... | ... | @@ -624,7 +624,7 @@ impl<'db> SemanticsImpl<'db> { |
| 624 | 624 | actual_macro_call: &ast::Attr, |
| 625 | 625 | speculative_args: &ast::Attr, |
| 626 | 626 | token_to_map: SyntaxToken, |
| 627 | ) -> Option<(SyntaxNode, SyntaxToken)> { | |
| 627 | ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> { | |
| 628 | 628 | let attr = self.wrap_node_infile(actual_macro_call.clone()); |
| 629 | 629 | let adt = actual_macro_call.syntax().parent().and_then(ast::Adt::cast)?; |
| 630 | 630 | let macro_call_id = self.with_ctx(|ctx| { |
| ... | ... | @@ -643,8 +643,7 @@ impl<'db> SemanticsImpl<'db> { |
| 643 | 643 | &self, |
| 644 | 644 | string: &ast::String, |
| 645 | 645 | ) -> Option<Vec<(TextRange, Option<Either<PathResolution, InlineAsmOperand>>)>> { |
| 646 | let quote = string.open_quote_text_range()?; | |
| 647 | ||
| 646 | let string_start = string.syntax().text_range().start(); | |
| 648 | 647 | let token = self.wrap_token_infile(string.syntax().clone()).into_real_file().ok()?; |
| 649 | 648 | self.descend_into_macros_breakable(token, |token, _| { |
| 650 | 649 | (|| { |
| ... | ... | @@ -658,7 +657,7 @@ impl<'db> SemanticsImpl<'db> { |
| 658 | 657 | let format_args = self.wrap_node_infile(format_args); |
| 659 | 658 | let res = source_analyzer |
| 660 | 659 | .as_format_args_parts(self.db, format_args.as_ref())? |
| 661 | .map(|(range, res)| (range + quote.end(), res.map(Either::Left))) | |
| 660 | .map(|(range, res)| (range + string_start, res.map(Either::Left))) | |
| 662 | 661 | .collect(); |
| 663 | 662 | Some(res) |
| 664 | 663 | } else { |
| ... | ... | @@ -672,7 +671,7 @@ impl<'db> SemanticsImpl<'db> { |
| 672 | 671 | .iter() |
| 673 | 672 | .map(|&(range, index)| { |
| 674 | 673 | ( |
| 675 | range + quote.end(), | |
| 674 | range + string_start, | |
| 676 | 675 | Some(Either::Right(InlineAsmOperand { owner, expr, index })), |
| 677 | 676 | ) |
| 678 | 677 | }) |
| ... | ... | @@ -690,17 +689,16 @@ impl<'db> SemanticsImpl<'db> { |
| 690 | 689 | original_token: SyntaxToken, |
| 691 | 690 | offset: TextSize, |
| 692 | 691 | ) -> Option<(TextRange, Option<Either<PathResolution, InlineAsmOperand>>)> { |
| 693 | let original_string = ast::String::cast(original_token.clone())?; | |
| 692 | let string_start = original_token.text_range().start(); | |
| 694 | 693 | let original_token = self.wrap_token_infile(original_token).into_real_file().ok()?; |
| 695 | let quote = original_string.open_quote_text_range()?; | |
| 696 | 694 | self.descend_into_macros_breakable(original_token, |token, _| { |
| 697 | 695 | (|| { |
| 698 | 696 | let token = token.value; |
| 699 | 697 | self.resolve_offset_in_format_args( |
| 700 | 698 | ast::String::cast(token)?, |
| 701 | offset.checked_sub(quote.end())?, | |
| 699 | offset.checked_sub(string_start)?, | |
| 702 | 700 | ) |
| 703 | .map(|(range, res)| (range + quote.end(), res)) | |
| 701 | .map(|(range, res)| (range + string_start, res)) | |
| 704 | 702 | })() |
| 705 | 703 | .map_or(ControlFlow::Continue(()), ControlFlow::Break) |
| 706 | 704 | }) |
| ... | ... | @@ -1542,6 +1540,21 @@ impl<'db> SemanticsImpl<'db> { |
| 1542 | 1540 | Some(items.iter_items().map(|(item, _)| item.into())) |
| 1543 | 1541 | } |
| 1544 | 1542 | |
| 1543 | pub fn resolve_mod_path_relative( | |
| 1544 | &self, | |
| 1545 | to: Module, | |
| 1546 | segments: impl IntoIterator<Item = SmolStr>, | |
| 1547 | ) -> Option<impl Iterator<Item = ItemInNs>> { | |
| 1548 | let items = to.id.resolver(self.db.upcast()).resolve_module_path_in_items( | |
| 1549 | self.db.upcast(), | |
| 1550 | &ModPath::from_segments( | |
| 1551 | hir_def::path::PathKind::Plain, | |
| 1552 | segments.into_iter().map(|it| Name::new(&it, SyntaxContextId::ROOT)), | |
| 1553 | ), | |
| 1554 | ); | |
| 1555 | Some(items.iter_items().map(|(item, _)| item.into())) | |
| 1556 | } | |
| 1557 | ||
| 1545 | 1558 | fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> { |
| 1546 | 1559 | self.analyze(record_lit.syntax())?.resolve_variant(self.db, record_lit) |
| 1547 | 1560 | } |
src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs+5| ... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 | use hir::{FileRange, Semantics}; |
| 4 | 4 | use ide_db::EditionedFileId; |
| 5 | 5 | use ide_db::{label::Label, FileId, RootDatabase}; |
| 6 | use syntax::Edition; | |
| 6 | 7 | use syntax::{ |
| 7 | 8 | algo::{self, find_node_at_offset, find_node_at_range}, |
| 8 | 9 | AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange, |
| ... | ... | @@ -94,6 +95,10 @@ impl<'a> AssistContext<'a> { |
| 94 | 95 | self.frange.file_id |
| 95 | 96 | } |
| 96 | 97 | |
| 98 | pub(crate) fn edition(&self) -> Edition { | |
| 99 | self.frange.file_id.edition() | |
| 100 | } | |
| 101 | ||
| 97 | 102 | pub(crate) fn has_empty_selection(&self) -> bool { |
| 98 | 103 | self.trimmed_range.is_empty() |
| 99 | 104 | } |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs+67-74| ... | ... | @@ -1,10 +1,12 @@ |
| 1 | use ide_db::text_edit::TextRange; | |
| 2 | 1 | use ide_db::{ |
| 3 | 2 | assists::{AssistId, AssistKind}, |
| 4 | 3 | defs::Definition, |
| 5 | search::{FileReference, SearchScope, UsageSearchResult}, | |
| 4 | search::{FileReference, SearchScope}, | |
| 5 | syntax_helpers::suggest_name, | |
| 6 | text_edit::TextRange, | |
| 6 | 7 | }; |
| 7 | 8 | use itertools::Itertools; |
| 9 | use syntax::SmolStr; | |
| 8 | 10 | use syntax::{ |
| 9 | 11 | ast::{self, make, AstNode, FieldExpr, HasName, IdentPat}, |
| 10 | 12 | ted, |
| ... | ... | @@ -122,33 +124,43 @@ fn collect_data(ident_pat: IdentPat, ctx: &AssistContext<'_>) -> Option<TupleDat |
| 122 | 124 | return None; |
| 123 | 125 | } |
| 124 | 126 | |
| 125 | let name = ident_pat.name()?.to_string(); | |
| 126 | ||
| 127 | let usages = ctx.sema.to_def(&ident_pat).map(|def| { | |
| 127 | let usages = ctx.sema.to_def(&ident_pat).and_then(|def| { | |
| 128 | 128 | Definition::Local(def) |
| 129 | 129 | .usages(&ctx.sema) |
| 130 | 130 | .in_scope(&SearchScope::single_file(ctx.file_id())) |
| 131 | 131 | .all() |
| 132 | .iter() | |
| 133 | .next() | |
| 134 | .map(|(_, refs)| refs.to_vec()) | |
| 132 | 135 | }); |
| 133 | 136 | |
| 134 | let field_names = (0..field_types.len()) | |
| 135 | .map(|i| generate_name(ctx, i, &name, &ident_pat, &usages)) | |
| 137 | let mut name_generator = { | |
| 138 | let mut names = vec![]; | |
| 139 | if let Some(scope) = ctx.sema.scope(ident_pat.syntax()) { | |
| 140 | scope.process_all_names(&mut |name, scope| { | |
| 141 | if let hir::ScopeDef::Local(_) = scope { | |
| 142 | names.push(name.as_str().into()) | |
| 143 | } | |
| 144 | }) | |
| 145 | } | |
| 146 | suggest_name::NameGenerator::new_with_names(names.iter().map(|s: &SmolStr| s.as_str())) | |
| 147 | }; | |
| 148 | ||
| 149 | let field_names = field_types | |
| 150 | .into_iter() | |
| 151 | .enumerate() | |
| 152 | .map(|(id, ty)| { | |
| 153 | match name_generator.for_type(&ty, ctx.db(), ctx.edition()) { | |
| 154 | Some(name) => name, | |
| 155 | None => name_generator.suggest_name(&format!("_{}", id)), | |
| 156 | } | |
| 157 | .to_string() | |
| 158 | }) | |
| 136 | 159 | .collect::<Vec<_>>(); |
| 137 | 160 | |
| 138 | 161 | Some(TupleData { ident_pat, ref_type, field_names, usages }) |
| 139 | 162 | } |
| 140 | 163 | |
| 141 | fn generate_name( | |
| 142 | _ctx: &AssistContext<'_>, | |
| 143 | index: usize, | |
| 144 | _tuple_name: &str, | |
| 145 | _ident_pat: &IdentPat, | |
| 146 | _usages: &Option<UsageSearchResult>, | |
| 147 | ) -> String { | |
| 148 | // FIXME: detect if name already used | |
| 149 | format!("_{index}") | |
| 150 | } | |
| 151 | ||
| 152 | 164 | enum RefType { |
| 153 | 165 | ReadOnly, |
| 154 | 166 | Mutable, |
| ... | ... | @@ -157,7 +169,7 @@ struct TupleData { |
| 157 | 169 | ident_pat: IdentPat, |
| 158 | 170 | ref_type: Option<RefType>, |
| 159 | 171 | field_names: Vec<String>, |
| 160 | usages: Option<UsageSearchResult>, | |
| 172 | usages: Option<Vec<FileReference>>, | |
| 161 | 173 | } |
| 162 | 174 | fn edit_tuple_assignment( |
| 163 | 175 | ctx: &AssistContext<'_>, |
| ... | ... | @@ -213,42 +225,23 @@ fn edit_tuple_usages( |
| 213 | 225 | ctx: &AssistContext<'_>, |
| 214 | 226 | in_sub_pattern: bool, |
| 215 | 227 | ) -> Option<Vec<EditTupleUsage>> { |
| 216 | let mut current_file_usages = None; | |
| 217 | ||
| 218 | if let Some(usages) = data.usages.as_ref() { | |
| 219 | // We need to collect edits first before actually applying them | |
| 220 | // as mapping nodes to their mutable node versions requires an | |
| 221 | // unmodified syntax tree. | |
| 222 | // | |
| 223 | // We also defer editing usages in the current file first since | |
| 224 | // tree mutation in the same file breaks when `builder.edit_file` | |
| 225 | // is called | |
| 226 | ||
| 227 | if let Some((_, refs)) = usages.iter().find(|(file_id, _)| *file_id == ctx.file_id()) { | |
| 228 | current_file_usages = Some( | |
| 229 | refs.iter() | |
| 230 | .filter_map(|r| edit_tuple_usage(ctx, edit, r, data, in_sub_pattern)) | |
| 231 | .collect_vec(), | |
| 232 | ); | |
| 233 | } | |
| 234 | ||
| 235 | for (file_id, refs) in usages.iter() { | |
| 236 | if file_id == ctx.file_id() { | |
| 237 | continue; | |
| 238 | } | |
| 239 | ||
| 240 | edit.edit_file(file_id.file_id()); | |
| 241 | ||
| 242 | let tuple_edits = refs | |
| 243 | .iter() | |
| 244 | .filter_map(|r| edit_tuple_usage(ctx, edit, r, data, in_sub_pattern)) | |
| 245 | .collect_vec(); | |
| 246 | ||
| 247 | tuple_edits.into_iter().for_each(|tuple_edit| tuple_edit.apply(edit)) | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 251 | current_file_usages | |
| 228 | // We need to collect edits first before actually applying them | |
| 229 | // as mapping nodes to their mutable node versions requires an | |
| 230 | // unmodified syntax tree. | |
| 231 | // | |
| 232 | // We also defer editing usages in the current file first since | |
| 233 | // tree mutation in the same file breaks when `builder.edit_file` | |
| 234 | // is called | |
| 235 | ||
| 236 | let edits = data | |
| 237 | .usages | |
| 238 | .as_ref()? | |
| 239 | .as_slice() | |
| 240 | .iter() | |
| 241 | .filter_map(|r| edit_tuple_usage(ctx, edit, r, data, in_sub_pattern)) | |
| 242 | .collect_vec(); | |
| 243 | ||
| 244 | Some(edits) | |
| 252 | 245 | } |
| 253 | 246 | fn edit_tuple_usage( |
| 254 | 247 | ctx: &AssistContext<'_>, |
| ... | ... | @@ -1769,14 +1762,14 @@ struct S4 { |
| 1769 | 1762 | } |
| 1770 | 1763 | |
| 1771 | 1764 | fn foo() -> Option<()> { |
| 1772 | let ($0_0, _1, _2, _3, _4, _5) = &(0, (1,"1"), Some(2), [3;3], S4 { value: 4 }, &5); | |
| 1765 | let ($0_0, _1, _2, _3, s4, _5) = &(0, (1,"1"), Some(2), [3;3], S4 { value: 4 }, &5); | |
| 1773 | 1766 | let v: i32 = *_0; // deref, no parens |
| 1774 | 1767 | let v: &i32 = _0; // no deref, no parens, remove `&` |
| 1775 | 1768 | f1(*_0); // deref, no parens |
| 1776 | 1769 | f2(_0); // `&*` -> cancel out -> no deref, no parens |
| 1777 | 1770 | // https://github.com/rust-lang/rust-analyzer/issues/1109#issuecomment-658868639 |
| 1778 | 1771 | // let v: i32 = t.1.0; // no deref, no parens |
| 1779 | let v: i32 = _4.value; // no deref, no parens | |
| 1772 | let v: i32 = s4.value; // no deref, no parens | |
| 1780 | 1773 | (*_0).do_stuff(); // deref, parens |
| 1781 | 1774 | let v: i32 = (*_2)?; // deref, parens |
| 1782 | 1775 | let v: i32 = _3[0]; // no deref, no parens |
| ... | ... | @@ -1815,8 +1808,8 @@ impl S { |
| 1815 | 1808 | } |
| 1816 | 1809 | |
| 1817 | 1810 | fn main() { |
| 1818 | let ($0_0, _1) = &(S,2); | |
| 1819 | let s = _0.f(); | |
| 1811 | let ($0s, _1) = &(S,2); | |
| 1812 | let s = s.f(); | |
| 1820 | 1813 | } |
| 1821 | 1814 | "#, |
| 1822 | 1815 | ) |
| ... | ... | @@ -1845,8 +1838,8 @@ impl S { |
| 1845 | 1838 | } |
| 1846 | 1839 | |
| 1847 | 1840 | fn main() { |
| 1848 | let ($0_0, _1) = &(S,2); | |
| 1849 | let s = (*_0).f(); | |
| 1841 | let ($0s, _1) = &(S,2); | |
| 1842 | let s = (*s).f(); | |
| 1850 | 1843 | } |
| 1851 | 1844 | "#, |
| 1852 | 1845 | ) |
| ... | ... | @@ -1882,8 +1875,8 @@ impl T for &S { |
| 1882 | 1875 | } |
| 1883 | 1876 | |
| 1884 | 1877 | fn main() { |
| 1885 | let ($0_0, _1) = &(S,2); | |
| 1886 | let s = (*_0).f(); | |
| 1878 | let ($0s, _1) = &(S,2); | |
| 1879 | let s = (*s).f(); | |
| 1887 | 1880 | } |
| 1888 | 1881 | "#, |
| 1889 | 1882 | ) |
| ... | ... | @@ -1923,8 +1916,8 @@ impl T for &S { |
| 1923 | 1916 | } |
| 1924 | 1917 | |
| 1925 | 1918 | fn main() { |
| 1926 | let ($0_0, _1) = &(S,2); | |
| 1927 | let s = (*_0).f(); | |
| 1919 | let ($0s, _1) = &(S,2); | |
| 1920 | let s = (*s).f(); | |
| 1928 | 1921 | } |
| 1929 | 1922 | "#, |
| 1930 | 1923 | ) |
| ... | ... | @@ -1951,8 +1944,8 @@ impl S { |
| 1951 | 1944 | fn do_stuff(&self) -> i32 { 42 } |
| 1952 | 1945 | } |
| 1953 | 1946 | fn main() { |
| 1954 | let ($0_0, _1) = &(S,&S); | |
| 1955 | let v = _0.do_stuff(); | |
| 1947 | let ($0s, s1) = &(S,&S); | |
| 1948 | let v = s.do_stuff(); | |
| 1956 | 1949 | } |
| 1957 | 1950 | "#, |
| 1958 | 1951 | ) |
| ... | ... | @@ -1973,7 +1966,7 @@ fn main() { |
| 1973 | 1966 | // `t.0` gets auto-refed -> no deref needed -> no parens |
| 1974 | 1967 | let v = t.0.do_stuff(); // no deref, no parens |
| 1975 | 1968 | let v = &t.0.do_stuff(); // `&` is for result -> no deref, no parens |
| 1976 | // deref: `_1` is `&&S`, but method called is on `&S` -> there might be a method accepting `&&S` | |
| 1969 | // deref: `s1` is `&&S`, but method called is on `&S` -> there might be a method accepting `&&S` | |
| 1977 | 1970 | let v = t.1.do_stuff(); // deref, parens |
| 1978 | 1971 | } |
| 1979 | 1972 | "#, |
| ... | ... | @@ -1984,13 +1977,13 @@ impl S { |
| 1984 | 1977 | fn do_stuff(&self) -> i32 { 42 } |
| 1985 | 1978 | } |
| 1986 | 1979 | fn main() { |
| 1987 | let ($0_0, _1) = &(S,&S); | |
| 1988 | let v = _0.do_stuff(); // no deref, remove parens | |
| 1980 | let ($0s, s1) = &(S,&S); | |
| 1981 | let v = s.do_stuff(); // no deref, remove parens | |
| 1989 | 1982 | // `t.0` gets auto-refed -> no deref needed -> no parens |
| 1990 | let v = _0.do_stuff(); // no deref, no parens | |
| 1991 | let v = &_0.do_stuff(); // `&` is for result -> no deref, no parens | |
| 1992 | // deref: `_1` is `&&S`, but method called is on `&S` -> there might be a method accepting `&&S` | |
| 1993 | let v = (*_1).do_stuff(); // deref, parens | |
| 1983 | let v = s.do_stuff(); // no deref, no parens | |
| 1984 | let v = &s.do_stuff(); // `&` is for result -> no deref, no parens | |
| 1985 | // deref: `s1` is `&&S`, but method called is on `&S` -> there might be a method accepting `&&S` | |
| 1986 | let v = (*s1).do_stuff(); // deref, parens | |
| 1994 | 1987 | } |
| 1995 | 1988 | "#, |
| 1996 | 1989 | ) |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs+168-15| ... | ... | @@ -1,5 +1,8 @@ |
| 1 | 1 | use hir::{HirDisplay, TypeInfo}; |
| 2 | use ide_db::{assists::GroupLabel, syntax_helpers::suggest_name}; | |
| 2 | use ide_db::{ | |
| 3 | assists::GroupLabel, | |
| 4 | syntax_helpers::{suggest_name, LexedStr}, | |
| 5 | }; | |
| 3 | 6 | use syntax::{ |
| 4 | 7 | ast::{ |
| 5 | 8 | self, edit::IndentLevel, edit_in_place::Indent, make, syntax_factory::SyntaxFactory, |
| ... | ... | @@ -320,24 +323,58 @@ impl ExtractionKind { |
| 320 | 323 | ctx: &AssistContext<'_>, |
| 321 | 324 | to_extract: &ast::Expr, |
| 322 | 325 | ) -> (String, SyntaxNode) { |
| 323 | let field_shorthand = to_extract | |
| 324 | .syntax() | |
| 325 | .parent() | |
| 326 | .and_then(ast::RecordExprField::cast) | |
| 327 | .filter(|field| field.name_ref().is_some()); | |
| 328 | let (var_name, expr_replace) = match field_shorthand { | |
| 329 | Some(field) => (field.to_string(), field.syntax().clone()), | |
| 330 | None => { | |
| 331 | (suggest_name::for_variable(to_extract, &ctx.sema), to_extract.syntax().clone()) | |
| 326 | // We only do this sort of extraction for fields because they should have lowercase names | |
| 327 | if let ExtractionKind::Variable = self { | |
| 328 | let field_shorthand = to_extract | |
| 329 | .syntax() | |
| 330 | .parent() | |
| 331 | .and_then(ast::RecordExprField::cast) | |
| 332 | .filter(|field| field.name_ref().is_some()); | |
| 333 | ||
| 334 | if let Some(field) = field_shorthand { | |
| 335 | return (field.to_string(), field.syntax().clone()); | |
| 332 | 336 | } |
| 337 | } | |
| 338 | ||
| 339 | let var_name = if let Some(literal_name) = get_literal_name(ctx, to_extract) { | |
| 340 | literal_name | |
| 341 | } else { | |
| 342 | suggest_name::for_variable(to_extract, &ctx.sema) | |
| 333 | 343 | }; |
| 334 | 344 | |
| 335 | 345 | let var_name = match self { |
| 336 | ExtractionKind::Variable => var_name, | |
| 346 | ExtractionKind::Variable => var_name.to_lowercase(), | |
| 337 | 347 | ExtractionKind::Constant | ExtractionKind::Static => var_name.to_uppercase(), |
| 338 | 348 | }; |
| 339 | 349 | |
| 340 | (var_name, expr_replace) | |
| 350 | (var_name, to_extract.syntax().clone()) | |
| 351 | } | |
| 352 | } | |
| 353 | ||
| 354 | fn get_literal_name(ctx: &AssistContext<'_>, expr: &ast::Expr) -> Option<String> { | |
| 355 | let literal = match expr { | |
| 356 | ast::Expr::Literal(literal) => literal, | |
| 357 | _ => return None, | |
| 358 | }; | |
| 359 | let inner = match literal.kind() { | |
| 360 | ast::LiteralKind::String(string) => string.value().ok()?.into_owned(), | |
| 361 | ast::LiteralKind::ByteString(byte_string) => { | |
| 362 | String::from_utf8(byte_string.value().ok()?.into_owned()).ok()? | |
| 363 | } | |
| 364 | ast::LiteralKind::CString(cstring) => { | |
| 365 | String::from_utf8(cstring.value().ok()?.into_owned()).ok()? | |
| 366 | } | |
| 367 | _ => return None, | |
| 368 | }; | |
| 369 | ||
| 370 | // Entirely arbitrary | |
| 371 | if inner.len() > 32 { | |
| 372 | return None; | |
| 373 | } | |
| 374 | ||
| 375 | match LexedStr::single_token(ctx.file_id().edition(), &inner) { | |
| 376 | Some((SyntaxKind::IDENT, None)) => Some(inner), | |
| 377 | _ => None, | |
| 341 | 378 | } |
| 342 | 379 | } |
| 343 | 380 | |
| ... | ... | @@ -493,7 +530,7 @@ fn main() { |
| 493 | 530 | "#, |
| 494 | 531 | r#" |
| 495 | 532 | fn main() { |
| 496 | let $0var_name = "hello"; | |
| 533 | let $0hello = "hello"; | |
| 497 | 534 | } |
| 498 | 535 | "#, |
| 499 | 536 | "Extract into variable", |
| ... | ... | @@ -588,7 +625,7 @@ fn main() { |
| 588 | 625 | "#, |
| 589 | 626 | r#" |
| 590 | 627 | fn main() { |
| 591 | const $0VAR_NAME: &str = "hello"; | |
| 628 | const $0HELLO: &str = "hello"; | |
| 592 | 629 | } |
| 593 | 630 | "#, |
| 594 | 631 | "Extract into constant", |
| ... | ... | @@ -683,7 +720,7 @@ fn main() { |
| 683 | 720 | "#, |
| 684 | 721 | r#" |
| 685 | 722 | fn main() { |
| 686 | static $0VAR_NAME: &str = "hello"; | |
| 723 | static $0HELLO: &str = "hello"; | |
| 687 | 724 | } |
| 688 | 725 | "#, |
| 689 | 726 | "Extract into static", |
| ... | ... | @@ -2479,4 +2516,120 @@ fn foo() { |
| 2479 | 2516 | "Extract into variable", |
| 2480 | 2517 | ); |
| 2481 | 2518 | } |
| 2519 | ||
| 2520 | #[test] | |
| 2521 | fn extract_string_literal() { | |
| 2522 | check_assist_by_label( | |
| 2523 | extract_variable, | |
| 2524 | r#" | |
| 2525 | struct Entry(&str); | |
| 2526 | fn foo() { | |
| 2527 | let entry = Entry($0"Hello"$0); | |
| 2528 | } | |
| 2529 | "#, | |
| 2530 | r#" | |
| 2531 | struct Entry(&str); | |
| 2532 | fn foo() { | |
| 2533 | let $0hello = "Hello"; | |
| 2534 | let entry = Entry(hello); | |
| 2535 | } | |
| 2536 | "#, | |
| 2537 | "Extract into variable", | |
| 2538 | ); | |
| 2539 | ||
| 2540 | check_assist_by_label( | |
| 2541 | extract_variable, | |
| 2542 | r#" | |
| 2543 | struct Entry(&str); | |
| 2544 | fn foo() { | |
| 2545 | let entry = Entry($0"Hello"$0); | |
| 2546 | } | |
| 2547 | "#, | |
| 2548 | r#" | |
| 2549 | struct Entry(&str); | |
| 2550 | fn foo() { | |
| 2551 | const $0HELLO: &str = "Hello"; | |
| 2552 | let entry = Entry(HELLO); | |
| 2553 | } | |
| 2554 | "#, | |
| 2555 | "Extract into constant", | |
| 2556 | ); | |
| 2557 | ||
| 2558 | check_assist_by_label( | |
| 2559 | extract_variable, | |
| 2560 | r#" | |
| 2561 | struct Entry(&str); | |
| 2562 | fn foo() { | |
| 2563 | let entry = Entry($0"Hello"$0); | |
| 2564 | } | |
| 2565 | "#, | |
| 2566 | r#" | |
| 2567 | struct Entry(&str); | |
| 2568 | fn foo() { | |
| 2569 | static $0HELLO: &str = "Hello"; | |
| 2570 | let entry = Entry(HELLO); | |
| 2571 | } | |
| 2572 | "#, | |
| 2573 | "Extract into static", | |
| 2574 | ); | |
| 2575 | } | |
| 2576 | ||
| 2577 | #[test] | |
| 2578 | fn extract_variable_string_literal_use_field_shorthand() { | |
| 2579 | // When field shorthand is available, it should | |
| 2580 | // only be used when extracting into a variable | |
| 2581 | check_assist_by_label( | |
| 2582 | extract_variable, | |
| 2583 | r#" | |
| 2584 | struct Entry { message: &str } | |
| 2585 | fn foo() { | |
| 2586 | let entry = Entry { message: $0"Hello"$0 }; | |
| 2587 | } | |
| 2588 | "#, | |
| 2589 | r#" | |
| 2590 | struct Entry { message: &str } | |
| 2591 | fn foo() { | |
| 2592 | let $0message = "Hello"; | |
| 2593 | let entry = Entry { message }; | |
| 2594 | } | |
| 2595 | "#, | |
| 2596 | "Extract into variable", | |
| 2597 | ); | |
| 2598 | ||
| 2599 | check_assist_by_label( | |
| 2600 | extract_variable, | |
| 2601 | r#" | |
| 2602 | struct Entry { message: &str } | |
| 2603 | fn foo() { | |
| 2604 | let entry = Entry { message: $0"Hello"$0 }; | |
| 2605 | } | |
| 2606 | "#, | |
| 2607 | r#" | |
| 2608 | struct Entry { message: &str } | |
| 2609 | fn foo() { | |
| 2610 | const $0HELLO: &str = "Hello"; | |
| 2611 | let entry = Entry { message: HELLO }; | |
| 2612 | } | |
| 2613 | "#, | |
| 2614 | "Extract into constant", | |
| 2615 | ); | |
| 2616 | ||
| 2617 | check_assist_by_label( | |
| 2618 | extract_variable, | |
| 2619 | r#" | |
| 2620 | struct Entry { message: &str } | |
| 2621 | fn foo() { | |
| 2622 | let entry = Entry { message: $0"Hello"$0 }; | |
| 2623 | } | |
| 2624 | "#, | |
| 2625 | r#" | |
| 2626 | struct Entry { message: &str } | |
| 2627 | fn foo() { | |
| 2628 | static $0HELLO: &str = "Hello"; | |
| 2629 | let entry = Entry { message: HELLO }; | |
| 2630 | } | |
| 2631 | "#, | |
| 2632 | "Extract into static", | |
| 2633 | ); | |
| 2634 | } | |
| 2482 | 2635 | } |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs+1-1| ... | ... | @@ -86,7 +86,7 @@ fn item_for_path_search(db: &dyn HirDatabase, item: ItemInNs) -> Option<ItemInNs |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | 88 | fn item_as_assoc(db: &dyn HirDatabase, item: ItemInNs) -> Option<AssocItem> { |
| 89 | item.as_module_def().and_then(|module_def| module_def.as_assoc_item(db)) | |
| 89 | item.into_module_def().as_assoc_item(db) | |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | #[cfg(test)] |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs+4-6| ... | ... | @@ -51,7 +51,7 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option |
| 51 | 51 | let candidate = import_assets.import_candidate(); |
| 52 | 52 | let qualify_candidate = match syntax_under_caret.clone() { |
| 53 | 53 | NodeOrToken::Node(syntax_under_caret) => match candidate { |
| 54 | ImportCandidate::Path(candidate) if candidate.qualifier.is_some() => { | |
| 54 | ImportCandidate::Path(candidate) if !candidate.qualifier.is_empty() => { | |
| 55 | 55 | cov_mark::hit!(qualify_path_qualifier_start); |
| 56 | 56 | let path = ast::Path::cast(syntax_under_caret)?; |
| 57 | 57 | let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?); |
| ... | ... | @@ -219,11 +219,9 @@ fn find_trait_method( |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | 221 | fn item_as_trait(db: &RootDatabase, item: hir::ItemInNs) -> Option<hir::Trait> { |
| 222 | let item_module_def = item.as_module_def()?; | |
| 223 | ||
| 224 | match item_module_def { | |
| 222 | match item.into_module_def() { | |
| 225 | 223 | hir::ModuleDef::Trait(trait_) => Some(trait_), |
| 226 | _ => item_module_def.as_assoc_item(db)?.container_trait(db), | |
| 224 | item_module_def => item_module_def.as_assoc_item(db)?.container_trait(db), | |
| 227 | 225 | } |
| 228 | 226 | } |
| 229 | 227 | |
| ... | ... | @@ -247,7 +245,7 @@ fn label( |
| 247 | 245 | let import_path = &import.import_path; |
| 248 | 246 | |
| 249 | 247 | match candidate { |
| 250 | ImportCandidate::Path(candidate) if candidate.qualifier.is_none() => { | |
| 248 | ImportCandidate::Path(candidate) if candidate.qualifier.is_empty() => { | |
| 251 | 249 | format!("Qualify as `{}`", import_path.display(db, edition)) |
| 252 | 250 | } |
| 253 | 251 | _ => format!("Qualify with `{}`", import_path.display(db, edition)), |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs+1-1| ... | ... | @@ -78,7 +78,7 @@ pub(crate) fn replace_derive_with_manual_impl( |
| 78 | 78 | NameToImport::exact_case_sensitive(path.segments().last()?.to_string()), |
| 79 | 79 | items_locator::AssocSearchMode::Exclude, |
| 80 | 80 | ) |
| 81 | .filter_map(|item| match item.as_module_def()? { | |
| 81 | .filter_map(|item| match item.into_module_def() { | |
| 82 | 82 | ModuleDef::Trait(trait_) => Some(trait_), |
| 83 | 83 | _ => None, |
| 84 | 84 | }) |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs+18-25| ... | ... | @@ -12,13 +12,15 @@ use syntax::{ |
| 12 | 12 | |
| 13 | 13 | use crate::{AssistContext, Assists}; |
| 14 | 14 | |
| 15 | // FIXME: This ought to be a diagnostic lint. | |
| 16 | ||
| 15 | 17 | // Assist: unnecessary_async |
| 16 | 18 | // |
| 17 | 19 | // Removes the `async` mark from functions which have no `.await` in their body. |
| 18 | 20 | // Looks for calls to the functions and removes the `.await` on the call site. |
| 19 | 21 | // |
| 20 | 22 | // ``` |
| 21 | // pub async f$0n foo() {} | |
| 23 | // pub asy$0nc fn foo() {} | |
| 22 | 24 | // pub async fn bar() { foo().await } |
| 23 | 25 | // ``` |
| 24 | 26 | // -> |
| ... | ... | @@ -29,15 +31,11 @@ use crate::{AssistContext, Assists}; |
| 29 | 31 | pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { |
| 30 | 32 | let function: ast::Fn = ctx.find_node_at_offset()?; |
| 31 | 33 | |
| 32 | // Do nothing if the cursor is not on the prototype. This is so that the check does not pollute | |
| 33 | // when the user asks us for assists when in the middle of the function body. | |
| 34 | // We consider the prototype to be anything that is before the body of the function. | |
| 35 | let cursor_position = ctx.offset(); | |
| 36 | if cursor_position >= function.body()?.syntax().text_range().start() { | |
| 34 | // Do nothing if the cursor isn't on the async token. | |
| 35 | let async_token = function.async_token()?; | |
| 36 | if !async_token.text_range().contains_inclusive(ctx.offset()) { | |
| 37 | 37 | return None; |
| 38 | 38 | } |
| 39 | // Do nothing if the function isn't async. | |
| 40 | function.async_token()?; | |
| 41 | 39 | // Do nothing if the function has an `await` expression in its body. |
| 42 | 40 | if function.body()?.syntax().descendants().find_map(ast::AwaitExpr::cast).is_some() { |
| 43 | 41 | return None; |
| ... | ... | @@ -138,27 +136,22 @@ mod tests { |
| 138 | 136 | |
| 139 | 137 | #[test] |
| 140 | 138 | fn applies_on_empty_function() { |
| 141 | check_assist(unnecessary_async, "pub async f$0n f() {}", "pub fn f() {}") | |
| 139 | check_assist(unnecessary_async, "pub asy$0nc fn f() {}", "pub fn f() {}") | |
| 142 | 140 | } |
| 143 | 141 | |
| 144 | 142 | #[test] |
| 145 | 143 | fn applies_and_removes_whitespace() { |
| 146 | check_assist(unnecessary_async, "pub async f$0n f() {}", "pub fn f() {}") | |
| 147 | } | |
| 148 | ||
| 149 | #[test] | |
| 150 | fn does_not_apply_on_non_async_function() { | |
| 151 | check_assist_not_applicable(unnecessary_async, "pub f$0n f() {}") | |
| 144 | check_assist(unnecessary_async, "pub async$0 fn f() {}", "pub fn f() {}") | |
| 152 | 145 | } |
| 153 | 146 | |
| 154 | 147 | #[test] |
| 155 | 148 | fn applies_on_function_with_a_non_await_expr() { |
| 156 | check_assist(unnecessary_async, "pub async f$0n f() { f2() }", "pub fn f() { f2() }") | |
| 149 | check_assist(unnecessary_async, "pub asy$0nc fn f() { f2() }", "pub fn f() { f2() }") | |
| 157 | 150 | } |
| 158 | 151 | |
| 159 | 152 | #[test] |
| 160 | 153 | fn does_not_apply_on_function_with_an_await_expr() { |
| 161 | check_assist_not_applicable(unnecessary_async, "pub async f$0n f() { f2().await }") | |
| 154 | check_assist_not_applicable(unnecessary_async, "pub asy$0nc fn f() { f2().await }") | |
| 162 | 155 | } |
| 163 | 156 | |
| 164 | 157 | #[test] |
| ... | ... | @@ -167,7 +160,7 @@ mod tests { |
| 167 | 160 | unnecessary_async, |
| 168 | 161 | r#" |
| 169 | 162 | pub async fn f4() { } |
| 170 | pub async f$0n f2() { } | |
| 163 | pub asy$0nc fn f2() { } | |
| 171 | 164 | pub async fn f() { f2().await } |
| 172 | 165 | pub async fn f3() { f2().await }"#, |
| 173 | 166 | r#" |
| ... | ... | @@ -184,7 +177,7 @@ pub async fn f3() { f2() }"#, |
| 184 | 177 | unnecessary_async, |
| 185 | 178 | r#" |
| 186 | 179 | pub async fn f4() { } |
| 187 | mod a { pub async f$0n f2() { } } | |
| 180 | mod a { pub asy$0nc fn f2() { } } | |
| 188 | 181 | pub async fn f() { a::f2().await } |
| 189 | 182 | pub async fn f3() { a::f2().await }"#, |
| 190 | 183 | r#" |
| ... | ... | @@ -202,7 +195,7 @@ pub async fn f3() { a::f2() }"#, |
| 202 | 195 | // Ensure that it is the first await on the 3rd line that is removed |
| 203 | 196 | r#" |
| 204 | 197 | pub async fn f() { f2().await } |
| 205 | pub async f$0n f2() -> i32 { 1 } | |
| 198 | pub asy$0nc fn f2() -> i32 { 1 } | |
| 206 | 199 | pub async fn f3() { f4(f2().await).await } |
| 207 | 200 | pub async fn f4(i: i32) { }"#, |
| 208 | 201 | r#" |
| ... | ... | @@ -220,7 +213,7 @@ pub async fn f4(i: i32) { }"#, |
| 220 | 213 | // Ensure that it is the second await on the 3rd line that is removed |
| 221 | 214 | r#" |
| 222 | 215 | pub async fn f() { f2().await } |
| 223 | pub async f$0n f2(i: i32) { } | |
| 216 | pub async$0 fn f2(i: i32) { } | |
| 224 | 217 | pub async fn f3() { f2(f4().await).await } |
| 225 | 218 | pub async fn f4() -> i32 { 1 }"#, |
| 226 | 219 | r#" |
| ... | ... | @@ -237,7 +230,7 @@ pub async fn f4() -> i32 { 1 }"#, |
| 237 | 230 | unnecessary_async, |
| 238 | 231 | r#" |
| 239 | 232 | pub struct S { } |
| 240 | impl S { pub async f$0n f2(&self) { } } | |
| 233 | impl S { pub async$0 fn f2(&self) { } } | |
| 241 | 234 | pub async fn f(s: &S) { s.f2().await }"#, |
| 242 | 235 | r#" |
| 243 | 236 | pub struct S { } |
| ... | ... | @@ -250,13 +243,13 @@ pub async fn f(s: &S) { s.f2() }"#, |
| 250 | 243 | fn does_not_apply_on_function_with_a_nested_await_expr() { |
| 251 | 244 | check_assist_not_applicable( |
| 252 | 245 | unnecessary_async, |
| 253 | "async f$0n f() { if true { loop { f2().await } } }", | |
| 246 | "async$0 fn f() { if true { loop { f2().await } } }", | |
| 254 | 247 | ) |
| 255 | 248 | } |
| 256 | 249 | |
| 257 | 250 | #[test] |
| 258 | fn does_not_apply_when_not_on_prototype() { | |
| 259 | check_assist_not_applicable(unnecessary_async, "pub async fn f() { $0f2() }") | |
| 251 | fn does_not_apply_when_not_on_async_token() { | |
| 252 | check_assist_not_applicable(unnecessary_async, "pub async fn$0 f() { f2() }") | |
| 260 | 253 | } |
| 261 | 254 | |
| 262 | 255 | #[test] |
src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs+1-1| ... | ... | @@ -198,7 +198,7 @@ fn wrapper_alias( |
| 198 | 198 | ); |
| 199 | 199 | |
| 200 | 200 | ctx.sema.resolve_mod_path(ret_type.syntax(), &wrapper_path).and_then(|def| { |
| 201 | def.filter_map(|def| match def.as_module_def()? { | |
| 201 | def.filter_map(|def| match def.into_module_def() { | |
| 202 | 202 | hir::ModuleDef::TypeAlias(alias) => { |
| 203 | 203 | let enum_ty = alias.ty(ctx.db()).as_adt()?.as_enum()?; |
| 204 | 204 | (&enum_ty == core_wrapper).then_some(alias) |
src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs+1-1| ... | ... | @@ -3280,7 +3280,7 @@ fn doctest_unnecessary_async() { |
| 3280 | 3280 | check_doc_test( |
| 3281 | 3281 | "unnecessary_async", |
| 3282 | 3282 | r#####" |
| 3283 | pub async f$0n foo() {} | |
| 3283 | pub asy$0nc fn foo() {} | |
| 3284 | 3284 | pub async fn bar() { foo().await } |
| 3285 | 3285 | "#####, |
| 3286 | 3286 | r#####" |
src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs+25-25| ... | ... | @@ -205,7 +205,7 @@ impl S { |
| 205 | 205 | fn foo(s: S) { s.$0 } |
| 206 | 206 | "#, |
| 207 | 207 | expect![[r#" |
| 208 | fd foo u32 | |
| 208 | fd foo u32 | |
| 209 | 209 | me bar() fn(&self) |
| 210 | 210 | "#]], |
| 211 | 211 | ); |
| ... | ... | @@ -259,7 +259,7 @@ impl S { |
| 259 | 259 | "#, |
| 260 | 260 | expect![[r#" |
| 261 | 261 | fd the_field (u32,) |
| 262 | me foo() fn(self) | |
| 262 | me foo() fn(self) | |
| 263 | 263 | "#]], |
| 264 | 264 | ) |
| 265 | 265 | } |
| ... | ... | @@ -275,7 +275,7 @@ impl A { |
| 275 | 275 | "#, |
| 276 | 276 | expect![[r#" |
| 277 | 277 | fd the_field (u32, i32) |
| 278 | me foo() fn(&self) | |
| 278 | me foo() fn(&self) | |
| 279 | 279 | "#]], |
| 280 | 280 | ) |
| 281 | 281 | } |
| ... | ... | @@ -536,7 +536,7 @@ impl A { |
| 536 | 536 | } |
| 537 | 537 | "#, |
| 538 | 538 | expect![[r#" |
| 539 | fd pub_field u32 | |
| 539 | fd pub_field u32 | |
| 540 | 540 | me pub_method() fn(&self) |
| 541 | 541 | "#]], |
| 542 | 542 | ) |
| ... | ... | @@ -550,7 +550,7 @@ union U { field: u8, other: u16 } |
| 550 | 550 | fn foo(u: U) { u.$0 } |
| 551 | 551 | "#, |
| 552 | 552 | expect![[r#" |
| 553 | fd field u8 | |
| 553 | fd field u8 | |
| 554 | 554 | fd other u16 |
| 555 | 555 | "#]], |
| 556 | 556 | ); |
| ... | ... | @@ -725,8 +725,8 @@ fn test(a: A) { |
| 725 | 725 | } |
| 726 | 726 | "#, |
| 727 | 727 | expect![[r#" |
| 728 | fd another u32 | |
| 729 | fd field u8 | |
| 728 | fd another u32 | |
| 729 | fd field u8 | |
| 730 | 730 | me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target |
| 731 | 731 | "#]], |
| 732 | 732 | ); |
| ... | ... | @@ -748,8 +748,8 @@ fn test(a: A) { |
| 748 | 748 | } |
| 749 | 749 | "#, |
| 750 | 750 | expect![[r#" |
| 751 | fd 0 u8 | |
| 752 | fd 1 u32 | |
| 751 | fd 0 u8 | |
| 752 | fd 1 u32 | |
| 753 | 753 | me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target |
| 754 | 754 | "#]], |
| 755 | 755 | ); |
| ... | ... | @@ -770,8 +770,8 @@ fn test(a: A) { |
| 770 | 770 | } |
| 771 | 771 | "#, |
| 772 | 772 | expect![[r#" |
| 773 | fd 0 u8 | |
| 774 | fd 1 u32 | |
| 773 | fd 0 u8 | |
| 774 | fd 1 u32 | |
| 775 | 775 | me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target |
| 776 | 776 | "#]], |
| 777 | 777 | ); |
| ... | ... | @@ -964,12 +964,12 @@ struct Foo { field: i32 } |
| 964 | 964 | |
| 965 | 965 | impl Foo { fn foo(&self) { $0 } }"#, |
| 966 | 966 | expect![[r#" |
| 967 | fd self.field i32 | |
| 967 | fd self.field i32 | |
| 968 | 968 | me self.foo() fn(&self) |
| 969 | lc self &Foo | |
| 970 | sp Self Foo | |
| 971 | st Foo Foo | |
| 972 | bt u32 u32 | |
| 969 | lc self &Foo | |
| 970 | sp Self Foo | |
| 971 | st Foo Foo | |
| 972 | bt u32 u32 | |
| 973 | 973 | "#]], |
| 974 | 974 | ); |
| 975 | 975 | check( |
| ... | ... | @@ -978,12 +978,12 @@ struct Foo(i32); |
| 978 | 978 | |
| 979 | 979 | impl Foo { fn foo(&mut self) { $0 } }"#, |
| 980 | 980 | expect![[r#" |
| 981 | fd self.0 i32 | |
| 981 | fd self.0 i32 | |
| 982 | 982 | me self.foo() fn(&mut self) |
| 983 | lc self &mut Foo | |
| 984 | sp Self Foo | |
| 985 | st Foo Foo | |
| 986 | bt u32 u32 | |
| 983 | lc self &mut Foo | |
| 984 | sp Self Foo | |
| 985 | st Foo Foo | |
| 986 | bt u32 u32 | |
| 987 | 987 | "#]], |
| 988 | 988 | ); |
| 989 | 989 | } |
| ... | ... | @@ -1106,7 +1106,7 @@ fn test(a: A) { |
| 1106 | 1106 | } |
| 1107 | 1107 | "#, |
| 1108 | 1108 | expect![[r#" |
| 1109 | fd 0 u8 | |
| 1109 | fd 0 u8 | |
| 1110 | 1110 | me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target |
| 1111 | 1111 | "#]], |
| 1112 | 1112 | ); |
| ... | ... | @@ -1162,7 +1162,7 @@ impl<F: core::ops::Deref<Target = impl Bar>> Foo<F> { |
| 1162 | 1162 | } |
| 1163 | 1163 | "#, |
| 1164 | 1164 | expect![[r#" |
| 1165 | fd foo &u8 | |
| 1165 | fd foo &u8 | |
| 1166 | 1166 | me foobar() fn(&self) |
| 1167 | 1167 | "#]], |
| 1168 | 1168 | ); |
| ... | ... | @@ -1199,8 +1199,8 @@ impl<B: Bar, F: core::ops::Deref<Target = B>> Foo<F> { |
| 1199 | 1199 | } |
| 1200 | 1200 | "#, |
| 1201 | 1201 | expect![[r#" |
| 1202 | fd foo &u8 | |
| 1203 | "#]], | |
| 1202 | fd foo &u8 | |
| 1203 | "#]], | |
| 1204 | 1204 | ); |
| 1205 | 1205 | } |
| 1206 | 1206 |
src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs+15-15| ... | ... | @@ -537,10 +537,10 @@ impl Test for T { |
| 537 | 537 | } |
| 538 | 538 | ", |
| 539 | 539 | expect![[r#" |
| 540 | sp Self T | |
| 541 | st T T | |
| 540 | sp Self T | |
| 541 | st T T | |
| 542 | 542 | tt Test |
| 543 | bt u32 u32 | |
| 543 | bt u32 u32 | |
| 544 | 544 | "#]], |
| 545 | 545 | ); |
| 546 | 546 | |
| ... | ... | @@ -646,10 +646,10 @@ impl Test for T { |
| 646 | 646 | } |
| 647 | 647 | ", |
| 648 | 648 | expect![[r#" |
| 649 | sp Self T | |
| 650 | st T T | |
| 649 | sp Self T | |
| 650 | st T T | |
| 651 | 651 | tt Test |
| 652 | bt u32 u32 | |
| 652 | bt u32 u32 | |
| 653 | 653 | "#]], |
| 654 | 654 | ); |
| 655 | 655 | |
| ... | ... | @@ -663,10 +663,10 @@ impl Test for T { |
| 663 | 663 | } |
| 664 | 664 | ", |
| 665 | 665 | expect![[r#" |
| 666 | sp Self T | |
| 667 | st T T | |
| 666 | sp Self T | |
| 667 | st T T | |
| 668 | 668 | tt Test |
| 669 | bt u32 u32 | |
| 669 | bt u32 u32 | |
| 670 | 670 | "#]], |
| 671 | 671 | ); |
| 672 | 672 | |
| ... | ... | @@ -682,10 +682,10 @@ impl Test for T { |
| 682 | 682 | } |
| 683 | 683 | ", |
| 684 | 684 | expect![[r#" |
| 685 | sp Self T | |
| 686 | st T T | |
| 685 | sp Self T | |
| 686 | st T T | |
| 687 | 687 | tt Test |
| 688 | bt u32 u32 | |
| 688 | bt u32 u32 | |
| 689 | 689 | "#]], |
| 690 | 690 | ); |
| 691 | 691 | |
| ... | ... | @@ -730,10 +730,10 @@ impl Test for T { |
| 730 | 730 | } |
| 731 | 731 | ", |
| 732 | 732 | expect![[r#" |
| 733 | sp Self T | |
| 734 | st T T | |
| 733 | sp Self T | |
| 734 | st T T | |
| 735 | 735 | tt Test |
| 736 | bt u32 u32 | |
| 736 | bt u32 u32 | |
| 737 | 737 | "#]], |
| 738 | 738 | ); |
| 739 | 739 |
src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs+39-39| ... | ... | @@ -78,19 +78,19 @@ fn foo(a: A) { a.$0 } |
| 78 | 78 | "#, |
| 79 | 79 | expect![[r#" |
| 80 | 80 | me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture |
| 81 | kw await expr.await | |
| 82 | sn box Box::new(expr) | |
| 83 | sn call function(expr) | |
| 84 | sn dbg dbg!(expr) | |
| 85 | sn dbgr dbg!(&expr) | |
| 86 | sn deref *expr | |
| 87 | sn let let | |
| 88 | sn letm let mut | |
| 89 | sn match match expr {} | |
| 90 | sn ref &expr | |
| 91 | sn refm &mut expr | |
| 92 | sn return return expr | |
| 93 | sn unsafe unsafe {} | |
| 81 | kw await expr.await | |
| 82 | sn box Box::new(expr) | |
| 83 | sn call function(expr) | |
| 84 | sn dbg dbg!(expr) | |
| 85 | sn dbgr dbg!(&expr) | |
| 86 | sn deref *expr | |
| 87 | sn let let | |
| 88 | sn letm let mut | |
| 89 | sn match match expr {} | |
| 90 | sn ref &expr | |
| 91 | sn refm &mut expr | |
| 92 | sn return return expr | |
| 93 | sn unsafe unsafe {} | |
| 94 | 94 | "#]], |
| 95 | 95 | ); |
| 96 | 96 | |
| ... | ... | @@ -105,19 +105,19 @@ fn foo() { |
| 105 | 105 | "#, |
| 106 | 106 | expect![[r#" |
| 107 | 107 | me into_future() (use core::future::IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture |
| 108 | kw await expr.await | |
| 109 | sn box Box::new(expr) | |
| 110 | sn call function(expr) | |
| 111 | sn dbg dbg!(expr) | |
| 112 | sn dbgr dbg!(&expr) | |
| 113 | sn deref *expr | |
| 114 | sn let let | |
| 115 | sn letm let mut | |
| 116 | sn match match expr {} | |
| 117 | sn ref &expr | |
| 118 | sn refm &mut expr | |
| 119 | sn return return expr | |
| 120 | sn unsafe unsafe {} | |
| 108 | kw await expr.await | |
| 109 | sn box Box::new(expr) | |
| 110 | sn call function(expr) | |
| 111 | sn dbg dbg!(expr) | |
| 112 | sn dbgr dbg!(&expr) | |
| 113 | sn deref *expr | |
| 114 | sn let let | |
| 115 | sn letm let mut | |
| 116 | sn match match expr {} | |
| 117 | sn ref &expr | |
| 118 | sn refm &mut expr | |
| 119 | sn return return expr | |
| 120 | sn unsafe unsafe {} | |
| 121 | 121 | "#]], |
| 122 | 122 | ); |
| 123 | 123 | } |
| ... | ... | @@ -134,19 +134,19 @@ fn foo(a: A) { a.$0 } |
| 134 | 134 | "#, |
| 135 | 135 | expect![[r#" |
| 136 | 136 | me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture |
| 137 | kw await expr.await | |
| 138 | sn box Box::new(expr) | |
| 139 | sn call function(expr) | |
| 140 | sn dbg dbg!(expr) | |
| 141 | sn dbgr dbg!(&expr) | |
| 142 | sn deref *expr | |
| 143 | sn let let | |
| 144 | sn letm let mut | |
| 145 | sn match match expr {} | |
| 146 | sn ref &expr | |
| 147 | sn refm &mut expr | |
| 148 | sn return return expr | |
| 149 | sn unsafe unsafe {} | |
| 137 | kw await expr.await | |
| 138 | sn box Box::new(expr) | |
| 139 | sn call function(expr) | |
| 140 | sn dbg dbg!(expr) | |
| 141 | sn dbgr dbg!(&expr) | |
| 142 | sn deref *expr | |
| 143 | sn let let | |
| 144 | sn letm let mut | |
| 145 | sn match match expr {} | |
| 146 | sn ref &expr | |
| 147 | sn refm &mut expr | |
| 148 | sn return return expr | |
| 149 | sn unsafe unsafe {} | |
| 150 | 150 | "#]], |
| 151 | 151 | ); |
| 152 | 152 | } |
src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs+55-55| ... | ... | @@ -423,21 +423,21 @@ fn main() { |
| 423 | 423 | } |
| 424 | 424 | "#, |
| 425 | 425 | expect![[r#" |
| 426 | sn box Box::new(expr) | |
| 427 | sn call function(expr) | |
| 428 | sn dbg dbg!(expr) | |
| 429 | sn dbgr dbg!(&expr) | |
| 430 | sn deref *expr | |
| 431 | sn if if expr {} | |
| 432 | sn let let | |
| 433 | sn letm let mut | |
| 434 | sn match match expr {} | |
| 435 | sn not !expr | |
| 436 | sn ref &expr | |
| 437 | sn refm &mut expr | |
| 438 | sn return return expr | |
| 439 | sn unsafe unsafe {} | |
| 440 | sn while while expr {} | |
| 426 | sn box Box::new(expr) | |
| 427 | sn call function(expr) | |
| 428 | sn dbg dbg!(expr) | |
| 429 | sn dbgr dbg!(&expr) | |
| 430 | sn deref *expr | |
| 431 | sn if if expr {} | |
| 432 | sn let let | |
| 433 | sn letm let mut | |
| 434 | sn match match expr {} | |
| 435 | sn not !expr | |
| 436 | sn ref &expr | |
| 437 | sn refm &mut expr | |
| 438 | sn return return expr | |
| 439 | sn unsafe unsafe {} | |
| 440 | sn while while expr {} | |
| 441 | 441 | "#]], |
| 442 | 442 | ); |
| 443 | 443 | } |
| ... | ... | @@ -456,19 +456,19 @@ fn main() { |
| 456 | 456 | } |
| 457 | 457 | "#, |
| 458 | 458 | expect![[r#" |
| 459 | sn box Box::new(expr) | |
| 460 | sn call function(expr) | |
| 461 | sn dbg dbg!(expr) | |
| 462 | sn dbgr dbg!(&expr) | |
| 463 | sn deref *expr | |
| 464 | sn if if expr {} | |
| 465 | sn match match expr {} | |
| 466 | sn not !expr | |
| 467 | sn ref &expr | |
| 468 | sn refm &mut expr | |
| 469 | sn return return expr | |
| 470 | sn unsafe unsafe {} | |
| 471 | sn while while expr {} | |
| 459 | sn box Box::new(expr) | |
| 460 | sn call function(expr) | |
| 461 | sn dbg dbg!(expr) | |
| 462 | sn dbgr dbg!(&expr) | |
| 463 | sn deref *expr | |
| 464 | sn if if expr {} | |
| 465 | sn match match expr {} | |
| 466 | sn not !expr | |
| 467 | sn ref &expr | |
| 468 | sn refm &mut expr | |
| 469 | sn return return expr | |
| 470 | sn unsafe unsafe {} | |
| 471 | sn while while expr {} | |
| 472 | 472 | "#]], |
| 473 | 473 | ); |
| 474 | 474 | } |
| ... | ... | @@ -483,18 +483,18 @@ fn main() { |
| 483 | 483 | } |
| 484 | 484 | "#, |
| 485 | 485 | expect![[r#" |
| 486 | sn box Box::new(expr) | |
| 487 | sn call function(expr) | |
| 488 | sn dbg dbg!(expr) | |
| 489 | sn dbgr dbg!(&expr) | |
| 490 | sn deref *expr | |
| 491 | sn let let | |
| 492 | sn letm let mut | |
| 493 | sn match match expr {} | |
| 494 | sn ref &expr | |
| 495 | sn refm &mut expr | |
| 496 | sn return return expr | |
| 497 | sn unsafe unsafe {} | |
| 486 | sn box Box::new(expr) | |
| 487 | sn call function(expr) | |
| 488 | sn dbg dbg!(expr) | |
| 489 | sn dbgr dbg!(&expr) | |
| 490 | sn deref *expr | |
| 491 | sn let let | |
| 492 | sn letm let mut | |
| 493 | sn match match expr {} | |
| 494 | sn ref &expr | |
| 495 | sn refm &mut expr | |
| 496 | sn return return expr | |
| 497 | sn unsafe unsafe {} | |
| 498 | 498 | "#]], |
| 499 | 499 | ) |
| 500 | 500 | } |
| ... | ... | @@ -509,21 +509,21 @@ fn main() { |
| 509 | 509 | } |
| 510 | 510 | "#, |
| 511 | 511 | expect![[r#" |
| 512 | sn box Box::new(expr) | |
| 513 | sn call function(expr) | |
| 514 | sn dbg dbg!(expr) | |
| 515 | sn dbgr dbg!(&expr) | |
| 516 | sn deref *expr | |
| 517 | sn if if expr {} | |
| 518 | sn let let | |
| 519 | sn letm let mut | |
| 520 | sn match match expr {} | |
| 521 | sn not !expr | |
| 522 | sn ref &expr | |
| 523 | sn refm &mut expr | |
| 524 | sn return return expr | |
| 525 | sn unsafe unsafe {} | |
| 526 | sn while while expr {} | |
| 512 | sn box Box::new(expr) | |
| 513 | sn call function(expr) | |
| 514 | sn dbg dbg!(expr) | |
| 515 | sn dbgr dbg!(&expr) | |
| 516 | sn deref *expr | |
| 517 | sn if if expr {} | |
| 518 | sn let let | |
| 519 | sn letm let mut | |
| 520 | sn match match expr {} | |
| 521 | sn not !expr | |
| 522 | sn ref &expr | |
| 523 | sn refm &mut expr | |
| 524 | sn return return expr | |
| 525 | sn unsafe unsafe {} | |
| 526 | sn while while expr {} | |
| 527 | 527 | "#]], |
| 528 | 528 | ); |
| 529 | 529 | } |
src/tools/rust-analyzer/crates/ide-completion/src/context.rs+2-2| ... | ... | @@ -718,7 +718,7 @@ impl<'a> CompletionContext<'a> { |
| 718 | 718 | expected: (expected_type, expected_name), |
| 719 | 719 | qualifier_ctx, |
| 720 | 720 | token, |
| 721 | offset, | |
| 721 | original_offset, | |
| 722 | 722 | } = expand_and_analyze( |
| 723 | 723 | &sema, |
| 724 | 724 | original_file.syntax().clone(), |
| ... | ... | @@ -728,7 +728,7 @@ impl<'a> CompletionContext<'a> { |
| 728 | 728 | )?; |
| 729 | 729 | |
| 730 | 730 | // adjust for macro input, this still fails if there is no token written yet |
| 731 | let scope = sema.scope_at_offset(&token.parent()?, offset)?; | |
| 731 | let scope = sema.scope_at_offset(&token.parent()?, original_offset)?; | |
| 732 | 732 | |
| 733 | 733 | let krate = scope.krate(); |
| 734 | 734 | let module = scope.module(); |
src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs+438-288| ... | ... | @@ -22,10 +22,14 @@ use crate::context::{ |
| 22 | 22 | COMPLETION_MARKER, |
| 23 | 23 | }; |
| 24 | 24 | |
| 25 | #[derive(Debug)] | |
| 25 | 26 | struct ExpansionResult { |
| 26 | 27 | original_file: SyntaxNode, |
| 27 | 28 | speculative_file: SyntaxNode, |
| 28 | offset: TextSize, | |
| 29 | /// The offset in the original file. | |
| 30 | original_offset: TextSize, | |
| 31 | /// The offset in the speculatively expanded file. | |
| 32 | speculative_offset: TextSize, | |
| 29 | 33 | fake_ident_token: SyntaxToken, |
| 30 | 34 | derive_ctx: Option<(SyntaxNode, SyntaxNode, TextSize, ast::Attr)>, |
| 31 | 35 | } |
| ... | ... | @@ -36,7 +40,8 @@ pub(super) struct AnalysisResult { |
| 36 | 40 | pub(super) qualifier_ctx: QualifierCtx, |
| 37 | 41 | /// the original token of the expanded file |
| 38 | 42 | pub(super) token: SyntaxToken, |
| 39 | pub(super) offset: TextSize, | |
| 43 | /// The offset in the original file. | |
| 44 | pub(super) original_offset: TextSize, | |
| 40 | 45 | } |
| 41 | 46 | |
| 42 | 47 | pub(super) fn expand_and_analyze( |
| ... | ... | @@ -54,226 +59,344 @@ pub(super) fn expand_and_analyze( |
| 54 | 59 | // make the offset point to the start of the original token, as that is what the |
| 55 | 60 | // intermediate offsets calculated in expansion always points to |
| 56 | 61 | let offset = offset - relative_offset; |
| 57 | let expansion = | |
| 58 | expand(sema, original_file, speculative_file, offset, fake_ident_token, relative_offset); | |
| 62 | let expansion = expand( | |
| 63 | sema, | |
| 64 | original_file.clone(), | |
| 65 | speculative_file.clone(), | |
| 66 | offset, | |
| 67 | fake_ident_token.clone(), | |
| 68 | relative_offset, | |
| 69 | ) | |
| 70 | .unwrap_or(ExpansionResult { | |
| 71 | original_file, | |
| 72 | speculative_file, | |
| 73 | original_offset: offset, | |
| 74 | speculative_offset: fake_ident_token.text_range().start(), | |
| 75 | fake_ident_token, | |
| 76 | derive_ctx: None, | |
| 77 | }); | |
| 59 | 78 | |
| 60 | 79 | // add the relative offset back, so that left_biased finds the proper token |
| 61 | let offset = expansion.offset + relative_offset; | |
| 62 | let token = expansion.original_file.token_at_offset(offset).left_biased()?; | |
| 80 | let original_offset = expansion.original_offset + relative_offset; | |
| 81 | let token = expansion.original_file.token_at_offset(original_offset).left_biased()?; | |
| 63 | 82 | |
| 64 | 83 | analyze(sema, expansion, original_token, &token).map(|(analysis, expected, qualifier_ctx)| { |
| 65 | AnalysisResult { analysis, expected, qualifier_ctx, token, offset } | |
| 84 | AnalysisResult { analysis, expected, qualifier_ctx, token, original_offset } | |
| 66 | 85 | }) |
| 67 | 86 | } |
| 68 | 87 | |
| 69 | 88 | /// Expand attributes and macro calls at the current cursor position for both the original file |
| 70 | 89 | /// and fake file repeatedly. As soon as one of the two expansions fail we stop so the original |
| 71 | 90 | /// and speculative states stay in sync. |
| 91 | /// | |
| 92 | /// We do this by recursively expanding all macros and picking the best possible match. We cannot just | |
| 93 | /// choose the first expansion each time because macros can expand to something that does not include | |
| 94 | /// our completion marker, e.g.: | |
| 95 | /// ``` | |
| 96 | /// macro_rules! helper { ($v:ident) => {} } | |
| 97 | /// macro_rules! my_macro { | |
| 98 | /// ($v:ident) => { | |
| 99 | /// helper!($v); | |
| 100 | /// $v | |
| 101 | /// }; | |
| 102 | /// } | |
| 103 | /// | |
| 104 | /// my_macro!(complete_me_here) | |
| 105 | /// ``` | |
| 106 | /// If we would expand the first thing we encounter only (which in fact this method used to do), we would | |
| 107 | /// be unable to complete here, because we would be walking directly into the void. So we instead try | |
| 108 | /// *every* possible path. | |
| 109 | /// | |
| 110 | /// This can also creates discrepancies between the speculative and real expansions: because we insert | |
| 111 | /// tokens, we insert characters, which means if we try the second occurrence it may not be at the same | |
| 112 | /// position in the original and speculative file. We take an educated guess here, and for each token | |
| 113 | /// that we check, we subtract `COMPLETION_MARKER.len()`. This may not be accurate because proc macros | |
| 114 | /// can insert the text of the completion marker in other places while removing the span, but this is | |
| 115 | /// the best we can do. | |
| 72 | 116 | fn expand( |
| 73 | 117 | sema: &Semantics<'_, RootDatabase>, |
| 74 | mut original_file: SyntaxNode, | |
| 75 | mut speculative_file: SyntaxNode, | |
| 76 | mut offset: TextSize, | |
| 77 | mut fake_ident_token: SyntaxToken, | |
| 118 | original_file: SyntaxNode, | |
| 119 | speculative_file: SyntaxNode, | |
| 120 | original_offset: TextSize, | |
| 121 | fake_ident_token: SyntaxToken, | |
| 78 | 122 | relative_offset: TextSize, |
| 79 | ) -> ExpansionResult { | |
| 123 | ) -> Option<ExpansionResult> { | |
| 80 | 124 | let _p = tracing::info_span!("CompletionContext::expand").entered(); |
| 81 | let mut derive_ctx = None; | |
| 82 | ||
| 83 | 'expansion: loop { | |
| 84 | let parent_item = | |
| 85 | |item: &ast::Item| item.syntax().ancestors().skip(1).find_map(ast::Item::cast); | |
| 86 | let ancestor_items = iter::successors( | |
| 87 | Option::zip( | |
| 88 | find_node_at_offset::<ast::Item>(&original_file, offset), | |
| 89 | find_node_at_offset::<ast::Item>(&speculative_file, offset), | |
| 125 | ||
| 126 | if !sema.might_be_inside_macro_call(&fake_ident_token) | |
| 127 | && original_file | |
| 128 | .token_at_offset(original_offset + relative_offset) | |
| 129 | .right_biased() | |
| 130 | .is_some_and(|original_token| !sema.might_be_inside_macro_call(&original_token)) | |
| 131 | { | |
| 132 | // Recursion base case. | |
| 133 | return Some(ExpansionResult { | |
| 134 | original_file, | |
| 135 | speculative_file, | |
| 136 | original_offset, | |
| 137 | speculative_offset: fake_ident_token.text_range().start(), | |
| 138 | fake_ident_token, | |
| 139 | derive_ctx: None, | |
| 140 | }); | |
| 141 | } | |
| 142 | ||
| 143 | let parent_item = | |
| 144 | |item: &ast::Item| item.syntax().ancestors().skip(1).find_map(ast::Item::cast); | |
| 145 | let ancestor_items = iter::successors( | |
| 146 | Option::zip( | |
| 147 | find_node_at_offset::<ast::Item>(&original_file, original_offset), | |
| 148 | find_node_at_offset::<ast::Item>( | |
| 149 | &speculative_file, | |
| 150 | fake_ident_token.text_range().start(), | |
| 90 | 151 | ), |
| 91 | |(a, b)| parent_item(a).zip(parent_item(b)), | |
| 92 | ); | |
| 93 | ||
| 94 | // first try to expand attributes as these are always the outermost macro calls | |
| 95 | 'ancestors: for (actual_item, item_with_fake_ident) in ancestor_items { | |
| 96 | match ( | |
| 97 | sema.expand_attr_macro(&actual_item), | |
| 98 | sema.speculative_expand_attr_macro( | |
| 99 | &actual_item, | |
| 100 | &item_with_fake_ident, | |
| 101 | fake_ident_token.clone(), | |
| 102 | ), | |
| 103 | ) { | |
| 104 | // maybe parent items have attributes, so continue walking the ancestors | |
| 105 | (None, None) => continue 'ancestors, | |
| 106 | // successful expansions | |
| 107 | ( | |
| 108 | Some(ExpandResult { value: actual_expansion, err: _ }), | |
| 109 | Some((fake_expansion, fake_mapped_token)), | |
| 110 | ) => { | |
| 111 | let new_offset = fake_mapped_token.text_range().start(); | |
| 112 | if new_offset + relative_offset > actual_expansion.text_range().end() { | |
| 113 | // offset outside of bounds from the original expansion, | |
| 114 | // stop here to prevent problems from happening | |
| 115 | break 'expansion; | |
| 116 | } | |
| 117 | original_file = actual_expansion; | |
| 118 | speculative_file = fake_expansion; | |
| 119 | fake_ident_token = fake_mapped_token; | |
| 120 | offset = new_offset; | |
| 121 | continue 'expansion; | |
| 152 | ), | |
| 153 | |(a, b)| parent_item(a).zip(parent_item(b)), | |
| 154 | ); | |
| 155 | ||
| 156 | // first try to expand attributes as these are always the outermost macro calls | |
| 157 | 'ancestors: for (actual_item, item_with_fake_ident) in ancestor_items { | |
| 158 | match ( | |
| 159 | sema.expand_attr_macro(&actual_item), | |
| 160 | sema.speculative_expand_attr_macro( | |
| 161 | &actual_item, | |
| 162 | &item_with_fake_ident, | |
| 163 | fake_ident_token.clone(), | |
| 164 | ), | |
| 165 | ) { | |
| 166 | // maybe parent items have attributes, so continue walking the ancestors | |
| 167 | (None, None) => continue 'ancestors, | |
| 168 | // successful expansions | |
| 169 | ( | |
| 170 | Some(ExpandResult { value: actual_expansion, err: _ }), | |
| 171 | Some((fake_expansion, fake_mapped_tokens)), | |
| 172 | ) => { | |
| 173 | let mut accumulated_offset_from_fake_tokens = 0; | |
| 174 | let actual_range = actual_expansion.text_range().end(); | |
| 175 | let result = fake_mapped_tokens | |
| 176 | .into_iter() | |
| 177 | .filter_map(|(fake_mapped_token, rank)| { | |
| 178 | let accumulated_offset = accumulated_offset_from_fake_tokens; | |
| 179 | if !fake_mapped_token.text().contains(COMPLETION_MARKER) { | |
| 180 | // Proc macros can make the same span with different text, we don't | |
| 181 | // want them to participate in completion because the macro author probably | |
| 182 | // didn't intend them to. | |
| 183 | return None; | |
| 184 | } | |
| 185 | accumulated_offset_from_fake_tokens += COMPLETION_MARKER.len(); | |
| 186 | ||
| 187 | let new_offset = fake_mapped_token.text_range().start() | |
| 188 | - TextSize::new(accumulated_offset as u32); | |
| 189 | if new_offset + relative_offset > actual_range { | |
| 190 | // offset outside of bounds from the original expansion, | |
| 191 | // stop here to prevent problems from happening | |
| 192 | return None; | |
| 193 | } | |
| 194 | let result = expand( | |
| 195 | sema, | |
| 196 | actual_expansion.clone(), | |
| 197 | fake_expansion.clone(), | |
| 198 | new_offset, | |
| 199 | fake_mapped_token, | |
| 200 | relative_offset, | |
| 201 | )?; | |
| 202 | Some((result, rank)) | |
| 203 | }) | |
| 204 | .min_by_key(|(_, rank)| *rank) | |
| 205 | .map(|(result, _)| result); | |
| 206 | if result.is_some() { | |
| 207 | return result; | |
| 122 | 208 | } |
| 123 | // exactly one expansion failed, inconsistent state so stop expanding completely | |
| 124 | _ => break 'expansion, | |
| 125 | 209 | } |
| 210 | // exactly one expansion failed, inconsistent state so stop expanding completely | |
| 211 | _ => break 'ancestors, | |
| 126 | 212 | } |
| 213 | } | |
| 127 | 214 | |
| 128 | // No attributes have been expanded, so look for macro_call! token trees or derive token trees | |
| 129 | let orig_tt = match ancestors_at_offset(&original_file, offset) | |
| 130 | .map_while(Either::<ast::TokenTree, ast::Meta>::cast) | |
| 131 | .last() | |
| 132 | { | |
| 133 | Some(it) => it, | |
| 134 | None => break 'expansion, | |
| 135 | }; | |
| 136 | let spec_tt = match ancestors_at_offset(&speculative_file, offset) | |
| 137 | .map_while(Either::<ast::TokenTree, ast::Meta>::cast) | |
| 138 | .last() | |
| 139 | { | |
| 140 | Some(it) => it, | |
| 141 | None => break 'expansion, | |
| 142 | }; | |
| 143 | ||
| 144 | let (tts, attrs) = match (orig_tt, spec_tt) { | |
| 145 | (Either::Left(orig_tt), Either::Left(spec_tt)) => { | |
| 146 | let attrs = orig_tt | |
| 147 | .syntax() | |
| 148 | .parent() | |
| 149 | .and_then(ast::Meta::cast) | |
| 150 | .and_then(|it| it.parent_attr()) | |
| 151 | .zip( | |
| 152 | spec_tt | |
| 153 | .syntax() | |
| 154 | .parent() | |
| 155 | .and_then(ast::Meta::cast) | |
| 156 | .and_then(|it| it.parent_attr()), | |
| 157 | ); | |
| 158 | (Some((orig_tt, spec_tt)), attrs) | |
| 159 | } | |
| 160 | (Either::Right(orig_path), Either::Right(spec_path)) => { | |
| 161 | (None, orig_path.parent_attr().zip(spec_path.parent_attr())) | |
| 162 | } | |
| 163 | _ => break 'expansion, | |
| 164 | }; | |
| 215 | // No attributes have been expanded, so look for macro_call! token trees or derive token trees | |
| 216 | let orig_tt = ancestors_at_offset(&original_file, original_offset) | |
| 217 | .map_while(Either::<ast::TokenTree, ast::Meta>::cast) | |
| 218 | .last()?; | |
| 219 | let spec_tt = ancestors_at_offset(&speculative_file, fake_ident_token.text_range().start()) | |
| 220 | .map_while(Either::<ast::TokenTree, ast::Meta>::cast) | |
| 221 | .last()?; | |
| 222 | ||
| 223 | let (tts, attrs) = match (orig_tt, spec_tt) { | |
| 224 | (Either::Left(orig_tt), Either::Left(spec_tt)) => { | |
| 225 | let attrs = orig_tt | |
| 226 | .syntax() | |
| 227 | .parent() | |
| 228 | .and_then(ast::Meta::cast) | |
| 229 | .and_then(|it| it.parent_attr()) | |
| 230 | .zip( | |
| 231 | spec_tt | |
| 232 | .syntax() | |
| 233 | .parent() | |
| 234 | .and_then(ast::Meta::cast) | |
| 235 | .and_then(|it| it.parent_attr()), | |
| 236 | ); | |
| 237 | (Some((orig_tt, spec_tt)), attrs) | |
| 238 | } | |
| 239 | (Either::Right(orig_path), Either::Right(spec_path)) => { | |
| 240 | (None, orig_path.parent_attr().zip(spec_path.parent_attr())) | |
| 241 | } | |
| 242 | _ => return None, | |
| 243 | }; | |
| 165 | 244 | |
| 166 | // Expand pseudo-derive expansion aka `derive(Debug$0)` | |
| 167 | if let Some((orig_attr, spec_attr)) = attrs { | |
| 168 | if let (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) = ( | |
| 169 | sema.expand_derive_as_pseudo_attr_macro(&orig_attr), | |
| 170 | sema.speculative_expand_derive_as_pseudo_attr_macro( | |
| 171 | &orig_attr, | |
| 172 | &spec_attr, | |
| 173 | fake_ident_token.clone(), | |
| 174 | ), | |
| 175 | ) { | |
| 176 | derive_ctx = Some(( | |
| 177 | actual_expansion, | |
| 178 | fake_expansion, | |
| 179 | fake_mapped_token.text_range().start(), | |
| 180 | orig_attr, | |
| 181 | )); | |
| 182 | break 'expansion; | |
| 245 | // Expand pseudo-derive expansion aka `derive(Debug$0)` | |
| 246 | if let Some((orig_attr, spec_attr)) = attrs { | |
| 247 | if let (Some(actual_expansion), Some((fake_expansion, fake_mapped_tokens))) = ( | |
| 248 | sema.expand_derive_as_pseudo_attr_macro(&orig_attr), | |
| 249 | sema.speculative_expand_derive_as_pseudo_attr_macro( | |
| 250 | &orig_attr, | |
| 251 | &spec_attr, | |
| 252 | fake_ident_token.clone(), | |
| 253 | ), | |
| 254 | ) { | |
| 255 | if let Some((fake_mapped_token, _)) = | |
| 256 | fake_mapped_tokens.into_iter().min_by_key(|(_, rank)| *rank) | |
| 257 | { | |
| 258 | return Some(ExpansionResult { | |
| 259 | original_file, | |
| 260 | speculative_file, | |
| 261 | original_offset, | |
| 262 | speculative_offset: fake_ident_token.text_range().start(), | |
| 263 | fake_ident_token, | |
| 264 | derive_ctx: Some(( | |
| 265 | actual_expansion, | |
| 266 | fake_expansion, | |
| 267 | fake_mapped_token.text_range().start(), | |
| 268 | orig_attr, | |
| 269 | )), | |
| 270 | }); | |
| 183 | 271 | } |
| 272 | } | |
| 184 | 273 | |
| 185 | if let Some(spec_adt) = | |
| 186 | spec_attr.syntax().ancestors().find_map(ast::Item::cast).and_then(|it| match it { | |
| 187 | ast::Item::Struct(it) => Some(ast::Adt::Struct(it)), | |
| 188 | ast::Item::Enum(it) => Some(ast::Adt::Enum(it)), | |
| 189 | ast::Item::Union(it) => Some(ast::Adt::Union(it)), | |
| 190 | _ => None, | |
| 191 | }) | |
| 192 | { | |
| 193 | // might be the path of derive helper or a token tree inside of one | |
| 194 | if let Some(helpers) = sema.derive_helper(&orig_attr) { | |
| 195 | for (_mac, file) in helpers { | |
| 196 | if let Some((fake_expansion, fake_mapped_token)) = sema | |
| 197 | .speculative_expand_raw( | |
| 198 | file, | |
| 199 | spec_adt.syntax(), | |
| 200 | fake_ident_token.clone(), | |
| 201 | ) | |
| 202 | { | |
| 203 | // we are inside a derive helper token tree, treat this as being inside | |
| 204 | // the derive expansion | |
| 205 | let actual_expansion = sema.parse_or_expand(file.into()); | |
| 206 | let new_offset = fake_mapped_token.text_range().start(); | |
| 207 | if new_offset + relative_offset > actual_expansion.text_range().end() { | |
| 208 | // offset outside of bounds from the original expansion, | |
| 209 | // stop here to prevent problems from happening | |
| 210 | break 'expansion; | |
| 211 | } | |
| 212 | original_file = actual_expansion; | |
| 213 | speculative_file = fake_expansion; | |
| 214 | fake_ident_token = fake_mapped_token; | |
| 215 | offset = new_offset; | |
| 216 | continue 'expansion; | |
| 274 | if let Some(spec_adt) = | |
| 275 | spec_attr.syntax().ancestors().find_map(ast::Item::cast).and_then(|it| match it { | |
| 276 | ast::Item::Struct(it) => Some(ast::Adt::Struct(it)), | |
| 277 | ast::Item::Enum(it) => Some(ast::Adt::Enum(it)), | |
| 278 | ast::Item::Union(it) => Some(ast::Adt::Union(it)), | |
| 279 | _ => None, | |
| 280 | }) | |
| 281 | { | |
| 282 | // might be the path of derive helper or a token tree inside of one | |
| 283 | if let Some(helpers) = sema.derive_helper(&orig_attr) { | |
| 284 | for (_mac, file) in helpers { | |
| 285 | if let Some((fake_expansion, fake_mapped_tokens)) = sema.speculative_expand_raw( | |
| 286 | file, | |
| 287 | spec_adt.syntax(), | |
| 288 | fake_ident_token.clone(), | |
| 289 | ) { | |
| 290 | // we are inside a derive helper token tree, treat this as being inside | |
| 291 | // the derive expansion | |
| 292 | let actual_expansion = sema.parse_or_expand(file.into()); | |
| 293 | let mut accumulated_offset_from_fake_tokens = 0; | |
| 294 | let actual_range = actual_expansion.text_range().end(); | |
| 295 | let result = fake_mapped_tokens | |
| 296 | .into_iter() | |
| 297 | .filter_map(|(fake_mapped_token, rank)| { | |
| 298 | let accumulated_offset = accumulated_offset_from_fake_tokens; | |
| 299 | if !fake_mapped_token.text().contains(COMPLETION_MARKER) { | |
| 300 | // Proc macros can make the same span with different text, we don't | |
| 301 | // want them to participate in completion because the macro author probably | |
| 302 | // didn't intend them to. | |
| 303 | return None; | |
| 304 | } | |
| 305 | accumulated_offset_from_fake_tokens += COMPLETION_MARKER.len(); | |
| 306 | ||
| 307 | let new_offset = fake_mapped_token.text_range().start() | |
| 308 | - TextSize::new(accumulated_offset as u32); | |
| 309 | if new_offset + relative_offset > actual_range { | |
| 310 | // offset outside of bounds from the original expansion, | |
| 311 | // stop here to prevent problems from happening | |
| 312 | return None; | |
| 313 | } | |
| 314 | let result = expand( | |
| 315 | sema, | |
| 316 | actual_expansion.clone(), | |
| 317 | fake_expansion.clone(), | |
| 318 | new_offset, | |
| 319 | fake_mapped_token, | |
| 320 | relative_offset, | |
| 321 | )?; | |
| 322 | Some((result, rank)) | |
| 323 | }) | |
| 324 | .min_by_key(|(_, rank)| *rank) | |
| 325 | .map(|(result, _)| result); | |
| 326 | if result.is_some() { | |
| 327 | return result; | |
| 217 | 328 | } |
| 218 | 329 | } |
| 219 | 330 | } |
| 220 | 331 | } |
| 221 | // at this point we won't have any more successful expansions, so stop | |
| 222 | break 'expansion; | |
| 223 | 332 | } |
| 333 | // at this point we won't have any more successful expansions, so stop | |
| 334 | return None; | |
| 335 | } | |
| 224 | 336 | |
| 225 | // Expand fn-like macro calls | |
| 226 | let Some((orig_tt, spec_tt)) = tts else { break 'expansion }; | |
| 227 | if let (Some(actual_macro_call), Some(macro_call_with_fake_ident)) = ( | |
| 228 | orig_tt.syntax().parent().and_then(ast::MacroCall::cast), | |
| 229 | spec_tt.syntax().parent().and_then(ast::MacroCall::cast), | |
| 230 | ) { | |
| 231 | let mac_call_path0 = actual_macro_call.path().as_ref().map(|s| s.syntax().text()); | |
| 232 | let mac_call_path1 = | |
| 233 | macro_call_with_fake_ident.path().as_ref().map(|s| s.syntax().text()); | |
| 337 | // Expand fn-like macro calls | |
| 338 | let (orig_tt, spec_tt) = tts?; | |
| 339 | let (actual_macro_call, macro_call_with_fake_ident) = ( | |
| 340 | orig_tt.syntax().parent().and_then(ast::MacroCall::cast)?, | |
| 341 | spec_tt.syntax().parent().and_then(ast::MacroCall::cast)?, | |
| 342 | ); | |
| 343 | let mac_call_path0 = actual_macro_call.path().as_ref().map(|s| s.syntax().text()); | |
| 344 | let mac_call_path1 = macro_call_with_fake_ident.path().as_ref().map(|s| s.syntax().text()); | |
| 234 | 345 | |
| 235 | // inconsistent state, stop expanding | |
| 236 | if mac_call_path0 != mac_call_path1 { | |
| 237 | break 'expansion; | |
| 238 | } | |
| 239 | let speculative_args = match macro_call_with_fake_ident.token_tree() { | |
| 240 | Some(tt) => tt, | |
| 241 | None => break 'expansion, | |
| 242 | }; | |
| 346 | // inconsistent state, stop expanding | |
| 347 | if mac_call_path0 != mac_call_path1 { | |
| 348 | return None; | |
| 349 | } | |
| 350 | let speculative_args = macro_call_with_fake_ident.token_tree()?; | |
| 351 | ||
| 352 | match ( | |
| 353 | sema.expand_macro_call(&actual_macro_call), | |
| 354 | sema.speculative_expand_macro_call( | |
| 355 | &actual_macro_call, | |
| 356 | &speculative_args, | |
| 357 | fake_ident_token.clone(), | |
| 358 | ), | |
| 359 | ) { | |
| 360 | // successful expansions | |
| 361 | (Some(actual_expansion), Some((fake_expansion, fake_mapped_tokens))) => { | |
| 362 | let mut accumulated_offset_from_fake_tokens = 0; | |
| 363 | let actual_range = actual_expansion.text_range().end(); | |
| 364 | fake_mapped_tokens | |
| 365 | .into_iter() | |
| 366 | .filter_map(|(fake_mapped_token, rank)| { | |
| 367 | let accumulated_offset = accumulated_offset_from_fake_tokens; | |
| 368 | if !fake_mapped_token.text().contains(COMPLETION_MARKER) { | |
| 369 | // Proc macros can make the same span with different text, we don't | |
| 370 | // want them to participate in completion because the macro author probably | |
| 371 | // didn't intend them to. | |
| 372 | return None; | |
| 373 | } | |
| 374 | accumulated_offset_from_fake_tokens += COMPLETION_MARKER.len(); | |
| 243 | 375 | |
| 244 | match ( | |
| 245 | sema.expand_macro_call(&actual_macro_call), | |
| 246 | sema.speculative_expand_macro_call( | |
| 247 | &actual_macro_call, | |
| 248 | &speculative_args, | |
| 249 | fake_ident_token.clone(), | |
| 250 | ), | |
| 251 | ) { | |
| 252 | // successful expansions | |
| 253 | (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => { | |
| 254 | let new_offset = fake_mapped_token.text_range().start(); | |
| 255 | if new_offset + relative_offset > actual_expansion.text_range().end() { | |
| 376 | let new_offset = fake_mapped_token.text_range().start() | |
| 377 | - TextSize::new(accumulated_offset as u32); | |
| 378 | if new_offset + relative_offset > actual_range { | |
| 256 | 379 | // offset outside of bounds from the original expansion, |
| 257 | 380 | // stop here to prevent problems from happening |
| 258 | break 'expansion; | |
| 381 | return None; | |
| 259 | 382 | } |
| 260 | original_file = actual_expansion; | |
| 261 | speculative_file = fake_expansion; | |
| 262 | fake_ident_token = fake_mapped_token; | |
| 263 | offset = new_offset; | |
| 264 | continue 'expansion; | |
| 265 | } | |
| 266 | // at least on expansion failed, we won't have anything to expand from this point | |
| 267 | // onwards so break out | |
| 268 | _ => break 'expansion, | |
| 269 | } | |
| 383 | let result = expand( | |
| 384 | sema, | |
| 385 | actual_expansion.clone(), | |
| 386 | fake_expansion.clone(), | |
| 387 | new_offset, | |
| 388 | fake_mapped_token, | |
| 389 | relative_offset, | |
| 390 | )?; | |
| 391 | Some((result, rank)) | |
| 392 | }) | |
| 393 | .min_by_key(|(_, rank)| *rank) | |
| 394 | .map(|(result, _)| result) | |
| 270 | 395 | } |
| 271 | ||
| 272 | // none of our states have changed so stop the loop | |
| 273 | break 'expansion; | |
| 396 | // at least one expansion failed, we won't have anything to expand from this point | |
| 397 | // onwards so break out | |
| 398 | _ => None, | |
| 274 | 399 | } |
| 275 | ||
| 276 | ExpansionResult { original_file, speculative_file, offset, fake_ident_token, derive_ctx } | |
| 277 | 400 | } |
| 278 | 401 | |
| 279 | 402 | /// Fill the completion context, this is what does semantic reasoning about the surrounding context |
| ... | ... | @@ -285,8 +408,14 @@ fn analyze( |
| 285 | 408 | self_token: &SyntaxToken, |
| 286 | 409 | ) -> Option<(CompletionAnalysis, (Option<Type>, Option<ast::NameOrNameRef>), QualifierCtx)> { |
| 287 | 410 | let _p = tracing::info_span!("CompletionContext::analyze").entered(); |
| 288 | let ExpansionResult { original_file, speculative_file, offset, fake_ident_token, derive_ctx } = | |
| 289 | expansion_result; | |
| 411 | let ExpansionResult { | |
| 412 | original_file, | |
| 413 | speculative_file, | |
| 414 | original_offset: _, | |
| 415 | speculative_offset, | |
| 416 | fake_ident_token, | |
| 417 | derive_ctx, | |
| 418 | } = expansion_result; | |
| 290 | 419 | |
| 291 | 420 | // Overwrite the path kind for derives |
| 292 | 421 | if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx { |
| ... | ... | @@ -294,7 +423,8 @@ fn analyze( |
| 294 | 423 | find_node_at_offset(&file_with_fake_ident, offset) |
| 295 | 424 | { |
| 296 | 425 | let parent = name_ref.syntax().parent()?; |
| 297 | let (mut nameref_ctx, _) = classify_name_ref(sema, &original_file, name_ref, parent)?; | |
| 426 | let (mut nameref_ctx, _) = | |
| 427 | classify_name_ref(sema, &original_file, name_ref, offset, parent)?; | |
| 298 | 428 | if let NameRefKind::Path(path_ctx) = &mut nameref_ctx.kind { |
| 299 | 429 | path_ctx.kind = PathKind::Derive { |
| 300 | 430 | existing_derives: sema |
| ... | ... | @@ -314,7 +444,7 @@ fn analyze( |
| 314 | 444 | return None; |
| 315 | 445 | } |
| 316 | 446 | |
| 317 | let Some(name_like) = find_node_at_offset(&speculative_file, offset) else { | |
| 447 | let Some(name_like) = find_node_at_offset(&speculative_file, speculative_offset) else { | |
| 318 | 448 | let analysis = if let Some(original) = ast::String::cast(original_token.clone()) { |
| 319 | 449 | CompletionAnalysis::String { original, expanded: ast::String::cast(self_token.clone()) } |
| 320 | 450 | } else { |
| ... | ... | @@ -350,8 +480,13 @@ fn analyze( |
| 350 | 480 | } |
| 351 | 481 | ast::NameLike::NameRef(name_ref) => { |
| 352 | 482 | let parent = name_ref.syntax().parent()?; |
| 353 | let (nameref_ctx, qualifier_ctx) = | |
| 354 | classify_name_ref(sema, &original_file, name_ref, parent)?; | |
| 483 | let (nameref_ctx, qualifier_ctx) = classify_name_ref( | |
| 484 | sema, | |
| 485 | &original_file, | |
| 486 | name_ref, | |
| 487 | expansion_result.original_offset, | |
| 488 | parent, | |
| 489 | )?; | |
| 355 | 490 | |
| 356 | 491 | if let NameRefContext { |
| 357 | 492 | kind: |
| ... | ... | @@ -636,9 +771,10 @@ fn classify_name_ref( |
| 636 | 771 | sema: &Semantics<'_, RootDatabase>, |
| 637 | 772 | original_file: &SyntaxNode, |
| 638 | 773 | name_ref: ast::NameRef, |
| 774 | original_offset: TextSize, | |
| 639 | 775 | parent: SyntaxNode, |
| 640 | 776 | ) -> Option<(NameRefContext, QualifierCtx)> { |
| 641 | let nameref = find_node_at_offset(original_file, name_ref.syntax().text_range().start()); | |
| 777 | let nameref = find_node_at_offset(original_file, original_offset); | |
| 642 | 778 | |
| 643 | 779 | let make_res = |kind| (NameRefContext { nameref: nameref.clone(), kind }, Default::default()); |
| 644 | 780 | |
| ... | ... | @@ -760,7 +896,7 @@ fn classify_name_ref( |
| 760 | 896 | // We do not want to generate path completions when we are sandwiched between an item decl signature and its body. |
| 761 | 897 | // ex. trait Foo $0 {} |
| 762 | 898 | // in these cases parser recovery usually kicks in for our inserted identifier, causing it |
| 763 | // to either be parsed as an ExprStmt or a MacroCall, depending on whether it is in a block | |
| 899 | // to either be parsed as an ExprStmt or a ItemRecovery, depending on whether it is in a block | |
| 764 | 900 | // expression or an item list. |
| 765 | 901 | // The following code checks if the body is missing, if it is we either cut off the body |
| 766 | 902 | // from the item or it was missing in the first place |
| ... | ... | @@ -1088,15 +1224,10 @@ fn classify_name_ref( |
| 1088 | 1224 | PathKind::Type { location: location.unwrap_or(TypeLocation::Other) } |
| 1089 | 1225 | }; |
| 1090 | 1226 | |
| 1091 | let mut kind_macro_call = |it: ast::MacroCall| { | |
| 1092 | path_ctx.has_macro_bang = it.excl_token().is_some(); | |
| 1093 | let parent = it.syntax().parent()?; | |
| 1094 | // Any path in an item list will be treated as a macro call by the parser | |
| 1227 | let kind_item = |it: &SyntaxNode| { | |
| 1228 | let parent = it.parent()?; | |
| 1095 | 1229 | let kind = match_ast! { |
| 1096 | 1230 | match parent { |
| 1097 | ast::MacroExpr(expr) => make_path_kind_expr(expr.into()), | |
| 1098 | ast::MacroPat(it) => PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into())}, | |
| 1099 | ast::MacroType(ty) => make_path_kind_type(ty.into()), | |
| 1100 | 1231 | ast::ItemList(_) => PathKind::Item { kind: ItemListKind::Module }, |
| 1101 | 1232 | ast::AssocItemList(_) => PathKind::Item { kind: match parent.parent() { |
| 1102 | 1233 | Some(it) => match_ast! { |
| ... | ... | @@ -1126,6 +1257,23 @@ fn classify_name_ref( |
| 1126 | 1257 | }; |
| 1127 | 1258 | Some(kind) |
| 1128 | 1259 | }; |
| 1260 | ||
| 1261 | let mut kind_macro_call = |it: ast::MacroCall| { | |
| 1262 | path_ctx.has_macro_bang = it.excl_token().is_some(); | |
| 1263 | let parent = it.syntax().parent()?; | |
| 1264 | if let Some(kind) = kind_item(it.syntax()) { | |
| 1265 | return Some(kind); | |
| 1266 | } | |
| 1267 | let kind = match_ast! { | |
| 1268 | match parent { | |
| 1269 | ast::MacroExpr(expr) => make_path_kind_expr(expr.into()), | |
| 1270 | ast::MacroPat(it) => PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into())}, | |
| 1271 | ast::MacroType(ty) => make_path_kind_type(ty.into()), | |
| 1272 | _ => return None, | |
| 1273 | } | |
| 1274 | }; | |
| 1275 | Some(kind) | |
| 1276 | }; | |
| 1129 | 1277 | let make_path_kind_attr = |meta: ast::Meta| { |
| 1130 | 1278 | let attr = meta.parent_attr()?; |
| 1131 | 1279 | let kind = attr.kind(); |
| ... | ... | @@ -1153,94 +1301,98 @@ fn classify_name_ref( |
| 1153 | 1301 | |
| 1154 | 1302 | // Infer the path kind |
| 1155 | 1303 | let parent = path.syntax().parent()?; |
| 1156 | let kind = match_ast! { | |
| 1157 | match parent { | |
| 1158 | ast::PathType(it) => make_path_kind_type(it.into()), | |
| 1159 | ast::PathExpr(it) => { | |
| 1160 | if let Some(p) = it.syntax().parent() { | |
| 1161 | let p_kind = p.kind(); | |
| 1162 | // The syntax node of interest, for which we want to check whether | |
| 1163 | // it is sandwiched between an item decl signature and its body. | |
| 1164 | let probe = if ast::ExprStmt::can_cast(p_kind) { | |
| 1165 | Some(p) | |
| 1166 | } else if ast::StmtList::can_cast(p_kind) { | |
| 1167 | Some(it.syntax().clone()) | |
| 1168 | } else { | |
| 1169 | None | |
| 1170 | }; | |
| 1171 | if let Some(kind) = probe.and_then(inbetween_body_and_decl_check) { | |
| 1172 | return Some(make_res(NameRefKind::Keyword(kind))); | |
| 1173 | } | |
| 1174 | } | |
| 1304 | let kind = 'find_kind: { | |
| 1305 | if parent.kind() == SyntaxKind::ERROR { | |
| 1306 | if let Some(kind) = inbetween_body_and_decl_check(parent.clone()) { | |
| 1307 | return Some(make_res(NameRefKind::Keyword(kind))); | |
| 1308 | } | |
| 1175 | 1309 | |
| 1176 | path_ctx.has_call_parens = it.syntax().parent().map_or(false, |it| ast::CallExpr::can_cast(it.kind())); | |
| 1310 | break 'find_kind kind_item(&parent)?; | |
| 1311 | } | |
| 1312 | match_ast! { | |
| 1313 | match parent { | |
| 1314 | ast::PathType(it) => make_path_kind_type(it.into()), | |
| 1315 | ast::PathExpr(it) => { | |
| 1316 | if let Some(p) = it.syntax().parent() { | |
| 1317 | let p_kind = p.kind(); | |
| 1318 | // The syntax node of interest, for which we want to check whether | |
| 1319 | // it is sandwiched between an item decl signature and its body. | |
| 1320 | let probe = if ast::ExprStmt::can_cast(p_kind) { | |
| 1321 | Some(p) | |
| 1322 | } else if ast::StmtList::can_cast(p_kind) { | |
| 1323 | Some(it.syntax().clone()) | |
| 1324 | } else { | |
| 1325 | None | |
| 1326 | }; | |
| 1327 | if let Some(kind) = probe.and_then(inbetween_body_and_decl_check) { | |
| 1328 | return Some(make_res(NameRefKind::Keyword(kind))); | |
| 1329 | } | |
| 1330 | } | |
| 1177 | 1331 | |
| 1178 | make_path_kind_expr(it.into()) | |
| 1179 | }, | |
| 1180 | ast::TupleStructPat(it) => { | |
| 1181 | path_ctx.has_call_parens = true; | |
| 1182 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into()) } | |
| 1183 | }, | |
| 1184 | ast::RecordPat(it) => { | |
| 1185 | path_ctx.has_call_parens = true; | |
| 1186 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into()) } | |
| 1187 | }, | |
| 1188 | ast::PathPat(it) => { | |
| 1189 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into())} | |
| 1190 | }, | |
| 1191 | ast::MacroCall(it) => { | |
| 1192 | // A macro call in this position is usually a result of parsing recovery, so check that | |
| 1193 | if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) { | |
| 1194 | return Some(make_res(NameRefKind::Keyword(kind))); | |
| 1195 | } | |
| 1332 | path_ctx.has_call_parens = it.syntax().parent().map_or(false, |it| ast::CallExpr::can_cast(it.kind())); | |
| 1196 | 1333 | |
| 1197 | kind_macro_call(it)? | |
| 1198 | }, | |
| 1199 | ast::Meta(meta) => make_path_kind_attr(meta)?, | |
| 1200 | ast::Visibility(it) => PathKind::Vis { has_in_token: it.in_token().is_some() }, | |
| 1201 | ast::UseTree(_) => PathKind::Use, | |
| 1202 | // completing inside a qualifier | |
| 1203 | ast::Path(parent) => { | |
| 1204 | path_ctx.parent = Some(parent.clone()); | |
| 1205 | let parent = iter::successors(Some(parent), |it| it.parent_path()).last()?.syntax().parent()?; | |
| 1206 | match_ast! { | |
| 1207 | match parent { | |
| 1208 | ast::PathType(it) => make_path_kind_type(it.into()), | |
| 1209 | ast::PathExpr(it) => { | |
| 1210 | path_ctx.has_call_parens = it.syntax().parent().map_or(false, |it| ast::CallExpr::can_cast(it.kind())); | |
| 1334 | make_path_kind_expr(it.into()) | |
| 1335 | }, | |
| 1336 | ast::TupleStructPat(it) => { | |
| 1337 | path_ctx.has_call_parens = true; | |
| 1338 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into()) } | |
| 1339 | }, | |
| 1340 | ast::RecordPat(it) => { | |
| 1341 | path_ctx.has_call_parens = true; | |
| 1342 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into()) } | |
| 1343 | }, | |
| 1344 | ast::PathPat(it) => { | |
| 1345 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into())} | |
| 1346 | }, | |
| 1347 | ast::MacroCall(it) => { | |
| 1348 | kind_macro_call(it)? | |
| 1349 | }, | |
| 1350 | ast::Meta(meta) => make_path_kind_attr(meta)?, | |
| 1351 | ast::Visibility(it) => PathKind::Vis { has_in_token: it.in_token().is_some() }, | |
| 1352 | ast::UseTree(_) => PathKind::Use, | |
| 1353 | // completing inside a qualifier | |
| 1354 | ast::Path(parent) => { | |
| 1355 | path_ctx.parent = Some(parent.clone()); | |
| 1356 | let parent = iter::successors(Some(parent), |it| it.parent_path()).last()?.syntax().parent()?; | |
| 1357 | match_ast! { | |
| 1358 | match parent { | |
| 1359 | ast::PathType(it) => make_path_kind_type(it.into()), | |
| 1360 | ast::PathExpr(it) => { | |
| 1361 | path_ctx.has_call_parens = it.syntax().parent().map_or(false, |it| ast::CallExpr::can_cast(it.kind())); | |
| 1211 | 1362 | |
| 1212 | make_path_kind_expr(it.into()) | |
| 1213 | }, | |
| 1214 | ast::TupleStructPat(it) => { | |
| 1215 | path_ctx.has_call_parens = true; | |
| 1216 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into()) } | |
| 1217 | }, | |
| 1218 | ast::RecordPat(it) => { | |
| 1219 | path_ctx.has_call_parens = true; | |
| 1220 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into()) } | |
| 1221 | }, | |
| 1222 | ast::PathPat(it) => { | |
| 1223 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into())} | |
| 1224 | }, | |
| 1225 | ast::MacroCall(it) => { | |
| 1226 | kind_macro_call(it)? | |
| 1227 | }, | |
| 1228 | ast::Meta(meta) => make_path_kind_attr(meta)?, | |
| 1229 | ast::Visibility(it) => PathKind::Vis { has_in_token: it.in_token().is_some() }, | |
| 1230 | ast::UseTree(_) => PathKind::Use, | |
| 1231 | ast::RecordExpr(it) => make_path_kind_expr(it.into()), | |
| 1232 | _ => return None, | |
| 1363 | make_path_kind_expr(it.into()) | |
| 1364 | }, | |
| 1365 | ast::TupleStructPat(it) => { | |
| 1366 | path_ctx.has_call_parens = true; | |
| 1367 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into()) } | |
| 1368 | }, | |
| 1369 | ast::RecordPat(it) => { | |
| 1370 | path_ctx.has_call_parens = true; | |
| 1371 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into()) } | |
| 1372 | }, | |
| 1373 | ast::PathPat(it) => { | |
| 1374 | PathKind::Pat { pat_ctx: pattern_context_for(sema, original_file, it.into())} | |
| 1375 | }, | |
| 1376 | ast::MacroCall(it) => { | |
| 1377 | kind_macro_call(it)? | |
| 1378 | }, | |
| 1379 | ast::Meta(meta) => make_path_kind_attr(meta)?, | |
| 1380 | ast::Visibility(it) => PathKind::Vis { has_in_token: it.in_token().is_some() }, | |
| 1381 | ast::UseTree(_) => PathKind::Use, | |
| 1382 | ast::RecordExpr(it) => make_path_kind_expr(it.into()), | |
| 1383 | _ => return None, | |
| 1384 | } | |
| 1233 | 1385 | } |
| 1234 | } | |
| 1235 | }, | |
| 1236 | ast::RecordExpr(it) => { | |
| 1237 | // A record expression in this position is usually a result of parsing recovery, so check that | |
| 1238 | if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) { | |
| 1239 | return Some(make_res(NameRefKind::Keyword(kind))); | |
| 1240 | } | |
| 1241 | make_path_kind_expr(it.into()) | |
| 1242 | }, | |
| 1243 | _ => return None, | |
| 1386 | }, | |
| 1387 | ast::RecordExpr(it) => { | |
| 1388 | // A record expression in this position is usually a result of parsing recovery, so check that | |
| 1389 | if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) { | |
| 1390 | return Some(make_res(NameRefKind::Keyword(kind))); | |
| 1391 | } | |
| 1392 | make_path_kind_expr(it.into()) | |
| 1393 | }, | |
| 1394 | _ => return None, | |
| 1395 | } | |
| 1244 | 1396 | } |
| 1245 | 1397 | }; |
| 1246 | 1398 | |
| ... | ... | @@ -1320,9 +1472,7 @@ fn classify_name_ref( |
| 1320 | 1472 | } |
| 1321 | 1473 | }) |
| 1322 | 1474 | } |
| 1323 | PathKind::Item { .. } => { | |
| 1324 | parent.ancestors().find(|it| ast::MacroCall::can_cast(it.kind())) | |
| 1325 | } | |
| 1475 | PathKind::Item { .. } => parent.ancestors().find(|it| it.kind() == SyntaxKind::ERROR), | |
| 1326 | 1476 | _ => None, |
| 1327 | 1477 | }; |
| 1328 | 1478 | if let Some(top) = top_node { |
src/tools/rust-analyzer/crates/ide-completion/src/item.rs+36-20| ... | ... | @@ -10,7 +10,7 @@ use ide_db::{ |
| 10 | 10 | }; |
| 11 | 11 | use itertools::Itertools; |
| 12 | 12 | use smallvec::SmallVec; |
| 13 | use stdx::{impl_from, never}; | |
| 13 | use stdx::{format_to, impl_from, never}; | |
| 14 | 14 | use syntax::{format_smolstr, Edition, SmolStr, TextRange, TextSize}; |
| 15 | 15 | |
| 16 | 16 | use crate::{ |
| ... | ... | @@ -27,10 +27,7 @@ use crate::{ |
| 27 | 27 | #[non_exhaustive] |
| 28 | 28 | pub struct CompletionItem { |
| 29 | 29 | /// Label in the completion pop up which identifies completion. |
| 30 | pub label: SmolStr, | |
| 31 | /// Additional label details in the completion pop up that are | |
| 32 | /// displayed and aligned on the right side after the label. | |
| 33 | pub label_detail: Option<SmolStr>, | |
| 30 | pub label: CompletionItemLabel, | |
| 34 | 31 | |
| 35 | 32 | /// Range of identifier that is being completed. |
| 36 | 33 | /// |
| ... | ... | @@ -89,11 +86,23 @@ pub struct CompletionItem { |
| 89 | 86 | pub import_to_add: SmallVec<[(String, String); 1]>, |
| 90 | 87 | } |
| 91 | 88 | |
| 89 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] | |
| 90 | pub struct CompletionItemLabel { | |
| 91 | /// The primary label for the completion item. | |
| 92 | pub primary: SmolStr, | |
| 93 | /// The left detail for the completion item, usually rendered right next to the primary label. | |
| 94 | pub detail_left: Option<String>, | |
| 95 | /// The right detail for the completion item, usually rendered right aligned at the end of the completion item. | |
| 96 | pub detail_right: Option<String>, | |
| 97 | } | |
| 92 | 98 | // We use custom debug for CompletionItem to make snapshot tests more readable. |
| 93 | 99 | impl fmt::Debug for CompletionItem { |
| 94 | 100 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 95 | 101 | let mut s = f.debug_struct("CompletionItem"); |
| 96 | s.field("label", &self.label).field("source_range", &self.source_range); | |
| 102 | s.field("label", &self.label.primary) | |
| 103 | .field("detail_left", &self.label.detail_left) | |
| 104 | .field("detail_right", &self.label.detail_right) | |
| 105 | .field("source_range", &self.source_range); | |
| 97 | 106 | if self.text_edit.len() == 1 { |
| 98 | 107 | let atom = self.text_edit.iter().next().unwrap(); |
| 99 | 108 | s.field("delete", &atom.delete); |
| ... | ... | @@ -102,7 +111,7 @@ impl fmt::Debug for CompletionItem { |
| 102 | 111 | s.field("text_edit", &self.text_edit); |
| 103 | 112 | } |
| 104 | 113 | s.field("kind", &self.kind); |
| 105 | if self.lookup() != self.label { | |
| 114 | if self.lookup() != self.label.primary { | |
| 106 | 115 | s.field("lookup", &self.lookup()); |
| 107 | 116 | } |
| 108 | 117 | if let Some(detail) = &self.detail { |
| ... | ... | @@ -434,7 +443,7 @@ impl CompletionItem { |
| 434 | 443 | |
| 435 | 444 | self.ref_match.map(|(mutability, offset)| { |
| 436 | 445 | ( |
| 437 | format!("&{}{}", mutability.as_keyword_for_ref(), self.label), | |
| 446 | format!("&{}{}", mutability.as_keyword_for_ref(), self.label.primary), | |
| 438 | 447 | ide_db::text_edit::Indel::insert( |
| 439 | 448 | offset, |
| 440 | 449 | format!("&{}", mutability.as_keyword_for_ref()), |
| ... | ... | @@ -488,13 +497,13 @@ impl Builder { |
| 488 | 497 | let _p = tracing::info_span!("item::Builder::build").entered(); |
| 489 | 498 | |
| 490 | 499 | let label = self.label; |
| 491 | let mut label_detail = None; | |
| 492 | 500 | let mut lookup = self.lookup.unwrap_or_else(|| label.clone()); |
| 493 | 501 | let insert_text = self.insert_text.unwrap_or_else(|| label.to_string()); |
| 494 | 502 | |
| 503 | let mut detail_left = None; | |
| 495 | 504 | if !self.doc_aliases.is_empty() { |
| 496 | 505 | let doc_aliases = self.doc_aliases.iter().join(", "); |
| 497 | label_detail.replace(format_smolstr!(" (alias {doc_aliases})")); | |
| 506 | detail_left = Some(format!("(alias {doc_aliases})")); | |
| 498 | 507 | let lookup_doc_aliases = self |
| 499 | 508 | .doc_aliases |
| 500 | 509 | .iter() |
| ... | ... | @@ -516,16 +525,20 @@ impl Builder { |
| 516 | 525 | } |
| 517 | 526 | if let [import_edit] = &*self.imports_to_add { |
| 518 | 527 | // snippets can have multiple imports, but normal completions only have up to one |
| 519 | label_detail.replace(format_smolstr!( | |
| 520 | "{} (use {})", | |
| 521 | label_detail.as_deref().unwrap_or_default(), | |
| 528 | let detail_left = detail_left.get_or_insert_with(String::new); | |
| 529 | format_to!( | |
| 530 | detail_left, | |
| 531 | "{}(use {})", | |
| 532 | if detail_left.is_empty() { "" } else { " " }, | |
| 522 | 533 | import_edit.import_path.display(db, self.edition) |
| 523 | )); | |
| 534 | ); | |
| 524 | 535 | } else if let Some(trait_name) = self.trait_name { |
| 525 | label_detail.replace(format_smolstr!( | |
| 526 | "{} (as {trait_name})", | |
| 527 | label_detail.as_deref().unwrap_or_default(), | |
| 528 | )); | |
| 536 | let detail_left = detail_left.get_or_insert_with(String::new); | |
| 537 | format_to!( | |
| 538 | detail_left, | |
| 539 | "{}(as {trait_name})", | |
| 540 | if detail_left.is_empty() { "" } else { " " }, | |
| 541 | ); | |
| 529 | 542 | } |
| 530 | 543 | |
| 531 | 544 | let text_edit = match self.text_edit { |
| ... | ... | @@ -546,8 +559,11 @@ impl Builder { |
| 546 | 559 | |
| 547 | 560 | CompletionItem { |
| 548 | 561 | source_range: self.source_range, |
| 549 | label, | |
| 550 | label_detail, | |
| 562 | label: CompletionItemLabel { | |
| 563 | primary: label, | |
| 564 | detail_left, | |
| 565 | detail_right: self.detail.clone(), | |
| 566 | }, | |
| 551 | 567 | text_edit, |
| 552 | 568 | is_snippet: self.is_snippet, |
| 553 | 569 | detail: self.detail, |
src/tools/rust-analyzer/crates/ide-completion/src/render.rs+322-218| ... | ... | @@ -748,9 +748,9 @@ mod tests { |
| 748 | 748 | let tag = it.kind.tag(); |
| 749 | 749 | let relevance = display_relevance(it.relevance); |
| 750 | 750 | items.push(format!( |
| 751 | "{tag} {}{} {relevance}\n", | |
| 752 | it.label, | |
| 753 | it.label_detail.clone().unwrap_or_default(), | |
| 751 | "{tag} {} {} {relevance}\n", | |
| 752 | it.label.primary, | |
| 753 | it.label.detail_right.clone().unwrap_or_default(), | |
| 754 | 754 | )); |
| 755 | 755 | |
| 756 | 756 | if let Some((label, _indel, relevance)) = it.ref_match() { |
| ... | ... | @@ -812,13 +812,13 @@ fn main() { |
| 812 | 812 | } |
| 813 | 813 | "#, |
| 814 | 814 | expect![[r#" |
| 815 | st dep::test_mod_b::Struct {…} [type_could_unify] | |
| 816 | ex dep::test_mod_b::Struct { } [type_could_unify] | |
| 817 | st Struct (use dep::test_mod_b::Struct) [type_could_unify+requires_import] | |
| 818 | fn main() [] | |
| 819 | fn test(…) [] | |
| 820 | md dep [] | |
| 821 | st Struct (use dep::test_mod_a::Struct) [requires_import] | |
| 815 | st dep::test_mod_b::Struct {…} dep::test_mod_b::Struct { } [type_could_unify] | |
| 816 | ex dep::test_mod_b::Struct { } [type_could_unify] | |
| 817 | st Struct Struct [type_could_unify+requires_import] | |
| 818 | fn main() fn() [] | |
| 819 | fn test(…) fn(Struct) [] | |
| 820 | md dep [] | |
| 821 | st Struct Struct [requires_import] | |
| 822 | 822 | "#]], |
| 823 | 823 | ); |
| 824 | 824 | } |
| ... | ... | @@ -852,11 +852,11 @@ fn main() { |
| 852 | 852 | } |
| 853 | 853 | "#, |
| 854 | 854 | expect![[r#" |
| 855 | un Union (use dep::test_mod_b::Union) [type_could_unify+requires_import] | |
| 856 | fn main() [] | |
| 857 | fn test(…) [] | |
| 858 | md dep [] | |
| 859 | en Union (use dep::test_mod_a::Union) [requires_import] | |
| 855 | un Union Union [type_could_unify+requires_import] | |
| 856 | fn main() fn() [] | |
| 857 | fn test(…) fn(Union) [] | |
| 858 | md dep [] | |
| 859 | en Union Union [requires_import] | |
| 860 | 860 | "#]], |
| 861 | 861 | ); |
| 862 | 862 | } |
| ... | ... | @@ -888,13 +888,13 @@ fn main() { |
| 888 | 888 | } |
| 889 | 889 | "#, |
| 890 | 890 | expect![[r#" |
| 891 | ev dep::test_mod_b::Enum::variant [type_could_unify] | |
| 892 | ex dep::test_mod_b::Enum::variant [type_could_unify] | |
| 893 | en Enum (use dep::test_mod_b::Enum) [type_could_unify+requires_import] | |
| 894 | fn main() [] | |
| 895 | fn test(…) [] | |
| 896 | md dep [] | |
| 897 | en Enum (use dep::test_mod_a::Enum) [requires_import] | |
| 891 | ev dep::test_mod_b::Enum::variant dep::test_mod_b::Enum::variant [type_could_unify] | |
| 892 | ex dep::test_mod_b::Enum::variant [type_could_unify] | |
| 893 | en Enum Enum [type_could_unify+requires_import] | |
| 894 | fn main() fn() [] | |
| 895 | fn test(…) fn(Enum) [] | |
| 896 | md dep [] | |
| 897 | en Enum Enum [requires_import] | |
| 898 | 898 | "#]], |
| 899 | 899 | ); |
| 900 | 900 | } |
| ... | ... | @@ -926,11 +926,11 @@ fn main() { |
| 926 | 926 | } |
| 927 | 927 | "#, |
| 928 | 928 | expect![[r#" |
| 929 | ev dep::test_mod_b::Enum::Variant [type_could_unify] | |
| 930 | ex dep::test_mod_b::Enum::Variant [type_could_unify] | |
| 931 | fn main() [] | |
| 932 | fn test(…) [] | |
| 933 | md dep [] | |
| 929 | ev dep::test_mod_b::Enum::Variant dep::test_mod_b::Enum::Variant [type_could_unify] | |
| 930 | ex dep::test_mod_b::Enum::Variant [type_could_unify] | |
| 931 | fn main() fn() [] | |
| 932 | fn test(…) fn(Enum) [] | |
| 933 | md dep [] | |
| 934 | 934 | "#]], |
| 935 | 935 | ); |
| 936 | 936 | } |
| ... | ... | @@ -958,11 +958,11 @@ fn main() { |
| 958 | 958 | } |
| 959 | 959 | "#, |
| 960 | 960 | expect![[r#" |
| 961 | fn main() [] | |
| 962 | fn test(…) [] | |
| 963 | md dep [] | |
| 964 | fn function (use dep::test_mod_a::function) [requires_import] | |
| 965 | fn function(…) (use dep::test_mod_b::function) [requires_import] | |
| 961 | fn main() fn() [] | |
| 962 | fn test(…) fn(fn(usize) -> i32) [] | |
| 963 | md dep [] | |
| 964 | fn function fn(usize) -> i32 [requires_import] | |
| 965 | fn function(…) fn(isize) -> i32 [requires_import] | |
| 966 | 966 | "#]], |
| 967 | 967 | ); |
| 968 | 968 | } |
| ... | ... | @@ -990,11 +990,11 @@ fn main() { |
| 990 | 990 | } |
| 991 | 991 | "#, |
| 992 | 992 | expect![[r#" |
| 993 | ct CONST (use dep::test_mod_b::CONST) [type_could_unify+requires_import] | |
| 994 | fn main() [] | |
| 995 | fn test(…) [] | |
| 996 | md dep [] | |
| 997 | ct CONST (use dep::test_mod_a::CONST) [requires_import] | |
| 993 | ct CONST i32 [type_could_unify+requires_import] | |
| 994 | fn main() fn() [] | |
| 995 | fn test(…) fn(i32) [] | |
| 996 | md dep [] | |
| 997 | ct CONST i64 [requires_import] | |
| 998 | 998 | "#]], |
| 999 | 999 | ); |
| 1000 | 1000 | } |
| ... | ... | @@ -1022,11 +1022,11 @@ fn main() { |
| 1022 | 1022 | } |
| 1023 | 1023 | "#, |
| 1024 | 1024 | expect![[r#" |
| 1025 | sc STATIC (use dep::test_mod_b::STATIC) [type_could_unify+requires_import] | |
| 1026 | fn main() [] | |
| 1027 | fn test(…) [] | |
| 1028 | md dep [] | |
| 1029 | sc STATIC (use dep::test_mod_a::STATIC) [requires_import] | |
| 1025 | sc STATIC i32 [type_could_unify+requires_import] | |
| 1026 | fn main() fn() [] | |
| 1027 | fn test(…) fn(i32) [] | |
| 1028 | md dep [] | |
| 1029 | sc STATIC i64 [requires_import] | |
| 1030 | 1030 | "#]], |
| 1031 | 1031 | ); |
| 1032 | 1032 | } |
| ... | ... | @@ -1058,7 +1058,7 @@ fn main() { |
| 1058 | 1058 | |
| 1059 | 1059 | "#, |
| 1060 | 1060 | expect![[r#" |
| 1061 | me Function [] | |
| 1061 | me Function fn(&self, i32) -> bool [] | |
| 1062 | 1062 | "#]], |
| 1063 | 1063 | ); |
| 1064 | 1064 | } |
| ... | ... | @@ -1081,14 +1081,14 @@ fn func(input: Struct) { } |
| 1081 | 1081 | |
| 1082 | 1082 | "#, |
| 1083 | 1083 | expect![[r#" |
| 1084 | st Struct [type] | |
| 1085 | st Self [type] | |
| 1086 | sp Self [type] | |
| 1087 | st Struct [type] | |
| 1088 | ex Struct [type] | |
| 1089 | lc self [local] | |
| 1090 | fn func(…) [] | |
| 1091 | me self.test() [] | |
| 1084 | st Struct Struct [type] | |
| 1085 | st Self Self [type] | |
| 1086 | sp Self Struct [type] | |
| 1087 | st Struct Struct [type] | |
| 1088 | ex Struct [type] | |
| 1089 | lc self &Struct [local] | |
| 1090 | fn func(…) fn(Struct) [] | |
| 1091 | me self.test() fn(&self) [] | |
| 1092 | 1092 | "#]], |
| 1093 | 1093 | ); |
| 1094 | 1094 | } |
| ... | ... | @@ -1109,13 +1109,13 @@ fn main() { |
| 1109 | 1109 | } |
| 1110 | 1110 | "#, |
| 1111 | 1111 | expect![[r#" |
| 1112 | lc input [type+name+local] | |
| 1113 | ex input [type] | |
| 1114 | ex true [type] | |
| 1115 | ex false [type] | |
| 1116 | lc inputbad [local] | |
| 1117 | fn main() [] | |
| 1118 | fn test(…) [] | |
| 1112 | lc input bool [type+name+local] | |
| 1113 | ex input [type] | |
| 1114 | ex true [type] | |
| 1115 | ex false [type] | |
| 1116 | lc inputbad i32 [local] | |
| 1117 | fn main() fn() [] | |
| 1118 | fn test(…) fn(bool) [] | |
| 1119 | 1119 | "#]], |
| 1120 | 1120 | ); |
| 1121 | 1121 | } |
| ... | ... | @@ -1133,6 +1133,10 @@ fn main() { Foo::Fo$0 } |
| 1133 | 1133 | [ |
| 1134 | 1134 | CompletionItem { |
| 1135 | 1135 | label: "Foo {…}", |
| 1136 | detail_left: None, | |
| 1137 | detail_right: Some( | |
| 1138 | "Foo { x: i32, y: i32 }", | |
| 1139 | ), | |
| 1136 | 1140 | source_range: 54..56, |
| 1137 | 1141 | delete: 54..56, |
| 1138 | 1142 | insert: "Foo { x: ${1:()}, y: ${2:()} }$0", |
| ... | ... | @@ -1161,6 +1165,10 @@ fn main() { Foo::Fo$0 } |
| 1161 | 1165 | [ |
| 1162 | 1166 | CompletionItem { |
| 1163 | 1167 | label: "Foo(…)", |
| 1168 | detail_left: None, | |
| 1169 | detail_right: Some( | |
| 1170 | "Foo(i32, i32)", | |
| 1171 | ), | |
| 1164 | 1172 | source_range: 46..48, |
| 1165 | 1173 | delete: 46..48, |
| 1166 | 1174 | insert: "Foo(${1:()}, ${2:()})$0", |
| ... | ... | @@ -1189,6 +1197,10 @@ fn main() { fo$0 } |
| 1189 | 1197 | [ |
| 1190 | 1198 | CompletionItem { |
| 1191 | 1199 | label: "foo(…)", |
| 1200 | detail_left: None, | |
| 1201 | detail_right: Some( | |
| 1202 | "fn(u32, u32, T) -> (u32, T)", | |
| 1203 | ), | |
| 1192 | 1204 | source_range: 68..70, |
| 1193 | 1205 | delete: 68..70, |
| 1194 | 1206 | insert: "foo(${1:a}, ${2:b}, ${3:t})$0", |
| ... | ... | @@ -1201,6 +1213,10 @@ fn main() { fo$0 } |
| 1201 | 1213 | }, |
| 1202 | 1214 | CompletionItem { |
| 1203 | 1215 | label: "main()", |
| 1216 | detail_left: None, | |
| 1217 | detail_right: Some( | |
| 1218 | "fn()", | |
| 1219 | ), | |
| 1204 | 1220 | source_range: 68..70, |
| 1205 | 1221 | delete: 68..70, |
| 1206 | 1222 | insert: "main();$0", |
| ... | ... | @@ -1228,6 +1244,10 @@ fn main() { Foo::Fo$0 } |
| 1228 | 1244 | [ |
| 1229 | 1245 | CompletionItem { |
| 1230 | 1246 | label: "Foo", |
| 1247 | detail_left: None, | |
| 1248 | detail_right: Some( | |
| 1249 | "Foo", | |
| 1250 | ), | |
| 1231 | 1251 | source_range: 35..37, |
| 1232 | 1252 | delete: 35..37, |
| 1233 | 1253 | insert: "Foo$0", |
| ... | ... | @@ -1260,6 +1280,10 @@ fn main() { let _: m::Spam = S$0 } |
| 1260 | 1280 | [ |
| 1261 | 1281 | CompletionItem { |
| 1262 | 1282 | label: "main()", |
| 1283 | detail_left: None, | |
| 1284 | detail_right: Some( | |
| 1285 | "fn()", | |
| 1286 | ), | |
| 1263 | 1287 | source_range: 75..76, |
| 1264 | 1288 | delete: 75..76, |
| 1265 | 1289 | insert: "main();$0", |
| ... | ... | @@ -1271,6 +1295,8 @@ fn main() { let _: m::Spam = S$0 } |
| 1271 | 1295 | }, |
| 1272 | 1296 | CompletionItem { |
| 1273 | 1297 | label: "m", |
| 1298 | detail_left: None, | |
| 1299 | detail_right: None, | |
| 1274 | 1300 | source_range: 75..76, |
| 1275 | 1301 | delete: 75..76, |
| 1276 | 1302 | insert: "m", |
| ... | ... | @@ -1280,6 +1306,10 @@ fn main() { let _: m::Spam = S$0 } |
| 1280 | 1306 | }, |
| 1281 | 1307 | CompletionItem { |
| 1282 | 1308 | label: "m::Spam::Bar(…)", |
| 1309 | detail_left: None, | |
| 1310 | detail_right: Some( | |
| 1311 | "m::Spam::Bar(i32)", | |
| 1312 | ), | |
| 1283 | 1313 | source_range: 75..76, |
| 1284 | 1314 | delete: 75..76, |
| 1285 | 1315 | insert: "m::Spam::Bar(${1:()})$0", |
| ... | ... | @@ -1305,6 +1335,10 @@ fn main() { let _: m::Spam = S$0 } |
| 1305 | 1335 | }, |
| 1306 | 1336 | CompletionItem { |
| 1307 | 1337 | label: "m::Spam::Foo", |
| 1338 | detail_left: None, | |
| 1339 | detail_right: Some( | |
| 1340 | "m::Spam::Foo", | |
| 1341 | ), | |
| 1308 | 1342 | source_range: 75..76, |
| 1309 | 1343 | delete: 75..76, |
| 1310 | 1344 | insert: "m::Spam::Foo$0", |
| ... | ... | @@ -1347,6 +1381,10 @@ fn main() { som$0 } |
| 1347 | 1381 | [ |
| 1348 | 1382 | CompletionItem { |
| 1349 | 1383 | label: "main()", |
| 1384 | detail_left: None, | |
| 1385 | detail_right: Some( | |
| 1386 | "fn()", | |
| 1387 | ), | |
| 1350 | 1388 | source_range: 56..59, |
| 1351 | 1389 | delete: 56..59, |
| 1352 | 1390 | insert: "main();$0", |
| ... | ... | @@ -1358,6 +1396,10 @@ fn main() { som$0 } |
| 1358 | 1396 | }, |
| 1359 | 1397 | CompletionItem { |
| 1360 | 1398 | label: "something_deprecated()", |
| 1399 | detail_left: None, | |
| 1400 | detail_right: Some( | |
| 1401 | "fn()", | |
| 1402 | ), | |
| 1361 | 1403 | source_range: 56..59, |
| 1362 | 1404 | delete: 56..59, |
| 1363 | 1405 | insert: "something_deprecated();$0", |
| ... | ... | @@ -1382,6 +1424,10 @@ fn foo() { A { the$0 } } |
| 1382 | 1424 | [ |
| 1383 | 1425 | CompletionItem { |
| 1384 | 1426 | label: "the_field", |
| 1427 | detail_left: None, | |
| 1428 | detail_right: Some( | |
| 1429 | "u32", | |
| 1430 | ), | |
| 1385 | 1431 | source_range: 57..60, |
| 1386 | 1432 | delete: 57..60, |
| 1387 | 1433 | insert: "the_field", |
| ... | ... | @@ -1429,6 +1475,10 @@ impl S { |
| 1429 | 1475 | [ |
| 1430 | 1476 | CompletionItem { |
| 1431 | 1477 | label: "bar()", |
| 1478 | detail_left: None, | |
| 1479 | detail_right: Some( | |
| 1480 | "fn(self)", | |
| 1481 | ), | |
| 1432 | 1482 | source_range: 94..94, |
| 1433 | 1483 | delete: 94..94, |
| 1434 | 1484 | insert: "bar();$0", |
| ... | ... | @@ -1460,6 +1510,10 @@ impl S { |
| 1460 | 1510 | }, |
| 1461 | 1511 | CompletionItem { |
| 1462 | 1512 | label: "foo", |
| 1513 | detail_left: None, | |
| 1514 | detail_right: Some( | |
| 1515 | "{unknown}", | |
| 1516 | ), | |
| 1463 | 1517 | source_range: 94..94, |
| 1464 | 1518 | delete: 94..94, |
| 1465 | 1519 | insert: "foo", |
| ... | ... | @@ -1498,6 +1552,8 @@ use self::E::*; |
| 1498 | 1552 | [ |
| 1499 | 1553 | CompletionItem { |
| 1500 | 1554 | label: "my", |
| 1555 | detail_left: None, | |
| 1556 | detail_right: None, | |
| 1501 | 1557 | source_range: 10..12, |
| 1502 | 1558 | delete: 10..12, |
| 1503 | 1559 | insert: "my", |
| ... | ... | @@ -1510,6 +1566,10 @@ use self::E::*; |
| 1510 | 1566 | }, |
| 1511 | 1567 | CompletionItem { |
| 1512 | 1568 | label: "V", |
| 1569 | detail_left: None, | |
| 1570 | detail_right: Some( | |
| 1571 | "V", | |
| 1572 | ), | |
| 1513 | 1573 | source_range: 10..12, |
| 1514 | 1574 | delete: 10..12, |
| 1515 | 1575 | insert: "V$0", |
| ... | ... | @@ -1524,6 +1584,10 @@ use self::E::*; |
| 1524 | 1584 | }, |
| 1525 | 1585 | CompletionItem { |
| 1526 | 1586 | label: "E", |
| 1587 | detail_left: None, | |
| 1588 | detail_right: Some( | |
| 1589 | "E", | |
| 1590 | ), | |
| 1527 | 1591 | source_range: 10..12, |
| 1528 | 1592 | delete: 10..12, |
| 1529 | 1593 | insert: "E", |
| ... | ... | @@ -1556,6 +1620,10 @@ fn foo(s: S) { s.$0 } |
| 1556 | 1620 | [ |
| 1557 | 1621 | CompletionItem { |
| 1558 | 1622 | label: "the_method()", |
| 1623 | detail_left: None, | |
| 1624 | detail_right: Some( | |
| 1625 | "fn(&self)", | |
| 1626 | ), | |
| 1559 | 1627 | source_range: 81..81, |
| 1560 | 1628 | delete: 81..81, |
| 1561 | 1629 | insert: "the_method();$0", |
| ... | ... | @@ -1729,9 +1797,9 @@ fn test(bar: u32) { } |
| 1729 | 1797 | fn foo(s: S) { test(s.$0) } |
| 1730 | 1798 | "#, |
| 1731 | 1799 | expect![[r#" |
| 1732 | fd bar [type+name] | |
| 1733 | fd baz [type] | |
| 1734 | fd foo [] | |
| 1800 | fd bar u32 [type+name] | |
| 1801 | fd baz u32 [type] | |
| 1802 | fd foo i64 [] | |
| 1735 | 1803 | "#]], |
| 1736 | 1804 | ); |
| 1737 | 1805 | } |
| ... | ... | @@ -1745,9 +1813,9 @@ struct B { x: (), y: f32, bar: u32 } |
| 1745 | 1813 | fn foo(a: A) { B { bar: a.$0 }; } |
| 1746 | 1814 | "#, |
| 1747 | 1815 | expect![[r#" |
| 1748 | fd bar [type+name] | |
| 1749 | fd baz [type] | |
| 1750 | fd foo [] | |
| 1816 | fd bar u32 [type+name] | |
| 1817 | fd baz u32 [type] | |
| 1818 | fd foo i64 [] | |
| 1751 | 1819 | "#]], |
| 1752 | 1820 | ) |
| 1753 | 1821 | } |
| ... | ... | @@ -1768,6 +1836,10 @@ fn f() -> i32 { |
| 1768 | 1836 | [ |
| 1769 | 1837 | CompletionItem { |
| 1770 | 1838 | label: "0", |
| 1839 | detail_left: None, | |
| 1840 | detail_right: Some( | |
| 1841 | "i32", | |
| 1842 | ), | |
| 1771 | 1843 | source_range: 56..57, |
| 1772 | 1844 | delete: 56..57, |
| 1773 | 1845 | insert: "0", |
| ... | ... | @@ -1804,9 +1876,9 @@ fn f(foo: i64) { } |
| 1804 | 1876 | fn foo(a: A) { B { bar: f(a.$0) }; } |
| 1805 | 1877 | "#, |
| 1806 | 1878 | expect![[r#" |
| 1807 | fd foo [type+name] | |
| 1808 | fd bar [] | |
| 1809 | fd baz [] | |
| 1879 | fd foo i64 [type+name] | |
| 1880 | fd bar u32 [] | |
| 1881 | fd baz u32 [] | |
| 1810 | 1882 | "#]], |
| 1811 | 1883 | ); |
| 1812 | 1884 | check_relevance( |
| ... | ... | @@ -1817,9 +1889,9 @@ fn f(foo: i64) { } |
| 1817 | 1889 | fn foo(a: A) { f(B { bar: a.$0 }); } |
| 1818 | 1890 | "#, |
| 1819 | 1891 | expect![[r#" |
| 1820 | fd bar [type+name] | |
| 1821 | fd baz [type] | |
| 1822 | fd foo [] | |
| 1892 | fd bar u32 [type+name] | |
| 1893 | fd baz u32 [type] | |
| 1894 | fd foo i64 [] | |
| 1823 | 1895 | "#]], |
| 1824 | 1896 | ); |
| 1825 | 1897 | } |
| ... | ... | @@ -1832,13 +1904,13 @@ struct WorldSnapshot { _f: () }; |
| 1832 | 1904 | fn go(world: &WorldSnapshot) { go(w$0) } |
| 1833 | 1905 | "#, |
| 1834 | 1906 | expect![[r#" |
| 1835 | lc world [type+name+local] | |
| 1836 | ex world [type] | |
| 1837 | st WorldSnapshot {…} [] | |
| 1907 | lc world &WorldSnapshot [type+name+local] | |
| 1908 | ex world [type] | |
| 1909 | st WorldSnapshot {…} WorldSnapshot { _f: () } [] | |
| 1838 | 1910 | st &WorldSnapshot {…} [type] |
| 1839 | st WorldSnapshot [] | |
| 1911 | st WorldSnapshot WorldSnapshot [] | |
| 1840 | 1912 | st &WorldSnapshot [type] |
| 1841 | fn go(…) [] | |
| 1913 | fn go(…) fn(&WorldSnapshot) [] | |
| 1842 | 1914 | "#]], |
| 1843 | 1915 | ); |
| 1844 | 1916 | } |
| ... | ... | @@ -1852,9 +1924,9 @@ struct Foo; |
| 1852 | 1924 | fn f(foo: &Foo) { f(foo, w$0) } |
| 1853 | 1925 | "#, |
| 1854 | 1926 | expect![[r#" |
| 1855 | lc foo [local] | |
| 1856 | st Foo [] | |
| 1857 | fn f(…) [] | |
| 1927 | lc foo &Foo [local] | |
| 1928 | st Foo Foo [] | |
| 1929 | fn f(…) fn(&Foo) [] | |
| 1858 | 1930 | "#]], |
| 1859 | 1931 | ); |
| 1860 | 1932 | } |
| ... | ... | @@ -1869,12 +1941,12 @@ fn bar() -> u8 { 0 } |
| 1869 | 1941 | fn f() { A { bar: b$0 }; } |
| 1870 | 1942 | "#, |
| 1871 | 1943 | expect![[r#" |
| 1872 | fn bar() [type+name] | |
| 1873 | fn baz() [type] | |
| 1874 | ex bar() [type] | |
| 1875 | ex baz() [type] | |
| 1876 | st A [] | |
| 1877 | fn f() [] | |
| 1944 | fn bar() fn() -> u8 [type+name] | |
| 1945 | fn baz() fn() -> u8 [type] | |
| 1946 | ex bar() [type] | |
| 1947 | ex baz() [type] | |
| 1948 | st A A [] | |
| 1949 | fn f() fn() [] | |
| 1878 | 1950 | "#]], |
| 1879 | 1951 | ); |
| 1880 | 1952 | } |
| ... | ... | @@ -1895,9 +1967,9 @@ fn f() { |
| 1895 | 1967 | } |
| 1896 | 1968 | "#, |
| 1897 | 1969 | expect![[r#" |
| 1898 | me aaa() [type+name] | |
| 1899 | me bbb() [type] | |
| 1900 | me ccc() [] | |
| 1970 | me aaa() fn(&self) -> u32 [type+name] | |
| 1971 | me bbb() fn(&self) -> u32 [type] | |
| 1972 | me ccc() fn(&self) -> u64 [] | |
| 1901 | 1973 | "#]], |
| 1902 | 1974 | ); |
| 1903 | 1975 | } |
| ... | ... | @@ -1916,7 +1988,7 @@ fn f() { |
| 1916 | 1988 | } |
| 1917 | 1989 | "#, |
| 1918 | 1990 | expect![[r#" |
| 1919 | me aaa() [name] | |
| 1991 | me aaa() fn(&self) -> u64 [name] | |
| 1920 | 1992 | "#]], |
| 1921 | 1993 | ); |
| 1922 | 1994 | } |
| ... | ... | @@ -1934,14 +2006,14 @@ fn main() { |
| 1934 | 2006 | } |
| 1935 | 2007 | "#, |
| 1936 | 2008 | expect![[r#" |
| 1937 | lc s [name+local] | |
| 2009 | lc s S [name+local] | |
| 1938 | 2010 | lc &mut s [type+name+local] |
| 1939 | st S [] | |
| 2011 | st S S [] | |
| 1940 | 2012 | st &mut S [type] |
| 1941 | st S [] | |
| 2013 | st S S [] | |
| 1942 | 2014 | st &mut S [type] |
| 1943 | fn foo(…) [] | |
| 1944 | fn main() [] | |
| 2015 | fn foo(…) fn(&mut S) [] | |
| 2016 | fn main() fn() [] | |
| 1945 | 2017 | "#]], |
| 1946 | 2018 | ); |
| 1947 | 2019 | check_relevance( |
| ... | ... | @@ -1954,13 +2026,13 @@ fn main() { |
| 1954 | 2026 | } |
| 1955 | 2027 | "#, |
| 1956 | 2028 | expect![[r#" |
| 1957 | lc s [type+name+local] | |
| 1958 | st S [type] | |
| 1959 | st S [type] | |
| 1960 | ex s [type] | |
| 1961 | ex S [type] | |
| 1962 | fn foo(…) [] | |
| 1963 | fn main() [] | |
| 2029 | lc s S [type+name+local] | |
| 2030 | st S S [type] | |
| 2031 | st S S [type] | |
| 2032 | ex s [type] | |
| 2033 | ex S [type] | |
| 2034 | fn foo(…) fn(&mut S) [] | |
| 2035 | fn main() fn() [] | |
| 1964 | 2036 | "#]], |
| 1965 | 2037 | ); |
| 1966 | 2038 | check_relevance( |
| ... | ... | @@ -1973,13 +2045,13 @@ fn main() { |
| 1973 | 2045 | } |
| 1974 | 2046 | "#, |
| 1975 | 2047 | expect![[r#" |
| 1976 | lc ssss [type+local] | |
| 1977 | st S [type] | |
| 1978 | st S [type] | |
| 1979 | ex ssss [type] | |
| 1980 | ex S [type] | |
| 1981 | fn foo(…) [] | |
| 1982 | fn main() [] | |
| 2048 | lc ssss S [type+local] | |
| 2049 | st S S [type] | |
| 2050 | st S S [type] | |
| 2051 | ex ssss [type] | |
| 2052 | ex S [type] | |
| 2053 | fn foo(…) fn(&mut S) [] | |
| 2054 | fn main() fn() [] | |
| 1983 | 2055 | "#]], |
| 1984 | 2056 | ); |
| 1985 | 2057 | } |
| ... | ... | @@ -2010,19 +2082,19 @@ fn main() { |
| 2010 | 2082 | } |
| 2011 | 2083 | "#, |
| 2012 | 2084 | expect![[r#" |
| 2013 | ex core::ops::Deref::deref(&t) (use core::ops::Deref) [type_could_unify] | |
| 2014 | lc m [local] | |
| 2015 | lc t [local] | |
| 2085 | ex core::ops::Deref::deref(&t) [type_could_unify] | |
| 2086 | lc m i32 [local] | |
| 2087 | lc t T [local] | |
| 2016 | 2088 | lc &t [type+local] |
| 2017 | st S [] | |
| 2089 | st S S [] | |
| 2018 | 2090 | st &S [type] |
| 2019 | st S [] | |
| 2091 | st S S [] | |
| 2020 | 2092 | st &S [type] |
| 2021 | st T [] | |
| 2093 | st T T [] | |
| 2022 | 2094 | st &T [type] |
| 2023 | fn foo(…) [] | |
| 2024 | fn main() [] | |
| 2025 | md core [] | |
| 2095 | fn foo(…) fn(&S) [] | |
| 2096 | fn main() fn() [] | |
| 2097 | md core [] | |
| 2026 | 2098 | "#]], |
| 2027 | 2099 | ) |
| 2028 | 2100 | } |
| ... | ... | @@ -2059,19 +2131,19 @@ fn main() { |
| 2059 | 2131 | } |
| 2060 | 2132 | "#, |
| 2061 | 2133 | expect![[r#" |
| 2062 | ex core::ops::DerefMut::deref_mut(&mut t) (use core::ops::DerefMut) [type_could_unify] | |
| 2063 | lc m [local] | |
| 2064 | lc t [local] | |
| 2134 | ex core::ops::DerefMut::deref_mut(&mut t) [type_could_unify] | |
| 2135 | lc m i32 [local] | |
| 2136 | lc t T [local] | |
| 2065 | 2137 | lc &mut t [type+local] |
| 2066 | st S [] | |
| 2138 | st S S [] | |
| 2067 | 2139 | st &mut S [type] |
| 2068 | st S [] | |
| 2140 | st S S [] | |
| 2069 | 2141 | st &mut S [type] |
| 2070 | st T [] | |
| 2142 | st T T [] | |
| 2071 | 2143 | st &mut T [type] |
| 2072 | fn foo(…) [] | |
| 2073 | fn main() [] | |
| 2074 | md core [] | |
| 2144 | fn foo(…) fn(&mut S) [] | |
| 2145 | fn main() fn() [] | |
| 2146 | md core [] | |
| 2075 | 2147 | "#]], |
| 2076 | 2148 | ) |
| 2077 | 2149 | } |
| ... | ... | @@ -2087,9 +2159,9 @@ fn foo(bar: u32) { |
| 2087 | 2159 | } |
| 2088 | 2160 | "#, |
| 2089 | 2161 | expect![[r#" |
| 2090 | lc baz [local] | |
| 2091 | lc bar [local] | |
| 2092 | fn foo(…) [] | |
| 2162 | lc baz i32 [local] | |
| 2163 | lc bar u32 [local] | |
| 2164 | fn foo(…) fn(u32) [] | |
| 2093 | 2165 | "#]], |
| 2094 | 2166 | ); |
| 2095 | 2167 | } |
| ... | ... | @@ -2105,13 +2177,13 @@ fn foo() { |
| 2105 | 2177 | fn bar(t: Foo) {} |
| 2106 | 2178 | "#, |
| 2107 | 2179 | expect![[r#" |
| 2108 | ev Foo::A [type] | |
| 2109 | ev Foo::B [type] | |
| 2110 | en Foo [type] | |
| 2111 | ex Foo::A [type] | |
| 2112 | ex Foo::B [type] | |
| 2113 | fn bar(…) [] | |
| 2114 | fn foo() [] | |
| 2180 | ev Foo::A Foo::A [type] | |
| 2181 | ev Foo::B Foo::B [type] | |
| 2182 | en Foo Foo [type] | |
| 2183 | ex Foo::A [type] | |
| 2184 | ex Foo::B [type] | |
| 2185 | fn bar(…) fn(Foo) [] | |
| 2186 | fn foo() fn() [] | |
| 2115 | 2187 | "#]], |
| 2116 | 2188 | ); |
| 2117 | 2189 | } |
| ... | ... | @@ -2127,14 +2199,14 @@ fn foo() { |
| 2127 | 2199 | fn bar(t: &Foo) {} |
| 2128 | 2200 | "#, |
| 2129 | 2201 | expect![[r#" |
| 2130 | ev Foo::A [] | |
| 2202 | ev Foo::A Foo::A [] | |
| 2131 | 2203 | ev &Foo::A [type] |
| 2132 | ev Foo::B [] | |
| 2204 | ev Foo::B Foo::B [] | |
| 2133 | 2205 | ev &Foo::B [type] |
| 2134 | en Foo [] | |
| 2206 | en Foo Foo [] | |
| 2135 | 2207 | en &Foo [type] |
| 2136 | fn bar(…) [] | |
| 2137 | fn foo() [] | |
| 2208 | fn bar(…) fn(&Foo) [] | |
| 2209 | fn foo() fn() [] | |
| 2138 | 2210 | "#]], |
| 2139 | 2211 | ); |
| 2140 | 2212 | } |
| ... | ... | @@ -2163,18 +2235,18 @@ fn main() { |
| 2163 | 2235 | } |
| 2164 | 2236 | "#, |
| 2165 | 2237 | expect![[r#" |
| 2166 | ex core::ops::Deref::deref(&bar()) (use core::ops::Deref) [type_could_unify] | |
| 2167 | st S [] | |
| 2238 | ex core::ops::Deref::deref(&bar()) [type_could_unify] | |
| 2239 | st S S [] | |
| 2168 | 2240 | st &S [type] |
| 2169 | st S [] | |
| 2241 | st S S [] | |
| 2170 | 2242 | st &S [type] |
| 2171 | st T [] | |
| 2243 | st T T [] | |
| 2172 | 2244 | st &T [type] |
| 2173 | fn bar() [] | |
| 2245 | fn bar() fn() -> T [] | |
| 2174 | 2246 | fn &bar() [type] |
| 2175 | fn foo(…) [] | |
| 2176 | fn main() [] | |
| 2177 | md core [] | |
| 2247 | fn foo(…) fn(&S) [] | |
| 2248 | fn main() fn() [] | |
| 2249 | md core [] | |
| 2178 | 2250 | "#]], |
| 2179 | 2251 | ) |
| 2180 | 2252 | } |
| ... | ... | @@ -2191,7 +2263,7 @@ impl Sub for u32 {} |
| 2191 | 2263 | fn foo(a: u32) { a.$0 } |
| 2192 | 2264 | "#, |
| 2193 | 2265 | expect![[r#" |
| 2194 | me sub(…) (as Sub) [op_method] | |
| 2266 | me sub(…) fn(self, Self) -> Self [op_method] | |
| 2195 | 2267 | "#]], |
| 2196 | 2268 | ); |
| 2197 | 2269 | check_relevance( |
| ... | ... | @@ -2212,9 +2284,9 @@ fn main() { |
| 2212 | 2284 | } |
| 2213 | 2285 | "#, |
| 2214 | 2286 | expect![[r#" |
| 2215 | fn new() [] | |
| 2216 | me eq(…) (as PartialEq) [op_method] | |
| 2217 | me ne(…) (as PartialEq) [op_method] | |
| 2287 | fn new() fn() -> Foo [] | |
| 2288 | me eq(…) fn(&self, &Rhs) -> bool [op_method] | |
| 2289 | me ne(…) fn(&self, &Rhs) -> bool [op_method] | |
| 2218 | 2290 | "#]], |
| 2219 | 2291 | ); |
| 2220 | 2292 | } |
| ... | ... | @@ -2238,9 +2310,9 @@ fn test() { |
| 2238 | 2310 | } |
| 2239 | 2311 | "#, |
| 2240 | 2312 | expect![[r#" |
| 2241 | fn fn_ctr() [type_could_unify] | |
| 2242 | fn fn_ctr_self() [type_could_unify] | |
| 2243 | fn fn_another(…) [type_could_unify] | |
| 2313 | fn fn_ctr() fn() -> Foo [type_could_unify] | |
| 2314 | fn fn_ctr_self() fn() -> Option<Foo> [type_could_unify] | |
| 2315 | fn fn_another(…) fn(u32) -> Other [type_could_unify] | |
| 2244 | 2316 | "#]], |
| 2245 | 2317 | ); |
| 2246 | 2318 | } |
| ... | ... | @@ -2384,12 +2456,12 @@ fn test() { |
| 2384 | 2456 | // Constructor |
| 2385 | 2457 | // Others |
| 2386 | 2458 | expect![[r#" |
| 2387 | fn fn_direct_ctr() [type_could_unify] | |
| 2388 | fn fn_ctr_with_args(…) [type_could_unify] | |
| 2389 | fn fn_builder() [type_could_unify] | |
| 2390 | fn fn_ctr() [type_could_unify] | |
| 2391 | me fn_no_ret(…) [type_could_unify] | |
| 2392 | fn fn_other() [type_could_unify] | |
| 2459 | fn fn_direct_ctr() fn() -> Foo [type_could_unify] | |
| 2460 | fn fn_ctr_with_args(…) fn(u32) -> Foo [type_could_unify] | |
| 2461 | fn fn_builder() fn() -> FooBuilder [type_could_unify] | |
| 2462 | fn fn_ctr() fn() -> Result<Foo> [type_could_unify] | |
| 2463 | me fn_no_ret(…) fn(&self) [type_could_unify] | |
| 2464 | fn fn_other() fn() -> Result<u32> [type_could_unify] | |
| 2393 | 2465 | "#]], |
| 2394 | 2466 | ); |
| 2395 | 2467 | |
| ... | ... | @@ -2420,14 +2492,14 @@ fn test() { |
| 2420 | 2492 | } |
| 2421 | 2493 | "#, |
| 2422 | 2494 | expect![[r#" |
| 2423 | fn fn_direct_ctr() [type_could_unify] | |
| 2424 | fn fn_ctr_with_args(…) [type_could_unify] | |
| 2425 | fn fn_builder() [type_could_unify] | |
| 2426 | fn fn_ctr_wrapped() [type_could_unify] | |
| 2427 | fn fn_ctr_wrapped_2() [type_could_unify] | |
| 2428 | me fn_returns_unit(…) [type_could_unify] | |
| 2429 | fn fn_other() [type_could_unify] | |
| 2430 | "#]], | |
| 2495 | fn fn_direct_ctr() fn() -> Foo<T> [type_could_unify] | |
| 2496 | fn fn_ctr_with_args(…) fn(T) -> Foo<T> [type_could_unify] | |
| 2497 | fn fn_builder() fn() -> FooBuilder [type_could_unify] | |
| 2498 | fn fn_ctr_wrapped() fn() -> Option<Foo<T>> [type_could_unify] | |
| 2499 | fn fn_ctr_wrapped_2() fn() -> Result<Foo<T>, u32> [type_could_unify] | |
| 2500 | me fn_returns_unit(…) fn(&self) [type_could_unify] | |
| 2501 | fn fn_other() fn() -> Option<u32> [type_could_unify] | |
| 2502 | "#]], | |
| 2431 | 2503 | ); |
| 2432 | 2504 | } |
| 2433 | 2505 | |
| ... | ... | @@ -2456,13 +2528,13 @@ fn test() { |
| 2456 | 2528 | } |
| 2457 | 2529 | "#, |
| 2458 | 2530 | expect![[r#" |
| 2459 | fn fn_direct_ctr() [type_could_unify] | |
| 2460 | fn fn_ctr_with_args(…) [type_could_unify] | |
| 2461 | fn fn_builder() [type_could_unify] | |
| 2462 | fn fn_ctr() [type_could_unify] | |
| 2463 | fn fn_ctr2() [type_could_unify] | |
| 2464 | me fn_no_ret(…) [type_could_unify] | |
| 2465 | fn fn_other() [type_could_unify] | |
| 2531 | fn fn_direct_ctr() fn() -> Foo<T> [type_could_unify] | |
| 2532 | fn fn_ctr_with_args(…) fn(T) -> Foo<T> [type_could_unify] | |
| 2533 | fn fn_builder() fn() -> FooBuilder [type_could_unify] | |
| 2534 | fn fn_ctr() fn() -> Option<Foo<T>> [type_could_unify] | |
| 2535 | fn fn_ctr2() fn() -> Result<Foo<T>, u32> [type_could_unify] | |
| 2536 | me fn_no_ret(…) fn(&self) [type_could_unify] | |
| 2537 | fn fn_other() fn() -> Option<u32> [type_could_unify] | |
| 2466 | 2538 | "#]], |
| 2467 | 2539 | ); |
| 2468 | 2540 | } |
| ... | ... | @@ -2484,6 +2556,10 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 } |
| 2484 | 2556 | [ |
| 2485 | 2557 | CompletionItem { |
| 2486 | 2558 | label: "baz()", |
| 2559 | detail_left: None, | |
| 2560 | detail_right: Some( | |
| 2561 | "fn(&self) -> u32", | |
| 2562 | ), | |
| 2487 | 2563 | source_range: 109..110, |
| 2488 | 2564 | delete: 109..110, |
| 2489 | 2565 | insert: "baz()$0", |
| ... | ... | @@ -2513,6 +2589,10 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 } |
| 2513 | 2589 | }, |
| 2514 | 2590 | CompletionItem { |
| 2515 | 2591 | label: "bar", |
| 2592 | detail_left: None, | |
| 2593 | detail_right: Some( | |
| 2594 | "u32", | |
| 2595 | ), | |
| 2516 | 2596 | source_range: 109..110, |
| 2517 | 2597 | delete: 109..110, |
| 2518 | 2598 | insert: "bar", |
| ... | ... | @@ -2524,6 +2604,10 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 } |
| 2524 | 2604 | }, |
| 2525 | 2605 | CompletionItem { |
| 2526 | 2606 | label: "qux", |
| 2607 | detail_left: None, | |
| 2608 | detail_right: Some( | |
| 2609 | "fn()", | |
| 2610 | ), | |
| 2527 | 2611 | source_range: 109..110, |
| 2528 | 2612 | text_edit: TextEdit { |
| 2529 | 2613 | indels: [ |
| ... | ... | @@ -2562,6 +2646,10 @@ fn foo() { |
| 2562 | 2646 | [ |
| 2563 | 2647 | CompletionItem { |
| 2564 | 2648 | label: "field", |
| 2649 | detail_left: None, | |
| 2650 | detail_right: Some( | |
| 2651 | "fn()", | |
| 2652 | ), | |
| 2565 | 2653 | source_range: 76..78, |
| 2566 | 2654 | delete: 76..78, |
| 2567 | 2655 | insert: "field", |
| ... | ... | @@ -2610,6 +2698,10 @@ fn main() { |
| 2610 | 2698 | [ |
| 2611 | 2699 | CompletionItem { |
| 2612 | 2700 | label: "foo()", |
| 2701 | detail_left: None, | |
| 2702 | detail_right: Some( | |
| 2703 | "fn() -> S", | |
| 2704 | ), | |
| 2613 | 2705 | source_range: 95..95, |
| 2614 | 2706 | delete: 95..95, |
| 2615 | 2707 | insert: "foo()$0", |
| ... | ... | @@ -2661,15 +2753,15 @@ fn foo() { |
| 2661 | 2753 | } |
| 2662 | 2754 | "#, |
| 2663 | 2755 | expect![[r#" |
| 2664 | lc foo [type+local] | |
| 2665 | ex foo [type] | |
| 2666 | ex Foo::B [type] | |
| 2667 | ev Foo::A(…) [type_could_unify] | |
| 2668 | ev Foo::B [type_could_unify] | |
| 2669 | en Foo [type_could_unify] | |
| 2670 | fn foo() [] | |
| 2671 | fn bar() [] | |
| 2672 | fn baz() [] | |
| 2756 | lc foo Foo<u32> [type+local] | |
| 2757 | ex foo [type] | |
| 2758 | ex Foo::B [type] | |
| 2759 | ev Foo::A(…) Foo::A(T) [type_could_unify] | |
| 2760 | ev Foo::B Foo::B [type_could_unify] | |
| 2761 | en Foo Foo<{unknown}> [type_could_unify] | |
| 2762 | fn foo() fn() [] | |
| 2763 | fn bar() fn() -> Foo<u8> [] | |
| 2764 | fn baz() fn() -> Foo<T> [] | |
| 2673 | 2765 | "#]], |
| 2674 | 2766 | ); |
| 2675 | 2767 | } |
| ... | ... | @@ -2697,20 +2789,20 @@ fn main() { |
| 2697 | 2789 | "#, |
| 2698 | 2790 | &[CompletionItemKind::Snippet, CompletionItemKind::SymbolKind(SymbolKind::Method)], |
| 2699 | 2791 | expect![[r#" |
| 2700 | sn not [snippet] | |
| 2701 | me not() (use ops::Not) [type_could_unify+requires_import] | |
| 2702 | sn if [] | |
| 2703 | sn while [] | |
| 2704 | sn ref [] | |
| 2705 | sn refm [] | |
| 2706 | sn deref [] | |
| 2707 | sn unsafe [] | |
| 2708 | sn match [] | |
| 2709 | sn box [] | |
| 2710 | sn dbg [] | |
| 2711 | sn dbgr [] | |
| 2712 | sn call [] | |
| 2713 | sn return [] | |
| 2792 | sn not !expr [snippet] | |
| 2793 | me not() fn(self) -> <Self as Not>::Output [type_could_unify+requires_import] | |
| 2794 | sn if if expr {} [] | |
| 2795 | sn while while expr {} [] | |
| 2796 | sn ref &expr [] | |
| 2797 | sn refm &mut expr [] | |
| 2798 | sn deref *expr [] | |
| 2799 | sn unsafe unsafe {} [] | |
| 2800 | sn match match expr {} [] | |
| 2801 | sn box Box::new(expr) [] | |
| 2802 | sn dbg dbg!(expr) [] | |
| 2803 | sn dbgr dbg!(&expr) [] | |
| 2804 | sn call function(expr) [] | |
| 2805 | sn return return expr [] | |
| 2714 | 2806 | "#]], |
| 2715 | 2807 | ); |
| 2716 | 2808 | } |
| ... | ... | @@ -2730,19 +2822,19 @@ fn main() { |
| 2730 | 2822 | "#, |
| 2731 | 2823 | &[CompletionItemKind::Snippet, CompletionItemKind::SymbolKind(SymbolKind::Method)], |
| 2732 | 2824 | expect![[r#" |
| 2733 | me f() [] | |
| 2734 | sn ref [] | |
| 2735 | sn refm [] | |
| 2736 | sn deref [] | |
| 2737 | sn unsafe [] | |
| 2738 | sn match [] | |
| 2739 | sn box [] | |
| 2740 | sn dbg [] | |
| 2741 | sn dbgr [] | |
| 2742 | sn call [] | |
| 2743 | sn let [] | |
| 2744 | sn letm [] | |
| 2745 | sn return [] | |
| 2825 | me f() fn(&self) [] | |
| 2826 | sn ref &expr [] | |
| 2827 | sn refm &mut expr [] | |
| 2828 | sn deref *expr [] | |
| 2829 | sn unsafe unsafe {} [] | |
| 2830 | sn match match expr {} [] | |
| 2831 | sn box Box::new(expr) [] | |
| 2832 | sn dbg dbg!(expr) [] | |
| 2833 | sn dbgr dbg!(&expr) [] | |
| 2834 | sn call function(expr) [] | |
| 2835 | sn let let [] | |
| 2836 | sn letm let mut [] | |
| 2837 | sn return return expr [] | |
| 2746 | 2838 | "#]], |
| 2747 | 2839 | ); |
| 2748 | 2840 | } |
| ... | ... | @@ -2765,12 +2857,12 @@ fn f() { |
| 2765 | 2857 | } |
| 2766 | 2858 | "#, |
| 2767 | 2859 | expect![[r#" |
| 2768 | st Buffer [] | |
| 2769 | fn f() [] | |
| 2770 | md std [] | |
| 2771 | tt BufRead (use std::io::BufRead) [requires_import] | |
| 2772 | st BufReader (use std::io::BufReader) [requires_import] | |
| 2773 | st BufWriter (use std::io::BufWriter) [requires_import] | |
| 2860 | st Buffer Buffer [] | |
| 2861 | fn f() fn() [] | |
| 2862 | md std [] | |
| 2863 | tt BufRead [requires_import] | |
| 2864 | st BufReader BufReader [requires_import] | |
| 2865 | st BufWriter BufWriter [requires_import] | |
| 2774 | 2866 | "#]], |
| 2775 | 2867 | ); |
| 2776 | 2868 | } |
| ... | ... | @@ -2979,6 +3071,12 @@ fn main() { |
| 2979 | 3071 | [ |
| 2980 | 3072 | CompletionItem { |
| 2981 | 3073 | label: "flush()", |
| 3074 | detail_left: Some( | |
| 3075 | "(as Write)", | |
| 3076 | ), | |
| 3077 | detail_right: Some( | |
| 3078 | "fn(&self)", | |
| 3079 | ), | |
| 2982 | 3080 | source_range: 193..193, |
| 2983 | 3081 | delete: 193..193, |
| 2984 | 3082 | insert: "flush();$0", |
| ... | ... | @@ -3006,6 +3104,12 @@ fn main() { |
| 3006 | 3104 | }, |
| 3007 | 3105 | CompletionItem { |
| 3008 | 3106 | label: "write()", |
| 3107 | detail_left: Some( | |
| 3108 | "(as Write)", | |
| 3109 | ), | |
| 3110 | detail_right: Some( | |
| 3111 | "fn(&self)", | |
| 3112 | ), | |
| 3009 | 3113 | source_range: 193..193, |
| 3010 | 3114 | delete: 193..193, |
| 3011 | 3115 | insert: "write();$0", |
src/tools/rust-analyzer/crates/ide-completion/src/tests.rs+24-15| ... | ... | @@ -118,10 +118,16 @@ fn completion_list_with_config_raw( |
| 118 | 118 | let items = get_all_items(config, ra_fixture, trigger_character); |
| 119 | 119 | items |
| 120 | 120 | .into_iter() |
| 121 | .filter(|it| it.kind != CompletionItemKind::BuiltinType || it.label == "u32") | |
| 121 | .filter(|it| it.kind != CompletionItemKind::BuiltinType || it.label.primary == "u32") | |
| 122 | 122 | .filter(|it| include_keywords || it.kind != CompletionItemKind::Keyword) |
| 123 | 123 | .filter(|it| include_keywords || it.kind != CompletionItemKind::Snippet) |
| 124 | .sorted_by_key(|it| (it.kind, it.label.clone(), it.detail.as_ref().map(ToOwned::to_owned))) | |
| 124 | .sorted_by_key(|it| { | |
| 125 | ( | |
| 126 | it.kind, | |
| 127 | it.label.primary.clone(), | |
| 128 | it.label.detail_left.as_ref().map(ToOwned::to_owned), | |
| 129 | ) | |
| 130 | }) | |
| 125 | 131 | .collect() |
| 126 | 132 | } |
| 127 | 133 | |
| ... | ... | @@ -173,27 +179,30 @@ fn render_completion_list(completions: Vec<CompletionItem>) -> String { |
| 173 | 179 | let label_width = completions |
| 174 | 180 | .iter() |
| 175 | 181 | .map(|it| { |
| 176 | monospace_width(&it.label) | |
| 177 | + monospace_width(it.label_detail.as_deref().unwrap_or_default()) | |
| 182 | monospace_width(&it.label.primary) | |
| 183 | + monospace_width(it.label.detail_left.as_deref().unwrap_or_default()) | |
| 184 | + monospace_width(it.label.detail_right.as_deref().unwrap_or_default()) | |
| 185 | + it.label.detail_left.is_some() as usize | |
| 186 | + it.label.detail_right.is_some() as usize | |
| 178 | 187 | }) |
| 179 | 188 | .max() |
| 180 | .unwrap_or_default() | |
| 181 | .min(22); | |
| 189 | .unwrap_or_default(); | |
| 182 | 190 | completions |
| 183 | 191 | .into_iter() |
| 184 | 192 | .map(|it| { |
| 185 | 193 | let tag = it.kind.tag(); |
| 186 | let var_name = format!("{tag} {}", it.label); | |
| 187 | let mut buf = var_name; | |
| 188 | if let Some(ref label_detail) = it.label_detail { | |
| 189 | format_to!(buf, "{label_detail}"); | |
| 194 | let mut buf = format!("{tag} {}", it.label.primary); | |
| 195 | if let Some(label_detail) = &it.label.detail_left { | |
| 196 | format_to!(buf, " {label_detail}"); | |
| 190 | 197 | } |
| 191 | if let Some(detail) = it.detail { | |
| 192 | let width = label_width.saturating_sub( | |
| 193 | monospace_width(&it.label) | |
| 194 | + monospace_width(&it.label_detail.unwrap_or_default()), | |
| 198 | if let Some(detail_right) = it.label.detail_right { | |
| 199 | let pad_with = label_width.saturating_sub( | |
| 200 | monospace_width(&it.label.primary) | |
| 201 | + monospace_width(it.label.detail_left.as_deref().unwrap_or_default()) | |
| 202 | + monospace_width(&detail_right) | |
| 203 | + it.label.detail_left.is_some() as usize, | |
| 195 | 204 | ); |
| 196 | format_to!(buf, "{:width$} {}", "", detail, width = width); | |
| 205 | format_to!(buf, "{:pad_with$}{detail_right}", "",); | |
| 197 | 206 | } |
| 198 | 207 | if it.deprecated { |
| 199 | 208 | format_to!(buf, " DEPRECATED"); |
src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs+12-12| ... | ... | @@ -33,7 +33,7 @@ pub struct Foo(#[m$0] i32); |
| 33 | 33 | at cold |
| 34 | 34 | at deny(…) |
| 35 | 35 | at deprecated |
| 36 | at derive macro derive | |
| 36 | at derive macro derive | |
| 37 | 37 | at derive(…) |
| 38 | 38 | at doc = "…" |
| 39 | 39 | at doc(alias = "…") |
| ... | ... | @@ -367,9 +367,9 @@ struct Foo; |
| 367 | 367 | at cfg_attr(…) |
| 368 | 368 | at deny(…) |
| 369 | 369 | at deprecated |
| 370 | at derive macro derive | |
| 370 | at derive macro derive | |
| 371 | 371 | at derive(…) |
| 372 | at derive_const macro derive_const | |
| 372 | at derive_const macro derive_const | |
| 373 | 373 | at doc = "…" |
| 374 | 374 | at doc(alias = "…") |
| 375 | 375 | at doc(hidden) |
| ... | ... | @@ -790,10 +790,10 @@ mod derive { |
| 790 | 790 | #[derive($0)] struct Test; |
| 791 | 791 | "#, |
| 792 | 792 | expect![[r#" |
| 793 | de Clone macro Clone | |
| 793 | de Clone macro Clone | |
| 794 | 794 | de Clone, Copy |
| 795 | de Default macro Default | |
| 796 | de PartialEq macro PartialEq | |
| 795 | de Default macro Default | |
| 796 | de PartialEq macro PartialEq | |
| 797 | 797 | de PartialEq, Eq |
| 798 | 798 | de PartialEq, Eq, PartialOrd, Ord |
| 799 | 799 | de PartialEq, PartialOrd |
| ... | ... | @@ -812,9 +812,9 @@ mod derive { |
| 812 | 812 | #[derive(serde::Serialize, PartialEq, $0)] struct Test; |
| 813 | 813 | "#, |
| 814 | 814 | expect![[r#" |
| 815 | de Clone macro Clone | |
| 815 | de Clone macro Clone | |
| 816 | 816 | de Clone, Copy |
| 817 | de Default macro Default | |
| 817 | de Default macro Default | |
| 818 | 818 | de Eq |
| 819 | 819 | de Eq, PartialOrd, Ord |
| 820 | 820 | de PartialOrd |
| ... | ... | @@ -833,9 +833,9 @@ mod derive { |
| 833 | 833 | #[derive($0 serde::Serialize, PartialEq)] struct Test; |
| 834 | 834 | "#, |
| 835 | 835 | expect![[r#" |
| 836 | de Clone macro Clone | |
| 836 | de Clone macro Clone | |
| 837 | 837 | de Clone, Copy |
| 838 | de Default macro Default | |
| 838 | de Default macro Default | |
| 839 | 839 | de Eq |
| 840 | 840 | de Eq, PartialOrd, Ord |
| 841 | 841 | de PartialOrd |
| ... | ... | @@ -854,9 +854,9 @@ mod derive { |
| 854 | 854 | #[derive(PartialEq, Eq, Or$0)] struct Test; |
| 855 | 855 | "#, |
| 856 | 856 | expect![[r#" |
| 857 | de Clone macro Clone | |
| 857 | de Clone macro Clone | |
| 858 | 858 | de Clone, Copy |
| 859 | de Default macro Default | |
| 859 | de Default macro Default | |
| 860 | 860 | de PartialOrd |
| 861 | 861 | de PartialOrd, Ord |
| 862 | 862 | md core |
src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs+266-196| ... | ... | @@ -26,22 +26,22 @@ fn baz() { |
| 26 | 26 | "#, |
| 27 | 27 | // This should not contain `FooDesc {…}`. |
| 28 | 28 | expect![[r#" |
| 29 | ct CONST Unit | |
| 30 | en Enum Enum | |
| 31 | fn baz() fn() | |
| 32 | fn create_foo(…) fn(&FooDesc) | |
| 33 | fn function() fn() | |
| 34 | ma makro!(…) macro_rules! makro | |
| 29 | ct CONST Unit | |
| 30 | en Enum Enum | |
| 31 | fn baz() fn() | |
| 32 | fn create_foo(…) fn(&FooDesc) | |
| 33 | fn function() fn() | |
| 34 | ma makro!(…) macro_rules! makro | |
| 35 | 35 | md _69latrick |
| 36 | 36 | md module |
| 37 | sc STATIC Unit | |
| 38 | st FooDesc FooDesc | |
| 39 | st Record Record | |
| 40 | st Tuple Tuple | |
| 41 | st Unit Unit | |
| 42 | un Union Union | |
| 43 | ev TupleV(…) TupleV(u32) | |
| 44 | bt u32 u32 | |
| 37 | sc STATIC Unit | |
| 38 | st FooDesc FooDesc | |
| 39 | st Record Record | |
| 40 | st Tuple Tuple | |
| 41 | st Unit Unit | |
| 42 | un Union Union | |
| 43 | ev TupleV(…) TupleV(u32) | |
| 44 | bt u32 u32 | |
| 45 | 45 | kw crate:: |
| 46 | 46 | kw false |
| 47 | 47 | kw for |
| ... | ... | @@ -76,14 +76,14 @@ fn func(param0 @ (param1, param2): (i32, i32)) { |
| 76 | 76 | } |
| 77 | 77 | "#, |
| 78 | 78 | expect![[r#" |
| 79 | fn func(…) fn((i32, i32)) | |
| 80 | lc ifletlocal i32 | |
| 81 | lc letlocal i32 | |
| 82 | lc matcharm i32 | |
| 83 | lc param0 (i32, i32) | |
| 84 | lc param1 i32 | |
| 85 | lc param2 i32 | |
| 86 | bt u32 u32 | |
| 79 | fn func(…) fn((i32, i32)) | |
| 80 | lc ifletlocal i32 | |
| 81 | lc letlocal i32 | |
| 82 | lc matcharm i32 | |
| 83 | lc param0 (i32, i32) | |
| 84 | lc param1 i32 | |
| 85 | lc param2 i32 | |
| 86 | bt u32 u32 | |
| 87 | 87 | kw crate:: |
| 88 | 88 | kw false |
| 89 | 89 | kw for |
| ... | ... | @@ -122,25 +122,25 @@ impl Unit { |
| 122 | 122 | "#, |
| 123 | 123 | // `self` is in here twice, once as the module, once as the local |
| 124 | 124 | expect![[r#" |
| 125 | ct CONST Unit | |
| 125 | ct CONST Unit | |
| 126 | 126 | cp CONST_PARAM |
| 127 | en Enum Enum | |
| 128 | fn function() fn() | |
| 129 | fn local_func() fn() | |
| 130 | me self.foo() fn(self) | |
| 131 | lc self Unit | |
| 132 | ma makro!(…) macro_rules! makro | |
| 127 | en Enum Enum | |
| 128 | fn function() fn() | |
| 129 | fn local_func() fn() | |
| 130 | me self.foo() fn(self) | |
| 131 | lc self Unit | |
| 132 | ma makro!(…) macro_rules! makro | |
| 133 | 133 | md module |
| 134 | 134 | md qualified |
| 135 | sp Self Unit | |
| 136 | sc STATIC Unit | |
| 137 | st Record Record | |
| 138 | st Tuple Tuple | |
| 139 | st Unit Unit | |
| 135 | sp Self Unit | |
| 136 | sc STATIC Unit | |
| 137 | st Record Record | |
| 138 | st Tuple Tuple | |
| 139 | st Unit Unit | |
| 140 | 140 | tp TypeParam |
| 141 | un Union Union | |
| 142 | ev TupleV(…) TupleV(u32) | |
| 143 | bt u32 u32 | |
| 141 | un Union Union | |
| 142 | ev TupleV(…) TupleV(u32) | |
| 143 | bt u32 u32 | |
| 144 | 144 | kw async |
| 145 | 145 | kw const |
| 146 | 146 | kw crate:: |
| ... | ... | @@ -187,19 +187,19 @@ impl Unit { |
| 187 | 187 | } |
| 188 | 188 | "#, |
| 189 | 189 | expect![[r#" |
| 190 | ct CONST Unit | |
| 191 | en Enum Enum | |
| 192 | fn function() fn() | |
| 193 | ma makro!(…) macro_rules! makro | |
| 190 | ct CONST Unit | |
| 191 | en Enum Enum | |
| 192 | fn function() fn() | |
| 193 | ma makro!(…) macro_rules! makro | |
| 194 | 194 | md module |
| 195 | 195 | md qualified |
| 196 | sc STATIC Unit | |
| 197 | st Record Record | |
| 198 | st Tuple Tuple | |
| 199 | st Unit Unit | |
| 196 | sc STATIC Unit | |
| 197 | st Record Record | |
| 198 | st Tuple Tuple | |
| 199 | st Unit Unit | |
| 200 | 200 | tt Trait |
| 201 | un Union Union | |
| 202 | ev TupleV(…) TupleV(u32) | |
| 201 | un Union Union | |
| 202 | ev TupleV(…) TupleV(u32) | |
| 203 | 203 | ?? Unresolved |
| 204 | 204 | "#]], |
| 205 | 205 | ); |
| ... | ... | @@ -216,8 +216,8 @@ fn complete_in_block() { |
| 216 | 216 | } |
| 217 | 217 | "#, |
| 218 | 218 | expect![[r#" |
| 219 | fn foo() fn() | |
| 220 | bt u32 u32 | |
| 219 | fn foo() fn() | |
| 220 | bt u32 u32 | |
| 221 | 221 | kw async |
| 222 | 222 | kw const |
| 223 | 223 | kw crate:: |
| ... | ... | @@ -264,8 +264,8 @@ fn complete_after_if_expr() { |
| 264 | 264 | } |
| 265 | 265 | "#, |
| 266 | 266 | expect![[r#" |
| 267 | fn foo() fn() | |
| 268 | bt u32 u32 | |
| 267 | fn foo() fn() | |
| 268 | bt u32 u32 | |
| 269 | 269 | kw async |
| 270 | 270 | kw const |
| 271 | 271 | kw crate:: |
| ... | ... | @@ -313,8 +313,8 @@ fn complete_in_match_arm() { |
| 313 | 313 | } |
| 314 | 314 | "#, |
| 315 | 315 | expect![[r#" |
| 316 | fn foo() fn() | |
| 317 | bt u32 u32 | |
| 316 | fn foo() fn() | |
| 317 | bt u32 u32 | |
| 318 | 318 | kw crate:: |
| 319 | 319 | kw false |
| 320 | 320 | kw for |
| ... | ... | @@ -337,8 +337,8 @@ fn completes_in_loop_ctx() { |
| 337 | 337 | check_empty( |
| 338 | 338 | r"fn my() { loop { $0 } }", |
| 339 | 339 | expect![[r#" |
| 340 | fn my() fn() | |
| 341 | bt u32 u32 | |
| 340 | fn my() fn() | |
| 341 | bt u32 u32 | |
| 342 | 342 | kw async |
| 343 | 343 | kw break |
| 344 | 344 | kw const |
| ... | ... | @@ -376,22 +376,22 @@ fn completes_in_loop_ctx() { |
| 376 | 376 | check_empty( |
| 377 | 377 | r"fn my() { loop { foo.$0 } }", |
| 378 | 378 | expect![[r#" |
| 379 | sn box Box::new(expr) | |
| 380 | sn break break expr | |
| 381 | sn call function(expr) | |
| 382 | sn dbg dbg!(expr) | |
| 383 | sn dbgr dbg!(&expr) | |
| 384 | sn deref *expr | |
| 385 | sn if if expr {} | |
| 386 | sn let let | |
| 387 | sn letm let mut | |
| 388 | sn match match expr {} | |
| 389 | sn not !expr | |
| 390 | sn ref &expr | |
| 391 | sn refm &mut expr | |
| 392 | sn return return expr | |
| 393 | sn unsafe unsafe {} | |
| 394 | sn while while expr {} | |
| 379 | sn box Box::new(expr) | |
| 380 | sn break break expr | |
| 381 | sn call function(expr) | |
| 382 | sn dbg dbg!(expr) | |
| 383 | sn dbgr dbg!(&expr) | |
| 384 | sn deref *expr | |
| 385 | sn if if expr {} | |
| 386 | sn let let | |
| 387 | sn letm let mut | |
| 388 | sn match match expr {} | |
| 389 | sn not !expr | |
| 390 | sn ref &expr | |
| 391 | sn refm &mut expr | |
| 392 | sn return return expr | |
| 393 | sn unsafe unsafe {} | |
| 394 | sn while while expr {} | |
| 395 | 395 | "#]], |
| 396 | 396 | ); |
| 397 | 397 | } |
| ... | ... | @@ -401,8 +401,8 @@ fn completes_in_let_initializer() { |
| 401 | 401 | check_empty( |
| 402 | 402 | r#"fn main() { let _ = $0 }"#, |
| 403 | 403 | expect![[r#" |
| 404 | fn main() fn() | |
| 405 | bt u32 u32 | |
| 404 | fn main() fn() | |
| 405 | bt u32 u32 | |
| 406 | 406 | kw crate:: |
| 407 | 407 | kw false |
| 408 | 408 | kw for |
| ... | ... | @@ -434,9 +434,9 @@ fn foo() { |
| 434 | 434 | } |
| 435 | 435 | "#, |
| 436 | 436 | expect![[r#" |
| 437 | fn foo() fn() | |
| 438 | st Foo Foo | |
| 439 | bt u32 u32 | |
| 437 | fn foo() fn() | |
| 438 | st Foo Foo | |
| 439 | bt u32 u32 | |
| 440 | 440 | kw crate:: |
| 441 | 441 | kw false |
| 442 | 442 | kw for |
| ... | ... | @@ -469,9 +469,9 @@ fn foo() { |
| 469 | 469 | } |
| 470 | 470 | "#, |
| 471 | 471 | expect![[r#" |
| 472 | fn foo() fn() | |
| 473 | lc bar i32 | |
| 474 | bt u32 u32 | |
| 472 | fn foo() fn() | |
| 473 | lc bar i32 | |
| 474 | bt u32 u32 | |
| 475 | 475 | kw crate:: |
| 476 | 476 | kw false |
| 477 | 477 | kw for |
| ... | ... | @@ -499,10 +499,10 @@ fn quux(x: i32) { |
| 499 | 499 | } |
| 500 | 500 | "#, |
| 501 | 501 | expect![[r#" |
| 502 | fn quux(…) fn(i32) | |
| 503 | lc x i32 | |
| 504 | ma m!(…) macro_rules! m | |
| 505 | bt u32 u32 | |
| 502 | fn quux(…) fn(i32) | |
| 503 | lc x i32 | |
| 504 | ma m!(…) macro_rules! m | |
| 505 | bt u32 u32 | |
| 506 | 506 | kw crate:: |
| 507 | 507 | kw false |
| 508 | 508 | kw for |
| ... | ... | @@ -526,10 +526,10 @@ fn quux(x: i32) { |
| 526 | 526 | } |
| 527 | 527 | ", |
| 528 | 528 | expect![[r#" |
| 529 | fn quux(…) fn(i32) | |
| 530 | lc x i32 | |
| 531 | ma m!(…) macro_rules! m | |
| 532 | bt u32 u32 | |
| 529 | fn quux(…) fn(i32) | |
| 530 | lc x i32 | |
| 531 | ma m!(…) macro_rules! m | |
| 532 | bt u32 u32 | |
| 533 | 533 | kw crate:: |
| 534 | 534 | kw false |
| 535 | 535 | kw for |
| ... | ... | @@ -554,11 +554,11 @@ fn quux(x: i32) { |
| 554 | 554 | } |
| 555 | 555 | "#, |
| 556 | 556 | expect![[r#" |
| 557 | fn quux(…) fn(i32) | |
| 558 | lc x i32 | |
| 559 | lc y i32 | |
| 560 | ma m!(…) macro_rules! m | |
| 561 | bt u32 u32 | |
| 557 | fn quux(…) fn(i32) | |
| 558 | lc x i32 | |
| 559 | lc y i32 | |
| 560 | ma m!(…) macro_rules! m | |
| 561 | bt u32 u32 | |
| 562 | 562 | kw crate:: |
| 563 | 563 | kw false |
| 564 | 564 | kw for |
| ... | ... | @@ -590,12 +590,12 @@ fn func() { |
| 590 | 590 | } |
| 591 | 591 | "#, |
| 592 | 592 | expect![[r#" |
| 593 | ct ASSOC_CONST const ASSOC_CONST: () | |
| 594 | fn assoc_fn() fn() | |
| 595 | ta AssocType type AssocType = () | |
| 593 | ct ASSOC_CONST const ASSOC_CONST: () | |
| 594 | fn assoc_fn() fn() | |
| 595 | ta AssocType type AssocType = () | |
| 596 | 596 | ev RecordV {…} RecordV { field: u32 } |
| 597 | ev TupleV(…) TupleV(u32) | |
| 598 | ev UnitV UnitV | |
| 597 | ev TupleV(…) TupleV(u32) | |
| 598 | ev UnitV UnitV | |
| 599 | 599 | "#]], |
| 600 | 600 | ); |
| 601 | 601 | } |
| ... | ... | @@ -633,7 +633,7 @@ fn func() { |
| 633 | 633 | "#, |
| 634 | 634 | expect![[r#" |
| 635 | 635 | fn variant fn() -> Enum |
| 636 | ev Variant Variant | |
| 636 | ev Variant Variant | |
| 637 | 637 | "#]], |
| 638 | 638 | ); |
| 639 | 639 | } |
| ... | ... | @@ -650,8 +650,8 @@ fn main() { |
| 650 | 650 | } |
| 651 | 651 | ", |
| 652 | 652 | expect![[r#" |
| 653 | fn foo() fn() -> impl Trait<U> | |
| 654 | fn main() fn() | |
| 653 | fn foo() fn() -> impl Trait<U> | |
| 654 | fn main() fn() | |
| 655 | 655 | tt Trait |
| 656 | 656 | "#]], |
| 657 | 657 | ); |
| ... | ... | @@ -670,9 +670,9 @@ fn main() { |
| 670 | 670 | } |
| 671 | 671 | "#, |
| 672 | 672 | expect![[r#" |
| 673 | fn bar() async fn() -> impl Trait<U> | |
| 674 | fn foo() async fn() -> u8 | |
| 675 | fn main() fn() | |
| 673 | fn bar() async fn() -> impl Trait<U> | |
| 674 | fn foo() async fn() -> u8 | |
| 675 | fn main() fn() | |
| 676 | 676 | tt Trait |
| 677 | 677 | "#]], |
| 678 | 678 | ); |
| ... | ... | @@ -692,9 +692,9 @@ fn main() { |
| 692 | 692 | Foo::$0 |
| 693 | 693 | } |
| 694 | 694 | ", |
| 695 | expect![[r" | |
| 695 | expect![[r#" | |
| 696 | 696 | fn bar(…) fn(impl Trait<U>) |
| 697 | "]], | |
| 697 | "#]], | |
| 698 | 698 | ); |
| 699 | 699 | } |
| 700 | 700 | |
| ... | ... | @@ -712,7 +712,7 @@ fn main() { |
| 712 | 712 | } |
| 713 | 713 | "#, |
| 714 | 714 | expect![[r#" |
| 715 | fn test() fn() -> Zulu | |
| 715 | fn test() fn() -> Zulu | |
| 716 | 716 | ex Zulu |
| 717 | 717 | ex Zulu::test() |
| 718 | 718 | "#]], |
| ... | ... | @@ -736,11 +736,11 @@ fn brr() { |
| 736 | 736 | } |
| 737 | 737 | "#, |
| 738 | 738 | expect![[r#" |
| 739 | en HH HH | |
| 740 | fn brr() fn() | |
| 741 | st YoloVariant YoloVariant | |
| 739 | en HH HH | |
| 740 | fn brr() fn() | |
| 741 | st YoloVariant YoloVariant | |
| 742 | 742 | st YoloVariant {…} YoloVariant { f: usize } |
| 743 | bt u32 u32 | |
| 743 | bt u32 u32 | |
| 744 | 744 | kw crate:: |
| 745 | 745 | kw false |
| 746 | 746 | kw for |
| ... | ... | @@ -801,8 +801,8 @@ fn else_completion_after_if() { |
| 801 | 801 | fn foo() { if foo {} $0 } |
| 802 | 802 | "#, |
| 803 | 803 | expect![[r#" |
| 804 | fn foo() fn() | |
| 805 | bt u32 u32 | |
| 804 | fn foo() fn() | |
| 805 | bt u32 u32 | |
| 806 | 806 | kw async |
| 807 | 807 | kw const |
| 808 | 808 | kw crate:: |
| ... | ... | @@ -842,8 +842,8 @@ fn foo() { if foo {} $0 } |
| 842 | 842 | fn foo() { if foo {} el$0 } |
| 843 | 843 | "#, |
| 844 | 844 | expect![[r#" |
| 845 | fn foo() fn() | |
| 846 | bt u32 u32 | |
| 845 | fn foo() fn() | |
| 846 | bt u32 u32 | |
| 847 | 847 | kw async |
| 848 | 848 | kw const |
| 849 | 849 | kw crate:: |
| ... | ... | @@ -883,8 +883,8 @@ fn foo() { if foo {} el$0 } |
| 883 | 883 | fn foo() { bar(if foo {} $0) } |
| 884 | 884 | "#, |
| 885 | 885 | expect![[r#" |
| 886 | fn foo() fn() | |
| 887 | bt u32 u32 | |
| 886 | fn foo() fn() | |
| 887 | bt u32 u32 | |
| 888 | 888 | kw crate:: |
| 889 | 889 | kw else |
| 890 | 890 | kw else if |
| ... | ... | @@ -907,8 +907,8 @@ fn foo() { bar(if foo {} $0) } |
| 907 | 907 | fn foo() { bar(if foo {} el$0) } |
| 908 | 908 | "#, |
| 909 | 909 | expect![[r#" |
| 910 | fn foo() fn() | |
| 911 | bt u32 u32 | |
| 910 | fn foo() fn() | |
| 911 | bt u32 u32 | |
| 912 | 912 | kw crate:: |
| 913 | 913 | kw else |
| 914 | 914 | kw else if |
| ... | ... | @@ -931,8 +931,8 @@ fn foo() { bar(if foo {} el$0) } |
| 931 | 931 | fn foo() { if foo {} $0 let x = 92; } |
| 932 | 932 | "#, |
| 933 | 933 | expect![[r#" |
| 934 | fn foo() fn() | |
| 935 | bt u32 u32 | |
| 934 | fn foo() fn() | |
| 935 | bt u32 u32 | |
| 936 | 936 | kw async |
| 937 | 937 | kw const |
| 938 | 938 | kw crate:: |
| ... | ... | @@ -972,8 +972,8 @@ fn foo() { if foo {} $0 let x = 92; } |
| 972 | 972 | fn foo() { if foo {} el$0 let x = 92; } |
| 973 | 973 | "#, |
| 974 | 974 | expect![[r#" |
| 975 | fn foo() fn() | |
| 976 | bt u32 u32 | |
| 975 | fn foo() fn() | |
| 976 | bt u32 u32 | |
| 977 | 977 | kw async |
| 978 | 978 | kw const |
| 979 | 979 | kw crate:: |
| ... | ... | @@ -1013,8 +1013,8 @@ fn foo() { if foo {} el$0 let x = 92; } |
| 1013 | 1013 | fn foo() { if foo {} el$0 { let x = 92; } } |
| 1014 | 1014 | "#, |
| 1015 | 1015 | expect![[r#" |
| 1016 | fn foo() fn() | |
| 1017 | bt u32 u32 | |
| 1016 | fn foo() fn() | |
| 1017 | bt u32 u32 | |
| 1018 | 1018 | kw async |
| 1019 | 1019 | kw const |
| 1020 | 1020 | kw crate:: |
| ... | ... | @@ -1065,9 +1065,9 @@ fn main() { |
| 1065 | 1065 | pub struct UnstableThisShouldNotBeListed; |
| 1066 | 1066 | "#, |
| 1067 | 1067 | expect![[r#" |
| 1068 | fn main() fn() | |
| 1068 | fn main() fn() | |
| 1069 | 1069 | md std |
| 1070 | bt u32 u32 | |
| 1070 | bt u32 u32 | |
| 1071 | 1071 | kw async |
| 1072 | 1072 | kw const |
| 1073 | 1073 | kw crate:: |
| ... | ... | @@ -1117,10 +1117,10 @@ fn main() { |
| 1117 | 1117 | pub struct UnstableButWeAreOnNightlyAnyway; |
| 1118 | 1118 | "#, |
| 1119 | 1119 | expect![[r#" |
| 1120 | fn main() fn() | |
| 1120 | fn main() fn() | |
| 1121 | 1121 | md std |
| 1122 | 1122 | st UnstableButWeAreOnNightlyAnyway UnstableButWeAreOnNightlyAnyway |
| 1123 | bt u32 u32 | |
| 1123 | bt u32 u32 | |
| 1124 | 1124 | kw async |
| 1125 | 1125 | kw const |
| 1126 | 1126 | kw crate:: |
| ... | ... | @@ -1170,17 +1170,17 @@ fn main() { |
| 1170 | 1170 | } |
| 1171 | 1171 | "#, |
| 1172 | 1172 | expect![[r#" |
| 1173 | me foo() fn(&self) | |
| 1174 | sn box Box::new(expr) | |
| 1175 | sn call function(expr) | |
| 1176 | sn dbg dbg!(expr) | |
| 1177 | sn dbgr dbg!(&expr) | |
| 1178 | sn deref *expr | |
| 1179 | sn match match expr {} | |
| 1180 | sn ref &expr | |
| 1181 | sn refm &mut expr | |
| 1182 | sn return return expr | |
| 1183 | sn unsafe unsafe {} | |
| 1173 | me foo() fn(&self) | |
| 1174 | sn box Box::new(expr) | |
| 1175 | sn call function(expr) | |
| 1176 | sn dbg dbg!(expr) | |
| 1177 | sn dbgr dbg!(&expr) | |
| 1178 | sn deref *expr | |
| 1179 | sn match match expr {} | |
| 1180 | sn ref &expr | |
| 1181 | sn refm &mut expr | |
| 1182 | sn return return expr | |
| 1183 | sn unsafe unsafe {} | |
| 1184 | 1184 | "#]], |
| 1185 | 1185 | ); |
| 1186 | 1186 | check_empty( |
| ... | ... | @@ -1196,17 +1196,17 @@ fn main() { |
| 1196 | 1196 | } |
| 1197 | 1197 | "#, |
| 1198 | 1198 | expect![[r#" |
| 1199 | me foo() fn(&self) | |
| 1200 | sn box Box::new(expr) | |
| 1201 | sn call function(expr) | |
| 1202 | sn dbg dbg!(expr) | |
| 1203 | sn dbgr dbg!(&expr) | |
| 1204 | sn deref *expr | |
| 1205 | sn match match expr {} | |
| 1206 | sn ref &expr | |
| 1207 | sn refm &mut expr | |
| 1208 | sn return return expr | |
| 1209 | sn unsafe unsafe {} | |
| 1199 | me foo() fn(&self) | |
| 1200 | sn box Box::new(expr) | |
| 1201 | sn call function(expr) | |
| 1202 | sn dbg dbg!(expr) | |
| 1203 | sn dbgr dbg!(&expr) | |
| 1204 | sn deref *expr | |
| 1205 | sn match match expr {} | |
| 1206 | sn ref &expr | |
| 1207 | sn refm &mut expr | |
| 1208 | sn return return expr | |
| 1209 | sn unsafe unsafe {} | |
| 1210 | 1210 | "#]], |
| 1211 | 1211 | ); |
| 1212 | 1212 | } |
| ... | ... | @@ -1226,17 +1226,17 @@ fn main() { |
| 1226 | 1226 | } |
| 1227 | 1227 | "#, |
| 1228 | 1228 | expect![[r#" |
| 1229 | me foo() fn(&self) | |
| 1230 | sn box Box::new(expr) | |
| 1231 | sn call function(expr) | |
| 1232 | sn dbg dbg!(expr) | |
| 1233 | sn dbgr dbg!(&expr) | |
| 1234 | sn deref *expr | |
| 1235 | sn match match expr {} | |
| 1236 | sn ref &expr | |
| 1237 | sn refm &mut expr | |
| 1238 | sn return return expr | |
| 1239 | sn unsafe unsafe {} | |
| 1229 | me foo() fn(&self) | |
| 1230 | sn box Box::new(expr) | |
| 1231 | sn call function(expr) | |
| 1232 | sn dbg dbg!(expr) | |
| 1233 | sn dbgr dbg!(&expr) | |
| 1234 | sn deref *expr | |
| 1235 | sn match match expr {} | |
| 1236 | sn ref &expr | |
| 1237 | sn refm &mut expr | |
| 1238 | sn return return expr | |
| 1239 | sn unsafe unsafe {} | |
| 1240 | 1240 | "#]], |
| 1241 | 1241 | ); |
| 1242 | 1242 | check_empty( |
| ... | ... | @@ -1252,17 +1252,17 @@ fn main() { |
| 1252 | 1252 | } |
| 1253 | 1253 | "#, |
| 1254 | 1254 | expect![[r#" |
| 1255 | me foo() fn(&self) | |
| 1256 | sn box Box::new(expr) | |
| 1257 | sn call function(expr) | |
| 1258 | sn dbg dbg!(expr) | |
| 1259 | sn dbgr dbg!(&expr) | |
| 1260 | sn deref *expr | |
| 1261 | sn match match expr {} | |
| 1262 | sn ref &expr | |
| 1263 | sn refm &mut expr | |
| 1264 | sn return return expr | |
| 1265 | sn unsafe unsafe {} | |
| 1255 | me foo() fn(&self) | |
| 1256 | sn box Box::new(expr) | |
| 1257 | sn call function(expr) | |
| 1258 | sn dbg dbg!(expr) | |
| 1259 | sn dbgr dbg!(&expr) | |
| 1260 | sn deref *expr | |
| 1261 | sn match match expr {} | |
| 1262 | sn ref &expr | |
| 1263 | sn refm &mut expr | |
| 1264 | sn return return expr | |
| 1265 | sn unsafe unsafe {} | |
| 1266 | 1266 | "#]], |
| 1267 | 1267 | ); |
| 1268 | 1268 | check_empty( |
| ... | ... | @@ -1278,17 +1278,17 @@ fn main() { |
| 1278 | 1278 | } |
| 1279 | 1279 | "#, |
| 1280 | 1280 | expect![[r#" |
| 1281 | me foo() fn(&self) | |
| 1282 | sn box Box::new(expr) | |
| 1283 | sn call function(expr) | |
| 1284 | sn dbg dbg!(expr) | |
| 1285 | sn dbgr dbg!(&expr) | |
| 1286 | sn deref *expr | |
| 1287 | sn match match expr {} | |
| 1288 | sn ref &expr | |
| 1289 | sn refm &mut expr | |
| 1290 | sn return return expr | |
| 1291 | sn unsafe unsafe {} | |
| 1281 | me foo() fn(&self) | |
| 1282 | sn box Box::new(expr) | |
| 1283 | sn call function(expr) | |
| 1284 | sn dbg dbg!(expr) | |
| 1285 | sn dbgr dbg!(&expr) | |
| 1286 | sn deref *expr | |
| 1287 | sn match match expr {} | |
| 1288 | sn ref &expr | |
| 1289 | sn refm &mut expr | |
| 1290 | sn return return expr | |
| 1291 | sn unsafe unsafe {} | |
| 1292 | 1292 | "#]], |
| 1293 | 1293 | ); |
| 1294 | 1294 | check_empty( |
| ... | ... | @@ -1304,19 +1304,89 @@ fn main() { |
| 1304 | 1304 | } |
| 1305 | 1305 | "#, |
| 1306 | 1306 | expect![[r#" |
| 1307 | sn box Box::new(expr) | |
| 1308 | sn call function(expr) | |
| 1309 | sn dbg dbg!(expr) | |
| 1310 | sn dbgr dbg!(&expr) | |
| 1311 | sn deref *expr | |
| 1312 | sn if if expr {} | |
| 1313 | sn match match expr {} | |
| 1314 | sn not !expr | |
| 1315 | sn ref &expr | |
| 1316 | sn refm &mut expr | |
| 1317 | sn return return expr | |
| 1318 | sn unsafe unsafe {} | |
| 1319 | sn while while expr {} | |
| 1307 | sn box Box::new(expr) | |
| 1308 | sn call function(expr) | |
| 1309 | sn dbg dbg!(expr) | |
| 1310 | sn dbgr dbg!(&expr) | |
| 1311 | sn deref *expr | |
| 1312 | sn if if expr {} | |
| 1313 | sn match match expr {} | |
| 1314 | sn not !expr | |
| 1315 | sn ref &expr | |
| 1316 | sn refm &mut expr | |
| 1317 | sn return return expr | |
| 1318 | sn unsafe unsafe {} | |
| 1319 | sn while while expr {} | |
| 1320 | "#]], | |
| 1321 | ); | |
| 1322 | } | |
| 1323 | ||
| 1324 | #[test] | |
| 1325 | fn macro_that_ignores_completion_marker() { | |
| 1326 | check( | |
| 1327 | r#" | |
| 1328 | macro_rules! helper { | |
| 1329 | ($v:ident) => {}; | |
| 1330 | } | |
| 1331 | ||
| 1332 | macro_rules! m { | |
| 1333 | ($v:ident) => {{ | |
| 1334 | helper!($v); | |
| 1335 | $v | |
| 1336 | }}; | |
| 1337 | } | |
| 1338 | ||
| 1339 | fn main() { | |
| 1340 | let variable = "test"; | |
| 1341 | m!(v$0); | |
| 1342 | } | |
| 1343 | "#, | |
| 1344 | expect![[r#" | |
| 1345 | ct CONST Unit | |
| 1346 | en Enum Enum | |
| 1347 | fn function() fn() | |
| 1348 | fn main() fn() | |
| 1349 | lc variable &str | |
| 1350 | ma helper!(…) macro_rules! helper | |
| 1351 | ma m!(…) macro_rules! m | |
| 1352 | ma makro!(…) macro_rules! makro | |
| 1353 | md module | |
| 1354 | sc STATIC Unit | |
| 1355 | st Record Record | |
| 1356 | st Tuple Tuple | |
| 1357 | st Unit Unit | |
| 1358 | un Union Union | |
| 1359 | ev TupleV(…) TupleV(u32) | |
| 1360 | bt u32 u32 | |
| 1361 | kw async | |
| 1362 | kw const | |
| 1363 | kw crate:: | |
| 1364 | kw enum | |
| 1365 | kw extern | |
| 1366 | kw false | |
| 1367 | kw fn | |
| 1368 | kw for | |
| 1369 | kw if | |
| 1370 | kw if let | |
| 1371 | kw impl | |
| 1372 | kw let | |
| 1373 | kw loop | |
| 1374 | kw match | |
| 1375 | kw mod | |
| 1376 | kw self:: | |
| 1377 | kw static | |
| 1378 | kw struct | |
| 1379 | kw trait | |
| 1380 | kw true | |
| 1381 | kw type | |
| 1382 | kw union | |
| 1383 | kw unsafe | |
| 1384 | kw use | |
| 1385 | kw while | |
| 1386 | kw while let | |
| 1387 | sn macro_rules | |
| 1388 | sn pd | |
| 1389 | sn ppd | |
| 1320 | 1390 | "#]], |
| 1321 | 1391 | ); |
| 1322 | 1392 | } |
src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs+74-32| ... | ... | @@ -139,9 +139,9 @@ fn main() { |
| 139 | 139 | } |
| 140 | 140 | "#, |
| 141 | 141 | expect![[r#" |
| 142 | st Rc (use dep::Rc) Rc | |
| 143 | st Rcar (use dep::Rcar) Rcar | |
| 144 | st Rc (use dep::some_module::Rc) Rc | |
| 142 | st Rc (use dep::Rc) Rc | |
| 143 | st Rcar (use dep::Rcar) Rcar | |
| 144 | st Rc (use dep::some_module::Rc) Rc | |
| 145 | 145 | st Rcar (use dep::some_module::Rcar) Rcar |
| 146 | 146 | "#]], |
| 147 | 147 | ); |
| ... | ... | @@ -165,11 +165,11 @@ fn main() { |
| 165 | 165 | } |
| 166 | 166 | "#, |
| 167 | 167 | expect![[r#" |
| 168 | ct RC (use dep::RC) () | |
| 169 | st Rc (use dep::Rc) Rc | |
| 170 | st Rcar (use dep::Rcar) Rcar | |
| 171 | ct RC (use dep::some_module::RC) () | |
| 172 | st Rc (use dep::some_module::Rc) Rc | |
| 168 | ct RC (use dep::RC) () | |
| 169 | st Rc (use dep::Rc) Rc | |
| 170 | st Rcar (use dep::Rcar) Rcar | |
| 171 | ct RC (use dep::some_module::RC) () | |
| 172 | st Rc (use dep::some_module::Rc) Rc | |
| 173 | 173 | st Rcar (use dep::some_module::Rcar) Rcar |
| 174 | 174 | "#]], |
| 175 | 175 | ); |
| ... | ... | @@ -193,7 +193,7 @@ fn main() { |
| 193 | 193 | } |
| 194 | 194 | "#, |
| 195 | 195 | expect![[r#" |
| 196 | ct RC (use dep::RC) () | |
| 196 | ct RC (use dep::RC) () | |
| 197 | 197 | ct RC (use dep::some_module::RC) () |
| 198 | 198 | "#]], |
| 199 | 199 | ); |
| ... | ... | @@ -227,7 +227,7 @@ fn main() { |
| 227 | 227 | } |
| 228 | 228 | "#, |
| 229 | 229 | expect![[r#" |
| 230 | st ThirdStruct (use dep::some_module::ThirdStruct) ThirdStruct | |
| 230 | st ThirdStruct (use dep::some_module::ThirdStruct) ThirdStruct | |
| 231 | 231 | st AfterThirdStruct (use dep::some_module::AfterThirdStruct) AfterThirdStruct |
| 232 | 232 | st ThiiiiiirdStruct (use dep::some_module::ThiiiiiirdStruct) ThiiiiiirdStruct |
| 233 | 233 | "#]], |
| ... | ... | @@ -263,8 +263,8 @@ fn trait_function_fuzzy_completion() { |
| 263 | 263 | check( |
| 264 | 264 | fixture, |
| 265 | 265 | expect![[r#" |
| 266 | fn weird_function() (use dep::test_mod::TestTrait) fn() | |
| 267 | "#]], | |
| 266 | fn weird_function() (use dep::test_mod::TestTrait) fn() | |
| 267 | "#]], | |
| 268 | 268 | ); |
| 269 | 269 | |
| 270 | 270 | check_edit( |
| ... | ... | @@ -356,8 +356,8 @@ fn trait_method_fuzzy_completion() { |
| 356 | 356 | check( |
| 357 | 357 | fixture, |
| 358 | 358 | expect![[r#" |
| 359 | me random_method() (use dep::test_mod::TestTrait) fn(&self) | |
| 360 | "#]], | |
| 359 | me random_method() (use dep::test_mod::TestTrait) fn(&self) | |
| 360 | "#]], | |
| 361 | 361 | ); |
| 362 | 362 | |
| 363 | 363 | check_edit( |
| ... | ... | @@ -401,8 +401,8 @@ fn main() { |
| 401 | 401 | check( |
| 402 | 402 | fixture, |
| 403 | 403 | expect![[r#" |
| 404 | me some_method() (use foo::TestTrait) fn(&self) | |
| 405 | "#]], | |
| 404 | me some_method() (use foo::TestTrait) fn(&self) | |
| 405 | "#]], | |
| 406 | 406 | ); |
| 407 | 407 | |
| 408 | 408 | check_edit( |
| ... | ... | @@ -448,8 +448,8 @@ fn main() { |
| 448 | 448 | check( |
| 449 | 449 | fixture, |
| 450 | 450 | expect![[r#" |
| 451 | me some_method() (use foo::TestTrait) fn(&self) | |
| 452 | "#]], | |
| 451 | me some_method() (use foo::TestTrait) fn(&self) | |
| 452 | "#]], | |
| 453 | 453 | ); |
| 454 | 454 | |
| 455 | 455 | check_edit( |
| ... | ... | @@ -496,8 +496,8 @@ fn completion<T: Wrapper>(whatever: T) { |
| 496 | 496 | check( |
| 497 | 497 | fixture, |
| 498 | 498 | expect![[r#" |
| 499 | me not_in_scope() (use foo::NotInScope) fn(&self) | |
| 500 | "#]], | |
| 499 | me not_in_scope() (use foo::NotInScope) fn(&self) | |
| 500 | "#]], | |
| 501 | 501 | ); |
| 502 | 502 | |
| 503 | 503 | check_edit( |
| ... | ... | @@ -539,8 +539,8 @@ fn main() { |
| 539 | 539 | check( |
| 540 | 540 | fixture, |
| 541 | 541 | expect![[r#" |
| 542 | me into() (use test_trait::TestInto) fn(self) -> T | |
| 543 | "#]], | |
| 542 | me into() (use test_trait::TestInto) fn(self) -> T | |
| 543 | "#]], | |
| 544 | 544 | ); |
| 545 | 545 | } |
| 546 | 546 | |
| ... | ... | @@ -568,8 +568,8 @@ fn main() { |
| 568 | 568 | check( |
| 569 | 569 | fixture, |
| 570 | 570 | expect![[r#" |
| 571 | fn random_method() (use dep::test_mod::TestTrait) fn() | |
| 572 | "#]], | |
| 571 | fn random_method() (use dep::test_mod::TestTrait) fn() | |
| 572 | "#]], | |
| 573 | 573 | ); |
| 574 | 574 | |
| 575 | 575 | check_edit( |
| ... | ... | @@ -737,8 +737,8 @@ fn main() { |
| 737 | 737 | } |
| 738 | 738 | "#, |
| 739 | 739 | expect![[r#" |
| 740 | me random_method() (use dep::test_mod::TestTrait) fn(&self) DEPRECATED | |
| 741 | "#]], | |
| 740 | me random_method() (use dep::test_mod::TestTrait) fn(&self) DEPRECATED | |
| 741 | "#]], | |
| 742 | 742 | ); |
| 743 | 743 | |
| 744 | 744 | check( |
| ... | ... | @@ -767,8 +767,8 @@ fn main() { |
| 767 | 767 | } |
| 768 | 768 | "#, |
| 769 | 769 | expect![[r#" |
| 770 | ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED | |
| 771 | fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED | |
| 770 | ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED | |
| 771 | fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED | |
| 772 | 772 | me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED |
| 773 | 773 | "#]], |
| 774 | 774 | ); |
| ... | ... | @@ -1117,7 +1117,7 @@ fn main() { |
| 1117 | 1117 | tes$0 |
| 1118 | 1118 | }"#, |
| 1119 | 1119 | expect![[r#" |
| 1120 | ct TEST_CONST (use foo::TEST_CONST) usize | |
| 1120 | ct TEST_CONST (use foo::TEST_CONST) usize | |
| 1121 | 1121 | fn test_function() (use foo::test_function) fn() -> i32 |
| 1122 | 1122 | "#]], |
| 1123 | 1123 | ); |
| ... | ... | @@ -1175,8 +1175,8 @@ fn main() { |
| 1175 | 1175 | } |
| 1176 | 1176 | "#, |
| 1177 | 1177 | expect![[r#" |
| 1178 | fn some_fn() (use m::some_fn) fn() -> i32 | |
| 1179 | "#]], | |
| 1178 | fn some_fn() (use m::some_fn) fn() -> i32 | |
| 1179 | "#]], | |
| 1180 | 1180 | ); |
| 1181 | 1181 | } |
| 1182 | 1182 | |
| ... | ... | @@ -1691,7 +1691,7 @@ fn function() { |
| 1691 | 1691 | expect![[r#" |
| 1692 | 1692 | st FooStruct (use outer::FooStruct) BarStruct |
| 1693 | 1693 | md foo (use outer::foo) |
| 1694 | fn foo_fun() (use outer::foo_fun) fn() | |
| 1694 | fn foo_fun() (use outer::foo_fun) fn() | |
| 1695 | 1695 | "#]], |
| 1696 | 1696 | ); |
| 1697 | 1697 | } |
| ... | ... | @@ -1720,3 +1720,45 @@ fn function() { |
| 1720 | 1720 | "#]], |
| 1721 | 1721 | ); |
| 1722 | 1722 | } |
| 1723 | ||
| 1724 | #[test] | |
| 1725 | fn intrinsics() { | |
| 1726 | check( | |
| 1727 | r#" | |
| 1728 | //- /core.rs crate:core | |
| 1729 | pub mod intrinsics { | |
| 1730 | extern "rust-intrinsic" { | |
| 1731 | pub fn transmute<Src, Dst>(src: Src) -> Dst; | |
| 1732 | } | |
| 1733 | } | |
| 1734 | pub mod mem { | |
| 1735 | pub use crate::intrinsics::transmute; | |
| 1736 | } | |
| 1737 | //- /main.rs crate:main deps:core | |
| 1738 | fn function() { | |
| 1739 | transmute$0 | |
| 1740 | } | |
| 1741 | "#, | |
| 1742 | expect![[r#" | |
| 1743 | fn transmute(…) (use core::mem::transmute) unsafe fn(Src) -> Dst | |
| 1744 | "#]], | |
| 1745 | ); | |
| 1746 | check( | |
| 1747 | r#" | |
| 1748 | //- /core.rs crate:core | |
| 1749 | pub mod intrinsics { | |
| 1750 | extern "rust-intrinsic" { | |
| 1751 | pub fn transmute<Src, Dst>(src: Src) -> Dst; | |
| 1752 | } | |
| 1753 | } | |
| 1754 | pub mod mem { | |
| 1755 | pub use crate::intrinsics::transmute; | |
| 1756 | } | |
| 1757 | //- /main.rs crate:main deps:core | |
| 1758 | fn function() { | |
| 1759 | mem::transmute$0 | |
| 1760 | } | |
| 1761 | "#, | |
| 1762 | expect![""], | |
| 1763 | ); | |
| 1764 | } |
src/tools/rust-analyzer/crates/ide-completion/src/tests/fn_param.rs+1-1| ... | ... | @@ -140,7 +140,7 @@ fn foo2($0) {} |
| 140 | 140 | expect![[r#" |
| 141 | 141 | st Bar |
| 142 | 142 | bn Bar { bar }: Bar |
| 143 | bn Bar {…} Bar { bar$1 }: Bar$0 | |
| 143 | bn Bar {…} Bar { bar$1 }: Bar$0 | |
| 144 | 144 | kw mut |
| 145 | 145 | kw ref |
| 146 | 146 | "#]], |
src/tools/rust-analyzer/crates/ide-completion/src/tests/item.rs+12-12| ... | ... | @@ -20,15 +20,15 @@ fn target_type_or_trait_in_impl_block() { |
| 20 | 20 | impl Tra$0 |
| 21 | 21 | "#, |
| 22 | 22 | expect![[r#" |
| 23 | en Enum Enum | |
| 23 | en Enum Enum | |
| 24 | 24 | ma makro!(…) macro_rules! makro |
| 25 | 25 | md module |
| 26 | st Record Record | |
| 27 | st Tuple Tuple | |
| 28 | st Unit Unit | |
| 26 | st Record Record | |
| 27 | st Tuple Tuple | |
| 28 | st Unit Unit | |
| 29 | 29 | tt Trait |
| 30 | un Union Union | |
| 31 | bt u32 u32 | |
| 30 | un Union Union | |
| 31 | bt u32 u32 | |
| 32 | 32 | kw crate:: |
| 33 | 33 | kw self:: |
| 34 | 34 | "#]], |
| ... | ... | @@ -42,15 +42,15 @@ fn target_type_in_trait_impl_block() { |
| 42 | 42 | impl Trait for Str$0 |
| 43 | 43 | "#, |
| 44 | 44 | expect![[r#" |
| 45 | en Enum Enum | |
| 45 | en Enum Enum | |
| 46 | 46 | ma makro!(…) macro_rules! makro |
| 47 | 47 | md module |
| 48 | st Record Record | |
| 49 | st Tuple Tuple | |
| 50 | st Unit Unit | |
| 48 | st Record Record | |
| 49 | st Tuple Tuple | |
| 50 | st Unit Unit | |
| 51 | 51 | tt Trait |
| 52 | un Union Union | |
| 53 | bt u32 u32 | |
| 52 | un Union Union | |
| 53 | bt u32 u32 | |
| 54 | 54 | kw crate:: |
| 55 | 55 | kw self:: |
| 56 | 56 | "#]], |
src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs+9-9| ... | ... | @@ -13,7 +13,7 @@ fn in_mod_item_list() { |
| 13 | 13 | check( |
| 14 | 14 | r#"mod tests { $0 }"#, |
| 15 | 15 | expect![[r#" |
| 16 | ma makro!(…) macro_rules! makro | |
| 16 | ma makro!(…) macro_rules! makro | |
| 17 | 17 | kw async |
| 18 | 18 | kw const |
| 19 | 19 | kw crate:: |
| ... | ... | @@ -46,7 +46,7 @@ fn in_source_file_item_list() { |
| 46 | 46 | check( |
| 47 | 47 | r#"$0"#, |
| 48 | 48 | expect![[r#" |
| 49 | ma makro!(…) macro_rules! makro | |
| 49 | ma makro!(…) macro_rules! makro | |
| 50 | 50 | md module |
| 51 | 51 | kw async |
| 52 | 52 | kw const |
| ... | ... | @@ -79,7 +79,7 @@ fn in_item_list_after_attr() { |
| 79 | 79 | check( |
| 80 | 80 | r#"#[attr] $0"#, |
| 81 | 81 | expect![[r#" |
| 82 | ma makro!(…) macro_rules! makro | |
| 82 | ma makro!(…) macro_rules! makro | |
| 83 | 83 | md module |
| 84 | 84 | kw async |
| 85 | 85 | kw const |
| ... | ... | @@ -182,7 +182,7 @@ fn in_impl_assoc_item_list() { |
| 182 | 182 | check( |
| 183 | 183 | r#"impl Struct { $0 }"#, |
| 184 | 184 | expect![[r#" |
| 185 | ma makro!(…) macro_rules! makro | |
| 185 | ma makro!(…) macro_rules! makro | |
| 186 | 186 | md module |
| 187 | 187 | kw async |
| 188 | 188 | kw const |
| ... | ... | @@ -202,7 +202,7 @@ fn in_impl_assoc_item_list_after_attr() { |
| 202 | 202 | check( |
| 203 | 203 | r#"impl Struct { #[attr] $0 }"#, |
| 204 | 204 | expect![[r#" |
| 205 | ma makro!(…) macro_rules! makro | |
| 205 | ma makro!(…) macro_rules! makro | |
| 206 | 206 | md module |
| 207 | 207 | kw async |
| 208 | 208 | kw const |
| ... | ... | @@ -315,7 +315,7 @@ impl Test for () { |
| 315 | 315 | fn async fn function2() |
| 316 | 316 | fn fn function1() |
| 317 | 317 | fn fn function2() |
| 318 | ma makro!(…) macro_rules! makro | |
| 318 | ma makro!(…) macro_rules! makro | |
| 319 | 319 | md module |
| 320 | 320 | ta type Type1 = |
| 321 | 321 | kw crate:: |
| ... | ... | @@ -381,7 +381,7 @@ fn after_unit_struct() { |
| 381 | 381 | check( |
| 382 | 382 | r#"struct S; f$0"#, |
| 383 | 383 | expect![[r#" |
| 384 | ma makro!(…) macro_rules! makro | |
| 384 | ma makro!(…) macro_rules! makro | |
| 385 | 385 | md module |
| 386 | 386 | kw async |
| 387 | 387 | kw const |
| ... | ... | @@ -503,7 +503,7 @@ fn inside_extern_blocks() { |
| 503 | 503 | check( |
| 504 | 504 | r#"extern { $0 }"#, |
| 505 | 505 | expect![[r#" |
| 506 | ma makro!(…) macro_rules! makro | |
| 506 | ma makro!(…) macro_rules! makro | |
| 507 | 507 | md module |
| 508 | 508 | kw crate:: |
| 509 | 509 | kw fn |
| ... | ... | @@ -520,7 +520,7 @@ fn inside_extern_blocks() { |
| 520 | 520 | check( |
| 521 | 521 | r#"unsafe extern { $0 }"#, |
| 522 | 522 | expect![[r#" |
| 523 | ma makro!(…) macro_rules! makro | |
| 523 | ma makro!(…) macro_rules! makro | |
| 524 | 524 | md module |
| 525 | 525 | kw crate:: |
| 526 | 526 | kw fn |
src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs+35-35| ... | ... | @@ -122,15 +122,15 @@ fn foo() { |
| 122 | 122 | expect![[r#" |
| 123 | 123 | ct CONST |
| 124 | 124 | en Enum |
| 125 | ma makro!(…) macro_rules! makro | |
| 125 | ma makro!(…) macro_rules! makro | |
| 126 | 126 | md module |
| 127 | 127 | st Record |
| 128 | 128 | st Tuple |
| 129 | 129 | st Unit |
| 130 | 130 | ev TupleV |
| 131 | 131 | bn Record {…} Record { field$1 }$0 |
| 132 | bn Tuple(…) Tuple($1)$0 | |
| 133 | bn TupleV(…) TupleV($1)$0 | |
| 132 | bn Tuple(…) Tuple($1)$0 | |
| 133 | bn TupleV(…) TupleV($1)$0 | |
| 134 | 134 | kw mut |
| 135 | 135 | kw ref |
| 136 | 136 | "#]], |
| ... | ... | @@ -151,15 +151,15 @@ fn foo() { |
| 151 | 151 | "#, |
| 152 | 152 | expect![[r#" |
| 153 | 153 | en SingleVariantEnum |
| 154 | ma makro!(…) macro_rules! makro | |
| 154 | ma makro!(…) macro_rules! makro | |
| 155 | 155 | md module |
| 156 | 156 | st Record |
| 157 | 157 | st Tuple |
| 158 | 158 | st Unit |
| 159 | 159 | ev Variant |
| 160 | bn Record {…} Record { field$1 }$0 | |
| 161 | bn Tuple(…) Tuple($1)$0 | |
| 162 | bn Variant Variant$0 | |
| 160 | bn Record {…} Record { field$1 }$0 | |
| 161 | bn Tuple(…) Tuple($1)$0 | |
| 162 | bn Variant Variant$0 | |
| 163 | 163 | kw mut |
| 164 | 164 | kw ref |
| 165 | 165 | "#]], |
| ... | ... | @@ -174,13 +174,13 @@ fn foo(a$0) { |
| 174 | 174 | } |
| 175 | 175 | "#, |
| 176 | 176 | expect![[r#" |
| 177 | ma makro!(…) macro_rules! makro | |
| 177 | ma makro!(…) macro_rules! makro | |
| 178 | 178 | md module |
| 179 | 179 | st Record |
| 180 | 180 | st Tuple |
| 181 | 181 | st Unit |
| 182 | 182 | bn Record {…} Record { field$1 }: Record$0 |
| 183 | bn Tuple(…) Tuple($1): Tuple$0 | |
| 183 | bn Tuple(…) Tuple($1): Tuple$0 | |
| 184 | 184 | kw mut |
| 185 | 185 | kw ref |
| 186 | 186 | "#]], |
| ... | ... | @@ -191,13 +191,13 @@ fn foo(a$0: Tuple) { |
| 191 | 191 | } |
| 192 | 192 | "#, |
| 193 | 193 | expect![[r#" |
| 194 | ma makro!(…) macro_rules! makro | |
| 194 | ma makro!(…) macro_rules! makro | |
| 195 | 195 | md module |
| 196 | 196 | st Record |
| 197 | 197 | st Tuple |
| 198 | 198 | st Unit |
| 199 | 199 | bn Record {…} Record { field$1 }$0 |
| 200 | bn Tuple(…) Tuple($1)$0 | |
| 200 | bn Tuple(…) Tuple($1)$0 | |
| 201 | 201 | bn tuple |
| 202 | 202 | kw mut |
| 203 | 203 | kw ref |
| ... | ... | @@ -240,7 +240,7 @@ fn foo() { |
| 240 | 240 | expect![[r#" |
| 241 | 241 | en E |
| 242 | 242 | ma m!(…) macro_rules! m |
| 243 | bn E::X E::X$0 | |
| 243 | bn E::X E::X$0 | |
| 244 | 244 | kw mut |
| 245 | 245 | kw ref |
| 246 | 246 | "#]], |
| ... | ... | @@ -268,7 +268,7 @@ fn outer() { |
| 268 | 268 | st Record |
| 269 | 269 | st Tuple |
| 270 | 270 | bn Record {…} Record { field$1, .. }$0 |
| 271 | bn Tuple(…) Tuple($1, ..)$0 | |
| 271 | bn Tuple(…) Tuple($1, ..)$0 | |
| 272 | 272 | kw mut |
| 273 | 273 | kw ref |
| 274 | 274 | "#]], |
| ... | ... | @@ -291,7 +291,7 @@ impl Foo { |
| 291 | 291 | expect![[r#" |
| 292 | 292 | sp Self |
| 293 | 293 | st Foo |
| 294 | bn Foo(…) Foo($1)$0 | |
| 294 | bn Foo(…) Foo($1)$0 | |
| 295 | 295 | bn Self(…) Self($1)$0 |
| 296 | 296 | kw mut |
| 297 | 297 | kw ref |
| ... | ... | @@ -315,8 +315,8 @@ fn func() { |
| 315 | 315 | expect![[r#" |
| 316 | 316 | ct ASSOC_CONST const ASSOC_CONST: () |
| 317 | 317 | bn RecordV {…} RecordV { field$1 }$0 |
| 318 | bn TupleV(…) TupleV($1)$0 | |
| 319 | bn UnitV UnitV$0 | |
| 318 | bn TupleV(…) TupleV($1)$0 | |
| 319 | bn UnitV UnitV$0 | |
| 320 | 320 | "#]], |
| 321 | 321 | ); |
| 322 | 322 | } |
| ... | ... | @@ -332,7 +332,7 @@ fn outer(Foo { bar: $0 }: Foo) {} |
| 332 | 332 | expect![[r#" |
| 333 | 333 | st Bar |
| 334 | 334 | st Foo |
| 335 | bn Bar(…) Bar($1)$0 | |
| 335 | bn Bar(…) Bar($1)$0 | |
| 336 | 336 | bn Foo {…} Foo { bar$1 }$0 |
| 337 | 337 | kw mut |
| 338 | 338 | kw ref |
| ... | ... | @@ -395,7 +395,7 @@ fn foo($0) {} |
| 395 | 395 | expect![[r#" |
| 396 | 396 | st Bar |
| 397 | 397 | st Foo |
| 398 | bn Bar(…) Bar($1): Bar$0 | |
| 398 | bn Bar(…) Bar($1): Bar$0 | |
| 399 | 399 | bn Foo {…} Foo { bar$1 }: Foo$0 |
| 400 | 400 | kw mut |
| 401 | 401 | kw ref |
| ... | ... | @@ -416,7 +416,7 @@ fn foo() { |
| 416 | 416 | expect![[r#" |
| 417 | 417 | st Bar |
| 418 | 418 | st Foo |
| 419 | bn Bar(…) Bar($1)$0 | |
| 419 | bn Bar(…) Bar($1)$0 | |
| 420 | 420 | bn Foo {…} Foo { bar$1 }$0 |
| 421 | 421 | kw mut |
| 422 | 422 | kw ref |
| ... | ... | @@ -436,7 +436,7 @@ fn foo() { |
| 436 | 436 | } |
| 437 | 437 | "#, |
| 438 | 438 | expect![[r#" |
| 439 | st Bar Bar | |
| 439 | st Bar Bar | |
| 440 | 440 | kw crate:: |
| 441 | 441 | kw self:: |
| 442 | 442 | "#]], |
| ... | ... | @@ -451,7 +451,7 @@ fn foo() { |
| 451 | 451 | } |
| 452 | 452 | "#, |
| 453 | 453 | expect![[r#" |
| 454 | st Foo Foo | |
| 454 | st Foo Foo | |
| 455 | 455 | kw crate:: |
| 456 | 456 | kw self:: |
| 457 | 457 | "#]], |
| ... | ... | @@ -535,10 +535,10 @@ fn foo() { |
| 535 | 535 | "#, |
| 536 | 536 | expect![[r#" |
| 537 | 537 | en Enum |
| 538 | bn Enum::A Enum::A$0 | |
| 539 | bn Enum::B {…} Enum::B { r#type$1 }$0 | |
| 538 | bn Enum::A Enum::A$0 | |
| 539 | bn Enum::B {…} Enum::B { r#type$1 }$0 | |
| 540 | 540 | bn Enum::struct {…} Enum::r#struct { r#type$1 }$0 |
| 541 | bn Enum::type Enum::r#type$0 | |
| 541 | bn Enum::type Enum::r#type$0 | |
| 542 | 542 | kw mut |
| 543 | 543 | kw ref |
| 544 | 544 | "#]], |
| ... | ... | @@ -559,10 +559,10 @@ fn foo() { |
| 559 | 559 | } |
| 560 | 560 | "#, |
| 561 | 561 | expect![[r#" |
| 562 | bn A A$0 | |
| 563 | bn B {…} B { r#type$1 }$0 | |
| 562 | bn A A$0 | |
| 563 | bn B {…} B { r#type$1 }$0 | |
| 564 | 564 | bn struct {…} r#struct { r#type$1 }$0 |
| 565 | bn type r#type$0 | |
| 565 | bn type r#type$0 | |
| 566 | 566 | "#]], |
| 567 | 567 | ); |
| 568 | 568 | } |
| ... | ... | @@ -672,8 +672,8 @@ impl Ty { |
| 672 | 672 | st Ty |
| 673 | 673 | bn &mut self |
| 674 | 674 | bn &self |
| 675 | bn Self(…) Self($1): Self$0 | |
| 676 | bn Ty(…) Ty($1): Ty$0 | |
| 675 | bn Self(…) Self($1): Self$0 | |
| 676 | bn Ty(…) Ty($1): Ty$0 | |
| 677 | 677 | bn mut self |
| 678 | 678 | bn self |
| 679 | 679 | kw mut |
| ... | ... | @@ -693,8 +693,8 @@ impl Ty { |
| 693 | 693 | st Ty |
| 694 | 694 | bn &mut self |
| 695 | 695 | bn &self |
| 696 | bn Self(…) Self($1): Self$0 | |
| 697 | bn Ty(…) Ty($1): Ty$0 | |
| 696 | bn Self(…) Self($1): Self$0 | |
| 697 | bn Ty(…) Ty($1): Ty$0 | |
| 698 | 698 | bn mut self |
| 699 | 699 | bn self |
| 700 | 700 | kw mut |
| ... | ... | @@ -714,8 +714,8 @@ impl Ty { |
| 714 | 714 | st Ty |
| 715 | 715 | bn &mut self |
| 716 | 716 | bn &self |
| 717 | bn Self(…) Self($1): Self$0 | |
| 718 | bn Ty(…) Ty($1): Ty$0 | |
| 717 | bn Self(…) Self($1): Self$0 | |
| 718 | bn Ty(…) Ty($1): Ty$0 | |
| 719 | 719 | bn mut self |
| 720 | 720 | bn self |
| 721 | 721 | kw mut |
| ... | ... | @@ -734,7 +734,7 @@ impl Ty { |
| 734 | 734 | sp Self |
| 735 | 735 | st Ty |
| 736 | 736 | bn Self(…) Self($1): Self$0 |
| 737 | bn Ty(…) Ty($1): Ty$0 | |
| 737 | bn Ty(…) Ty($1): Ty$0 | |
| 738 | 738 | kw mut |
| 739 | 739 | kw ref |
| 740 | 740 | "#]], |
| ... | ... | @@ -763,7 +763,7 @@ fn f(x: EnumAlias<u8>) { |
| 763 | 763 | "#, |
| 764 | 764 | expect![[r#" |
| 765 | 765 | bn Tuple(…) Tuple($1)$0 |
| 766 | bn Unit Unit$0 | |
| 766 | bn Unit Unit$0 | |
| 767 | 767 | "#]], |
| 768 | 768 | ); |
| 769 | 769 | } |
src/tools/rust-analyzer/crates/ide-completion/src/tests/predicate.rs+21-21| ... | ... | @@ -16,16 +16,16 @@ fn predicate_start() { |
| 16 | 16 | struct Foo<'lt, T, const C: usize> where $0 {} |
| 17 | 17 | "#, |
| 18 | 18 | expect![[r#" |
| 19 | en Enum Enum | |
| 19 | en Enum Enum | |
| 20 | 20 | ma makro!(…) macro_rules! makro |
| 21 | 21 | md module |
| 22 | st Foo<…> Foo<'_, {unknown}, _> | |
| 23 | st Record Record | |
| 24 | st Tuple Tuple | |
| 25 | st Unit Unit | |
| 22 | st Foo<…> Foo<'_, {unknown}, _> | |
| 23 | st Record Record | |
| 24 | st Tuple Tuple | |
| 25 | st Unit Unit | |
| 26 | 26 | tt Trait |
| 27 | un Union Union | |
| 28 | bt u32 u32 | |
| 27 | un Union Union | |
| 28 | bt u32 u32 | |
| 29 | 29 | kw crate:: |
| 30 | 30 | kw self:: |
| 31 | 31 | "#]], |
| ... | ... | @@ -89,16 +89,16 @@ fn param_list_for_for_pred() { |
| 89 | 89 | struct Foo<'lt, T, const C: usize> where for<'a> $0 {} |
| 90 | 90 | "#, |
| 91 | 91 | expect![[r#" |
| 92 | en Enum Enum | |
| 92 | en Enum Enum | |
| 93 | 93 | ma makro!(…) macro_rules! makro |
| 94 | 94 | md module |
| 95 | st Foo<…> Foo<'_, {unknown}, _> | |
| 96 | st Record Record | |
| 97 | st Tuple Tuple | |
| 98 | st Unit Unit | |
| 95 | st Foo<…> Foo<'_, {unknown}, _> | |
| 96 | st Record Record | |
| 97 | st Tuple Tuple | |
| 98 | st Unit Unit | |
| 99 | 99 | tt Trait |
| 100 | un Union Union | |
| 101 | bt u32 u32 | |
| 100 | un Union Union | |
| 101 | bt u32 u32 | |
| 102 | 102 | kw crate:: |
| 103 | 103 | kw self:: |
| 104 | 104 | "#]], |
| ... | ... | @@ -114,16 +114,16 @@ impl Record { |
| 114 | 114 | } |
| 115 | 115 | "#, |
| 116 | 116 | expect![[r#" |
| 117 | en Enum Enum | |
| 117 | en Enum Enum | |
| 118 | 118 | ma makro!(…) macro_rules! makro |
| 119 | 119 | md module |
| 120 | sp Self Record | |
| 121 | st Record Record | |
| 122 | st Tuple Tuple | |
| 123 | st Unit Unit | |
| 120 | sp Self Record | |
| 121 | st Record Record | |
| 122 | st Tuple Tuple | |
| 123 | st Unit Unit | |
| 124 | 124 | tt Trait |
| 125 | un Union Union | |
| 126 | bt u32 u32 | |
| 125 | un Union Union | |
| 126 | bt u32 u32 | |
| 127 | 127 | kw crate:: |
| 128 | 128 | kw self:: |
| 129 | 129 | "#]], |
src/tools/rust-analyzer/crates/ide-completion/src/tests/proc_macros.rs+52-52| ... | ... | @@ -24,19 +24,19 @@ fn main() { |
| 24 | 24 | } |
| 25 | 25 | "#, |
| 26 | 26 | expect![[r#" |
| 27 | me foo() fn(&self) | |
| 28 | sn box Box::new(expr) | |
| 29 | sn call function(expr) | |
| 30 | sn dbg dbg!(expr) | |
| 31 | sn dbgr dbg!(&expr) | |
| 32 | sn deref *expr | |
| 33 | sn let let | |
| 34 | sn letm let mut | |
| 35 | sn match match expr {} | |
| 36 | sn ref &expr | |
| 37 | sn refm &mut expr | |
| 38 | sn return return expr | |
| 39 | sn unsafe unsafe {} | |
| 27 | me foo() fn(&self) | |
| 28 | sn box Box::new(expr) | |
| 29 | sn call function(expr) | |
| 30 | sn dbg dbg!(expr) | |
| 31 | sn dbgr dbg!(&expr) | |
| 32 | sn deref *expr | |
| 33 | sn let let | |
| 34 | sn letm let mut | |
| 35 | sn match match expr {} | |
| 36 | sn ref &expr | |
| 37 | sn refm &mut expr | |
| 38 | sn return return expr | |
| 39 | sn unsafe unsafe {} | |
| 40 | 40 | "#]], |
| 41 | 41 | ) |
| 42 | 42 | } |
| ... | ... | @@ -57,19 +57,19 @@ fn main() { |
| 57 | 57 | } |
| 58 | 58 | "#, |
| 59 | 59 | expect![[r#" |
| 60 | me foo() fn(&self) | |
| 61 | sn box Box::new(expr) | |
| 62 | sn call function(expr) | |
| 63 | sn dbg dbg!(expr) | |
| 64 | sn dbgr dbg!(&expr) | |
| 65 | sn deref *expr | |
| 66 | sn let let | |
| 67 | sn letm let mut | |
| 68 | sn match match expr {} | |
| 69 | sn ref &expr | |
| 70 | sn refm &mut expr | |
| 71 | sn return return expr | |
| 72 | sn unsafe unsafe {} | |
| 60 | me foo() fn(&self) | |
| 61 | sn box Box::new(expr) | |
| 62 | sn call function(expr) | |
| 63 | sn dbg dbg!(expr) | |
| 64 | sn dbgr dbg!(&expr) | |
| 65 | sn deref *expr | |
| 66 | sn let let | |
| 67 | sn letm let mut | |
| 68 | sn match match expr {} | |
| 69 | sn ref &expr | |
| 70 | sn refm &mut expr | |
| 71 | sn return return expr | |
| 72 | sn unsafe unsafe {} | |
| 73 | 73 | "#]], |
| 74 | 74 | ) |
| 75 | 75 | } |
| ... | ... | @@ -92,19 +92,19 @@ impl Foo { |
| 92 | 92 | fn main() {} |
| 93 | 93 | "#, |
| 94 | 94 | expect![[r#" |
| 95 | me foo() fn(&self) | |
| 96 | sn box Box::new(expr) | |
| 97 | sn call function(expr) | |
| 98 | sn dbg dbg!(expr) | |
| 99 | sn dbgr dbg!(&expr) | |
| 100 | sn deref *expr | |
| 101 | sn let let | |
| 102 | sn letm let mut | |
| 103 | sn match match expr {} | |
| 104 | sn ref &expr | |
| 105 | sn refm &mut expr | |
| 106 | sn return return expr | |
| 107 | sn unsafe unsafe {} | |
| 95 | me foo() fn(&self) | |
| 96 | sn box Box::new(expr) | |
| 97 | sn call function(expr) | |
| 98 | sn dbg dbg!(expr) | |
| 99 | sn dbgr dbg!(&expr) | |
| 100 | sn deref *expr | |
| 101 | sn let let | |
| 102 | sn letm let mut | |
| 103 | sn match match expr {} | |
| 104 | sn ref &expr | |
| 105 | sn refm &mut expr | |
| 106 | sn return return expr | |
| 107 | sn unsafe unsafe {} | |
| 108 | 108 | "#]], |
| 109 | 109 | ) |
| 110 | 110 | } |
| ... | ... | @@ -127,19 +127,19 @@ impl Foo { |
| 127 | 127 | fn main() {} |
| 128 | 128 | "#, |
| 129 | 129 | expect![[r#" |
| 130 | me foo() fn(&self) | |
| 131 | sn box Box::new(expr) | |
| 132 | sn call function(expr) | |
| 133 | sn dbg dbg!(expr) | |
| 134 | sn dbgr dbg!(&expr) | |
| 135 | sn deref *expr | |
| 136 | sn let let | |
| 137 | sn letm let mut | |
| 138 | sn match match expr {} | |
| 139 | sn ref &expr | |
| 140 | sn refm &mut expr | |
| 141 | sn return return expr | |
| 142 | sn unsafe unsafe {} | |
| 130 | me foo() fn(&self) | |
| 131 | sn box Box::new(expr) | |
| 132 | sn call function(expr) | |
| 133 | sn dbg dbg!(expr) | |
| 134 | sn dbgr dbg!(&expr) | |
| 135 | sn deref *expr | |
| 136 | sn let let | |
| 137 | sn letm let mut | |
| 138 | sn match match expr {} | |
| 139 | sn ref &expr | |
| 140 | sn refm &mut expr | |
| 141 | sn return return expr | |
| 142 | sn unsafe unsafe {} | |
| 143 | 143 | "#]], |
| 144 | 144 | ) |
| 145 | 145 | } |
src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs+24-24| ... | ... | @@ -70,8 +70,8 @@ fn foo(baz: Baz) { |
| 70 | 70 | ev Ok |
| 71 | 71 | bn Baz::Bar Baz::Bar$0 |
| 72 | 72 | bn Baz::Foo Baz::Foo$0 |
| 73 | bn Err(…) Err($1)$0 | |
| 74 | bn Ok(…) Ok($1)$0 | |
| 73 | bn Err(…) Err($1)$0 | |
| 74 | bn Ok(…) Ok($1)$0 | |
| 75 | 75 | kw mut |
| 76 | 76 | kw ref |
| 77 | 77 | "#]], |
| ... | ... | @@ -91,20 +91,20 @@ fn foo(baz: Baz) { |
| 91 | 91 | } |
| 92 | 92 | "#, |
| 93 | 93 | expect![[r#" |
| 94 | en Baz | |
| 95 | en Result | |
| 96 | md core | |
| 97 | ev Bar | |
| 98 | ev Err | |
| 99 | ev Foo | |
| 100 | ev Ok | |
| 101 | bn Bar Bar$0 | |
| 102 | bn Err(…) Err($1)$0 | |
| 103 | bn Foo Foo$0 | |
| 104 | bn Ok(…) Ok($1)$0 | |
| 105 | kw mut | |
| 106 | kw ref | |
| 107 | "#]], | |
| 94 | en Baz | |
| 95 | en Result | |
| 96 | md core | |
| 97 | ev Bar | |
| 98 | ev Err | |
| 99 | ev Foo | |
| 100 | ev Ok | |
| 101 | bn Bar Bar$0 | |
| 102 | bn Err(…) Err($1)$0 | |
| 103 | bn Foo Foo$0 | |
| 104 | bn Ok(…) Ok($1)$0 | |
| 105 | kw mut | |
| 106 | kw ref | |
| 107 | "#]], | |
| 108 | 108 | ); |
| 109 | 109 | } |
| 110 | 110 | |
| ... | ... | @@ -184,14 +184,14 @@ fn main() { |
| 184 | 184 | "#, |
| 185 | 185 | expect![[r#" |
| 186 | 186 | fd ..Default::default() |
| 187 | fn main() fn() | |
| 188 | lc foo Foo | |
| 189 | lc thing i32 | |
| 187 | fn main() fn() | |
| 188 | lc foo Foo | |
| 189 | lc thing i32 | |
| 190 | 190 | md core |
| 191 | st Foo Foo | |
| 192 | st Foo {…} Foo { foo1: u32, foo2: u32 } | |
| 191 | st Foo Foo | |
| 192 | st Foo {…} Foo { foo1: u32, foo2: u32 } | |
| 193 | 193 | tt Default |
| 194 | bt u32 u32 | |
| 194 | bt u32 u32 | |
| 195 | 195 | kw crate:: |
| 196 | 196 | kw self:: |
| 197 | 197 | ex Foo::default() |
| ... | ... | @@ -238,8 +238,8 @@ fn main() { |
| 238 | 238 | "#, |
| 239 | 239 | expect![[r#" |
| 240 | 240 | fd ..Default::default() |
| 241 | fd foo1 u32 | |
| 242 | fd foo2 u32 | |
| 241 | fd foo1 u32 | |
| 242 | fd foo2 u32 | |
| 243 | 243 | "#]], |
| 244 | 244 | ); |
| 245 | 245 | } |
src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs+82-83| ... | ... | @@ -87,7 +87,7 @@ pub mod prelude { |
| 87 | 87 | expect![[r#" |
| 88 | 88 | md std |
| 89 | 89 | st Option Option |
| 90 | bt u32 u32 | |
| 90 | bt u32 u32 | |
| 91 | 91 | "#]], |
| 92 | 92 | ); |
| 93 | 93 | } |
| ... | ... | @@ -113,10 +113,10 @@ mod macros { |
| 113 | 113 | } |
| 114 | 114 | "#, |
| 115 | 115 | expect![[r#" |
| 116 | fn f() fn() | |
| 116 | fn f() fn() | |
| 117 | 117 | ma concat!(…) macro_rules! concat |
| 118 | 118 | md std |
| 119 | bt u32 u32 | |
| 119 | bt u32 u32 | |
| 120 | 120 | "#]], |
| 121 | 121 | ); |
| 122 | 122 | } |
| ... | ... | @@ -146,7 +146,7 @@ pub mod prelude { |
| 146 | 146 | md core |
| 147 | 147 | md std |
| 148 | 148 | st String String |
| 149 | bt u32 u32 | |
| 149 | bt u32 u32 | |
| 150 | 150 | "#]], |
| 151 | 151 | ); |
| 152 | 152 | } |
| ... | ... | @@ -174,7 +174,7 @@ pub mod prelude { |
| 174 | 174 | expect![[r#" |
| 175 | 175 | fn f() fn() |
| 176 | 176 | md std |
| 177 | bt u32 u32 | |
| 177 | bt u32 u32 | |
| 178 | 178 | "#]], |
| 179 | 179 | ); |
| 180 | 180 | } |
| ... | ... | @@ -226,9 +226,9 @@ impl S { |
| 226 | 226 | fn foo() { let _ = lib::S::$0 } |
| 227 | 227 | "#, |
| 228 | 228 | expect![[r#" |
| 229 | ct PUBLIC_CONST pub const PUBLIC_CONST: u32 | |
| 230 | fn public_method() fn() | |
| 231 | ta PublicType pub type PublicType = u32 | |
| 229 | ct PUBLIC_CONST pub const PUBLIC_CONST: u32 | |
| 230 | fn public_method() fn() | |
| 231 | ta PublicType pub type PublicType = u32 | |
| 232 | 232 | "#]], |
| 233 | 233 | ); |
| 234 | 234 | } |
| ... | ... | @@ -317,14 +317,14 @@ trait Sub: Super { |
| 317 | 317 | fn foo<T: Sub>() { T::$0 } |
| 318 | 318 | "#, |
| 319 | 319 | expect![[r#" |
| 320 | ct C2 (as Sub) const C2: () | |
| 321 | ct CONST (as Super) const CONST: u8 | |
| 322 | fn func() (as Super) fn() | |
| 323 | fn subfunc() (as Sub) fn() | |
| 324 | me method(…) (as Super) fn(&self) | |
| 325 | me submethod(…) (as Sub) fn(&self) | |
| 320 | ct C2 (as Sub) const C2: () | |
| 321 | ct CONST (as Super) const CONST: u8 | |
| 322 | fn func() (as Super) fn() | |
| 323 | fn subfunc() (as Sub) fn() | |
| 324 | me method(…) (as Super) fn(&self) | |
| 325 | me submethod(…) (as Sub) fn(&self) | |
| 326 | 326 | ta SubTy (as Sub) type SubTy |
| 327 | ta Ty (as Super) type Ty | |
| 327 | ta Ty (as Super) type Ty | |
| 328 | 328 | "#]], |
| 329 | 329 | ); |
| 330 | 330 | } |
| ... | ... | @@ -357,14 +357,14 @@ impl<T> Sub for Wrap<T> { |
| 357 | 357 | } |
| 358 | 358 | "#, |
| 359 | 359 | expect![[r#" |
| 360 | ct C2 (as Sub) const C2: () | |
| 361 | ct CONST (as Super) const CONST: u8 | |
| 362 | fn func() (as Super) fn() | |
| 363 | fn subfunc() (as Sub) fn() | |
| 364 | me method(…) (as Super) fn(&self) | |
| 365 | me submethod(…) (as Sub) fn(&self) | |
| 360 | ct C2 (as Sub) const C2: () | |
| 361 | ct CONST (as Super) const CONST: u8 | |
| 362 | fn func() (as Super) fn() | |
| 363 | fn subfunc() (as Sub) fn() | |
| 364 | me method(…) (as Super) fn(&self) | |
| 365 | me submethod(…) (as Sub) fn(&self) | |
| 366 | 366 | ta SubTy (as Sub) type SubTy |
| 367 | ta Ty (as Super) type Ty | |
| 367 | ta Ty (as Super) type Ty | |
| 368 | 368 | "#]], |
| 369 | 369 | ); |
| 370 | 370 | } |
| ... | ... | @@ -381,9 +381,9 @@ impl T { fn bar() {} } |
| 381 | 381 | fn main() { T::$0; } |
| 382 | 382 | "#, |
| 383 | 383 | expect![[r#" |
| 384 | fn bar() fn() | |
| 385 | fn foo() fn() | |
| 386 | "#]], | |
| 384 | fn bar() fn() | |
| 385 | fn foo() fn() | |
| 386 | "#]], | |
| 387 | 387 | ); |
| 388 | 388 | } |
| 389 | 389 | |
| ... | ... | @@ -397,7 +397,7 @@ macro_rules! foo { () => {} } |
| 397 | 397 | fn main() { let _ = crate::$0 } |
| 398 | 398 | "#, |
| 399 | 399 | expect![[r#" |
| 400 | fn main() fn() | |
| 400 | fn main() fn() | |
| 401 | 401 | ma foo!(…) macro_rules! foo |
| 402 | 402 | "#]], |
| 403 | 403 | ); |
| ... | ... | @@ -447,9 +447,9 @@ mod p { |
| 447 | 447 | } |
| 448 | 448 | "#, |
| 449 | 449 | expect![[r#" |
| 450 | ct RIGHT_CONST u32 | |
| 451 | fn right_fn() fn() | |
| 452 | st RightType WrongType | |
| 450 | ct RIGHT_CONST u32 | |
| 451 | fn right_fn() fn() | |
| 452 | st RightType WrongType | |
| 453 | 453 | "#]], |
| 454 | 454 | ); |
| 455 | 455 | |
| ... | ... | @@ -495,9 +495,9 @@ fn main() { m!(self::f$0); } |
| 495 | 495 | fn foo() {} |
| 496 | 496 | "#, |
| 497 | 497 | expect![[r#" |
| 498 | fn foo() fn() | |
| 499 | fn main() fn() | |
| 500 | "#]], | |
| 498 | fn foo() fn() | |
| 499 | fn main() fn() | |
| 500 | "#]], | |
| 501 | 501 | ); |
| 502 | 502 | } |
| 503 | 503 | |
| ... | ... | @@ -513,9 +513,9 @@ mod m { |
| 513 | 513 | } |
| 514 | 514 | "#, |
| 515 | 515 | expect![[r#" |
| 516 | fn z() fn() | |
| 517 | md z | |
| 518 | "#]], | |
| 516 | fn z() fn() | |
| 517 | md z | |
| 518 | "#]], | |
| 519 | 519 | ); |
| 520 | 520 | } |
| 521 | 521 | |
| ... | ... | @@ -534,8 +534,8 @@ fn foo() { |
| 534 | 534 | } |
| 535 | 535 | "#, |
| 536 | 536 | expect![[r#" |
| 537 | fn new() fn() -> HashMap<K, V, RandomState> | |
| 538 | "#]], | |
| 537 | fn new() fn() -> HashMap<K, V, RandomState> | |
| 538 | "#]], | |
| 539 | 539 | ); |
| 540 | 540 | } |
| 541 | 541 | |
| ... | ... | @@ -557,8 +557,8 @@ impl Foo { |
| 557 | 557 | "#, |
| 558 | 558 | expect![[r#" |
| 559 | 559 | me foo(…) fn(self) |
| 560 | ev Bar Bar | |
| 561 | ev Baz Baz | |
| 560 | ev Bar Bar | |
| 561 | ev Baz Baz | |
| 562 | 562 | "#]], |
| 563 | 563 | ); |
| 564 | 564 | } |
| ... | ... | @@ -578,9 +578,9 @@ fn foo(self) { |
| 578 | 578 | } |
| 579 | 579 | "#, |
| 580 | 580 | expect![[r#" |
| 581 | ev Bar Bar | |
| 582 | ev Baz Baz | |
| 583 | "#]], | |
| 581 | ev Bar Bar | |
| 582 | ev Baz Baz | |
| 583 | "#]], | |
| 584 | 584 | ); |
| 585 | 585 | |
| 586 | 586 | check_no_kw( |
| ... | ... | @@ -598,8 +598,8 @@ enum Foo { |
| 598 | 598 | } |
| 599 | 599 | "#, |
| 600 | 600 | expect![[r#" |
| 601 | ev Baz Baz | |
| 602 | "#]], | |
| 601 | ev Baz Baz | |
| 602 | "#]], | |
| 603 | 603 | ); |
| 604 | 604 | } |
| 605 | 605 | |
| ... | ... | @@ -623,9 +623,9 @@ impl u8 { |
| 623 | 623 | } |
| 624 | 624 | "#, |
| 625 | 625 | expect![[r#" |
| 626 | ct MAX pub const MAX: Self | |
| 627 | me func(…) fn(self) | |
| 628 | "#]], | |
| 626 | ct MAX pub const MAX: Self | |
| 627 | me func(…) fn(self) | |
| 628 | "#]], | |
| 629 | 629 | ); |
| 630 | 630 | } |
| 631 | 631 | |
| ... | ... | @@ -643,8 +643,8 @@ fn main() { |
| 643 | 643 | } |
| 644 | 644 | "#, |
| 645 | 645 | expect![[r#" |
| 646 | ev Bar Bar | |
| 647 | "#]], | |
| 646 | ev Bar Bar | |
| 647 | "#]], | |
| 648 | 648 | ); |
| 649 | 649 | } |
| 650 | 650 | |
| ... | ... | @@ -723,7 +723,7 @@ fn bar() -> Bar { |
| 723 | 723 | } |
| 724 | 724 | "#, |
| 725 | 725 | expect![[r#" |
| 726 | fn bar() fn() | |
| 726 | fn bar() fn() | |
| 727 | 727 | fn foo() (as Foo) fn() -> Self |
| 728 | 728 | ex Bar |
| 729 | 729 | ex bar() |
| ... | ... | @@ -787,7 +787,7 @@ fn main() { |
| 787 | 787 | } |
| 788 | 788 | "#, |
| 789 | 789 | expect![[r#" |
| 790 | me by_macro() (as MyTrait) fn(&self) | |
| 790 | me by_macro() (as MyTrait) fn(&self) | |
| 791 | 791 | me not_by_macro() (as MyTrait) fn(&self) |
| 792 | 792 | "#]], |
| 793 | 793 | ) |
| ... | ... | @@ -827,7 +827,7 @@ fn main() { |
| 827 | 827 | } |
| 828 | 828 | "#, |
| 829 | 829 | expect![[r#" |
| 830 | me by_macro() (as MyTrait) fn(&self) | |
| 830 | me by_macro() (as MyTrait) fn(&self) | |
| 831 | 831 | me not_by_macro() (as MyTrait) fn(&self) |
| 832 | 832 | "#]], |
| 833 | 833 | ) |
| ... | ... | @@ -885,10 +885,10 @@ fn main() { |
| 885 | 885 | } |
| 886 | 886 | "#, |
| 887 | 887 | expect![[r#" |
| 888 | fn main() fn() | |
| 889 | lc foobar i32 | |
| 890 | ma x!(…) macro_rules! x | |
| 891 | bt u32 u32 | |
| 888 | fn main() fn() | |
| 889 | lc foobar i32 | |
| 890 | ma x!(…) macro_rules! x | |
| 891 | bt u32 u32 | |
| 892 | 892 | "#]], |
| 893 | 893 | ) |
| 894 | 894 | } |
| ... | ... | @@ -1014,7 +1014,7 @@ fn here_we_go() { |
| 1014 | 1014 | } |
| 1015 | 1015 | "#, |
| 1016 | 1016 | expect![[r#" |
| 1017 | fn here_we_go() fn() | |
| 1017 | fn here_we_go() fn() | |
| 1018 | 1018 | st Foo (alias Bar) Foo |
| 1019 | 1019 | bt u32 u32 |
| 1020 | 1020 | kw async |
| ... | ... | @@ -1064,9 +1064,9 @@ fn here_we_go() { |
| 1064 | 1064 | } |
| 1065 | 1065 | "#, |
| 1066 | 1066 | expect![[r#" |
| 1067 | fn here_we_go() fn() | |
| 1067 | fn here_we_go() fn() | |
| 1068 | 1068 | st Foo (alias Bar, Qux, Baz) Foo |
| 1069 | bt u32 u32 | |
| 1069 | bt u32 u32 | |
| 1070 | 1070 | kw async |
| 1071 | 1071 | kw const |
| 1072 | 1072 | kw crate:: |
| ... | ... | @@ -1160,20 +1160,20 @@ fn here_we_go() { |
| 1160 | 1160 | } |
| 1161 | 1161 | "#, |
| 1162 | 1162 | expect![[r#" |
| 1163 | fd bar u8 | |
| 1163 | fd bar u8 | |
| 1164 | 1164 | me baz() (alias qux) fn(&self) -> u8 |
| 1165 | sn box Box::new(expr) | |
| 1166 | sn call function(expr) | |
| 1167 | sn dbg dbg!(expr) | |
| 1168 | sn dbgr dbg!(&expr) | |
| 1169 | sn deref *expr | |
| 1170 | sn let let | |
| 1171 | sn letm let mut | |
| 1172 | sn match match expr {} | |
| 1173 | sn ref &expr | |
| 1174 | sn refm &mut expr | |
| 1175 | sn return return expr | |
| 1176 | sn unsafe unsafe {} | |
| 1165 | sn box Box::new(expr) | |
| 1166 | sn call function(expr) | |
| 1167 | sn dbg dbg!(expr) | |
| 1168 | sn dbgr dbg!(&expr) | |
| 1169 | sn deref *expr | |
| 1170 | sn let let | |
| 1171 | sn letm let mut | |
| 1172 | sn match match expr {} | |
| 1173 | sn ref &expr | |
| 1174 | sn refm &mut expr | |
| 1175 | sn return return expr | |
| 1176 | sn unsafe unsafe {} | |
| 1177 | 1177 | "#]], |
| 1178 | 1178 | ); |
| 1179 | 1179 | } |
| ... | ... | @@ -1189,7 +1189,7 @@ fn bar() { qu$0 } |
| 1189 | 1189 | expect![[r#" |
| 1190 | 1190 | fn bar() fn() |
| 1191 | 1191 | fn foo() (alias qux) fn() |
| 1192 | bt u32 u32 | |
| 1192 | bt u32 u32 | |
| 1193 | 1193 | kw async |
| 1194 | 1194 | kw const |
| 1195 | 1195 | kw crate:: |
| ... | ... | @@ -1277,10 +1277,10 @@ fn here_we_go() { |
| 1277 | 1277 | } |
| 1278 | 1278 | "#, |
| 1279 | 1279 | expect![[r#" |
| 1280 | fn here_we_go() fn() | |
| 1280 | fn here_we_go() fn() | |
| 1281 | 1281 | md foo |
| 1282 | 1282 | st Bar (alias Qux) (use foo::Bar) Bar |
| 1283 | bt u32 u32 | |
| 1283 | bt u32 u32 | |
| 1284 | 1284 | kw crate:: |
| 1285 | 1285 | kw false |
| 1286 | 1286 | kw for |
| ... | ... | @@ -1315,10 +1315,9 @@ use krate::e; |
| 1315 | 1315 | fn main() { |
| 1316 | 1316 | e::$0 |
| 1317 | 1317 | }"#, |
| 1318 | expect![ | |
| 1319 | "fn i_am_public() fn() | |
| 1320 | " | |
| 1321 | ], | |
| 1318 | expect![[r#" | |
| 1319 | fn i_am_public() fn() | |
| 1320 | "#]], | |
| 1322 | 1321 | ) |
| 1323 | 1322 | } |
| 1324 | 1323 | |
| ... | ... | @@ -1444,8 +1443,8 @@ fn foo() { |
| 1444 | 1443 | "#, |
| 1445 | 1444 | Some('_'), |
| 1446 | 1445 | expect![[r#" |
| 1447 | fn foo() fn() | |
| 1448 | bt u32 u32 | |
| 1446 | fn foo() fn() | |
| 1447 | bt u32 u32 | |
| 1449 | 1448 | kw async |
| 1450 | 1449 | kw const |
| 1451 | 1450 | kw crate:: |
| ... | ... | @@ -1498,7 +1497,7 @@ fn foo(_: a_$0) { } |
| 1498 | 1497 | "#, |
| 1499 | 1498 | Some('_'), |
| 1500 | 1499 | expect![[r#" |
| 1501 | bt u32 u32 | |
| 1500 | bt u32 u32 | |
| 1502 | 1501 | kw crate:: |
| 1503 | 1502 | kw self:: |
| 1504 | 1503 | "#]], |
| ... | ... | @@ -1512,7 +1511,7 @@ fn foo<T>() { |
| 1512 | 1511 | Some('_'), |
| 1513 | 1512 | expect![[r#" |
| 1514 | 1513 | tp T |
| 1515 | bt u32 u32 | |
| 1514 | bt u32 u32 | |
| 1516 | 1515 | kw crate:: |
| 1517 | 1516 | kw self:: |
| 1518 | 1517 | "#]], |
src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs+189-189| ... | ... | @@ -17,18 +17,18 @@ struct Foo<'lt, T, const C: usize> { |
| 17 | 17 | } |
| 18 | 18 | "#, |
| 19 | 19 | expect![[r#" |
| 20 | en Enum Enum | |
| 20 | en Enum Enum | |
| 21 | 21 | ma makro!(…) macro_rules! makro |
| 22 | 22 | md module |
| 23 | sp Self Foo<'_, {unknown}, _> | |
| 24 | st Foo<…> Foo<'_, {unknown}, _> | |
| 25 | st Record Record | |
| 26 | st Tuple Tuple | |
| 27 | st Unit Unit | |
| 23 | sp Self Foo<'_, {unknown}, _> | |
| 24 | st Foo<…> Foo<'_, {unknown}, _> | |
| 25 | st Record Record | |
| 26 | st Tuple Tuple | |
| 27 | st Unit Unit | |
| 28 | 28 | tt Trait |
| 29 | 29 | tp T |
| 30 | un Union Union | |
| 31 | bt u32 u32 | |
| 30 | un Union Union | |
| 31 | bt u32 u32 | |
| 32 | 32 | kw crate:: |
| 33 | 33 | kw self:: |
| 34 | 34 | "#]], |
| ... | ... | @@ -42,18 +42,18 @@ fn tuple_struct_field() { |
| 42 | 42 | struct Foo<'lt, T, const C: usize>(f$0); |
| 43 | 43 | "#, |
| 44 | 44 | expect![[r#" |
| 45 | en Enum Enum | |
| 46 | ma makro!(…) macro_rules! makro | |
| 45 | en Enum Enum | |
| 46 | ma makro!(…) macro_rules! makro | |
| 47 | 47 | md module |
| 48 | sp Self Foo<'_, {unknown}, _> | |
| 49 | st Foo<…> Foo<'_, {unknown}, _> | |
| 50 | st Record Record | |
| 51 | st Tuple Tuple | |
| 52 | st Unit Unit | |
| 48 | sp Self Foo<'_, {unknown}, _> | |
| 49 | st Foo<…> Foo<'_, {unknown}, _> | |
| 50 | st Record Record | |
| 51 | st Tuple Tuple | |
| 52 | st Unit Unit | |
| 53 | 53 | tt Trait |
| 54 | 54 | tp T |
| 55 | un Union Union | |
| 56 | bt u32 u32 | |
| 55 | un Union Union | |
| 56 | bt u32 u32 | |
| 57 | 57 | kw crate:: |
| 58 | 58 | kw pub |
| 59 | 59 | kw pub(crate) |
| ... | ... | @@ -70,16 +70,16 @@ fn fn_return_type() { |
| 70 | 70 | fn x<'lt, T, const C: usize>() -> $0 |
| 71 | 71 | "#, |
| 72 | 72 | expect![[r#" |
| 73 | en Enum Enum | |
| 73 | en Enum Enum | |
| 74 | 74 | ma makro!(…) macro_rules! makro |
| 75 | 75 | md module |
| 76 | st Record Record | |
| 77 | st Tuple Tuple | |
| 78 | st Unit Unit | |
| 76 | st Record Record | |
| 77 | st Tuple Tuple | |
| 78 | st Unit Unit | |
| 79 | 79 | tt Trait |
| 80 | 80 | tp T |
| 81 | un Union Union | |
| 82 | bt u32 u32 | |
| 81 | un Union Union | |
| 82 | bt u32 u32 | |
| 83 | 83 | kw crate:: |
| 84 | 84 | kw self:: |
| 85 | 85 | "#]], |
| ... | ... | @@ -100,15 +100,15 @@ fn foo() -> B$0 { |
| 100 | 100 | } |
| 101 | 101 | "#, |
| 102 | 102 | expect![[r#" |
| 103 | en Enum Enum | |
| 103 | en Enum Enum | |
| 104 | 104 | ma makro!(…) macro_rules! makro |
| 105 | 105 | md module |
| 106 | st Record Record | |
| 107 | st Tuple Tuple | |
| 108 | st Unit Unit | |
| 106 | st Record Record | |
| 107 | st Tuple Tuple | |
| 108 | st Unit Unit | |
| 109 | 109 | tt Trait |
| 110 | un Union Union | |
| 111 | bt u32 u32 | |
| 110 | un Union Union | |
| 111 | bt u32 u32 | |
| 112 | 112 | it () |
| 113 | 113 | kw crate:: |
| 114 | 114 | kw self:: |
| ... | ... | @@ -124,16 +124,16 @@ struct Foo<T>(T); |
| 124 | 124 | const FOO: $0 = Foo(2); |
| 125 | 125 | "#, |
| 126 | 126 | expect![[r#" |
| 127 | en Enum Enum | |
| 127 | en Enum Enum | |
| 128 | 128 | ma makro!(…) macro_rules! makro |
| 129 | 129 | md module |
| 130 | st Foo<…> Foo<{unknown}> | |
| 131 | st Record Record | |
| 132 | st Tuple Tuple | |
| 133 | st Unit Unit | |
| 130 | st Foo<…> Foo<{unknown}> | |
| 131 | st Record Record | |
| 132 | st Tuple Tuple | |
| 133 | st Unit Unit | |
| 134 | 134 | tt Trait |
| 135 | un Union Union | |
| 136 | bt u32 u32 | |
| 135 | un Union Union | |
| 136 | bt u32 u32 | |
| 137 | 137 | it Foo<i32> |
| 138 | 138 | kw crate:: |
| 139 | 139 | kw self:: |
| ... | ... | @@ -151,15 +151,15 @@ fn f2() { |
| 151 | 151 | } |
| 152 | 152 | "#, |
| 153 | 153 | expect![[r#" |
| 154 | en Enum Enum | |
| 154 | en Enum Enum | |
| 155 | 155 | ma makro!(…) macro_rules! makro |
| 156 | 156 | md module |
| 157 | st Record Record | |
| 158 | st Tuple Tuple | |
| 159 | st Unit Unit | |
| 157 | st Record Record | |
| 158 | st Tuple Tuple | |
| 159 | st Unit Unit | |
| 160 | 160 | tt Trait |
| 161 | un Union Union | |
| 162 | bt u32 u32 | |
| 161 | un Union Union | |
| 162 | bt u32 u32 | |
| 163 | 163 | it i32 |
| 164 | 164 | kw crate:: |
| 165 | 165 | kw self:: |
| ... | ... | @@ -179,15 +179,15 @@ fn f2() { |
| 179 | 179 | } |
| 180 | 180 | "#, |
| 181 | 181 | expect![[r#" |
| 182 | en Enum Enum | |
| 182 | en Enum Enum | |
| 183 | 183 | ma makro!(…) macro_rules! makro |
| 184 | 184 | md module |
| 185 | st Record Record | |
| 186 | st Tuple Tuple | |
| 187 | st Unit Unit | |
| 185 | st Record Record | |
| 186 | st Tuple Tuple | |
| 187 | st Unit Unit | |
| 188 | 188 | tt Trait |
| 189 | un Union Union | |
| 190 | bt u32 u32 | |
| 189 | un Union Union | |
| 190 | bt u32 u32 | |
| 191 | 191 | it u64 |
| 192 | 192 | kw crate:: |
| 193 | 193 | kw self:: |
| ... | ... | @@ -204,15 +204,15 @@ fn f2(x: u64) -> $0 { |
| 204 | 204 | } |
| 205 | 205 | "#, |
| 206 | 206 | expect![[r#" |
| 207 | en Enum Enum | |
| 207 | en Enum Enum | |
| 208 | 208 | ma makro!(…) macro_rules! makro |
| 209 | 209 | md module |
| 210 | st Record Record | |
| 211 | st Tuple Tuple | |
| 212 | st Unit Unit | |
| 210 | st Record Record | |
| 211 | st Tuple Tuple | |
| 212 | st Unit Unit | |
| 213 | 213 | tt Trait |
| 214 | un Union Union | |
| 215 | bt u32 u32 | |
| 214 | un Union Union | |
| 215 | bt u32 u32 | |
| 216 | 216 | it u64 |
| 217 | 217 | kw crate:: |
| 218 | 218 | kw self:: |
| ... | ... | @@ -230,15 +230,15 @@ fn f2(x: $0) { |
| 230 | 230 | } |
| 231 | 231 | "#, |
| 232 | 232 | expect![[r#" |
| 233 | en Enum Enum | |
| 233 | en Enum Enum | |
| 234 | 234 | ma makro!(…) macro_rules! makro |
| 235 | 235 | md module |
| 236 | st Record Record | |
| 237 | st Tuple Tuple | |
| 238 | st Unit Unit | |
| 236 | st Record Record | |
| 237 | st Tuple Tuple | |
| 238 | st Unit Unit | |
| 239 | 239 | tt Trait |
| 240 | un Union Union | |
| 241 | bt u32 u32 | |
| 240 | un Union Union | |
| 241 | bt u32 u32 | |
| 242 | 242 | it i32 |
| 243 | 243 | kw crate:: |
| 244 | 244 | kw self:: |
| ... | ... | @@ -262,17 +262,17 @@ fn foo<'lt, T, const C: usize>() { |
| 262 | 262 | } |
| 263 | 263 | "#, |
| 264 | 264 | expect![[r#" |
| 265 | en Enum Enum | |
| 266 | ma makro!(…) macro_rules! makro | |
| 265 | en Enum Enum | |
| 266 | ma makro!(…) macro_rules! makro | |
| 267 | 267 | md a |
| 268 | 268 | md module |
| 269 | st Record Record | |
| 270 | st Tuple Tuple | |
| 271 | st Unit Unit | |
| 269 | st Record Record | |
| 270 | st Tuple Tuple | |
| 271 | st Unit Unit | |
| 272 | 272 | tt Trait |
| 273 | 273 | tp T |
| 274 | un Union Union | |
| 275 | bt u32 u32 | |
| 274 | un Union Union | |
| 275 | bt u32 u32 | |
| 276 | 276 | it a::Foo<a::Foo<i32>> |
| 277 | 277 | kw crate:: |
| 278 | 278 | kw self:: |
| ... | ... | @@ -291,17 +291,17 @@ fn foo<'lt, T, const C: usize>() { |
| 291 | 291 | } |
| 292 | 292 | "#, |
| 293 | 293 | expect![[r#" |
| 294 | en Enum Enum | |
| 294 | en Enum Enum | |
| 295 | 295 | ma makro!(…) macro_rules! makro |
| 296 | 296 | md module |
| 297 | st Foo<…> Foo<{unknown}> | |
| 298 | st Record Record | |
| 299 | st Tuple Tuple | |
| 300 | st Unit Unit | |
| 297 | st Foo<…> Foo<{unknown}> | |
| 298 | st Record Record | |
| 299 | st Tuple Tuple | |
| 300 | st Unit Unit | |
| 301 | 301 | tt Trait |
| 302 | 302 | tp T |
| 303 | un Union Union | |
| 304 | bt u32 u32 | |
| 303 | un Union Union | |
| 304 | bt u32 u32 | |
| 305 | 305 | it Foo<i32> |
| 306 | 306 | kw crate:: |
| 307 | 307 | kw self:: |
| ... | ... | @@ -319,16 +319,16 @@ fn foo<'lt, T, const C: usize>() { |
| 319 | 319 | } |
| 320 | 320 | "#, |
| 321 | 321 | expect![[r#" |
| 322 | en Enum Enum | |
| 322 | en Enum Enum | |
| 323 | 323 | ma makro!(…) macro_rules! makro |
| 324 | 324 | md module |
| 325 | st Record Record | |
| 326 | st Tuple Tuple | |
| 327 | st Unit Unit | |
| 325 | st Record Record | |
| 326 | st Tuple Tuple | |
| 327 | st Unit Unit | |
| 328 | 328 | tt Trait |
| 329 | 329 | tp T |
| 330 | un Union Union | |
| 331 | bt u32 u32 | |
| 330 | un Union Union | |
| 331 | bt u32 u32 | |
| 332 | 332 | kw crate:: |
| 333 | 333 | kw self:: |
| 334 | 334 | "#]], |
| ... | ... | @@ -341,14 +341,14 @@ fn foo<'lt, T, const C: usize>() { |
| 341 | 341 | } |
| 342 | 342 | "#, |
| 343 | 343 | expect![[r#" |
| 344 | en Enum Enum | |
| 344 | en Enum Enum | |
| 345 | 345 | ma makro!(…) macro_rules! makro |
| 346 | 346 | md module |
| 347 | st Record Record | |
| 348 | st Tuple Tuple | |
| 349 | st Unit Unit | |
| 347 | st Record Record | |
| 348 | st Tuple Tuple | |
| 349 | st Unit Unit | |
| 350 | 350 | tt Trait |
| 351 | un Union Union | |
| 351 | un Union Union | |
| 352 | 352 | "#]], |
| 353 | 353 | ); |
| 354 | 354 | } |
| ... | ... | @@ -368,7 +368,7 @@ trait Trait2: Trait1 { |
| 368 | 368 | fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {} |
| 369 | 369 | "#, |
| 370 | 370 | expect![[r#" |
| 371 | ta Foo = (as Trait2) type Foo | |
| 371 | ta Foo = (as Trait2) type Foo | |
| 372 | 372 | ta Super = (as Trait1) type Super |
| 373 | 373 | "#]], |
| 374 | 374 | ); |
| ... | ... | @@ -384,18 +384,18 @@ trait Trait2<T>: Trait1 { |
| 384 | 384 | fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {} |
| 385 | 385 | "#, |
| 386 | 386 | expect![[r#" |
| 387 | en Enum Enum | |
| 387 | en Enum Enum | |
| 388 | 388 | ma makro!(…) macro_rules! makro |
| 389 | 389 | md module |
| 390 | st Record Record | |
| 391 | st Tuple Tuple | |
| 392 | st Unit Unit | |
| 390 | st Record Record | |
| 391 | st Tuple Tuple | |
| 392 | st Unit Unit | |
| 393 | 393 | tt Trait |
| 394 | 394 | tt Trait1 |
| 395 | 395 | tt Trait2 |
| 396 | 396 | tp T |
| 397 | un Union Union | |
| 398 | bt u32 u32 | |
| 397 | un Union Union | |
| 398 | bt u32 u32 | |
| 399 | 399 | kw crate:: |
| 400 | 400 | kw self:: |
| 401 | 401 | "#]], |
| ... | ... | @@ -409,15 +409,15 @@ trait Trait2<T> { |
| 409 | 409 | fn foo<'lt, T: Trait2<self::$0>, const CONST_PARAM: usize>(_: T) {} |
| 410 | 410 | "#, |
| 411 | 411 | expect![[r#" |
| 412 | en Enum Enum | |
| 412 | en Enum Enum | |
| 413 | 413 | ma makro!(…) macro_rules! makro |
| 414 | 414 | md module |
| 415 | st Record Record | |
| 416 | st Tuple Tuple | |
| 417 | st Unit Unit | |
| 415 | st Record Record | |
| 416 | st Tuple Tuple | |
| 417 | st Unit Unit | |
| 418 | 418 | tt Trait |
| 419 | 419 | tt Trait2 |
| 420 | un Union Union | |
| 420 | un Union Union | |
| 421 | 421 | "#]], |
| 422 | 422 | ); |
| 423 | 423 | } |
| ... | ... | @@ -434,18 +434,18 @@ trait Tr<T> { |
| 434 | 434 | impl Tr<$0 |
| 435 | 435 | "#, |
| 436 | 436 | expect![[r#" |
| 437 | en Enum Enum | |
| 437 | en Enum Enum | |
| 438 | 438 | ma makro!(…) macro_rules! makro |
| 439 | 439 | md module |
| 440 | sp Self dyn Tr<{unknown}> | |
| 441 | st Record Record | |
| 442 | st S S | |
| 443 | st Tuple Tuple | |
| 444 | st Unit Unit | |
| 440 | sp Self dyn Tr<{unknown}> | |
| 441 | st Record Record | |
| 442 | st S S | |
| 443 | st Tuple Tuple | |
| 444 | st Unit Unit | |
| 445 | 445 | tt Tr |
| 446 | 446 | tt Trait |
| 447 | un Union Union | |
| 448 | bt u32 u32 | |
| 447 | un Union Union | |
| 448 | bt u32 u32 | |
| 449 | 449 | kw crate:: |
| 450 | 450 | kw self:: |
| 451 | 451 | "#]], |
| ... | ... | @@ -481,16 +481,16 @@ trait MyTrait<T, U> { |
| 481 | 481 | fn f(t: impl MyTrait<u$0 |
| 482 | 482 | "#, |
| 483 | 483 | expect![[r#" |
| 484 | en Enum Enum | |
| 484 | en Enum Enum | |
| 485 | 485 | ma makro!(…) macro_rules! makro |
| 486 | 486 | md module |
| 487 | st Record Record | |
| 488 | st Tuple Tuple | |
| 489 | st Unit Unit | |
| 487 | st Record Record | |
| 488 | st Tuple Tuple | |
| 489 | st Unit Unit | |
| 490 | 490 | tt MyTrait |
| 491 | 491 | tt Trait |
| 492 | un Union Union | |
| 493 | bt u32 u32 | |
| 492 | un Union Union | |
| 493 | bt u32 u32 | |
| 494 | 494 | kw crate:: |
| 495 | 495 | kw self:: |
| 496 | 496 | "#]], |
| ... | ... | @@ -506,16 +506,16 @@ trait MyTrait<T, U> { |
| 506 | 506 | fn f(t: impl MyTrait<u8, u$0 |
| 507 | 507 | "#, |
| 508 | 508 | expect![[r#" |
| 509 | en Enum Enum | |
| 509 | en Enum Enum | |
| 510 | 510 | ma makro!(…) macro_rules! makro |
| 511 | 511 | md module |
| 512 | st Record Record | |
| 513 | st Tuple Tuple | |
| 514 | st Unit Unit | |
| 512 | st Record Record | |
| 513 | st Tuple Tuple | |
| 514 | st Unit Unit | |
| 515 | 515 | tt MyTrait |
| 516 | 516 | tt Trait |
| 517 | un Union Union | |
| 518 | bt u32 u32 | |
| 517 | un Union Union | |
| 518 | bt u32 u32 | |
| 519 | 519 | kw crate:: |
| 520 | 520 | kw self:: |
| 521 | 521 | "#]], |
| ... | ... | @@ -549,16 +549,16 @@ trait MyTrait<T, U = u8> { |
| 549 | 549 | fn f(t: impl MyTrait<u$0 |
| 550 | 550 | "#, |
| 551 | 551 | expect![[r#" |
| 552 | en Enum Enum | |
| 552 | en Enum Enum | |
| 553 | 553 | ma makro!(…) macro_rules! makro |
| 554 | 554 | md module |
| 555 | st Record Record | |
| 556 | st Tuple Tuple | |
| 557 | st Unit Unit | |
| 555 | st Record Record | |
| 556 | st Tuple Tuple | |
| 557 | st Unit Unit | |
| 558 | 558 | tt MyTrait |
| 559 | 559 | tt Trait |
| 560 | un Union Union | |
| 561 | bt u32 u32 | |
| 560 | un Union Union | |
| 561 | bt u32 u32 | |
| 562 | 562 | kw crate:: |
| 563 | 563 | kw self:: |
| 564 | 564 | "#]], |
| ... | ... | @@ -574,18 +574,18 @@ trait MyTrait<T, U = u8> { |
| 574 | 574 | fn f(t: impl MyTrait<u8, u$0 |
| 575 | 575 | "#, |
| 576 | 576 | expect![[r#" |
| 577 | en Enum Enum | |
| 578 | ma makro!(…) macro_rules! makro | |
| 577 | en Enum Enum | |
| 578 | ma makro!(…) macro_rules! makro | |
| 579 | 579 | md module |
| 580 | st Record Record | |
| 581 | st Tuple Tuple | |
| 582 | st Unit Unit | |
| 580 | st Record Record | |
| 581 | st Tuple Tuple | |
| 582 | st Unit Unit | |
| 583 | 583 | tt MyTrait |
| 584 | 584 | tt Trait |
| 585 | 585 | ta Item1 = (as MyTrait) type Item1 |
| 586 | 586 | ta Item2 = (as MyTrait) type Item2 |
| 587 | un Union Union | |
| 588 | bt u32 u32 | |
| 587 | un Union Union | |
| 588 | bt u32 u32 | |
| 589 | 589 | kw crate:: |
| 590 | 590 | kw self:: |
| 591 | 591 | "#]], |
| ... | ... | @@ -619,16 +619,16 @@ trait MyTrait { |
| 619 | 619 | fn f(t: impl MyTrait<Item1 = $0 |
| 620 | 620 | "#, |
| 621 | 621 | expect![[r#" |
| 622 | en Enum Enum | |
| 622 | en Enum Enum | |
| 623 | 623 | ma makro!(…) macro_rules! makro |
| 624 | 624 | md module |
| 625 | st Record Record | |
| 626 | st Tuple Tuple | |
| 627 | st Unit Unit | |
| 625 | st Record Record | |
| 626 | st Tuple Tuple | |
| 627 | st Unit Unit | |
| 628 | 628 | tt MyTrait |
| 629 | 629 | tt Trait |
| 630 | un Union Union | |
| 631 | bt u32 u32 | |
| 630 | un Union Union | |
| 631 | bt u32 u32 | |
| 632 | 632 | kw crate:: |
| 633 | 633 | kw self:: |
| 634 | 634 | "#]], |
| ... | ... | @@ -644,16 +644,16 @@ trait MyTrait { |
| 644 | 644 | fn f(t: impl MyTrait<Item1 = u8, Item2 = $0 |
| 645 | 645 | "#, |
| 646 | 646 | expect![[r#" |
| 647 | en Enum Enum | |
| 647 | en Enum Enum | |
| 648 | 648 | ma makro!(…) macro_rules! makro |
| 649 | 649 | md module |
| 650 | st Record Record | |
| 651 | st Tuple Tuple | |
| 652 | st Unit Unit | |
| 650 | st Record Record | |
| 651 | st Tuple Tuple | |
| 652 | st Unit Unit | |
| 653 | 653 | tt MyTrait |
| 654 | 654 | tt Trait |
| 655 | un Union Union | |
| 656 | bt u32 u32 | |
| 655 | un Union Union | |
| 656 | bt u32 u32 | |
| 657 | 657 | kw crate:: |
| 658 | 658 | kw self:: |
| 659 | 659 | "#]], |
| ... | ... | @@ -668,7 +668,7 @@ trait MyTrait { |
| 668 | 668 | fn f(t: impl MyTrait<C = $0 |
| 669 | 669 | "#, |
| 670 | 670 | expect![[r#" |
| 671 | ct CONST Unit | |
| 671 | ct CONST Unit | |
| 672 | 672 | ma makro!(…) macro_rules! makro |
| 673 | 673 | kw crate:: |
| 674 | 674 | kw self:: |
| ... | ... | @@ -691,9 +691,9 @@ pub struct S; |
| 691 | 691 | "#, |
| 692 | 692 | expect![[r#" |
| 693 | 693 | md std |
| 694 | sp Self Foo | |
| 695 | st Foo Foo | |
| 696 | bt u32 u32 | |
| 694 | sp Self Foo | |
| 695 | st Foo Foo | |
| 696 | bt u32 u32 | |
| 697 | 697 | kw crate:: |
| 698 | 698 | kw self:: |
| 699 | 699 | "#]], |
| ... | ... | @@ -716,10 +716,10 @@ pub struct S; |
| 716 | 716 | "#, |
| 717 | 717 | expect![[r#" |
| 718 | 718 | md std |
| 719 | sp Self Foo | |
| 720 | st Foo Foo | |
| 721 | st S S | |
| 722 | bt u32 u32 | |
| 719 | sp Self Foo | |
| 720 | st Foo Foo | |
| 721 | st S S | |
| 722 | bt u32 u32 | |
| 723 | 723 | kw crate:: |
| 724 | 724 | kw self:: |
| 725 | 725 | "#]], |
| ... | ... | @@ -739,16 +739,16 @@ fn completes_const_and_type_generics_separately() { |
| 739 | 739 | } |
| 740 | 740 | "#, |
| 741 | 741 | expect![[r#" |
| 742 | en Enum Enum | |
| 742 | en Enum Enum | |
| 743 | 743 | ma makro!(…) macro_rules! makro |
| 744 | 744 | md module |
| 745 | st Foo Foo | |
| 746 | st Record Record | |
| 747 | st Tuple Tuple | |
| 748 | st Unit Unit | |
| 745 | st Foo Foo | |
| 746 | st Record Record | |
| 747 | st Tuple Tuple | |
| 748 | st Unit Unit | |
| 749 | 749 | tt Trait |
| 750 | un Union Union | |
| 751 | bt u32 u32 | |
| 750 | un Union Union | |
| 751 | bt u32 u32 | |
| 752 | 752 | kw crate:: |
| 753 | 753 | kw self:: |
| 754 | 754 | "#]], |
| ... | ... | @@ -766,8 +766,8 @@ fn completes_const_and_type_generics_separately() { |
| 766 | 766 | } |
| 767 | 767 | "#, |
| 768 | 768 | expect![[r#" |
| 769 | ct CONST Unit | |
| 770 | ct X usize | |
| 769 | ct CONST Unit | |
| 770 | ct X usize | |
| 771 | 771 | ma makro!(…) macro_rules! makro |
| 772 | 772 | kw crate:: |
| 773 | 773 | kw self:: |
| ... | ... | @@ -785,16 +785,16 @@ fn completes_const_and_type_generics_separately() { |
| 785 | 785 | } |
| 786 | 786 | "#, |
| 787 | 787 | expect![[r#" |
| 788 | en Enum Enum | |
| 788 | en Enum Enum | |
| 789 | 789 | ma makro!(…) macro_rules! makro |
| 790 | 790 | md module |
| 791 | st Foo Foo | |
| 792 | st Record Record | |
| 793 | st Tuple Tuple | |
| 794 | st Unit Unit | |
| 791 | st Foo Foo | |
| 792 | st Record Record | |
| 793 | st Tuple Tuple | |
| 794 | st Unit Unit | |
| 795 | 795 | tt Trait |
| 796 | un Union Union | |
| 797 | bt u32 u32 | |
| 796 | un Union Union | |
| 797 | bt u32 u32 | |
| 798 | 798 | kw crate:: |
| 799 | 799 | kw self:: |
| 800 | 800 | "#]], |
| ... | ... | @@ -809,8 +809,8 @@ fn completes_const_and_type_generics_separately() { |
| 809 | 809 | } |
| 810 | 810 | "#, |
| 811 | 811 | expect![[r#" |
| 812 | ct CONST Unit | |
| 813 | ct X usize | |
| 812 | ct CONST Unit | |
| 813 | ct X usize | |
| 814 | 814 | ma makro!(…) macro_rules! makro |
| 815 | 815 | kw crate:: |
| 816 | 816 | kw self:: |
| ... | ... | @@ -828,17 +828,17 @@ fn completes_const_and_type_generics_separately() { |
| 828 | 828 | fn foo(_: impl Bar<Baz<F$0, 0> = ()>) {} |
| 829 | 829 | "#, |
| 830 | 830 | expect![[r#" |
| 831 | en Enum Enum | |
| 831 | en Enum Enum | |
| 832 | 832 | ma makro!(…) macro_rules! makro |
| 833 | 833 | md module |
| 834 | st Foo Foo | |
| 835 | st Record Record | |
| 836 | st Tuple Tuple | |
| 837 | st Unit Unit | |
| 834 | st Foo Foo | |
| 835 | st Record Record | |
| 836 | st Tuple Tuple | |
| 837 | st Unit Unit | |
| 838 | 838 | tt Bar |
| 839 | 839 | tt Trait |
| 840 | un Union Union | |
| 841 | bt u32 u32 | |
| 840 | un Union Union | |
| 841 | bt u32 u32 | |
| 842 | 842 | kw crate:: |
| 843 | 843 | kw self:: |
| 844 | 844 | "#]], |
| ... | ... | @@ -853,8 +853,8 @@ fn completes_const_and_type_generics_separately() { |
| 853 | 853 | fn foo<T: Bar<Baz<(), $0> = ()>>() {} |
| 854 | 854 | "#, |
| 855 | 855 | expect![[r#" |
| 856 | ct CONST Unit | |
| 857 | ct X usize | |
| 856 | ct CONST Unit | |
| 857 | ct X usize | |
| 858 | 858 | ma makro!(…) macro_rules! makro |
| 859 | 859 | kw crate:: |
| 860 | 860 | kw self:: |
| ... | ... | @@ -871,8 +871,8 @@ fn completes_const_and_type_generics_separately() { |
| 871 | 871 | } |
| 872 | 872 | "#, |
| 873 | 873 | expect![[r#" |
| 874 | ct CONST Unit | |
| 875 | ct X usize | |
| 874 | ct CONST Unit | |
| 875 | ct X usize | |
| 876 | 876 | ma makro!(…) macro_rules! makro |
| 877 | 877 | kw crate:: |
| 878 | 878 | kw self:: |
| ... | ... | @@ -890,8 +890,8 @@ fn completes_const_and_type_generics_separately() { |
| 890 | 890 | } |
| 891 | 891 | "#, |
| 892 | 892 | expect![[r#" |
| 893 | ct CONST Unit | |
| 894 | ct X usize | |
| 893 | ct CONST Unit | |
| 894 | ct X usize | |
| 895 | 895 | ma makro!(…) macro_rules! makro |
| 896 | 896 | kw crate:: |
| 897 | 897 | kw self:: |
| ... | ... | @@ -908,8 +908,8 @@ fn completes_const_and_type_generics_separately() { |
| 908 | 908 | } |
| 909 | 909 | "#, |
| 910 | 910 | expect![[r#" |
| 911 | ct CONST Unit | |
| 912 | ct X usize | |
| 911 | ct CONST Unit | |
| 912 | ct X usize | |
| 913 | 913 | ma makro!(…) macro_rules! makro |
| 914 | 914 | kw crate:: |
| 915 | 915 | kw self:: |
| ... | ... | @@ -924,8 +924,8 @@ fn completes_const_and_type_generics_separately() { |
| 924 | 924 | impl Foo<(), $0> for () {} |
| 925 | 925 | "#, |
| 926 | 926 | expect![[r#" |
| 927 | ct CONST Unit | |
| 928 | ct X usize | |
| 927 | ct CONST Unit | |
| 928 | ct X usize | |
| 929 | 929 | ma makro!(…) macro_rules! makro |
| 930 | 930 | kw crate:: |
| 931 | 931 | kw self:: |
| ... | ... | @@ -942,8 +942,8 @@ fn completes_const_and_type_generics_separately() { |
| 942 | 942 | fn foo<T: Bar<X$0, ()>>() {} |
| 943 | 943 | "#, |
| 944 | 944 | expect![[r#" |
| 945 | ct CONST Unit | |
| 946 | ct X usize | |
| 945 | ct CONST Unit | |
| 946 | ct X usize | |
| 947 | 947 | ma makro!(…) macro_rules! makro |
| 948 | 948 | kw crate:: |
| 949 | 949 | kw self:: |
| ... | ... | @@ -957,7 +957,7 @@ struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>); |
| 957 | 957 | fn foo<'a>() { S::<F$0, _>; } |
| 958 | 958 | "#, |
| 959 | 959 | expect![[r#" |
| 960 | ct CONST Unit | |
| 960 | ct CONST Unit | |
| 961 | 961 | ma makro!(…) macro_rules! makro |
| 962 | 962 | kw crate:: |
| 963 | 963 | kw self:: |
| ... | ... | @@ -970,7 +970,7 @@ struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>); |
| 970 | 970 | fn foo<'a>() { S::<'static, 'static, F$0, _>; } |
| 971 | 971 | "#, |
| 972 | 972 | expect![[r#" |
| 973 | ct CONST Unit | |
| 973 | ct CONST Unit | |
| 974 | 974 | ma makro!(…) macro_rules! makro |
| 975 | 975 | kw crate:: |
| 976 | 976 | kw self:: |
src/tools/rust-analyzer/crates/ide-completion/src/tests/use_tree.rs+7-7| ... | ... | @@ -92,7 +92,7 @@ use self::{foo::*, bar$0}; |
| 92 | 92 | "#, |
| 93 | 93 | expect![[r#" |
| 94 | 94 | md foo |
| 95 | st S S | |
| 95 | st S S | |
| 96 | 96 | "#]], |
| 97 | 97 | ); |
| 98 | 98 | } |
| ... | ... | @@ -179,7 +179,7 @@ struct Bar; |
| 179 | 179 | "#, |
| 180 | 180 | expect![[r#" |
| 181 | 181 | ma foo macro_rules! foo_ |
| 182 | st Foo Foo | |
| 182 | st Foo Foo | |
| 183 | 183 | "#]], |
| 184 | 184 | ); |
| 185 | 185 | } |
| ... | ... | @@ -203,8 +203,8 @@ impl Foo { |
| 203 | 203 | "#, |
| 204 | 204 | expect![[r#" |
| 205 | 205 | ev RecordVariant RecordVariant |
| 206 | ev TupleVariant TupleVariant | |
| 207 | ev UnitVariant UnitVariant | |
| 206 | ev TupleVariant TupleVariant | |
| 207 | ev UnitVariant UnitVariant | |
| 208 | 208 | "#]], |
| 209 | 209 | ); |
| 210 | 210 | } |
| ... | ... | @@ -257,7 +257,7 @@ mod a { |
| 257 | 257 | } |
| 258 | 258 | "#, |
| 259 | 259 | expect![[r#" |
| 260 | ct A usize | |
| 260 | ct A usize | |
| 261 | 261 | md b |
| 262 | 262 | kw super:: |
| 263 | 263 | "#]], |
| ... | ... | @@ -450,9 +450,9 @@ pub fn foo() {} |
| 450 | 450 | marco_rules! m { () => {} } |
| 451 | 451 | "#, |
| 452 | 452 | expect![[r#" |
| 453 | fn foo fn() | |
| 453 | fn foo fn() | |
| 454 | 454 | md simd |
| 455 | st S S | |
| 455 | st S S | |
| 456 | 456 | "#]], |
| 457 | 457 | ); |
| 458 | 458 | } |
src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs+97-116| ... | ... | @@ -2,10 +2,10 @@ |
| 2 | 2 | |
| 3 | 3 | use hir::{ |
| 4 | 4 | db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ImportPathConfig, |
| 5 | ItemInNs, ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, | |
| 5 | ItemInNs, ModPath, Module, ModuleDef, PathResolution, PrefixKind, ScopeDef, Semantics, | |
| 6 | 6 | SemanticsScope, Trait, TyFingerprint, Type, |
| 7 | 7 | }; |
| 8 | use itertools::{EitherOrBoth, Itertools}; | |
| 8 | use itertools::Itertools; | |
| 9 | 9 | use rustc_hash::{FxHashMap, FxHashSet}; |
| 10 | 10 | use syntax::{ |
| 11 | 11 | ast::{self, make, HasName}, |
| ... | ... | @@ -13,7 +13,6 @@ use syntax::{ |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | 15 | use crate::{ |
| 16 | helpers::item_name, | |
| 17 | 16 | items_locator::{self, AssocSearchMode, DEFAULT_QUERY_SEARCH_LIMIT}, |
| 18 | 17 | FxIndexSet, RootDatabase, |
| 19 | 18 | }; |
| ... | ... | @@ -52,7 +51,7 @@ pub struct TraitImportCandidate { |
| 52 | 51 | #[derive(Debug)] |
| 53 | 52 | pub struct PathImportCandidate { |
| 54 | 53 | /// Optional qualifier before name. |
| 55 | pub qualifier: Option<Vec<SmolStr>>, | |
| 54 | pub qualifier: Vec<SmolStr>, | |
| 56 | 55 | /// The name the item (struct, trait, enum, etc.) should have. |
| 57 | 56 | pub name: NameToImport, |
| 58 | 57 | } |
| ... | ... | @@ -264,7 +263,6 @@ impl ImportAssets { |
| 264 | 263 | Some(it) => it, |
| 265 | 264 | None => return <FxIndexSet<_>>::default().into_iter(), |
| 266 | 265 | }; |
| 267 | ||
| 268 | 266 | let krate = self.module_with_candidate.krate(); |
| 269 | 267 | let scope_definitions = self.scope_definitions(sema); |
| 270 | 268 | let mod_path = |item| { |
| ... | ... | @@ -279,11 +277,14 @@ impl ImportAssets { |
| 279 | 277 | }; |
| 280 | 278 | |
| 281 | 279 | match &self.import_candidate { |
| 282 | ImportCandidate::Path(path_candidate) => { | |
| 283 | path_applicable_imports(sema, krate, path_candidate, mod_path, |item_to_import| { | |
| 284 | !scope_definitions.contains(&ScopeDef::from(item_to_import)) | |
| 285 | }) | |
| 286 | } | |
| 280 | ImportCandidate::Path(path_candidate) => path_applicable_imports( | |
| 281 | sema, | |
| 282 | &scope, | |
| 283 | krate, | |
| 284 | path_candidate, | |
| 285 | mod_path, | |
| 286 | |item_to_import| !scope_definitions.contains(&ScopeDef::from(item_to_import)), | |
| 287 | ), | |
| 287 | 288 | ImportCandidate::TraitAssocItem(trait_candidate) |
| 288 | 289 | | ImportCandidate::TraitMethod(trait_candidate) => trait_applicable_items( |
| 289 | 290 | sema, |
| ... | ... | @@ -315,6 +316,7 @@ impl ImportAssets { |
| 315 | 316 | |
| 316 | 317 | fn path_applicable_imports( |
| 317 | 318 | sema: &Semantics<'_, RootDatabase>, |
| 319 | scope: &SemanticsScope<'_>, | |
| 318 | 320 | current_crate: Crate, |
| 319 | 321 | path_candidate: &PathImportCandidate, |
| 320 | 322 | mod_path: impl Fn(ItemInNs) -> Option<ModPath> + Copy, |
| ... | ... | @@ -322,8 +324,8 @@ fn path_applicable_imports( |
| 322 | 324 | ) -> FxIndexSet<LocatedImport> { |
| 323 | 325 | let _p = tracing::info_span!("ImportAssets::path_applicable_imports").entered(); |
| 324 | 326 | |
| 325 | match &path_candidate.qualifier { | |
| 326 | None => { | |
| 327 | match &*path_candidate.qualifier { | |
| 328 | [] => { | |
| 327 | 329 | items_locator::items_with_name( |
| 328 | 330 | sema, |
| 329 | 331 | current_crate, |
| ... | ... | @@ -348,89 +350,107 @@ fn path_applicable_imports( |
| 348 | 350 | .take(DEFAULT_QUERY_SEARCH_LIMIT.inner()) |
| 349 | 351 | .collect() |
| 350 | 352 | } |
| 351 | Some(qualifier) => items_locator::items_with_name( | |
| 353 | [first_qsegment, qualifier_rest @ ..] => items_locator::items_with_name( | |
| 352 | 354 | sema, |
| 353 | 355 | current_crate, |
| 354 | path_candidate.name.clone(), | |
| 355 | AssocSearchMode::Include, | |
| 356 | NameToImport::Exact(first_qsegment.to_string(), true), | |
| 357 | AssocSearchMode::Exclude, | |
| 356 | 358 | ) |
| 357 | .filter_map(|item| import_for_item(sema.db, mod_path, qualifier, item, scope_filter)) | |
| 359 | .filter_map(|item| { | |
| 360 | import_for_item( | |
| 361 | sema, | |
| 362 | scope, | |
| 363 | mod_path, | |
| 364 | &path_candidate.name, | |
| 365 | item, | |
| 366 | qualifier_rest, | |
| 367 | scope_filter, | |
| 368 | ) | |
| 369 | }) | |
| 358 | 370 | .take(DEFAULT_QUERY_SEARCH_LIMIT.inner()) |
| 359 | 371 | .collect(), |
| 360 | 372 | } |
| 361 | 373 | } |
| 362 | 374 | |
| 363 | 375 | fn import_for_item( |
| 364 | db: &RootDatabase, | |
| 376 | sema: &Semantics<'_, RootDatabase>, | |
| 377 | scope: &SemanticsScope<'_>, | |
| 365 | 378 | mod_path: impl Fn(ItemInNs) -> Option<ModPath>, |
| 379 | candidate: &NameToImport, | |
| 380 | resolved_qualifier: ItemInNs, | |
| 366 | 381 | unresolved_qualifier: &[SmolStr], |
| 367 | original_item: ItemInNs, | |
| 368 | 382 | scope_filter: impl Fn(ItemInNs) -> bool, |
| 369 | 383 | ) -> Option<LocatedImport> { |
| 370 | 384 | let _p = tracing::info_span!("ImportAssets::import_for_item").entered(); |
| 371 | let [first_segment, ..] = unresolved_qualifier else { return None }; | |
| 372 | ||
| 373 | let item_as_assoc = item_as_assoc(db, original_item); | |
| 374 | 385 | |
| 375 | let (original_item_candidate, trait_item_to_import) = match item_as_assoc { | |
| 376 | Some(assoc_item) => match assoc_item.container(db) { | |
| 377 | AssocItemContainer::Trait(trait_) => { | |
| 378 | let trait_ = ItemInNs::from(ModuleDef::from(trait_)); | |
| 379 | (trait_, Some(trait_)) | |
| 380 | } | |
| 381 | AssocItemContainer::Impl(impl_) => { | |
| 382 | (ItemInNs::from(ModuleDef::from(impl_.self_ty(db).as_adt()?)), None) | |
| 386 | let qualifier = { | |
| 387 | let mut adjusted_resolved_qualifier = resolved_qualifier; | |
| 388 | if !unresolved_qualifier.is_empty() { | |
| 389 | match resolved_qualifier { | |
| 390 | ItemInNs::Types(ModuleDef::Module(module)) => { | |
| 391 | adjusted_resolved_qualifier = sema | |
| 392 | .resolve_mod_path_relative(module, unresolved_qualifier.iter().cloned())? | |
| 393 | .next()?; | |
| 394 | } | |
| 395 | // can't resolve multiple segments for non-module item path bases | |
| 396 | _ => return None, | |
| 383 | 397 | } |
| 384 | }, | |
| 385 | None => (original_item, None), | |
| 386 | }; | |
| 387 | let import_path_candidate = mod_path(original_item_candidate)?; | |
| 388 | ||
| 389 | let mut import_path_candidate_segments = import_path_candidate.segments().iter().rev(); | |
| 390 | let predicate = |it: EitherOrBoth<&SmolStr, &Name>| match it { | |
| 391 | // segments match, check next one | |
| 392 | EitherOrBoth::Both(a, b) if b.as_str() == &**a => None, | |
| 393 | // segments mismatch / qualifier is longer than the path, bail out | |
| 394 | EitherOrBoth::Both(..) | EitherOrBoth::Left(_) => Some(false), | |
| 395 | // all segments match and we have exhausted the qualifier, proceed | |
| 396 | EitherOrBoth::Right(_) => Some(true), | |
| 397 | }; | |
| 398 | if item_as_assoc.is_none() { | |
| 399 | let item_name = item_name(db, original_item)?; | |
| 400 | let last_segment = import_path_candidate_segments.next()?; | |
| 401 | if *last_segment != item_name { | |
| 402 | return None; | |
| 403 | 398 | } |
| 404 | } | |
| 405 | let ends_with = unresolved_qualifier | |
| 406 | .iter() | |
| 407 | .rev() | |
| 408 | .zip_longest(import_path_candidate_segments) | |
| 409 | .find_map(predicate) | |
| 410 | .unwrap_or(true); | |
| 411 | if !ends_with { | |
| 412 | return None; | |
| 413 | } | |
| 414 | 399 | |
| 415 | let segment_import = find_import_for_segment(db, original_item_candidate, first_segment)?; | |
| 416 | ||
| 417 | Some(match (segment_import == original_item_candidate, trait_item_to_import) { | |
| 418 | (true, Some(_)) => { | |
| 419 | // FIXME we should be able to import both the trait and the segment, | |
| 420 | // but it's unclear what to do with overlapping edits (merge imports?) | |
| 421 | // especially in case of lazy completion edit resolutions. | |
| 422 | return None; | |
| 400 | match adjusted_resolved_qualifier { | |
| 401 | ItemInNs::Types(def) => def, | |
| 402 | _ => return None, | |
| 423 | 403 | } |
| 424 | (false, Some(trait_to_import)) if scope_filter(trait_to_import) => { | |
| 425 | LocatedImport::new(mod_path(trait_to_import)?, trait_to_import, original_item) | |
| 404 | }; | |
| 405 | let import_path_candidate = mod_path(resolved_qualifier)?; | |
| 406 | let ty = match qualifier { | |
| 407 | ModuleDef::Module(module) => { | |
| 408 | return items_locator::items_with_name_in_module( | |
| 409 | sema, | |
| 410 | module, | |
| 411 | candidate.clone(), | |
| 412 | AssocSearchMode::Exclude, | |
| 413 | ) | |
| 414 | .find(|&it| scope_filter(it)) | |
| 415 | .map(|item| LocatedImport::new(import_path_candidate, resolved_qualifier, item)) | |
| 426 | 416 | } |
| 427 | (true, None) if scope_filter(original_item_candidate) => { | |
| 428 | LocatedImport::new(import_path_candidate, original_item_candidate, original_item) | |
| 417 | // FIXME | |
| 418 | ModuleDef::Trait(_) => return None, | |
| 419 | // FIXME | |
| 420 | ModuleDef::TraitAlias(_) => return None, | |
| 421 | ModuleDef::TypeAlias(alias) => alias.ty(sema.db), | |
| 422 | ModuleDef::BuiltinType(builtin) => builtin.ty(sema.db), | |
| 423 | ModuleDef::Adt(adt) => adt.ty(sema.db), | |
| 424 | _ => return None, | |
| 425 | }; | |
| 426 | ty.iterate_path_candidates(sema.db, scope, &FxHashSet::default(), None, None, |assoc| { | |
| 427 | // FIXME: Support extra trait imports | |
| 428 | if assoc.container_or_implemented_trait(sema.db).is_some() { | |
| 429 | return None; | |
| 429 | 430 | } |
| 430 | (false, None) if scope_filter(segment_import) => { | |
| 431 | LocatedImport::new(mod_path(segment_import)?, segment_import, original_item) | |
| 431 | let name = assoc.name(sema.db)?; | |
| 432 | let is_match = match candidate { | |
| 433 | NameToImport::Prefix(text, true) => name.as_str().starts_with(text), | |
| 434 | NameToImport::Prefix(text, false) => { | |
| 435 | name.as_str().chars().zip(text.chars()).all(|(name_char, candidate_char)| { | |
| 436 | name_char.eq_ignore_ascii_case(&candidate_char) | |
| 437 | }) | |
| 438 | } | |
| 439 | NameToImport::Exact(text, true) => name.as_str() == text, | |
| 440 | NameToImport::Exact(text, false) => name.as_str().eq_ignore_ascii_case(text), | |
| 441 | NameToImport::Fuzzy(text, true) => text.chars().all(|c| name.as_str().contains(c)), | |
| 442 | NameToImport::Fuzzy(text, false) => text | |
| 443 | .chars() | |
| 444 | .all(|c| name.as_str().chars().any(|name_char| name_char.eq_ignore_ascii_case(&c))), | |
| 445 | }; | |
| 446 | if !is_match { | |
| 447 | return None; | |
| 432 | 448 | } |
| 433 | _ => return None, | |
| 449 | Some(LocatedImport::new( | |
| 450 | import_path_candidate.clone(), | |
| 451 | resolved_qualifier, | |
| 452 | assoc_to_item(assoc), | |
| 453 | )) | |
| 434 | 454 | }) |
| 435 | 455 | } |
| 436 | 456 | |
| ... | ... | @@ -453,45 +473,6 @@ fn item_for_path_search_assoc(db: &RootDatabase, assoc_item: AssocItem) -> Optio |
| 453 | 473 | }) |
| 454 | 474 | } |
| 455 | 475 | |
| 456 | fn find_import_for_segment( | |
| 457 | db: &RootDatabase, | |
| 458 | original_item: ItemInNs, | |
| 459 | unresolved_first_segment: &str, | |
| 460 | ) -> Option<ItemInNs> { | |
| 461 | let segment_is_name = item_name(db, original_item) | |
| 462 | .map(|name| name.eq_ident(unresolved_first_segment)) | |
| 463 | .unwrap_or(false); | |
| 464 | ||
| 465 | Some(if segment_is_name { | |
| 466 | original_item | |
| 467 | } else { | |
| 468 | let matching_module = | |
| 469 | module_with_segment_name(db, unresolved_first_segment, original_item)?; | |
| 470 | ItemInNs::from(ModuleDef::from(matching_module)) | |
| 471 | }) | |
| 472 | } | |
| 473 | ||
| 474 | fn module_with_segment_name( | |
| 475 | db: &RootDatabase, | |
| 476 | segment_name: &str, | |
| 477 | candidate: ItemInNs, | |
| 478 | ) -> Option<Module> { | |
| 479 | let mut current_module = match candidate { | |
| 480 | ItemInNs::Types(module_def_id) => module_def_id.module(db), | |
| 481 | ItemInNs::Values(module_def_id) => module_def_id.module(db), | |
| 482 | ItemInNs::Macros(macro_def_id) => ModuleDef::from(macro_def_id).module(db), | |
| 483 | }; | |
| 484 | while let Some(module) = current_module { | |
| 485 | if let Some(module_name) = module.name(db) { | |
| 486 | if module_name.eq_ident(segment_name) { | |
| 487 | return Some(module); | |
| 488 | } | |
| 489 | } | |
| 490 | current_module = module.parent(db); | |
| 491 | } | |
| 492 | None | |
| 493 | } | |
| 494 | ||
| 495 | 476 | fn trait_applicable_items( |
| 496 | 477 | sema: &Semantics<'_, RootDatabase>, |
| 497 | 478 | current_crate: Crate, |
| ... | ... | @@ -703,7 +684,7 @@ impl ImportCandidate { |
| 703 | 684 | return None; |
| 704 | 685 | } |
| 705 | 686 | Some(ImportCandidate::Path(PathImportCandidate { |
| 706 | qualifier: None, | |
| 687 | qualifier: vec![], | |
| 707 | 688 | name: NameToImport::exact_case_sensitive(name.to_string()), |
| 708 | 689 | })) |
| 709 | 690 | } |
| ... | ... | @@ -730,7 +711,7 @@ fn path_import_candidate( |
| 730 | 711 | .segments() |
| 731 | 712 | .map(|seg| seg.name_ref().map(|name| SmolStr::new(name.text()))) |
| 732 | 713 | .collect::<Option<Vec<_>>>()?; |
| 733 | ImportCandidate::Path(PathImportCandidate { qualifier: Some(qualifier), name }) | |
| 714 | ImportCandidate::Path(PathImportCandidate { qualifier, name }) | |
| 734 | 715 | } else { |
| 735 | 716 | return None; |
| 736 | 717 | } |
| ... | ... | @@ -754,10 +735,10 @@ fn path_import_candidate( |
| 754 | 735 | } |
| 755 | 736 | Some(_) => return None, |
| 756 | 737 | }, |
| 757 | None => ImportCandidate::Path(PathImportCandidate { qualifier: None, name }), | |
| 738 | None => ImportCandidate::Path(PathImportCandidate { qualifier: vec![], name }), | |
| 758 | 739 | }) |
| 759 | 740 | } |
| 760 | 741 | |
| 761 | 742 | fn item_as_assoc(db: &RootDatabase, item: ItemInNs) -> Option<AssocItem> { |
| 762 | item.as_module_def().and_then(|module_def| module_def.as_assoc_item(db)) | |
| 743 | item.into_module_def().as_assoc_item(db) | |
| 763 | 744 | } |
src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs+55-4| ... | ... | @@ -3,10 +3,14 @@ |
| 3 | 3 | //! The main reason for this module to exist is the fact that project's items and dependencies' items |
| 4 | 4 | //! are located in different caches, with different APIs. |
| 5 | 5 | use either::Either; |
| 6 | use hir::{import_map, Crate, ItemInNs, Semantics}; | |
| 6 | use hir::{import_map, Crate, ItemInNs, Module, Semantics}; | |
| 7 | 7 | use limit::Limit; |
| 8 | 8 | |
| 9 | use crate::{imports::import_assets::NameToImport, symbol_index, RootDatabase}; | |
| 9 | use crate::{ | |
| 10 | imports::import_assets::NameToImport, | |
| 11 | symbol_index::{self, SymbolsDatabase as _}, | |
| 12 | RootDatabase, | |
| 13 | }; | |
| 10 | 14 | |
| 11 | 15 | /// A value to use, when uncertain which limit to pick. |
| 12 | 16 | pub static DEFAULT_QUERY_SEARCH_LIMIT: Limit = Limit::new(100); |
| ... | ... | @@ -20,8 +24,7 @@ pub fn items_with_name<'a>( |
| 20 | 24 | name: NameToImport, |
| 21 | 25 | assoc_item_search: AssocSearchMode, |
| 22 | 26 | ) -> impl Iterator<Item = ItemInNs> + 'a { |
| 23 | let krate_name = krate.display_name(sema.db).map(|name| name.to_string()); | |
| 24 | let _p = tracing::info_span!("items_with_name", name = name.text(), assoc_item_search = ?assoc_item_search, crate = ?krate_name) | |
| 27 | let _p = tracing::info_span!("items_with_name", name = name.text(), assoc_item_search = ?assoc_item_search, crate = ?krate.display_name(sema.db).map(|name| name.to_string())) | |
| 25 | 28 | .entered(); |
| 26 | 29 | |
| 27 | 30 | let prefix = matches!(name, NameToImport::Prefix(..)); |
| ... | ... | @@ -66,6 +69,54 @@ pub fn items_with_name<'a>( |
| 66 | 69 | find_items(sema, krate, local_query, external_query) |
| 67 | 70 | } |
| 68 | 71 | |
| 72 | /// Searches for importable items with the given name in the crate and its dependencies. | |
| 73 | pub fn items_with_name_in_module<'a>( | |
| 74 | sema: &'a Semantics<'_, RootDatabase>, | |
| 75 | module: Module, | |
| 76 | name: NameToImport, | |
| 77 | assoc_item_search: AssocSearchMode, | |
| 78 | ) -> impl Iterator<Item = ItemInNs> + 'a { | |
| 79 | let _p = tracing::info_span!("items_with_name_in", name = name.text(), assoc_item_search = ?assoc_item_search, ?module) | |
| 80 | .entered(); | |
| 81 | ||
| 82 | let prefix = matches!(name, NameToImport::Prefix(..)); | |
| 83 | let local_query = match name { | |
| 84 | NameToImport::Prefix(exact_name, case_sensitive) | |
| 85 | | NameToImport::Exact(exact_name, case_sensitive) => { | |
| 86 | let mut local_query = symbol_index::Query::new(exact_name.clone()); | |
| 87 | local_query.assoc_search_mode(assoc_item_search); | |
| 88 | if prefix { | |
| 89 | local_query.prefix(); | |
| 90 | } else { | |
| 91 | local_query.exact(); | |
| 92 | } | |
| 93 | if case_sensitive { | |
| 94 | local_query.case_sensitive(); | |
| 95 | } | |
| 96 | local_query | |
| 97 | } | |
| 98 | NameToImport::Fuzzy(fuzzy_search_string, case_sensitive) => { | |
| 99 | let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone()); | |
| 100 | local_query.fuzzy(); | |
| 101 | local_query.assoc_search_mode(assoc_item_search); | |
| 102 | ||
| 103 | if case_sensitive { | |
| 104 | local_query.case_sensitive(); | |
| 105 | } | |
| 106 | ||
| 107 | local_query | |
| 108 | } | |
| 109 | }; | |
| 110 | let mut local_results = Vec::new(); | |
| 111 | local_query.search(&[sema.db.module_symbols(module)], |local_candidate| { | |
| 112 | local_results.push(match local_candidate.def { | |
| 113 | hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def), | |
| 114 | def => ItemInNs::from(def), | |
| 115 | }) | |
| 116 | }); | |
| 117 | local_results.into_iter() | |
| 118 | } | |
| 119 | ||
| 69 | 120 | fn find_items<'a>( |
| 70 | 121 | sema: &'a Semantics<'_, RootDatabase>, |
| 71 | 122 | krate: Crate, |
src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs+2| ... | ... | @@ -377,6 +377,8 @@ fn name_of_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option<S |
| 377 | 377 | return None; |
| 378 | 378 | } |
| 379 | 379 | name |
| 380 | } else if let Some(inner_ty) = ty.remove_ref() { | |
| 381 | return name_of_type(&inner_ty, db, edition); | |
| 380 | 382 | } else { |
| 381 | 383 | return None; |
| 382 | 384 | }; |
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs+16| ... | ... | @@ -778,4 +778,20 @@ fn bar(mut v: Union2) { |
| 778 | 778 | "#, |
| 779 | 779 | ) |
| 780 | 780 | } |
| 781 | ||
| 782 | #[test] | |
| 783 | fn raw_ref_reborrow_is_safe() { | |
| 784 | check_diagnostics( | |
| 785 | r#" | |
| 786 | fn main() { | |
| 787 | let ptr: *mut i32; | |
| 788 | let _addr = &raw const *ptr; | |
| 789 | ||
| 790 | let local = 1; | |
| 791 | let ptr = &local as *const i32; | |
| 792 | let _addr = &raw const *ptr; | |
| 793 | } | |
| 794 | "#, | |
| 795 | ) | |
| 796 | } | |
| 781 | 797 | } |
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs+18-1| ... | ... | @@ -90,7 +90,9 @@ fn field_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option<A |
| 90 | 90 | make::ty("()") |
| 91 | 91 | }; |
| 92 | 92 | |
| 93 | if !is_editable_crate(target_module.krate(), ctx.sema.db) { | |
| 93 | if !is_editable_crate(target_module.krate(), ctx.sema.db) | |
| 94 | || SyntaxKind::from_keyword(field_name, ctx.edition).is_some() | |
| 95 | { | |
| 94 | 96 | return None; |
| 95 | 97 | } |
| 96 | 98 | |
| ... | ... | @@ -501,4 +503,19 @@ fn main() {} |
| 501 | 503 | "#, |
| 502 | 504 | ) |
| 503 | 505 | } |
| 506 | ||
| 507 | #[test] | |
| 508 | fn regression_18683() { | |
| 509 | check_diagnostics( | |
| 510 | r#" | |
| 511 | struct S; | |
| 512 | impl S { | |
| 513 | fn f(self) { | |
| 514 | self.self | |
| 515 | // ^^^^ error: no field `self` on type `S` | |
| 516 | } | |
| 517 | } | |
| 518 | "#, | |
| 519 | ); | |
| 520 | } | |
| 504 | 521 | } |
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_ident.rs+8-8| ... | ... | @@ -7,20 +7,19 @@ pub(crate) fn unresolved_ident( |
| 7 | 7 | ctx: &DiagnosticsContext<'_>, |
| 8 | 8 | d: &hir::UnresolvedIdent, |
| 9 | 9 | ) -> Diagnostic { |
| 10 | Diagnostic::new_with_syntax_node_ptr( | |
| 11 | ctx, | |
| 12 | DiagnosticCode::RustcHardError("E0425"), | |
| 13 | "no such value in this scope", | |
| 14 | d.expr_or_pat.map(Into::into), | |
| 15 | ) | |
| 16 | .experimental() | |
| 10 | let mut range = | |
| 11 | ctx.sema.diagnostics_display_range(d.node.map(|(node, _)| node.syntax_node_ptr())); | |
| 12 | if let Some(in_node_range) = d.node.value.1 { | |
| 13 | range.range = in_node_range + range.range.start(); | |
| 14 | } | |
| 15 | Diagnostic::new(DiagnosticCode::RustcHardError("E0425"), "no such value in this scope", range) | |
| 16 | .experimental() | |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | 19 | #[cfg(test)] |
| 20 | 20 | mod tests { |
| 21 | 21 | use crate::tests::check_diagnostics; |
| 22 | 22 | |
| 23 | // FIXME: This should show a diagnostic | |
| 24 | 23 | #[test] |
| 25 | 24 | fn feature() { |
| 26 | 25 | check_diagnostics( |
| ... | ... | @@ -28,6 +27,7 @@ mod tests { |
| 28 | 27 | //- minicore: fmt |
| 29 | 28 | fn main() { |
| 30 | 29 | format_args!("{unresolved}"); |
| 30 | // ^^^^^^^^^^ error: no such value in this scope | |
| 31 | 31 | } |
| 32 | 32 | "#, |
| 33 | 33 | ) |
src/tools/rust-analyzer/crates/ide/src/runnables.rs+3-16| ... | ... | @@ -16,7 +16,7 @@ use ide_db::{ |
| 16 | 16 | }; |
| 17 | 17 | use itertools::Itertools; |
| 18 | 18 | use span::{Edition, TextSize}; |
| 19 | use stdx::{always, format_to}; | |
| 19 | use stdx::format_to; | |
| 20 | 20 | use syntax::{ |
| 21 | 21 | ast::{self, AstNode}, |
| 22 | 22 | SmolStr, SyntaxNode, ToSmolStr, |
| ... | ... | @@ -130,14 +130,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
| 130 | 130 | // In case an expansion creates multiple runnables we want to name them to avoid emitting a bunch of equally named runnables. |
| 131 | 131 | let mut in_macro_expansion = FxHashMap::<hir::HirFileId, Vec<Runnable>>::default(); |
| 132 | 132 | let mut add_opt = |runnable: Option<Runnable>, def| { |
| 133 | if let Some(runnable) = runnable.filter(|runnable| { | |
| 134 | always!( | |
| 135 | runnable.nav.file_id == file_id, | |
| 136 | "tried adding a runnable pointing to a different file: {:?} for {:?}", | |
| 137 | runnable.kind, | |
| 138 | file_id | |
| 139 | ) | |
| 140 | }) { | |
| 133 | if let Some(runnable) = runnable.filter(|runnable| runnable.nav.file_id == file_id) { | |
| 141 | 134 | if let Some(def) = def { |
| 142 | 135 | let file_id = match def { |
| 143 | 136 | Definition::Module(it) => { |
| ... | ... | @@ -161,13 +154,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
| 161 | 154 | Definition::SelfType(impl_) => runnable_impl(&sema, &impl_), |
| 162 | 155 | _ => None, |
| 163 | 156 | }; |
| 164 | add_opt( | |
| 165 | runnable | |
| 166 | .or_else(|| module_def_doctest(sema.db, def)) | |
| 167 | // #[macro_export] mbe macros are declared in the root, while their definition may reside in a different module | |
| 168 | .filter(|it| it.nav.file_id == file_id), | |
| 169 | Some(def), | |
| 170 | ); | |
| 157 | add_opt(runnable.or_else(|| module_def_doctest(sema.db, def)), Some(def)); | |
| 171 | 158 | if let Definition::SelfType(impl_) = def { |
| 172 | 159 | impl_.items(db).into_iter().for_each(|assoc| { |
| 173 | 160 | let runnable = match assoc { |
src/tools/rust-analyzer/crates/ide/src/typing.rs+19| ... | ... | @@ -174,6 +174,9 @@ fn on_delimited_node_typed( |
| 174 | 174 | kinds: &[fn(SyntaxKind) -> bool], |
| 175 | 175 | ) -> Option<TextEdit> { |
| 176 | 176 | let t = reparsed.syntax().token_at_offset(offset).right_biased()?; |
| 177 | if t.prev_token().map_or(false, |t| t.kind().is_any_identifier()) { | |
| 178 | return None; | |
| 179 | } | |
| 177 | 180 | let (filter, node) = t |
| 178 | 181 | .parent_ancestors() |
| 179 | 182 | .take_while(|n| n.text_range().start() == offset) |
| ... | ... | @@ -1091,6 +1094,22 @@ fn f() { |
| 1091 | 1094 | ); |
| 1092 | 1095 | } |
| 1093 | 1096 | |
| 1097 | #[test] | |
| 1098 | fn preceding_whitespace_is_significant_for_closing_brackets() { | |
| 1099 | type_char_noop( | |
| 1100 | '(', | |
| 1101 | r#" | |
| 1102 | fn f() { a.b$0if true {} } | |
| 1103 | "#, | |
| 1104 | ); | |
| 1105 | type_char_noop( | |
| 1106 | '(', | |
| 1107 | r#" | |
| 1108 | fn f() { foo$0{} } | |
| 1109 | "#, | |
| 1110 | ); | |
| 1111 | } | |
| 1112 | ||
| 1094 | 1113 | #[test] |
| 1095 | 1114 | fn adds_closing_parenthesis_for_pat() { |
| 1096 | 1115 | type_char( |
src/tools/rust-analyzer/crates/load-cargo/src/lib.rs+1-1| ... | ... | @@ -487,7 +487,7 @@ impl ProcMacroExpander for Expander { |
| 487 | 487 | match self.0.expand( |
| 488 | 488 | subtree, |
| 489 | 489 | attrs, |
| 490 | env.clone(), | |
| 490 | env.clone().into(), | |
| 491 | 491 | def_site, |
| 492 | 492 | call_site, |
| 493 | 493 | mixed_site, |
src/tools/rust-analyzer/crates/parser/src/grammar/items.rs+14-4| ... | ... | @@ -72,8 +72,19 @@ pub(super) fn item_or_macro(p: &mut Parser<'_>, stop_on_r_curly: bool, is_in_ext |
| 72 | 72 | // macro_rules! () |
| 73 | 73 | // macro_rules! [] |
| 74 | 74 | if paths::is_use_path_start(p) { |
| 75 | macro_call(p, m); | |
| 76 | return; | |
| 75 | paths::use_path(p); | |
| 76 | // Do not create a MACRO_CALL node here if this isn't a macro call, this causes problems with completion. | |
| 77 | ||
| 78 | // test_err path_item_without_excl | |
| 79 | // foo | |
| 80 | if p.at(T![!]) { | |
| 81 | macro_call(p, m); | |
| 82 | return; | |
| 83 | } else { | |
| 84 | m.complete(p, ERROR); | |
| 85 | p.error("expected an item"); | |
| 86 | return; | |
| 87 | } | |
| 77 | 88 | } |
| 78 | 89 | |
| 79 | 90 | m.abandon(p); |
| ... | ... | @@ -410,8 +421,7 @@ fn fn_(p: &mut Parser<'_>, m: Marker) { |
| 410 | 421 | } |
| 411 | 422 | |
| 412 | 423 | fn macro_call(p: &mut Parser<'_>, m: Marker) { |
| 413 | assert!(paths::is_use_path_start(p)); | |
| 414 | paths::use_path(p); | |
| 424 | assert!(p.at(T![!])); | |
| 415 | 425 | match macro_call_after_excl(p) { |
| 416 | 426 | BlockLike::Block => (), |
| 417 | 427 | BlockLike::NotBlock => { |
src/tools/rust-analyzer/crates/parser/src/tests/top_entries.rs+14-16| ... | ... | @@ -30,22 +30,20 @@ fn source_file() { |
| 30 | 30 | TopEntryPoint::SourceFile, |
| 31 | 31 | "@error@", |
| 32 | 32 | expect![[r#" |
| 33 | SOURCE_FILE | |
| 34 | ERROR | |
| 35 | AT "@" | |
| 36 | MACRO_CALL | |
| 37 | PATH | |
| 38 | PATH_SEGMENT | |
| 39 | NAME_REF | |
| 40 | IDENT "error" | |
| 41 | ERROR | |
| 42 | AT "@" | |
| 43 | error 0: expected an item | |
| 44 | error 6: expected BANG | |
| 45 | error 6: expected `{`, `[`, `(` | |
| 46 | error 6: expected SEMICOLON | |
| 47 | error 6: expected an item | |
| 48 | "#]], | |
| 33 | SOURCE_FILE | |
| 34 | ERROR | |
| 35 | AT "@" | |
| 36 | ERROR | |
| 37 | PATH | |
| 38 | PATH_SEGMENT | |
| 39 | NAME_REF | |
| 40 | IDENT "error" | |
| 41 | ERROR | |
| 42 | AT "@" | |
| 43 | error 0: expected an item | |
| 44 | error 6: expected an item | |
| 45 | error 6: expected an item | |
| 46 | "#]], | |
| 49 | 47 | ); |
| 50 | 48 | } |
| 51 | 49 |
src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs+4| ... | ... | @@ -775,6 +775,10 @@ mod err { |
| 775 | 775 | run_and_expect_errors("test_data/parser/inline/err/missing_fn_param_type.rs"); |
| 776 | 776 | } |
| 777 | 777 | #[test] |
| 778 | fn path_item_without_excl() { | |
| 779 | run_and_expect_errors("test_data/parser/inline/err/path_item_without_excl.rs"); | |
| 780 | } | |
| 781 | #[test] | |
| 778 | 782 | fn pointer_type_no_mutability() { |
| 779 | 783 | run_and_expect_errors("test_data/parser/inline/err/pointer_type_no_mutability.rs"); |
| 780 | 784 | } |
src/tools/rust-analyzer/crates/parser/test_data/parser/err/0002_duplicate_shebang.rast+6-12| ... | ... | @@ -10,20 +10,20 @@ SOURCE_FILE |
| 10 | 10 | USE_KW "use" |
| 11 | 11 | ERROR |
| 12 | 12 | SLASH "/" |
| 13 | MACRO_CALL | |
| 13 | ERROR | |
| 14 | 14 | PATH |
| 15 | 15 | PATH_SEGMENT |
| 16 | 16 | NAME_REF |
| 17 | 17 | IDENT "bin" |
| 18 | 18 | ERROR |
| 19 | 19 | SLASH "/" |
| 20 | MACRO_CALL | |
| 20 | ERROR | |
| 21 | 21 | PATH |
| 22 | 22 | PATH_SEGMENT |
| 23 | 23 | NAME_REF |
| 24 | 24 | IDENT "env" |
| 25 | 25 | WHITESPACE " " |
| 26 | MACRO_CALL | |
| 26 | ERROR | |
| 27 | 27 | PATH |
| 28 | 28 | PATH_SEGMENT |
| 29 | 29 | NAME_REF |
| ... | ... | @@ -33,13 +33,7 @@ error 23: expected `[` |
| 33 | 33 | error 23: expected an item |
| 34 | 34 | error 27: expected one of `*`, `::`, `{`, `self`, `super` or an identifier |
| 35 | 35 | error 28: expected SEMICOLON |
| 36 | error 31: expected BANG | |
| 37 | error 31: expected `{`, `[`, `(` | |
| 38 | error 31: expected SEMICOLON | |
| 39 | 36 | error 31: expected an item |
| 40 | error 35: expected BANG | |
| 41 | error 35: expected `{`, `[`, `(` | |
| 42 | error 35: expected SEMICOLON | |
| 43 | error 41: expected BANG | |
| 44 | error 41: expected `{`, `[`, `(` | |
| 45 | error 41: expected SEMICOLON | |
| 37 | error 31: expected an item | |
| 38 | error 35: expected an item | |
| 39 | error 41: expected an item |
src/tools/rust-analyzer/crates/parser/test_data/parser/err/0008_item_block_recovery.rast+8-6| ... | ... | @@ -14,14 +14,15 @@ SOURCE_FILE |
| 14 | 14 | WHITESPACE "\n" |
| 15 | 15 | R_CURLY "}" |
| 16 | 16 | WHITESPACE "\n\n" |
| 17 | MACRO_CALL | |
| 17 | ERROR | |
| 18 | 18 | PATH |
| 19 | 19 | PATH_SEGMENT |
| 20 | 20 | NAME_REF |
| 21 | 21 | IDENT "bar" |
| 22 | TOKEN_TREE | |
| 23 | L_PAREN "(" | |
| 24 | R_PAREN ")" | |
| 22 | ERROR | |
| 23 | L_PAREN "(" | |
| 24 | ERROR | |
| 25 | R_PAREN ")" | |
| 25 | 26 | WHITESPACE " " |
| 26 | 27 | ERROR |
| 27 | 28 | L_CURLY "{" |
| ... | ... | @@ -75,6 +76,7 @@ SOURCE_FILE |
| 75 | 76 | WHITESPACE "\n" |
| 76 | 77 | R_CURLY "}" |
| 77 | 78 | WHITESPACE "\n" |
| 78 | error 17: expected BANG | |
| 79 | error 19: expected SEMICOLON | |
| 79 | error 17: expected an item | |
| 80 | error 17: expected an item | |
| 81 | error 18: expected an item | |
| 80 | 82 | error 20: expected an item |
src/tools/rust-analyzer/crates/parser/test_data/parser/err/0013_invalid_type.rast+2-4| ... | ... | @@ -46,7 +46,7 @@ SOURCE_FILE |
| 46 | 46 | ERROR |
| 47 | 47 | AT "@" |
| 48 | 48 | WHITESPACE " " |
| 49 | MACRO_CALL | |
| 49 | ERROR | |
| 50 | 50 | PATH |
| 51 | 51 | PATH_SEGMENT |
| 52 | 52 | NAME_REF |
| ... | ... | @@ -72,9 +72,7 @@ error 67: expected R_ANGLE |
| 72 | 72 | error 67: expected R_PAREN |
| 73 | 73 | error 67: expected SEMICOLON |
| 74 | 74 | error 67: expected an item |
| 75 | error 72: expected BANG | |
| 76 | error 72: expected `{`, `[`, `(` | |
| 77 | error 72: expected SEMICOLON | |
| 75 | error 72: expected an item | |
| 78 | 76 | error 72: expected an item |
| 79 | 77 | error 73: expected an item |
| 80 | 78 | error 79: expected an item |
src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast+8-6| ... | ... | @@ -26,14 +26,15 @@ SOURCE_FILE |
| 26 | 26 | ERROR |
| 27 | 27 | FN_KW "fn" |
| 28 | 28 | WHITESPACE " " |
| 29 | MACRO_CALL | |
| 29 | ERROR | |
| 30 | 30 | PATH |
| 31 | 31 | PATH_SEGMENT |
| 32 | 32 | NAME_REF |
| 33 | 33 | IDENT "bar" |
| 34 | TOKEN_TREE | |
| 35 | L_PAREN "(" | |
| 36 | R_PAREN ")" | |
| 34 | ERROR | |
| 35 | L_PAREN "(" | |
| 36 | ERROR | |
| 37 | R_PAREN ")" | |
| 37 | 38 | WHITESPACE " " |
| 38 | 39 | ERROR |
| 39 | 40 | L_CURLY "{" |
| ... | ... | @@ -43,6 +44,7 @@ error 6: expected fn, trait or impl |
| 43 | 44 | error 38: expected a name |
| 44 | 45 | error 40: missing type for `const` or `static` |
| 45 | 46 | error 40: expected SEMICOLON |
| 46 | error 44: expected BANG | |
| 47 | error 46: expected SEMICOLON | |
| 47 | error 44: expected an item | |
| 48 | error 44: expected an item | |
| 49 | error 45: expected an item | |
| 48 | 50 | error 47: expected an item |
src/tools/rust-analyzer/crates/parser/test_data/parser/err/0055_impl_use.rast+4-3| ... | ... | @@ -12,15 +12,16 @@ SOURCE_FILE |
| 12 | 12 | ERROR |
| 13 | 13 | USE_KW "use" |
| 14 | 14 | WHITESPACE " " |
| 15 | MACRO_CALL | |
| 15 | ERROR | |
| 16 | 16 | PATH |
| 17 | 17 | PATH_SEGMENT |
| 18 | 18 | NAME_REF |
| 19 | 19 | IDENT "std" |
| 20 | ERROR | |
| 20 | 21 | SEMICOLON ";" |
| 21 | 22 | WHITESPACE "\n" |
| 22 | 23 | error 8: expected R_ANGLE |
| 23 | 24 | error 8: expected type |
| 24 | 25 | error 11: expected `{` |
| 25 | error 15: expected BANG | |
| 26 | error 15: expected `{`, `[`, `(` | |
| 26 | error 15: expected an item | |
| 27 | error 15: expected an item |
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_fn.rast+4-8| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | SOURCE_FILE |
| 2 | MACRO_CALL | |
| 2 | ERROR | |
| 3 | 3 | PATH |
| 4 | 4 | PATH_SEGMENT |
| 5 | 5 | NAME_REF |
| ... | ... | @@ -22,7 +22,7 @@ SOURCE_FILE |
| 22 | 22 | ERROR |
| 23 | 23 | ASYNC_KW "async" |
| 24 | 24 | WHITESPACE " " |
| 25 | MACRO_CALL | |
| 25 | ERROR | |
| 26 | 26 | PATH |
| 27 | 27 | PATH_SEGMENT |
| 28 | 28 | NAME_REF |
| ... | ... | @@ -42,10 +42,6 @@ SOURCE_FILE |
| 42 | 42 | L_CURLY "{" |
| 43 | 43 | R_CURLY "}" |
| 44 | 44 | WHITESPACE "\n" |
| 45 | error 3: expected BANG | |
| 46 | error 3: expected `{`, `[`, `(` | |
| 47 | error 3: expected SEMICOLON | |
| 45 | error 3: expected an item | |
| 48 | 46 | error 24: expected fn, trait or impl |
| 49 | error 28: expected BANG | |
| 50 | error 28: expected `{`, `[`, `(` | |
| 51 | error 28: expected SEMICOLON | |
| 47 | error 28: expected an item |
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/path_item_without_excl.rast created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | SOURCE_FILE | |
| 2 | ERROR | |
| 3 | PATH | |
| 4 | PATH_SEGMENT | |
| 5 | NAME_REF | |
| 6 | IDENT "foo" | |
| 7 | WHITESPACE "\n" | |
| 8 | error 3: expected an item |
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/path_item_without_excl.rs created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | foo |
src/tools/rust-analyzer/crates/paths/Cargo.toml+1-2| ... | ... | @@ -14,10 +14,9 @@ doctest = false |
| 14 | 14 | |
| 15 | 15 | [dependencies] |
| 16 | 16 | camino.workspace = true |
| 17 | serde = { workspace = true, optional = true } | |
| 18 | 17 | |
| 19 | 18 | [features] |
| 20 | serde1 = ["camino/serde1", "dep:serde"] | |
| 19 | serde1 = ["camino/serde1"] | |
| 21 | 20 | |
| 22 | 21 | [lints] |
| 23 | 22 | workspace = true |
src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml+4-5| ... | ... | @@ -14,6 +14,7 @@ doctest = false |
| 14 | 14 | |
| 15 | 15 | [dependencies] |
| 16 | 16 | serde.workspace = true |
| 17 | serde_derive.workspace = true | |
| 17 | 18 | serde_json = { workspace = true, features = ["unbounded_depth"] } |
| 18 | 19 | tracing.workspace = true |
| 19 | 20 | rustc-hash.workspace = true |
| ... | ... | @@ -23,11 +24,9 @@ indexmap.workspace = true |
| 23 | 24 | paths = { workspace = true, features = ["serde1"] } |
| 24 | 25 | tt.workspace = true |
| 25 | 26 | stdx.workspace = true |
| 26 | # Ideally this crate would not depend on salsa things, but we need span information here which wraps | |
| 27 | # InternIds for the syntax context | |
| 28 | span.workspace = true | |
| 29 | # only here due to the `Env` newtype :/ | |
| 30 | base-db.workspace = true | |
| 27 | # span = {workspace = true, default-features = false} does not work | |
| 28 | span = { path = "../span", version = "0.0.0", default-features = false} | |
| 29 | ||
| 31 | 30 | intern.workspace = true |
| 32 | 31 | |
| 33 | 32 | [lints] |
src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs+2-3| ... | ... | @@ -9,7 +9,6 @@ pub mod json; |
| 9 | 9 | pub mod msg; |
| 10 | 10 | mod process; |
| 11 | 11 | |
| 12 | use base_db::Env; | |
| 13 | 12 | use paths::{AbsPath, AbsPathBuf}; |
| 14 | 13 | use span::Span; |
| 15 | 14 | use std::{fmt, io, sync::Arc}; |
| ... | ... | @@ -148,7 +147,7 @@ impl ProcMacro { |
| 148 | 147 | &self, |
| 149 | 148 | subtree: &tt::Subtree<Span>, |
| 150 | 149 | attr: Option<&tt::Subtree<Span>>, |
| 151 | env: Env, | |
| 150 | env: Vec<(String, String)>, | |
| 152 | 151 | def_site: Span, |
| 153 | 152 | call_site: Span, |
| 154 | 153 | mixed_site: Span, |
| ... | ... | @@ -179,7 +178,7 @@ impl ProcMacro { |
| 179 | 178 | }, |
| 180 | 179 | }, |
| 181 | 180 | lib: self.dylib_path.to_path_buf().into(), |
| 182 | env: env.into(), | |
| 181 | env, | |
| 183 | 182 | current_dir, |
| 184 | 183 | }; |
| 185 | 184 |
src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs+3-2| ... | ... | @@ -4,7 +4,8 @@ pub(crate) mod flat; |
| 4 | 4 | use std::io::{self, BufRead, Write}; |
| 5 | 5 | |
| 6 | 6 | use paths::Utf8PathBuf; |
| 7 | use serde::{de::DeserializeOwned, Deserialize, Serialize}; | |
| 7 | use serde::de::DeserializeOwned; | |
| 8 | use serde_derive::{Deserialize, Serialize}; | |
| 8 | 9 | |
| 9 | 10 | use crate::ProcMacroKind; |
| 10 | 11 | |
| ... | ... | @@ -123,7 +124,7 @@ impl ExpnGlobals { |
| 123 | 124 | } |
| 124 | 125 | } |
| 125 | 126 | |
| 126 | pub trait Message: Serialize + DeserializeOwned { | |
| 127 | pub trait Message: serde::Serialize + DeserializeOwned { | |
| 127 | 128 | fn read<R: BufRead>( |
| 128 | 129 | from_proto: ProtocolRead<R>, |
| 129 | 130 | inp: &mut R, |
src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs+43-8| ... | ... | @@ -39,10 +39,10 @@ use std::collections::VecDeque; |
| 39 | 39 | |
| 40 | 40 | use intern::Symbol; |
| 41 | 41 | use rustc_hash::FxHashMap; |
| 42 | use serde::{Deserialize, Serialize}; | |
| 42 | use serde_derive::{Deserialize, Serialize}; | |
| 43 | 43 | use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange}; |
| 44 | 44 | |
| 45 | use crate::msg::EXTENDED_LEAF_DATA; | |
| 45 | use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA}; | |
| 46 | 46 | |
| 47 | 47 | pub type SpanDataIndexMap = |
| 48 | 48 | indexmap::IndexSet<Span, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>; |
| ... | ... | @@ -145,7 +145,11 @@ impl FlatTree { |
| 145 | 145 | w.write(subtree); |
| 146 | 146 | |
| 147 | 147 | FlatTree { |
| 148 | subtree: write_vec(w.subtree, SubtreeRepr::write), | |
| 148 | subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { | |
| 149 | write_vec(w.subtree, SubtreeRepr::write_with_close_span) | |
| 150 | } else { | |
| 151 | write_vec(w.subtree, SubtreeRepr::write) | |
| 152 | }, | |
| 149 | 153 | literal: if version >= EXTENDED_LEAF_DATA { |
| 150 | 154 | write_vec(w.literal, LiteralRepr::write_with_kind) |
| 151 | 155 | } else { |
| ... | ... | @@ -179,7 +183,11 @@ impl FlatTree { |
| 179 | 183 | w.write(subtree); |
| 180 | 184 | |
| 181 | 185 | FlatTree { |
| 182 | subtree: write_vec(w.subtree, SubtreeRepr::write), | |
| 186 | subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { | |
| 187 | write_vec(w.subtree, SubtreeRepr::write_with_close_span) | |
| 188 | } else { | |
| 189 | write_vec(w.subtree, SubtreeRepr::write) | |
| 190 | }, | |
| 183 | 191 | literal: if version >= EXTENDED_LEAF_DATA { |
| 184 | 192 | write_vec(w.literal, LiteralRepr::write_with_kind) |
| 185 | 193 | } else { |
| ... | ... | @@ -202,7 +210,11 @@ impl FlatTree { |
| 202 | 210 | span_data_table: &SpanDataIndexMap, |
| 203 | 211 | ) -> tt::Subtree<Span> { |
| 204 | 212 | Reader { |
| 205 | subtree: read_vec(self.subtree, SubtreeRepr::read), | |
| 213 | subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { | |
| 214 | read_vec(self.subtree, SubtreeRepr::read_with_close_span) | |
| 215 | } else { | |
| 216 | read_vec(self.subtree, SubtreeRepr::read) | |
| 217 | }, | |
| 206 | 218 | literal: if version >= EXTENDED_LEAF_DATA { |
| 207 | 219 | read_vec(self.literal, LiteralRepr::read_with_kind) |
| 208 | 220 | } else { |
| ... | ... | @@ -224,7 +236,11 @@ impl FlatTree { |
| 224 | 236 | |
| 225 | 237 | pub fn to_subtree_unresolved(self, version: u32) -> tt::Subtree<TokenId> { |
| 226 | 238 | Reader { |
| 227 | subtree: read_vec(self.subtree, SubtreeRepr::read), | |
| 239 | subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { | |
| 240 | read_vec(self.subtree, SubtreeRepr::read_with_close_span) | |
| 241 | } else { | |
| 242 | read_vec(self.subtree, SubtreeRepr::read) | |
| 243 | }, | |
| 228 | 244 | literal: if version >= EXTENDED_LEAF_DATA { |
| 229 | 245 | read_vec(self.literal, LiteralRepr::read_with_kind) |
| 230 | 246 | } else { |
| ... | ... | @@ -257,7 +273,26 @@ fn write_vec<T, F: Fn(T) -> [u32; N], const N: usize>(xs: Vec<T>, f: F) -> Vec<u |
| 257 | 273 | } |
| 258 | 274 | |
| 259 | 275 | impl SubtreeRepr { |
| 260 | fn write(self) -> [u32; 5] { | |
| 276 | fn write(self) -> [u32; 4] { | |
| 277 | let kind = match self.kind { | |
| 278 | tt::DelimiterKind::Invisible => 0, | |
| 279 | tt::DelimiterKind::Parenthesis => 1, | |
| 280 | tt::DelimiterKind::Brace => 2, | |
| 281 | tt::DelimiterKind::Bracket => 3, | |
| 282 | }; | |
| 283 | [self.open.0, kind, self.tt[0], self.tt[1]] | |
| 284 | } | |
| 285 | fn read([open, kind, lo, len]: [u32; 4]) -> SubtreeRepr { | |
| 286 | let kind = match kind { | |
| 287 | 0 => tt::DelimiterKind::Invisible, | |
| 288 | 1 => tt::DelimiterKind::Parenthesis, | |
| 289 | 2 => tt::DelimiterKind::Brace, | |
| 290 | 3 => tt::DelimiterKind::Bracket, | |
| 291 | other => panic!("bad kind {other}"), | |
| 292 | }; | |
| 293 | SubtreeRepr { open: TokenId(open), close: TokenId(!0), kind, tt: [lo, len] } | |
| 294 | } | |
| 295 | fn write_with_close_span(self) -> [u32; 5] { | |
| 261 | 296 | let kind = match self.kind { |
| 262 | 297 | tt::DelimiterKind::Invisible => 0, |
| 263 | 298 | tt::DelimiterKind::Parenthesis => 1, |
| ... | ... | @@ -266,7 +301,7 @@ impl SubtreeRepr { |
| 266 | 301 | }; |
| 267 | 302 | [self.open.0, self.close.0, kind, self.tt[0], self.tt[1]] |
| 268 | 303 | } |
| 269 | fn read([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr { | |
| 304 | fn read_with_close_span([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr { | |
| 270 | 305 | let kind = match kind { |
| 271 | 306 | 0 => tt::DelimiterKind::Invisible, |
| 272 | 307 | 1 => tt::DelimiterKind::Parenthesis, |
src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs+6-23| ... | ... | @@ -56,25 +56,8 @@ impl ProcMacroProcessSrv { |
| 56 | 56 | match srv.version_check() { |
| 57 | 57 | Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new( |
| 58 | 58 | io::ErrorKind::Other, |
| 59 | format!( | |
| 60 | "The version of the proc-macro server ({v}) in your Rust toolchain \ | |
| 61 | is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}). | |
| 62 | \ | |
| 63 | This will prevent proc-macro expansion from working. \ | |
| 64 | Please consider updating your rust-analyzer to ensure compatibility with your \ | |
| 65 | current toolchain." | |
| 66 | ), | |
| 67 | )), | |
| 68 | Ok(v) if v < RUST_ANALYZER_SPAN_SUPPORT => Err(io::Error::new( | |
| 69 | io::ErrorKind::Other, | |
| 70 | format!( | |
| 71 | "The version of the proc-macro server ({v}) in your Rust toolchain \ | |
| 72 | is too old and no longer supported by your rust-analyzer which requires\ | |
| 73 | version {RUST_ANALYZER_SPAN_SUPPORT} or higher. | |
| 74 | \ | |
| 75 | This will prevent proc-macro expansion from working. \ | |
| 76 | Please consider updating your toolchain or downgrading your rust-analyzer \ | |
| 77 | to ensure compatibility with your current toolchain." | |
| 59 | format!( "The version of the proc-macro server ({v}) in your Rust toolchain is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}). | |
| 60 | This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain." | |
| 78 | 61 | ), |
| 79 | 62 | )), |
| 80 | 63 | Ok(v) => { |
| ... | ... | @@ -89,10 +72,10 @@ impl ProcMacroProcessSrv { |
| 89 | 72 | tracing::info!("Proc-macro server span mode: {:?}", srv.mode); |
| 90 | 73 | Ok(srv) |
| 91 | 74 | } |
| 92 | Err(e) => Err(io::Error::new( | |
| 93 | io::ErrorKind::Other, | |
| 94 | format!("Failed to fetch proc-macro server version: {e}"), | |
| 95 | )), | |
| 75 | Err(e) => { | |
| 76 | tracing::info!(%e, "proc-macro version check failed, restarting and assuming version 0"); | |
| 77 | create_srv(false) | |
| 78 | } | |
| 96 | 79 | } |
| 97 | 80 | } |
| 98 | 81 |
src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml+2-2| ... | ... | @@ -21,8 +21,8 @@ stdx.workspace = true |
| 21 | 21 | tt.workspace = true |
| 22 | 22 | syntax-bridge.workspace = true |
| 23 | 23 | paths.workspace = true |
| 24 | base-db.workspace = true | |
| 25 | span.workspace = true | |
| 24 | # span = {workspace = true, default-features = false} does not work | |
| 25 | span = { path = "../span", version = "0.0.0", default-features = false} | |
| 26 | 26 | proc-macro-api.workspace = true |
| 27 | 27 | intern.workspace = true |
| 28 | 28 |
src/tools/rust-analyzer/crates/project-model/Cargo.toml+1| ... | ... | @@ -19,6 +19,7 @@ rustc-hash.workspace = true |
| 19 | 19 | semver.workspace = true |
| 20 | 20 | serde_json.workspace = true |
| 21 | 21 | serde.workspace = true |
| 22 | serde_derive.workspace = true | |
| 22 | 23 | tracing.workspace = true |
| 23 | 24 | triomphe.workspace = true |
| 24 | 25 | la-arena.workspace = true |
src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs+1-1| ... | ... | @@ -15,7 +15,7 @@ use itertools::Itertools; |
| 15 | 15 | use la_arena::ArenaMap; |
| 16 | 16 | use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; |
| 17 | 17 | use rustc_hash::{FxHashMap, FxHashSet}; |
| 18 | use serde::Deserialize; | |
| 18 | use serde::Deserialize as _; | |
| 19 | 19 | use toolchain::Tool; |
| 20 | 20 | |
| 21 | 21 | use crate::{ |
src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs+1-1| ... | ... | @@ -8,7 +8,7 @@ use cargo_metadata::{CargoOpt, MetadataCommand}; |
| 8 | 8 | use la_arena::{Arena, Idx}; |
| 9 | 9 | use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; |
| 10 | 10 | use rustc_hash::{FxHashMap, FxHashSet}; |
| 11 | use serde::Deserialize; | |
| 11 | use serde_derive::Deserialize; | |
| 12 | 12 | use serde_json::from_value; |
| 13 | 13 | use span::Edition; |
| 14 | 14 | use toolchain::Tool; |
src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml+1-1| ... | ... | @@ -20,7 +20,7 @@ parking_lot = "0.12.1" |
| 20 | 20 | rustc-hash = "2.0.0" |
| 21 | 21 | smallvec = "1.0.0" |
| 22 | 22 | oorandom = "11" |
| 23 | triomphe = "0.1.11" | |
| 23 | triomphe.workspace = true | |
| 24 | 24 | itertools.workspace = true |
| 25 | 25 | |
| 26 | 26 | ra-salsa-macros = { version = "0.0.0", path = "ra-salsa-macros", package = "salsa-macros" } |
src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml+1| ... | ... | @@ -36,6 +36,7 @@ rayon.workspace = true |
| 36 | 36 | rustc-hash.workspace = true |
| 37 | 37 | serde_json = { workspace = true, features = ["preserve_order"] } |
| 38 | 38 | serde.workspace = true |
| 39 | serde_derive.workspace = true | |
| 39 | 40 | tenthash = "0.4.0" |
| 40 | 41 | num_cpus = "1.15.0" |
| 41 | 42 | mimalloc = { version = "0.1.30", default-features = false, optional = true } |
src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs+2-1| ... | ... | @@ -644,7 +644,8 @@ config_data! { |
| 644 | 644 | /// Aliased as `"checkOnSave.targets"`. |
| 645 | 645 | check_targets | checkOnSave_targets | checkOnSave_target: Option<CheckOnSaveTargets> = None, |
| 646 | 646 | /// Whether `--workspace` should be passed to `cargo check`. |
| 647 | /// If false, `-p <package>` will be passed instead. | |
| 647 | /// If false, `-p <package>` will be passed instead if applicable. In case it is not, no | |
| 648 | /// check will be performed. | |
| 648 | 649 | check_workspace: bool = true, |
| 649 | 650 | |
| 650 | 651 | /// These proc-macros will be ignored when trying to expand them. |
src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs+56-12| ... | ... | @@ -3,6 +3,7 @@ pub(crate) mod to_proto; |
| 3 | 3 | |
| 4 | 4 | use std::mem; |
| 5 | 5 | |
| 6 | use cargo_metadata::PackageId; | |
| 6 | 7 | use ide::FileId; |
| 7 | 8 | use ide_db::FxHashMap; |
| 8 | 9 | use itertools::Itertools; |
| ... | ... | @@ -13,7 +14,8 @@ use triomphe::Arc; |
| 13 | 14 | |
| 14 | 15 | use crate::{global_state::GlobalStateSnapshot, lsp, lsp_ext, main_loop::DiagnosticsTaskKind}; |
| 15 | 16 | |
| 16 | pub(crate) type CheckFixes = Arc<IntMap<usize, IntMap<FileId, Vec<Fix>>>>; | |
| 17 | pub(crate) type CheckFixes = | |
| 18 | Arc<IntMap<usize, FxHashMap<Option<Arc<PackageId>>, IntMap<FileId, Vec<Fix>>>>>; | |
| 17 | 19 | |
| 18 | 20 | #[derive(Debug, Default, Clone)] |
| 19 | 21 | pub struct DiagnosticsMapConfig { |
| ... | ... | @@ -31,7 +33,10 @@ pub(crate) struct DiagnosticCollection { |
| 31 | 33 | pub(crate) native_syntax: IntMap<FileId, (DiagnosticsGeneration, Vec<lsp_types::Diagnostic>)>, |
| 32 | 34 | pub(crate) native_semantic: IntMap<FileId, (DiagnosticsGeneration, Vec<lsp_types::Diagnostic>)>, |
| 33 | 35 | // FIXME: should be Vec<flycheck::Diagnostic> |
| 34 | pub(crate) check: IntMap<usize, IntMap<FileId, Vec<lsp_types::Diagnostic>>>, | |
| 36 | pub(crate) check: IntMap< | |
| 37 | usize, | |
| 38 | FxHashMap<Option<Arc<PackageId>>, IntMap<FileId, Vec<lsp_types::Diagnostic>>>, | |
| 39 | >, | |
| 35 | 40 | pub(crate) check_fixes: CheckFixes, |
| 36 | 41 | changes: IntSet<FileId>, |
| 37 | 42 | /// Counter for supplying a new generation number for diagnostics. |
| ... | ... | @@ -50,18 +55,37 @@ pub(crate) struct Fix { |
| 50 | 55 | |
| 51 | 56 | impl DiagnosticCollection { |
| 52 | 57 | pub(crate) fn clear_check(&mut self, flycheck_id: usize) { |
| 53 | if let Some(it) = Arc::make_mut(&mut self.check_fixes).get_mut(&flycheck_id) { | |
| 54 | it.clear(); | |
| 55 | } | |
| 56 | if let Some(it) = self.check.get_mut(&flycheck_id) { | |
| 57 | self.changes.extend(it.drain().map(|(key, _value)| key)); | |
| 58 | let Some(check) = self.check.get_mut(&flycheck_id) else { | |
| 59 | return; | |
| 60 | }; | |
| 61 | self.changes.extend(check.drain().flat_map(|(_, v)| v.into_keys())); | |
| 62 | if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(&flycheck_id) { | |
| 63 | fixes.clear(); | |
| 58 | 64 | } |
| 59 | 65 | } |
| 60 | 66 | |
| 61 | 67 | pub(crate) fn clear_check_all(&mut self) { |
| 62 | 68 | Arc::make_mut(&mut self.check_fixes).clear(); |
| 63 | self.changes | |
| 64 | .extend(self.check.values_mut().flat_map(|it| it.drain().map(|(key, _value)| key))) | |
| 69 | self.changes.extend( | |
| 70 | self.check.values_mut().flat_map(|it| it.drain().flat_map(|(_, v)| v.into_keys())), | |
| 71 | ) | |
| 72 | } | |
| 73 | ||
| 74 | pub(crate) fn clear_check_for_package( | |
| 75 | &mut self, | |
| 76 | flycheck_id: usize, | |
| 77 | package_id: Arc<PackageId>, | |
| 78 | ) { | |
| 79 | let Some(check) = self.check.get_mut(&flycheck_id) else { | |
| 80 | return; | |
| 81 | }; | |
| 82 | let package_id = Some(package_id); | |
| 83 | if let Some(checks) = check.remove(&package_id) { | |
| 84 | self.changes.extend(checks.into_keys()); | |
| 85 | } | |
| 86 | if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(&flycheck_id) { | |
| 87 | fixes.remove(&package_id); | |
| 88 | } | |
| 65 | 89 | } |
| 66 | 90 | |
| 67 | 91 | pub(crate) fn clear_native_for(&mut self, file_id: FileId) { |
| ... | ... | @@ -73,11 +97,19 @@ impl DiagnosticCollection { |
| 73 | 97 | pub(crate) fn add_check_diagnostic( |
| 74 | 98 | &mut self, |
| 75 | 99 | flycheck_id: usize, |
| 100 | package_id: &Option<Arc<PackageId>>, | |
| 76 | 101 | file_id: FileId, |
| 77 | 102 | diagnostic: lsp_types::Diagnostic, |
| 78 | 103 | fix: Option<Box<Fix>>, |
| 79 | 104 | ) { |
| 80 | let diagnostics = self.check.entry(flycheck_id).or_default().entry(file_id).or_default(); | |
| 105 | let diagnostics = self | |
| 106 | .check | |
| 107 | .entry(flycheck_id) | |
| 108 | .or_default() | |
| 109 | .entry(package_id.clone()) | |
| 110 | .or_default() | |
| 111 | .entry(file_id) | |
| 112 | .or_default(); | |
| 81 | 113 | for existing_diagnostic in diagnostics.iter() { |
| 82 | 114 | if are_diagnostics_equal(existing_diagnostic, &diagnostic) { |
| 83 | 115 | return; |
| ... | ... | @@ -86,7 +118,14 @@ impl DiagnosticCollection { |
| 86 | 118 | |
| 87 | 119 | if let Some(fix) = fix { |
| 88 | 120 | let check_fixes = Arc::make_mut(&mut self.check_fixes); |
| 89 | check_fixes.entry(flycheck_id).or_default().entry(file_id).or_default().push(*fix); | |
| 121 | check_fixes | |
| 122 | .entry(flycheck_id) | |
| 123 | .or_default() | |
| 124 | .entry(package_id.clone()) | |
| 125 | .or_default() | |
| 126 | .entry(file_id) | |
| 127 | .or_default() | |
| 128 | .push(*fix); | |
| 90 | 129 | } |
| 91 | 130 | diagnostics.push(diagnostic); |
| 92 | 131 | self.changes.insert(file_id); |
| ... | ... | @@ -135,7 +174,12 @@ impl DiagnosticCollection { |
| 135 | 174 | ) -> impl Iterator<Item = &lsp_types::Diagnostic> { |
| 136 | 175 | let native_syntax = self.native_syntax.get(&file_id).into_iter().flat_map(|(_, d)| d); |
| 137 | 176 | let native_semantic = self.native_semantic.get(&file_id).into_iter().flat_map(|(_, d)| d); |
| 138 | let check = self.check.values().filter_map(move |it| it.get(&file_id)).flatten(); | |
| 177 | let check = self | |
| 178 | .check | |
| 179 | .values() | |
| 180 | .flat_map(|it| it.values()) | |
| 181 | .filter_map(move |it| it.get(&file_id)) | |
| 182 | .flatten(); | |
| 139 | 183 | native_syntax.chain(native_semantic).chain(check) |
| 140 | 184 | } |
| 141 | 185 |
src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs+81-39| ... | ... | @@ -1,17 +1,20 @@ |
| 1 | 1 | //! Flycheck provides the functionality needed to run `cargo check` to provide |
| 2 | 2 | //! LSP diagnostics based on the output of the command. |
| 3 | 3 | |
| 4 | use std::{fmt, io, process::Command, time::Duration}; | |
| 4 | use std::{fmt, io, mem, process::Command, time::Duration}; | |
| 5 | 5 | |
| 6 | use cargo_metadata::PackageId; | |
| 6 | 7 | use crossbeam_channel::{select_biased, unbounded, Receiver, Sender}; |
| 7 | 8 | use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; |
| 8 | 9 | use rustc_hash::FxHashMap; |
| 9 | use serde::Deserialize; | |
| 10 | use serde::Deserialize as _; | |
| 11 | use serde_derive::Deserialize; | |
| 10 | 12 | |
| 11 | 13 | pub(crate) use cargo_metadata::diagnostic::{ |
| 12 | 14 | Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan, |
| 13 | 15 | }; |
| 14 | 16 | use toolchain::Tool; |
| 17 | use triomphe::Arc; | |
| 15 | 18 | |
| 16 | 19 | use crate::command::{CommandHandle, ParseFromLine}; |
| 17 | 20 | |
| ... | ... | @@ -150,10 +153,19 @@ impl FlycheckHandle { |
| 150 | 153 | |
| 151 | 154 | pub(crate) enum FlycheckMessage { |
| 152 | 155 | /// Request adding a diagnostic with fixes included to a file |
| 153 | AddDiagnostic { id: usize, workspace_root: AbsPathBuf, diagnostic: Diagnostic }, | |
| 156 | AddDiagnostic { | |
| 157 | id: usize, | |
| 158 | workspace_root: Arc<AbsPathBuf>, | |
| 159 | diagnostic: Diagnostic, | |
| 160 | package_id: Option<Arc<PackageId>>, | |
| 161 | }, | |
| 154 | 162 | |
| 155 | /// Request clearing all previous diagnostics | |
| 156 | ClearDiagnostics { id: usize }, | |
| 163 | /// Request clearing all outdated diagnostics. | |
| 164 | ClearDiagnostics { | |
| 165 | id: usize, | |
| 166 | /// The package whose diagnostics to clear, or if unspecified, all diagnostics. | |
| 167 | package_id: Option<Arc<PackageId>>, | |
| 168 | }, | |
| 157 | 169 | |
| 158 | 170 | /// Request check progress notification to client |
| 159 | 171 | Progress { |
| ... | ... | @@ -166,15 +178,18 @@ pub(crate) enum FlycheckMessage { |
| 166 | 178 | impl fmt::Debug for FlycheckMessage { |
| 167 | 179 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 168 | 180 | match self { |
| 169 | FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => f | |
| 181 | FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic, package_id } => f | |
| 170 | 182 | .debug_struct("AddDiagnostic") |
| 171 | 183 | .field("id", id) |
| 172 | 184 | .field("workspace_root", workspace_root) |
| 185 | .field("package_id", package_id) | |
| 173 | 186 | .field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code)) |
| 174 | 187 | .finish(), |
| 175 | FlycheckMessage::ClearDiagnostics { id } => { | |
| 176 | f.debug_struct("ClearDiagnostics").field("id", id).finish() | |
| 177 | } | |
| 188 | FlycheckMessage::ClearDiagnostics { id, package_id } => f | |
| 189 | .debug_struct("ClearDiagnostics") | |
| 190 | .field("id", id) | |
| 191 | .field("package_id", package_id) | |
| 192 | .finish(), | |
| 178 | 193 | FlycheckMessage::Progress { id, progress } => { |
| 179 | 194 | f.debug_struct("Progress").field("id", id).field("progress", progress).finish() |
| 180 | 195 | } |
| ... | ... | @@ -200,12 +215,13 @@ enum StateChange { |
| 200 | 215 | struct FlycheckActor { |
| 201 | 216 | /// The workspace id of this flycheck instance. |
| 202 | 217 | id: usize, |
| 218 | ||
| 203 | 219 | sender: Sender<FlycheckMessage>, |
| 204 | 220 | config: FlycheckConfig, |
| 205 | 221 | manifest_path: Option<AbsPathBuf>, |
| 206 | 222 | /// Either the workspace root of the workspace we are flychecking, |
| 207 | 223 | /// or the project root of the project. |
| 208 | root: AbsPathBuf, | |
| 224 | root: Arc<AbsPathBuf>, | |
| 209 | 225 | sysroot_root: Option<AbsPathBuf>, |
| 210 | 226 | /// CargoHandle exists to wrap around the communication needed to be able to |
| 211 | 227 | /// run `cargo check` without blocking. Currently the Rust standard library |
| ... | ... | @@ -215,8 +231,13 @@ struct FlycheckActor { |
| 215 | 231 | command_handle: Option<CommandHandle<CargoCheckMessage>>, |
| 216 | 232 | /// The receiver side of the channel mentioned above. |
| 217 | 233 | command_receiver: Option<Receiver<CargoCheckMessage>>, |
| 234 | package_status: FxHashMap<Arc<PackageId>, DiagnosticReceived>, | |
| 235 | } | |
| 218 | 236 | |
| 219 | status: FlycheckStatus, | |
| 237 | #[derive(PartialEq, Eq, Copy, Clone, Debug)] | |
| 238 | enum DiagnosticReceived { | |
| 239 | Yes, | |
| 240 | No, | |
| 220 | 241 | } |
| 221 | 242 | |
| 222 | 243 | #[allow(clippy::large_enum_variant)] |
| ... | ... | @@ -225,13 +246,6 @@ enum Event { |
| 225 | 246 | CheckEvent(Option<CargoCheckMessage>), |
| 226 | 247 | } |
| 227 | 248 | |
| 228 | #[derive(PartialEq)] | |
| 229 | enum FlycheckStatus { | |
| 230 | Started, | |
| 231 | DiagnosticSent, | |
| 232 | Finished, | |
| 233 | } | |
| 234 | ||
| 235 | 249 | pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file"; |
| 236 | 250 | |
| 237 | 251 | impl FlycheckActor { |
| ... | ... | @@ -249,11 +263,11 @@ impl FlycheckActor { |
| 249 | 263 | sender, |
| 250 | 264 | config, |
| 251 | 265 | sysroot_root, |
| 252 | root: workspace_root, | |
| 266 | root: Arc::new(workspace_root), | |
| 253 | 267 | manifest_path, |
| 254 | 268 | command_handle: None, |
| 255 | 269 | command_receiver: None, |
| 256 | status: FlycheckStatus::Finished, | |
| 270 | package_status: FxHashMap::default(), | |
| 257 | 271 | } |
| 258 | 272 | } |
| 259 | 273 | |
| ... | ... | @@ -306,13 +320,11 @@ impl FlycheckActor { |
| 306 | 320 | self.command_handle = Some(command_handle); |
| 307 | 321 | self.command_receiver = Some(receiver); |
| 308 | 322 | self.report_progress(Progress::DidStart); |
| 309 | self.status = FlycheckStatus::Started; | |
| 310 | 323 | } |
| 311 | 324 | Err(error) => { |
| 312 | 325 | self.report_progress(Progress::DidFailToRestart(format!( |
| 313 | 326 | "Failed to run the following command: {formatted_command} error={error}" |
| 314 | 327 | ))); |
| 315 | self.status = FlycheckStatus::Finished; | |
| 316 | 328 | } |
| 317 | 329 | } |
| 318 | 330 | } |
| ... | ... | @@ -332,37 +344,62 @@ impl FlycheckActor { |
| 332 | 344 | error |
| 333 | 345 | ); |
| 334 | 346 | } |
| 335 | if self.status == FlycheckStatus::Started { | |
| 336 | self.send(FlycheckMessage::ClearDiagnostics { id: self.id }); | |
| 347 | if self.package_status.is_empty() { | |
| 348 | // We finished without receiving any diagnostics. | |
| 349 | // That means all of them are stale. | |
| 350 | self.send(FlycheckMessage::ClearDiagnostics { | |
| 351 | id: self.id, | |
| 352 | package_id: None, | |
| 353 | }); | |
| 354 | } else { | |
| 355 | for (package_id, status) in mem::take(&mut self.package_status) { | |
| 356 | if let DiagnosticReceived::No = status { | |
| 357 | self.send(FlycheckMessage::ClearDiagnostics { | |
| 358 | id: self.id, | |
| 359 | package_id: Some(package_id), | |
| 360 | }); | |
| 361 | } | |
| 362 | } | |
| 337 | 363 | } |
| 364 | ||
| 338 | 365 | self.report_progress(Progress::DidFinish(res)); |
| 339 | self.status = FlycheckStatus::Finished; | |
| 340 | 366 | } |
| 341 | 367 | Event::CheckEvent(Some(message)) => match message { |
| 342 | 368 | CargoCheckMessage::CompilerArtifact(msg) => { |
| 343 | 369 | tracing::trace!( |
| 344 | 370 | flycheck_id = self.id, |
| 345 | 371 | artifact = msg.target.name, |
| 372 | package_id = msg.package_id.repr, | |
| 346 | 373 | "artifact received" |
| 347 | 374 | ); |
| 348 | 375 | self.report_progress(Progress::DidCheckCrate(msg.target.name)); |
| 376 | self.package_status | |
| 377 | .entry(Arc::new(msg.package_id)) | |
| 378 | .or_insert(DiagnosticReceived::No); | |
| 349 | 379 | } |
| 350 | ||
| 351 | CargoCheckMessage::Diagnostic(msg) => { | |
| 380 | CargoCheckMessage::Diagnostic { diagnostic, package_id } => { | |
| 352 | 381 | tracing::trace!( |
| 353 | 382 | flycheck_id = self.id, |
| 354 | message = msg.message, | |
| 383 | message = diagnostic.message, | |
| 384 | package_id = package_id.as_ref().map(|it| &it.repr), | |
| 355 | 385 | "diagnostic received" |
| 356 | 386 | ); |
| 357 | if self.status == FlycheckStatus::Started { | |
| 358 | self.send(FlycheckMessage::ClearDiagnostics { id: self.id }); | |
| 387 | if let Some(package_id) = &package_id { | |
| 388 | if !self.package_status.contains_key(package_id) { | |
| 389 | self.package_status | |
| 390 | .insert(package_id.clone(), DiagnosticReceived::Yes); | |
| 391 | self.send(FlycheckMessage::ClearDiagnostics { | |
| 392 | id: self.id, | |
| 393 | package_id: Some(package_id.clone()), | |
| 394 | }); | |
| 395 | } | |
| 359 | 396 | } |
| 360 | 397 | self.send(FlycheckMessage::AddDiagnostic { |
| 361 | 398 | id: self.id, |
| 399 | package_id, | |
| 362 | 400 | workspace_root: self.root.clone(), |
| 363 | diagnostic: msg, | |
| 401 | diagnostic, | |
| 364 | 402 | }); |
| 365 | self.status = FlycheckStatus::DiagnosticSent; | |
| 366 | 403 | } |
| 367 | 404 | }, |
| 368 | 405 | } |
| ... | ... | @@ -380,7 +417,7 @@ impl FlycheckActor { |
| 380 | 417 | command_handle.cancel(); |
| 381 | 418 | self.command_receiver.take(); |
| 382 | 419 | self.report_progress(Progress::DidCancel); |
| 383 | self.status = FlycheckStatus::Finished; | |
| 420 | self.package_status.clear(); | |
| 384 | 421 | } |
| 385 | 422 | } |
| 386 | 423 | |
| ... | ... | @@ -400,7 +437,7 @@ impl FlycheckActor { |
| 400 | 437 | cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(sysroot_root)); |
| 401 | 438 | } |
| 402 | 439 | cmd.arg(command); |
| 403 | cmd.current_dir(&self.root); | |
| 440 | cmd.current_dir(&*self.root); | |
| 404 | 441 | |
| 405 | 442 | match package { |
| 406 | 443 | Some(pkg) => cmd.arg("-p").arg(pkg), |
| ... | ... | @@ -442,11 +479,11 @@ impl FlycheckActor { |
| 442 | 479 | |
| 443 | 480 | match invocation_strategy { |
| 444 | 481 | InvocationStrategy::Once => { |
| 445 | cmd.current_dir(&self.root); | |
| 482 | cmd.current_dir(&*self.root); | |
| 446 | 483 | } |
| 447 | 484 | InvocationStrategy::PerWorkspace => { |
| 448 | 485 | // FIXME: cmd.current_dir(&affected_workspace); |
| 449 | cmd.current_dir(&self.root); | |
| 486 | cmd.current_dir(&*self.root); | |
| 450 | 487 | } |
| 451 | 488 | } |
| 452 | 489 | |
| ... | ... | @@ -486,7 +523,7 @@ impl FlycheckActor { |
| 486 | 523 | #[allow(clippy::large_enum_variant)] |
| 487 | 524 | enum CargoCheckMessage { |
| 488 | 525 | CompilerArtifact(cargo_metadata::Artifact), |
| 489 | Diagnostic(Diagnostic), | |
| 526 | Diagnostic { diagnostic: Diagnostic, package_id: Option<Arc<PackageId>> }, | |
| 490 | 527 | } |
| 491 | 528 | |
| 492 | 529 | impl ParseFromLine for CargoCheckMessage { |
| ... | ... | @@ -501,11 +538,16 @@ impl ParseFromLine for CargoCheckMessage { |
| 501 | 538 | Some(CargoCheckMessage::CompilerArtifact(artifact)) |
| 502 | 539 | } |
| 503 | 540 | cargo_metadata::Message::CompilerMessage(msg) => { |
| 504 | Some(CargoCheckMessage::Diagnostic(msg.message)) | |
| 541 | Some(CargoCheckMessage::Diagnostic { | |
| 542 | diagnostic: msg.message, | |
| 543 | package_id: Some(Arc::new(msg.package_id)), | |
| 544 | }) | |
| 505 | 545 | } |
| 506 | 546 | _ => None, |
| 507 | 547 | }, |
| 508 | JsonMessage::Rustc(message) => Some(CargoCheckMessage::Diagnostic(message)), | |
| 548 | JsonMessage::Rustc(message) => { | |
| 549 | Some(CargoCheckMessage::Diagnostic { diagnostic: message, package_id: None }) | |
| 550 | } | |
| 509 | 551 | }; |
| 510 | 552 | } |
| 511 | 553 |
src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs+6-2| ... | ... | @@ -92,7 +92,7 @@ pub(crate) struct GlobalState { |
| 92 | 92 | |
| 93 | 93 | // status |
| 94 | 94 | pub(crate) shutdown_requested: bool, |
| 95 | pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>, | |
| 95 | pub(crate) last_reported_status: lsp_ext::ServerStatusParams, | |
| 96 | 96 | |
| 97 | 97 | // proc macros |
| 98 | 98 | pub(crate) proc_macro_clients: Arc<[anyhow::Result<ProcMacroServer>]>, |
| ... | ... | @@ -238,7 +238,11 @@ impl GlobalState { |
| 238 | 238 | mem_docs: MemDocs::default(), |
| 239 | 239 | semantic_tokens_cache: Arc::new(Default::default()), |
| 240 | 240 | shutdown_requested: false, |
| 241 | last_reported_status: None, | |
| 241 | last_reported_status: lsp_ext::ServerStatusParams { | |
| 242 | health: lsp_ext::Health::Ok, | |
| 243 | quiescent: true, | |
| 244 | message: None, | |
| 245 | }, | |
| 242 | 246 | source_root_config: SourceRootConfig::default(), |
| 243 | 247 | local_roots_parent_map: Arc::new(FxHashMap::default()), |
| 244 | 248 | config_errors: Default::default(), |
src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs+1-1| ... | ... | @@ -126,7 +126,7 @@ impl RequestDispatcher<'_> { |
| 126 | 126 | |
| 127 | 127 | /// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not |
| 128 | 128 | /// ready this will return a `default` constructed [`R::Result`]. |
| 129 | pub(crate) fn on_with<R>( | |
| 129 | pub(crate) fn on_with_vfs_default<R>( | |
| 130 | 130 | &mut self, |
| 131 | 131 | f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, |
| 132 | 132 | default: impl FnOnce() -> R::Result, |
src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs+14-11| ... | ... | @@ -189,7 +189,7 @@ pub(crate) fn handle_did_save_text_document( |
| 189 | 189 | if !state.config.check_on_save(Some(sr)) || run_flycheck(state, vfs_path) { |
| 190 | 190 | return Ok(()); |
| 191 | 191 | } |
| 192 | } else if state.config.check_on_save(None) { | |
| 192 | } else if state.config.check_on_save(None) && state.config.flycheck_workspace(None) { | |
| 193 | 193 | // No specific flycheck was triggered, so let's trigger all of them. |
| 194 | 194 | for flycheck in state.flycheck.iter() { |
| 195 | 195 | flycheck.restart_workspace(None); |
| ... | ... | @@ -293,7 +293,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { |
| 293 | 293 | let file_id = state.vfs.read().0.file_id(&vfs_path); |
| 294 | 294 | if let Some(file_id) = file_id { |
| 295 | 295 | let world = state.snapshot(); |
| 296 | let source_root_id = world.analysis.source_root_id(file_id).ok(); | |
| 296 | let may_flycheck_workspace = state.config.flycheck_workspace(None); | |
| 297 | 297 | let mut updated = false; |
| 298 | 298 | let task = move || -> std::result::Result<(), ide::Cancelled> { |
| 299 | 299 | // Is the target binary? If so we let flycheck run only for the workspace that contains the crate. |
| ... | ... | @@ -375,21 +375,22 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { |
| 375 | 375 | let saved_file = vfs_path.as_path().map(|p| p.to_owned()); |
| 376 | 376 | |
| 377 | 377 | // Find and trigger corresponding flychecks |
| 378 | for flycheck in world.flycheck.iter() { | |
| 378 | 'flychecks: for flycheck in world.flycheck.iter() { | |
| 379 | 379 | for (id, package) in workspace_ids.clone() { |
| 380 | 380 | if id == flycheck.id() { |
| 381 | 381 | updated = true; |
| 382 | match package.filter(|_| !world.config.flycheck_workspace(source_root_id)) { | |
| 383 | Some(package) => flycheck | |
| 384 | .restart_for_package(package, target.clone().map(TupleExt::head)), | |
| 385 | None => flycheck.restart_workspace(saved_file.clone()), | |
| 382 | if may_flycheck_workspace { | |
| 383 | flycheck.restart_workspace(saved_file.clone()) | |
| 384 | } else if let Some(package) = package { | |
| 385 | flycheck | |
| 386 | .restart_for_package(package, target.clone().map(TupleExt::head)) | |
| 386 | 387 | } |
| 387 | continue; | |
| 388 | continue 'flychecks; | |
| 388 | 389 | } |
| 389 | 390 | } |
| 390 | 391 | } |
| 391 | 392 | // No specific flycheck was triggered, so let's trigger all of them. |
| 392 | if !updated { | |
| 393 | if !updated && may_flycheck_workspace { | |
| 393 | 394 | for flycheck in world.flycheck.iter() { |
| 394 | 395 | flycheck.restart_workspace(saved_file.clone()); |
| 395 | 396 | } |
| ... | ... | @@ -432,8 +433,10 @@ pub(crate) fn handle_run_flycheck( |
| 432 | 433 | } |
| 433 | 434 | } |
| 434 | 435 | // No specific flycheck was triggered, so let's trigger all of them. |
| 435 | for flycheck in state.flycheck.iter() { | |
| 436 | flycheck.restart_workspace(None); | |
| 436 | if state.config.flycheck_workspace(None) { | |
| 437 | for flycheck in state.flycheck.iter() { | |
| 438 | flycheck.restart_workspace(None); | |
| 439 | } | |
| 437 | 440 | } |
| 438 | 441 | Ok(()) |
| 439 | 442 | } |
src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs+19-9| ... | ... | @@ -481,27 +481,28 @@ pub(crate) fn handle_document_diagnostics( |
| 481 | 481 | snap: GlobalStateSnapshot, |
| 482 | 482 | params: lsp_types::DocumentDiagnosticParams, |
| 483 | 483 | ) -> anyhow::Result<lsp_types::DocumentDiagnosticReportResult> { |
| 484 | const EMPTY: lsp_types::DocumentDiagnosticReportResult = | |
| 484 | let empty = || { | |
| 485 | 485 | lsp_types::DocumentDiagnosticReportResult::Report( |
| 486 | 486 | lsp_types::DocumentDiagnosticReport::Full( |
| 487 | 487 | lsp_types::RelatedFullDocumentDiagnosticReport { |
| 488 | 488 | related_documents: None, |
| 489 | 489 | full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport { |
| 490 | result_id: None, | |
| 490 | result_id: Some("rust-analyzer".to_owned()), | |
| 491 | 491 | items: vec![], |
| 492 | 492 | }, |
| 493 | 493 | }, |
| 494 | 494 | ), |
| 495 | ); | |
| 495 | ) | |
| 496 | }; | |
| 496 | 497 | |
| 497 | 498 | let file_id = from_proto::file_id(&snap, &params.text_document.uri)?; |
| 498 | 499 | let source_root = snap.analysis.source_root_id(file_id)?; |
| 499 | 500 | if !snap.analysis.is_local_source_root(source_root)? { |
| 500 | return Ok(EMPTY); | |
| 501 | return Ok(empty()); | |
| 501 | 502 | } |
| 502 | 503 | let config = snap.config.diagnostics(Some(source_root)); |
| 503 | 504 | if !config.enabled { |
| 504 | return Ok(EMPTY); | |
| 505 | return Ok(empty()); | |
| 505 | 506 | } |
| 506 | 507 | let line_index = snap.file_line_index(file_id)?; |
| 507 | 508 | let supports_related = snap.config.text_document_diagnostic_related_document_support(); |
| ... | ... | @@ -529,7 +530,7 @@ pub(crate) fn handle_document_diagnostics( |
| 529 | 530 | Ok(lsp_types::DocumentDiagnosticReportResult::Report( |
| 530 | 531 | lsp_types::DocumentDiagnosticReport::Full(lsp_types::RelatedFullDocumentDiagnosticReport { |
| 531 | 532 | full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport { |
| 532 | result_id: None, | |
| 533 | result_id: Some("rust-analyzer".to_owned()), | |
| 533 | 534 | items: diagnostics.collect(), |
| 534 | 535 | }, |
| 535 | 536 | related_documents: related_documents.is_empty().not().then(|| { |
| ... | ... | @@ -539,7 +540,10 @@ pub(crate) fn handle_document_diagnostics( |
| 539 | 540 | ( |
| 540 | 541 | to_proto::url(&snap, id), |
| 541 | 542 | lsp_types::DocumentDiagnosticReportKind::Full( |
| 542 | lsp_types::FullDocumentDiagnosticReport { result_id: None, items }, | |
| 543 | lsp_types::FullDocumentDiagnosticReport { | |
| 544 | result_id: Some("rust-analyzer".to_owned()), | |
| 545 | items, | |
| 546 | }, | |
| 543 | 547 | ), |
| 544 | 548 | ) |
| 545 | 549 | }) |
| ... | ... | @@ -1144,7 +1148,7 @@ pub(crate) fn handle_completion_resolve( |
| 1144 | 1148 | let Some(corresponding_completion) = completions.into_iter().find(|completion_item| { |
| 1145 | 1149 | // Avoid computing hashes for items that obviously do not match |
| 1146 | 1150 | // r-a might append a detail-based suffix to the label, so we cannot check for equality |
| 1147 | original_completion.label.starts_with(completion_item.label.as_str()) | |
| 1151 | original_completion.label.starts_with(completion_item.label.primary.as_str()) | |
| 1148 | 1152 | && resolve_data_hash == completion_item_hash(completion_item, resolve_data.for_ref) |
| 1149 | 1153 | }) else { |
| 1150 | 1154 | return Ok(original_completion); |
| ... | ... | @@ -1441,7 +1445,13 @@ pub(crate) fn handle_code_action( |
| 1441 | 1445 | } |
| 1442 | 1446 | |
| 1443 | 1447 | // Fixes from `cargo check`. |
| 1444 | for fix in snap.check_fixes.values().filter_map(|it| it.get(&frange.file_id)).flatten() { | |
| 1448 | for fix in snap | |
| 1449 | .check_fixes | |
| 1450 | .values() | |
| 1451 | .flat_map(|it| it.values()) | |
| 1452 | .filter_map(|it| it.get(&frange.file_id)) | |
| 1453 | .flatten() | |
| 1454 | { | |
| 1445 | 1455 | // FIXME: this mapping is awkward and shouldn't exist. Refactor |
| 1446 | 1456 | // `snap.check_fixes` to not convert to LSP prematurely. |
| 1447 | 1457 | let intersect_fix_range = fix |
src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs+5-2| ... | ... | @@ -114,8 +114,11 @@ fn completion_item_hash(item: &CompletionItem, is_ref_completion: bool) -> [u8; |
| 114 | 114 | u8::from(item.deprecated), |
| 115 | 115 | u8::from(item.trigger_call_info), |
| 116 | 116 | ]); |
| 117 | hasher.update(&item.label); | |
| 118 | if let Some(label_detail) = &item.label_detail { | |
| 117 | hasher.update(&item.label.primary); | |
| 118 | if let Some(label_detail) = &item.label.detail_left { | |
| 119 | hasher.update(label_detail); | |
| 120 | } | |
| 121 | if let Some(label_detail) = &item.label.detail_right { | |
| 119 | 122 | hasher.update(label_detail); |
| 120 | 123 | } |
| 121 | 124 | // NB: do not hash edits or source range, as those may change between the time the client sends the resolve request |
src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs+4| ... | ... | @@ -823,8 +823,11 @@ impl Request for OnTypeFormatting { |
| 823 | 823 | #[derive(Debug, Serialize, Deserialize)] |
| 824 | 824 | pub struct CompletionResolveData { |
| 825 | 825 | pub position: lsp_types::TextDocumentPositionParams, |
| 826 | #[serde(skip_serializing_if = "Vec::is_empty", default)] | |
| 826 | 827 | pub imports: Vec<CompletionImport>, |
| 828 | #[serde(skip_serializing_if = "Option::is_none", default)] | |
| 827 | 829 | pub version: Option<i32>, |
| 830 | #[serde(skip_serializing_if = "Option::is_none", default)] | |
| 828 | 831 | pub trigger_character: Option<char>, |
| 829 | 832 | pub for_ref: bool, |
| 830 | 833 | pub hash: String, |
| ... | ... | @@ -836,6 +839,7 @@ pub struct InlayHintResolveData { |
| 836 | 839 | // This is a string instead of a u64 as javascript can't represent u64 fully |
| 837 | 840 | pub hash: String, |
| 838 | 841 | pub resolve_range: lsp_types::Range, |
| 842 | #[serde(skip_serializing_if = "Option::is_none", default)] | |
| 839 | 843 | pub version: Option<i32>, |
| 840 | 844 | } |
| 841 | 845 |
src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs+33-23| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | use std::{ |
| 3 | 3 | iter::once, |
| 4 | 4 | mem, |
| 5 | ops::Not as _, | |
| 5 | 6 | sync::atomic::{AtomicU32, Ordering}, |
| 6 | 7 | }; |
| 7 | 8 | |
| ... | ... | @@ -353,14 +354,17 @@ fn completion_item( |
| 353 | 354 | }; |
| 354 | 355 | |
| 355 | 356 | let mut lsp_item = lsp_types::CompletionItem { |
| 356 | label: item.label.to_string(), | |
| 357 | label: item.label.primary.to_string(), | |
| 357 | 358 | detail, |
| 358 | 359 | filter_text, |
| 359 | 360 | kind: Some(completion_item_kind(item.kind)), |
| 360 | 361 | text_edit, |
| 361 | additional_text_edits: Some(additional_text_edits), | |
| 362 | additional_text_edits: additional_text_edits | |
| 363 | .is_empty() | |
| 364 | .not() | |
| 365 | .then_some(additional_text_edits), | |
| 362 | 366 | documentation, |
| 363 | deprecated: Some(item.deprecated), | |
| 367 | deprecated: item.deprecated.then_some(item.deprecated), | |
| 364 | 368 | tags, |
| 365 | 369 | command, |
| 366 | 370 | insert_text_format, |
| ... | ... | @@ -368,15 +372,17 @@ fn completion_item( |
| 368 | 372 | }; |
| 369 | 373 | |
| 370 | 374 | if config.completion_label_details_support() { |
| 375 | let has_label_details = | |
| 376 | item.label.detail_left.is_some() || item.label.detail_right.is_some(); | |
| 371 | 377 | if fields_to_resolve.resolve_label_details { |
| 372 | something_to_resolve |= true; | |
| 373 | } else { | |
| 378 | something_to_resolve |= has_label_details; | |
| 379 | } else if has_label_details { | |
| 374 | 380 | lsp_item.label_details = Some(lsp_types::CompletionItemLabelDetails { |
| 375 | detail: item.label_detail.as_ref().map(ToString::to_string), | |
| 376 | description: item.detail.clone(), | |
| 381 | detail: item.label.detail_left.clone(), | |
| 382 | description: item.label.detail_right.clone(), | |
| 377 | 383 | }); |
| 378 | 384 | } |
| 379 | } else if let Some(label_detail) = &item.label_detail { | |
| 385 | } else if let Some(label_detail) = &item.label.detail_left { | |
| 380 | 386 | lsp_item.label.push_str(label_detail.as_str()); |
| 381 | 387 | } |
| 382 | 388 | |
| ... | ... | @@ -1578,22 +1584,26 @@ pub(crate) fn code_lens( |
| 1578 | 1584 | }; |
| 1579 | 1585 | |
| 1580 | 1586 | let lens_config = snap.config.lens(); |
| 1581 | if lens_config.run && client_commands_config.run_single && has_root { | |
| 1582 | let command = command::run_single(&r, &title); | |
| 1583 | acc.push(lsp_types::CodeLens { | |
| 1584 | range: annotation_range, | |
| 1585 | command: Some(command), | |
| 1586 | data: None, | |
| 1587 | }) | |
| 1588 | } | |
| 1589 | if lens_config.debug && can_debug && client_commands_config.debug_single { | |
| 1590 | let command = command::debug_single(&r); | |
| 1591 | acc.push(lsp_types::CodeLens { | |
| 1592 | range: annotation_range, | |
| 1593 | command: Some(command), | |
| 1594 | data: None, | |
| 1595 | }) | |
| 1587 | ||
| 1588 | if has_root { | |
| 1589 | if lens_config.run && client_commands_config.run_single { | |
| 1590 | let command = command::run_single(&r, &title); | |
| 1591 | acc.push(lsp_types::CodeLens { | |
| 1592 | range: annotation_range, | |
| 1593 | command: Some(command), | |
| 1594 | data: None, | |
| 1595 | }) | |
| 1596 | } | |
| 1597 | if lens_config.debug && can_debug && client_commands_config.debug_single { | |
| 1598 | let command = command::debug_single(&r); | |
| 1599 | acc.push(lsp_types::CodeLens { | |
| 1600 | range: annotation_range, | |
| 1601 | command: Some(command), | |
| 1602 | data: None, | |
| 1603 | }) | |
| 1604 | } | |
| 1596 | 1605 | } |
| 1606 | ||
| 1597 | 1607 | if lens_config.interpret { |
| 1598 | 1608 | let command = command::interpret_single(&r); |
| 1599 | 1609 | acc.push(lsp_types::CodeLens { |
src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs+17-9| ... | ... | @@ -408,7 +408,10 @@ impl GlobalState { |
| 408 | 408 | if self.is_quiescent() { |
| 409 | 409 | let became_quiescent = !was_quiescent; |
| 410 | 410 | if became_quiescent { |
| 411 | if self.config.check_on_save(None) { | |
| 411 | if self.config.check_on_save(None) | |
| 412 | && self.config.flycheck_workspace(None) | |
| 413 | && !self.fetch_build_data_queue.op_requested() | |
| 414 | { | |
| 412 | 415 | // Project has loaded properly, kick off initial flycheck |
| 413 | 416 | self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None)); |
| 414 | 417 | } |
| ... | ... | @@ -656,8 +659,8 @@ impl GlobalState { |
| 656 | 659 | |
| 657 | 660 | fn update_status_or_notify(&mut self) { |
| 658 | 661 | let status = self.current_status(); |
| 659 | if self.last_reported_status.as_ref() != Some(&status) { | |
| 660 | self.last_reported_status = Some(status.clone()); | |
| 662 | if self.last_reported_status != status { | |
| 663 | self.last_reported_status = status.clone(); | |
| 661 | 664 | |
| 662 | 665 | if self.config.server_status_notification() { |
| 663 | 666 | self.send_notification::<lsp_ext::ServerStatusNotification>(status); |
| ... | ... | @@ -715,6 +718,7 @@ impl GlobalState { |
| 715 | 718 | error!("FetchWorkspaceError: {e}"); |
| 716 | 719 | } |
| 717 | 720 | self.wants_to_switch = Some("fetched workspace".to_owned()); |
| 721 | self.diagnostics.clear_check_all(); | |
| 718 | 722 | (Progress::End, None) |
| 719 | 723 | } |
| 720 | 724 | }; |
| ... | ... | @@ -956,7 +960,7 @@ impl GlobalState { |
| 956 | 960 | |
| 957 | 961 | fn handle_flycheck_msg(&mut self, message: FlycheckMessage) { |
| 958 | 962 | match message { |
| 959 | FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => { | |
| 963 | FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic, package_id } => { | |
| 960 | 964 | let snap = self.snapshot(); |
| 961 | 965 | let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( |
| 962 | 966 | &self.config.diagnostics_map(None), |
| ... | ... | @@ -968,6 +972,7 @@ impl GlobalState { |
| 968 | 972 | match url_to_file_id(&self.vfs.read().0, &diag.url) { |
| 969 | 973 | Ok(file_id) => self.diagnostics.add_check_diagnostic( |
| 970 | 974 | id, |
| 975 | &package_id, | |
| 971 | 976 | file_id, |
| 972 | 977 | diag.diagnostic, |
| 973 | 978 | diag.fix, |
| ... | ... | @@ -981,9 +986,12 @@ impl GlobalState { |
| 981 | 986 | }; |
| 982 | 987 | } |
| 983 | 988 | } |
| 984 | ||
| 985 | FlycheckMessage::ClearDiagnostics { id } => self.diagnostics.clear_check(id), | |
| 986 | ||
| 989 | FlycheckMessage::ClearDiagnostics { id, package_id: None } => { | |
| 990 | self.diagnostics.clear_check(id) | |
| 991 | } | |
| 992 | FlycheckMessage::ClearDiagnostics { id, package_id: Some(package_id) } => { | |
| 993 | self.diagnostics.clear_check_for_package(id, package_id) | |
| 994 | } | |
| 987 | 995 | FlycheckMessage::Progress { id, progress } => { |
| 988 | 996 | let (state, message) = match progress { |
| 989 | 997 | flycheck::Progress::DidStart => (Progress::Begin, None), |
| ... | ... | @@ -1090,12 +1098,12 @@ impl GlobalState { |
| 1090 | 1098 | .on_latency_sensitive::<NO_RETRY, lsp_request::SemanticTokensRangeRequest>(handlers::handle_semantic_tokens_range) |
| 1091 | 1099 | // FIXME: Some of these NO_RETRY could be retries if the file they are interested didn't change. |
| 1092 | 1100 | // All other request handlers |
| 1093 | .on_with::<lsp_request::DocumentDiagnosticRequest>(handlers::handle_document_diagnostics, || lsp_types::DocumentDiagnosticReportResult::Report( | |
| 1101 | .on_with_vfs_default::<lsp_request::DocumentDiagnosticRequest>(handlers::handle_document_diagnostics, || lsp_types::DocumentDiagnosticReportResult::Report( | |
| 1094 | 1102 | lsp_types::DocumentDiagnosticReport::Full( |
| 1095 | 1103 | lsp_types::RelatedFullDocumentDiagnosticReport { |
| 1096 | 1104 | related_documents: None, |
| 1097 | 1105 | full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport { |
| 1098 | result_id: None, | |
| 1106 | result_id: Some("rust-analyzer".to_owned()), | |
| 1099 | 1107 | items: vec![], |
| 1100 | 1108 | }, |
| 1101 | 1109 | }, |
src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs-1| ... | ... | @@ -70,7 +70,6 @@ impl GlobalState { |
| 70 | 70 | /// are ready to do semantic work. |
| 71 | 71 | pub(crate) fn is_quiescent(&self) -> bool { |
| 72 | 72 | self.vfs_done |
| 73 | && self.last_reported_status.is_some() | |
| 74 | 73 | && !self.fetch_workspaces_queue.op_in_progress() |
| 75 | 74 | && !self.fetch_build_data_queue.op_in_progress() |
| 76 | 75 | && !self.fetch_proc_macros_queue.op_in_progress() |
src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs+2-1| ... | ... | @@ -5,7 +5,8 @@ use std::process::Command; |
| 5 | 5 | |
| 6 | 6 | use crossbeam_channel::Sender; |
| 7 | 7 | use paths::AbsPath; |
| 8 | use serde::Deserialize; | |
| 8 | use serde::Deserialize as _; | |
| 9 | use serde_derive::Deserialize; | |
| 9 | 10 | use toolchain::Tool; |
| 10 | 11 | |
| 11 | 12 | use crate::{ |
src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs+1-1| ... | ... | @@ -54,7 +54,7 @@ where |
| 54 | 54 | fn on_event(&self, _event: &Event<'_>, _ctx: Context<'_, S>) {} |
| 55 | 55 | |
| 56 | 56 | fn on_close(&self, id: Id, ctx: Context<'_, S>) { |
| 57 | #[derive(serde::Serialize)] | |
| 57 | #[derive(serde_derive::Serialize)] | |
| 58 | 58 | struct JsonDataInner { |
| 59 | 59 | name: &'static str, |
| 60 | 60 | elapsed_ms: u128, |
src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs+9-30| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | use std::{ |
| 2 | 2 | cell::{Cell, RefCell}, |
| 3 | 3 | env, fs, |
| 4 | sync::{Once, OnceLock}, | |
| 4 | sync::Once, | |
| 5 | 5 | time::Duration, |
| 6 | 6 | }; |
| 7 | 7 | |
| ... | ... | @@ -141,34 +141,15 @@ impl Project<'_> { |
| 141 | 141 | /// file in the config dir after server is run, something where our naive approach comes short. |
| 142 | 142 | /// Using a `prelock` allows us to force a lock when we know we need it. |
| 143 | 143 | pub(crate) fn server_with_lock(self, config_lock: bool) -> Server { |
| 144 | static CONFIG_DIR_LOCK: OnceLock<(Utf8PathBuf, Mutex<()>)> = OnceLock::new(); | |
| 144 | static CONFIG_DIR_LOCK: Mutex<()> = Mutex::new(()); | |
| 145 | 145 | |
| 146 | 146 | let config_dir_guard = if config_lock { |
| 147 | 147 | Some({ |
| 148 | let (path, mutex) = CONFIG_DIR_LOCK.get_or_init(|| { | |
| 149 | let value = TestDir::new().keep().path().to_owned(); | |
| 150 | env::set_var("__TEST_RA_USER_CONFIG_DIR", &value); | |
| 151 | (value, Mutex::new(())) | |
| 152 | }); | |
| 153 | #[allow(dyn_drop)] | |
| 154 | (mutex.lock(), { | |
| 155 | Box::new({ | |
| 156 | struct Dropper(Utf8PathBuf); | |
| 157 | impl Drop for Dropper { | |
| 158 | fn drop(&mut self) { | |
| 159 | for entry in fs::read_dir(&self.0).unwrap() { | |
| 160 | let path = entry.unwrap().path(); | |
| 161 | if path.is_file() { | |
| 162 | fs::remove_file(path).unwrap(); | |
| 163 | } else if path.is_dir() { | |
| 164 | fs::remove_dir_all(path).unwrap(); | |
| 165 | } | |
| 166 | } | |
| 167 | } | |
| 168 | } | |
| 169 | Dropper(path.clone()) | |
| 170 | }) as Box<dyn Drop> | |
| 171 | }) | |
| 148 | let guard = CONFIG_DIR_LOCK.lock(); | |
| 149 | let test_dir = TestDir::new(); | |
| 150 | let value = test_dir.path().to_owned(); | |
| 151 | env::set_var("__TEST_RA_USER_CONFIG_DIR", &value); | |
| 152 | (guard, test_dir) | |
| 172 | 153 | }) |
| 173 | 154 | } else { |
| 174 | 155 | None |
| ... | ... | @@ -311,14 +292,12 @@ pub(crate) struct Server { |
| 311 | 292 | client: Connection, |
| 312 | 293 | /// XXX: remove the tempdir last |
| 313 | 294 | dir: TestDir, |
| 314 | #[allow(dyn_drop)] | |
| 315 | _config_dir_guard: Option<(MutexGuard<'static, ()>, Box<dyn Drop>)>, | |
| 295 | _config_dir_guard: Option<(MutexGuard<'static, ()>, TestDir)>, | |
| 316 | 296 | } |
| 317 | 297 | |
| 318 | 298 | impl Server { |
| 319 | #[allow(dyn_drop)] | |
| 320 | 299 | fn new( |
| 321 | config_dir_guard: Option<(MutexGuard<'static, ()>, Box<dyn Drop>)>, | |
| 300 | config_dir_guard: Option<(MutexGuard<'static, ()>, TestDir)>, | |
| 322 | 301 | dir: TestDir, |
| 323 | 302 | config: Config, |
| 324 | 303 | ) -> Server { |
src/tools/rust-analyzer/crates/span/Cargo.toml+4-1| ... | ... | @@ -12,7 +12,7 @@ authors.workspace = true |
| 12 | 12 | |
| 13 | 13 | [dependencies] |
| 14 | 14 | la-arena.workspace = true |
| 15 | ra-salsa.workspace = true | |
| 15 | ra-salsa = { workspace = true, optional = true } | |
| 16 | 16 | rustc-hash.workspace = true |
| 17 | 17 | hashbrown.workspace = true |
| 18 | 18 | text-size.workspace = true |
| ... | ... | @@ -22,5 +22,8 @@ vfs.workspace = true |
| 22 | 22 | syntax.workspace = true |
| 23 | 23 | stdx.workspace = true |
| 24 | 24 | |
| 25 | [features] | |
| 26 | default = ["ra-salsa"] | |
| 27 | ||
| 25 | 28 | [lints] |
| 26 | 29 | workspace = true |
src/tools/rust-analyzer/crates/span/src/hygiene.rs+5| ... | ... | @@ -21,6 +21,9 @@ |
| 21 | 21 | //! `ExpnData::call_site` in rustc, [`MacroCallLoc::call_site`] in rust-analyzer. |
| 22 | 22 | use std::fmt; |
| 23 | 23 | |
| 24 | #[cfg(not(feature = "ra-salsa"))] | |
| 25 | use crate::InternId; | |
| 26 | #[cfg(feature = "ra-salsa")] | |
| 24 | 27 | use ra_salsa::{InternId, InternValue}; |
| 25 | 28 | |
| 26 | 29 | use crate::MacroCallId; |
| ... | ... | @@ -39,6 +42,7 @@ impl fmt::Debug for SyntaxContextId { |
| 39 | 42 | } |
| 40 | 43 | } |
| 41 | 44 | |
| 45 | #[cfg(feature = "ra-salsa")] | |
| 42 | 46 | impl ra_salsa::InternKey for SyntaxContextId { |
| 43 | 47 | fn from_intern_id(v: ra_salsa::InternId) -> Self { |
| 44 | 48 | SyntaxContextId(v) |
| ... | ... | @@ -92,6 +96,7 @@ pub struct SyntaxContextData { |
| 92 | 96 | pub opaque_and_semitransparent: SyntaxContextId, |
| 93 | 97 | } |
| 94 | 98 | |
| 99 | #[cfg(feature = "ra-salsa")] | |
| 95 | 100 | impl InternValue for SyntaxContextData { |
| 96 | 101 | type Key = (SyntaxContextId, Option<MacroCallId>, Transparency); |
| 97 | 102 |
src/tools/rust-analyzer/crates/span/src/lib.rs+72-1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | //! File and span related types. |
| 2 | 2 | use std::fmt::{self, Write}; |
| 3 | 3 | |
| 4 | #[cfg(feature = "ra-salsa")] | |
| 4 | 5 | use ra_salsa::InternId; |
| 5 | 6 | |
| 6 | 7 | mod ast_id; |
| ... | ... | @@ -261,8 +262,9 @@ pub struct MacroFileId { |
| 261 | 262 | /// `MacroCallId` identifies a particular macro invocation, like |
| 262 | 263 | /// `println!("Hello, {}", world)`. |
| 263 | 264 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 264 | pub struct MacroCallId(ra_salsa::InternId); | |
| 265 | pub struct MacroCallId(InternId); | |
| 265 | 266 | |
| 267 | #[cfg(feature = "ra-salsa")] | |
| 266 | 268 | impl ra_salsa::InternKey for MacroCallId { |
| 267 | 269 | fn from_intern_id(v: ra_salsa::InternId) -> Self { |
| 268 | 270 | MacroCallId(v) |
| ... | ... | @@ -355,3 +357,72 @@ impl HirFileId { |
| 355 | 357 | } |
| 356 | 358 | } |
| 357 | 359 | } |
| 360 | ||
| 361 | #[cfg(not(feature = "ra-salsa"))] | |
| 362 | mod intern_id_proxy { | |
| 363 | use std::fmt; | |
| 364 | use std::num::NonZeroU32; | |
| 365 | ||
| 366 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | |
| 367 | pub(super) struct InternId { | |
| 368 | value: NonZeroU32, | |
| 369 | } | |
| 370 | ||
| 371 | impl InternId { | |
| 372 | pub(super) const MAX: u32 = 0xFFFF_FF00; | |
| 373 | ||
| 374 | pub(super) const unsafe fn new_unchecked(value: u32) -> Self { | |
| 375 | debug_assert!(value < InternId::MAX); | |
| 376 | let value = unsafe { NonZeroU32::new_unchecked(value + 1) }; | |
| 377 | InternId { value } | |
| 378 | } | |
| 379 | ||
| 380 | pub(super) fn as_u32(self) -> u32 { | |
| 381 | self.value.get() - 1 | |
| 382 | } | |
| 383 | ||
| 384 | pub(super) fn as_usize(self) -> usize { | |
| 385 | self.as_u32() as usize | |
| 386 | } | |
| 387 | } | |
| 388 | ||
| 389 | impl From<InternId> for u32 { | |
| 390 | fn from(raw: InternId) -> u32 { | |
| 391 | raw.as_u32() | |
| 392 | } | |
| 393 | } | |
| 394 | ||
| 395 | impl From<InternId> for usize { | |
| 396 | fn from(raw: InternId) -> usize { | |
| 397 | raw.as_usize() | |
| 398 | } | |
| 399 | } | |
| 400 | ||
| 401 | impl From<u32> for InternId { | |
| 402 | fn from(id: u32) -> InternId { | |
| 403 | assert!(id < InternId::MAX); | |
| 404 | unsafe { InternId::new_unchecked(id) } | |
| 405 | } | |
| 406 | } | |
| 407 | ||
| 408 | impl From<usize> for InternId { | |
| 409 | fn from(id: usize) -> InternId { | |
| 410 | assert!(id < (InternId::MAX as usize)); | |
| 411 | unsafe { InternId::new_unchecked(id as u32) } | |
| 412 | } | |
| 413 | } | |
| 414 | ||
| 415 | impl fmt::Debug for InternId { | |
| 416 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| 417 | self.as_usize().fmt(f) | |
| 418 | } | |
| 419 | } | |
| 420 | ||
| 421 | impl fmt::Display for InternId { | |
| 422 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| 423 | self.as_usize().fmt(f) | |
| 424 | } | |
| 425 | } | |
| 426 | } | |
| 427 | #[cfg(not(feature = "ra-salsa"))] | |
| 428 | use intern_id_proxy::InternId; |
src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml+2-1| ... | ... | @@ -21,7 +21,8 @@ syntax.workspace = true |
| 21 | 21 | parser.workspace = true |
| 22 | 22 | tt.workspace = true |
| 23 | 23 | stdx.workspace = true |
| 24 | span.workspace = true | |
| 24 | # span = {workspace = true, default-features = false} does not work | |
| 25 | span = { path = "../span", version = "0.0.0", default-features = false} | |
| 25 | 26 | intern.workspace = true |
| 26 | 27 | |
| 27 | 28 | [dev-dependencies] |
src/tools/rust-analyzer/crates/syntax/rust.ungram+1-1| ... | ... | @@ -414,7 +414,7 @@ AsmClobberAbi = 'clobber_abi' '(' ('@string' (',' '@string')* ','?) ')' |
| 414 | 414 | // option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw" |
| 415 | 415 | AsmOption = 'pure' | 'nomem' | 'readonly' | 'preserves_flags' | 'noreturn' | 'nostack' | 'att_syntax' | 'raw' | 'may_unwind' |
| 416 | 416 | // options := "options(" option *("," option) [","] ")" |
| 417 | AsmOptions = 'options' '(' AsmOption *(',' AsmOption) ','? ')' | |
| 417 | AsmOptions = 'options' '(' (AsmOption (',' AsmOption)*) ','? ')' | |
| 418 | 418 | AsmLabel = 'label' BlockExpr |
| 419 | 419 | AsmSym = 'sym' Path |
| 420 | 420 | AsmConst = 'const' Expr |
src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs-2| ... | ... | @@ -211,8 +211,6 @@ pub struct AsmOptions { |
| 211 | 211 | pub(crate) syntax: SyntaxNode, |
| 212 | 212 | } |
| 213 | 213 | impl AsmOptions { |
| 214 | #[inline] | |
| 215 | pub fn asm_option(&self) -> Option<AsmOption> { support::child(&self.syntax) } | |
| 216 | 214 | #[inline] |
| 217 | 215 | pub fn asm_options(&self) -> AstChildren<AsmOption> { support::children(&self.syntax) } |
| 218 | 216 | #[inline] |
src/tools/rust-analyzer/docs/dev/lsp-extensions.md+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | <!--- |
| 2 | lsp/ext.rs hash: 14b7fb1309f5bb00 | |
| 2 | lsp/ext.rs hash: 9790509d87670c22 | |
| 3 | 3 | |
| 4 | 4 | If you need to change the above hash to make the test pass, please check if you |
| 5 | 5 | need to adjust this doc as well and ping this issue: |
src/tools/rust-analyzer/docs/user/generated_config.adoc+2-1| ... | ... | @@ -270,7 +270,8 @@ Aliased as `"checkOnSave.targets"`. |
| 270 | 270 | + |
| 271 | 271 | -- |
| 272 | 272 | Whether `--workspace` should be passed to `cargo check`. |
| 273 | If false, `-p <package>` will be passed instead. | |
| 273 | If false, `-p <package>` will be passed instead if applicable. In case it is not, no | |
| 274 | check will be performed. | |
| 274 | 275 | -- |
| 275 | 276 | [[rust-analyzer.completion.addSemicolonToUnit]]rust-analyzer.completion.addSemicolonToUnit (default: `true`):: |
| 276 | 277 | + |
src/tools/rust-analyzer/editors/code/package.json+1-1| ... | ... | @@ -1098,7 +1098,7 @@ |
| 1098 | 1098 | "title": "check", |
| 1099 | 1099 | "properties": { |
| 1100 | 1100 | "rust-analyzer.check.workspace": { |
| 1101 | "markdownDescription": "Whether `--workspace` should be passed to `cargo check`.\nIf false, `-p <package>` will be passed instead.", | |
| 1101 | "markdownDescription": "Whether `--workspace` should be passed to `cargo check`.\nIf false, `-p <package>` will be passed instead if applicable. In case it is not, no\ncheck will be performed.", | |
| 1102 | 1102 | "default": true, |
| 1103 | 1103 | "type": "boolean" |
| 1104 | 1104 | } |
src/tools/rust-analyzer/editors/code/src/ctx.ts+2| ... | ... | @@ -347,6 +347,8 @@ export class Ctx implements RustAnalyzerExtensionApi { |
| 347 | 347 | } |
| 348 | 348 | log.info("Disposing language client"); |
| 349 | 349 | this.updateCommands("disable"); |
| 350 | // we give the server 100ms to stop gracefully | |
| 351 | await this.client?.stop(100).catch((_) => {}); | |
| 350 | 352 | await this.disposeClient(); |
| 351 | 353 | } |
| 352 | 354 |
src/tools/rust-analyzer/lib/lsp-server/Cargo.toml+3-2| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | [package] |
| 2 | 2 | name = "lsp-server" |
| 3 | version = "0.7.7" | |
| 3 | version = "0.7.8" | |
| 4 | 4 | description = "Generic LSP server scaffold." |
| 5 | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server" |
| ... | ... | @@ -9,7 +9,8 @@ edition = "2021" |
| 9 | 9 | [dependencies] |
| 10 | 10 | log = "0.4.17" |
| 11 | 11 | serde_json = "1.0.108" |
| 12 | serde = { version = "1.0.192", features = ["derive"] } | |
| 12 | serde = { version = "1.0.216" } | |
| 13 | serde_derive = { version = "1.0.216" } | |
| 13 | 14 | crossbeam-channel.workspace = true |
| 14 | 15 | |
| 15 | 16 | [dev-dependencies] |
src/tools/rust-analyzer/lib/lsp-server/src/msg.rs+5-4| ... | ... | @@ -3,7 +3,8 @@ use std::{ |
| 3 | 3 | io::{self, BufRead, Write}, |
| 4 | 4 | }; |
| 5 | 5 | |
| 6 | use serde::{de::DeserializeOwned, Deserialize, Serialize}; | |
| 6 | use serde::de::DeserializeOwned; | |
| 7 | use serde_derive::{Deserialize, Serialize}; | |
| 7 | 8 | |
| 8 | 9 | use crate::error::ExtractError; |
| 9 | 10 | |
| ... | ... | @@ -196,7 +197,7 @@ impl Message { |
| 196 | 197 | } |
| 197 | 198 | |
| 198 | 199 | impl Response { |
| 199 | pub fn new_ok<R: Serialize>(id: RequestId, result: R) -> Response { | |
| 200 | pub fn new_ok<R: serde::Serialize>(id: RequestId, result: R) -> Response { | |
| 200 | 201 | Response { id, result: Some(serde_json::to_value(result).unwrap()), error: None } |
| 201 | 202 | } |
| 202 | 203 | pub fn new_err(id: RequestId, code: i32, message: String) -> Response { |
| ... | ... | @@ -206,7 +207,7 @@ impl Response { |
| 206 | 207 | } |
| 207 | 208 | |
| 208 | 209 | impl Request { |
| 209 | pub fn new<P: Serialize>(id: RequestId, method: String, params: P) -> Request { | |
| 210 | pub fn new<P: serde::Serialize>(id: RequestId, method: String, params: P) -> Request { | |
| 210 | 211 | Request { id, method, params: serde_json::to_value(params).unwrap() } |
| 211 | 212 | } |
| 212 | 213 | pub fn extract<P: DeserializeOwned>( |
| ... | ... | @@ -231,7 +232,7 @@ impl Request { |
| 231 | 232 | } |
| 232 | 233 | |
| 233 | 234 | impl Notification { |
| 234 | pub fn new(method: String, params: impl Serialize) -> Notification { | |
| 235 | pub fn new(method: String, params: impl serde::Serialize) -> Notification { | |
| 235 | 236 | Notification { method, params: serde_json::to_value(params).unwrap() } |
| 236 | 237 | } |
| 237 | 238 | pub fn extract<P: DeserializeOwned>( |
src/tools/rust-analyzer/lib/lsp-server/src/req_queue.rs+1-3| ... | ... | @@ -1,7 +1,5 @@ |
| 1 | 1 | use std::collections::HashMap; |
| 2 | 2 | |
| 3 | use serde::Serialize; | |
| 4 | ||
| 5 | 3 | use crate::{ErrorCode, Request, RequestId, Response, ResponseError}; |
| 6 | 4 | |
| 7 | 5 | /// Manages the set of pending requests, both incoming and outgoing. |
| ... | ... | @@ -56,7 +54,7 @@ impl<I> Incoming<I> { |
| 56 | 54 | } |
| 57 | 55 | |
| 58 | 56 | impl<O> Outgoing<O> { |
| 59 | pub fn register<P: Serialize>(&mut self, method: String, params: P, data: O) -> Request { | |
| 57 | pub fn register<P: serde::Serialize>(&mut self, method: String, params: P, data: O) -> Request { | |
| 60 | 58 | let id = RequestId::from(self.next_id); |
| 61 | 59 | self.pending.insert(id.clone(), data); |
| 62 | 60 | self.next_id += 1; |
src/tools/rust-analyzer/rust-version+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | 5a6036a1802262f8cf02192b02026688d396f1d7 | |
| 1 | 0eca4dd3205a01dba4bd7b7c140ec370aff03440 |
src/tools/rust-analyzer/xtask/Cargo.toml+2-1| ... | ... | @@ -16,7 +16,8 @@ xflags = "0.3.0" |
| 16 | 16 | time = { version = "0.3", default-features = false } |
| 17 | 17 | zip = { version = "0.6", default-features = false, features = ["deflate", "time"] } |
| 18 | 18 | stdx.workspace = true |
| 19 | proc-macro2 = "1.0.47" | |
| 19 | # https://github.com/dtolnay/proc-macro2/issues/475 | |
| 20 | proc-macro2 = "=1.0.86" | |
| 20 | 21 | quote = "1.0.20" |
| 21 | 22 | ungrammar = "1.16.1" |
| 22 | 23 | either.workspace = true |