authorbors <bors@rust-lang.org> 2024-12-23 12:18:14 UTC
committerbors <bors@rust-lang.org> 2024-12-23 12:18:14 UTC
log904d8f6b39ce98fb890ac3381a710f071ddae44d
tree0301bf9e4b4dbc841acadc026db5621d9f6e7de7
parent85c39893a761fe4c050523278da4e7e45ab42b6e
parent8dbdcc03ebfd5d3c21671d8a021669dc79d93038

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

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"
10111011[[package]]
10121012name = "lsp-server"
10131013version = "0.7.7"
1014source = "registry+https://github.com/rust-lang/crates.io-index"
1015checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9"
10141016dependencies = [
10151017 "crossbeam-channel",
1016 "ctrlc",
10171018 "log",
1018 "lsp-types",
10191019 "serde",
10201020 "serde_json",
10211021]
10221022
10231023[[package]]
10241024name = "lsp-server"
1025version = "0.7.7"
1026source = "registry+https://github.com/rust-lang/crates.io-index"
1027checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9"
1025version = "0.7.8"
10281026dependencies = [
10291027 "crossbeam-channel",
1028 "ctrlc",
10301029 "log",
1030 "lsp-types",
10311031 "serde",
1032 "serde_derive",
10321033 "serde_json",
10331034]
10341035
......@@ -1289,7 +1290,6 @@ name = "paths"
12891290version = "0.0.0"
12901291dependencies = [
12911292 "camino",
1292 "serde",
12931293]
12941294
12951295[[package]]
......@@ -1352,12 +1352,12 @@ dependencies = [
13521352name = "proc-macro-api"
13531353version = "0.0.0"
13541354dependencies = [
1355 "base-db",
13561355 "indexmap",
13571356 "intern",
13581357 "paths",
13591358 "rustc-hash 2.0.0",
13601359 "serde",
1360 "serde_derive",
13611361 "serde_json",
13621362 "span",
13631363 "stdx",
......@@ -1369,7 +1369,6 @@ dependencies = [
13691369name = "proc-macro-srv"
13701370version = "0.0.0"
13711371dependencies = [
1372 "base-db",
13731372 "expect-test",
13741373 "intern",
13751374 "libloading",
......@@ -1448,6 +1447,7 @@ dependencies = [
14481447 "rustc-hash 2.0.0",
14491448 "semver",
14501449 "serde",
1450 "serde_derive",
14511451 "serde_json",
14521452 "span",
14531453 "stdx",
......@@ -1507,9 +1507,9 @@ dependencies = [
15071507
15081508[[package]]
15091509name = "ra-ap-rustc_abi"
1510version = "0.85.0"
1510version = "0.87.0"
15111511source = "registry+https://github.com/rust-lang/crates.io-index"
1512checksum = "af462c3a2d524b84a51b6848b439787f01b35c6c1086d3e3086a5f5eea92ed9a"
1512checksum = "28b782af0a7a8df16ddf43cd70da9f17bc3b1ce712c9e4992b6edb16f5f53632"
15131513dependencies = [
15141514 "bitflags 2.6.0",
15151515 "ra-ap-rustc_index",
......@@ -1518,9 +1518,9 @@ dependencies = [
15181518
15191519[[package]]
15201520name = "ra-ap-rustc_index"
1521version = "0.85.0"
1521version = "0.87.0"
15221522source = "registry+https://github.com/rust-lang/crates.io-index"
1523checksum = "be6bb8cb0ab78d94a222f1ffd3e87254cdfb57413382b8d6ebe26a85482f99d1"
1523checksum = "ce5742f134960482f543b35ecebec3cacc6d79a9a685713518b4d8d70c5f9aa8"
15241524dependencies = [
15251525 "ra-ap-rustc_index_macros",
15261526 "smallvec",
......@@ -1528,9 +1528,9 @@ dependencies = [
15281528
15291529[[package]]
15301530name = "ra-ap-rustc_index_macros"
1531version = "0.85.0"
1531version = "0.87.0"
15321532source = "registry+https://github.com/rust-lang/crates.io-index"
1533checksum = "c24b1641455b46e87435b7321219672077066e678963d239a4a2904732979b16"
1533checksum = "d7ea011fcf68309a8835ad01d91c032cb18444617b00e2cab21d45b208164441"
15341534dependencies = [
15351535 "proc-macro2",
15361536 "quote",
......@@ -1539,9 +1539,9 @@ dependencies = [
15391539
15401540[[package]]
15411541name = "ra-ap-rustc_lexer"
1542version = "0.85.0"
1542version = "0.87.0"
15431543source = "registry+https://github.com/rust-lang/crates.io-index"
1544checksum = "94daa86974417981fed2f12bd8fb00158dfa6fee561152bed689278c846d0272"
1544checksum = "eb76f0a4d4c20859e41f0a23bff0f37ab9ca9171c214a6c7dd72ea69434865dc"
15451545dependencies = [
15461546 "unicode-properties",
15471547 "unicode-xid",
......@@ -1549,9 +1549,9 @@ dependencies = [
15491549
15501550[[package]]
15511551name = "ra-ap-rustc_parse_format"
1552version = "0.85.0"
1552version = "0.87.0"
15531553source = "registry+https://github.com/rust-lang/crates.io-index"
1554checksum = "fc07f6bd581746f358e39c4b6bfe8d455b3d6ad1a857821016d0d42eeb5e1e3e"
1554checksum = "06080bd35078305421a62da77f3c128482d8d44441b6da8ce9d146d1cd9cdb5b"
15551555dependencies = [
15561556 "ra-ap-rustc_index",
15571557 "ra-ap-rustc_lexer",
......@@ -1559,9 +1559,9 @@ dependencies = [
15591559
15601560[[package]]
15611561name = "ra-ap-rustc_pattern_analysis"
1562version = "0.85.0"
1562version = "0.87.0"
15631563source = "registry+https://github.com/rust-lang/crates.io-index"
1564checksum = "2f49b86e1276c1c3c72898410def29b699415f4e7d1dfb3531daf79794694372"
1564checksum = "68a3154fe4c20c177d7b3c678a2d3a97aba0cca156ddef88959915041889daf0"
15651565dependencies = [
15661566 "ra-ap-rustc_index",
15671567 "rustc-hash 2.0.0",
......@@ -1676,7 +1676,7 @@ dependencies = [
16761676 "intern",
16771677 "itertools",
16781678 "load-cargo",
1679 "lsp-server 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
1679 "lsp-server 0.7.7",
16801680 "lsp-types",
16811681 "memchr",
16821682 "mimalloc",
......@@ -1695,6 +1695,7 @@ dependencies = [
16951695 "scip",
16961696 "semver",
16971697 "serde",
1698 "serde_derive",
16981699 "serde_json",
16991700 "stdx",
17001701 "syntax",
......@@ -1822,18 +1823,18 @@ dependencies = [
18221823
18231824[[package]]
18241825name = "serde"
1825version = "1.0.206"
1826version = "1.0.216"
18261827source = "registry+https://github.com/rust-lang/crates.io-index"
1827checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284"
1828checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
18281829dependencies = [
18291830 "serde_derive",
18301831]
18311832
18321833[[package]]
18331834name = "serde_derive"
1834version = "1.0.206"
1835version = "1.0.216"
18351836source = "registry+https://github.com/rust-lang/crates.io-index"
1836checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97"
1837checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
18371838dependencies = [
18381839 "proc-macro2",
18391840 "quote",
......@@ -1924,12 +1925,6 @@ version = "0.3.2"
19241925source = "registry+https://github.com/rust-lang/crates.io-index"
19251926checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a"
19261927
1927[[package]]
1928name = "stable_deref_trait"
1929version = "1.2.0"
1930source = "registry+https://github.com/rust-lang/crates.io-index"
1931checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
1932
19331928[[package]]
19341929name = "stdx"
19351930version = "0.0.0"
......@@ -1946,9 +1941,9 @@ dependencies = [
19461941
19471942[[package]]
19481943name = "syn"
1949version = "2.0.74"
1944version = "2.0.87"
19501945source = "registry+https://github.com/rust-lang/crates.io-index"
1951checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7"
1946checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
19521947dependencies = [
19531948 "proc-macro2",
19541949 "quote",
......@@ -2264,13 +2259,9 @@ dependencies = [
22642259
22652260[[package]]
22662261name = "triomphe"
2267version = "0.1.13"
2262version = "0.1.14"
22682263source = "registry+https://github.com/rust-lang/crates.io-index"
2269checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369"
2270dependencies = [
2271 "serde",
2272 "stable_deref_trait",
2273]
2264checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85"
22742265
22752266[[package]]
22762267name = "tt"
src/tools/rust-analyzer/Cargo.toml+8-7
......@@ -85,11 +85,11 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
8585vfs = { path = "./crates/vfs", version = "0.0.0" }
8686edition = { path = "./crates/edition", version = "0.0.0" }
8787
88ra-ap-rustc_lexer = { version = "0.85", default-features = false }
89ra-ap-rustc_parse_format = { version = "0.85", default-features = false }
90ra-ap-rustc_index = { version = "0.85", default-features = false }
91ra-ap-rustc_abi = { version = "0.85", default-features = false }
92ra-ap-rustc_pattern_analysis = { version = "0.85", default-features = false }
88ra-ap-rustc_lexer = { version = "0.87", default-features = false }
89ra-ap-rustc_parse_format = { version = "0.87", default-features = false }
90ra-ap-rustc_index = { version = "0.87", default-features = false }
91ra-ap-rustc_abi = { version = "0.87", default-features = false }
92ra-ap-rustc_pattern_analysis = { version = "0.87", default-features = false }
9393
9494# local crates that aren't published to crates.io. These should not have versions.
9595test-fixture = { path = "./crates/test-fixture" }
......@@ -138,7 +138,8 @@ pulldown-cmark = { version = "0.9.0", default-features = false }
138138rayon = "1.8.0"
139139rustc-hash = "2.0.0"
140140semver = "1.0.14"
141serde = { version = "1.0.192", features = ["derive"] }
141serde = { version = "1.0.192" }
142serde_derive = { version = "1.0.192" }
142143serde_json = "1.0.108"
143144smallvec = { version = "1.10.0", features = [
144145 "const_new",
......@@ -157,7 +158,7 @@ tracing-subscriber = { version = "0.3.18", default-features = false, features =
157158 "time",
158159 "tracing-log",
159160] }
160triomphe = { version = "0.1.10", default-features = false, features = ["std"] }
161triomphe = { version = "0.1.14", default-features = false, features = ["std"] }
161162url = "2.3.1"
162163xshell = "0.2.5"
163164
src/tools/rust-analyzer/crates/hir-def/src/body.rs+38-14
......@@ -18,6 +18,7 @@ use smallvec::SmallVec;
1818use span::{Edition, MacroFileId};
1919use syntax::{ast, AstPtr, SyntaxNodePtr};
2020use triomphe::Arc;
21use tt::TextRange;
2122
2223use crate::{
2324 db::DefDatabase,
......@@ -143,15 +144,7 @@ pub struct BodySourceMap {
143144
144145 pub types: TypesSourceMap,
145146
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>>,
155148
156149 expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, MacroFileId>,
157150
......@@ -160,6 +153,20 @@ pub struct BodySourceMap {
160153 diagnostics: Vec<BodyDiagnostic>,
161154}
162155
156#[derive(Default, Debug, Eq, PartialEq)]
157struct 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
163170#[derive(Debug, Eq, PartialEq)]
164171pub enum BodyDiagnostic {
165172 InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
......@@ -798,18 +805,29 @@ impl BodySourceMap {
798805 node: InFile<&ast::FormatArgsExpr>,
799806 ) -> Option<(HygieneId, &[(syntax::TextRange, Name)])> {
800807 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()?)?;
803813 Some((*hygiene, &**names))
804814 }
805815
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
806823 pub fn asm_template_args(
807824 &self,
808825 node: InFile<&ast::AsmExpr>,
809826 ) -> Option<(ExprId, &[Vec<(syntax::TextRange, usize)>])> {
810827 let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
811828 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))
813831 }
814832
815833 /// Get a reference to the body source map's diagnostics.
......@@ -835,8 +853,14 @@ impl BodySourceMap {
835853 types,
836854 } = self;
837855 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();
840864 }
841865 expr_map.shrink_to_fit();
842866 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<'_> {
19571957 _ => None,
19581958 });
19591959 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)) => {
19621964 let call_ctx = self.expander.syntax_context();
19631965 let hygiene = self.hygiene_id_for(s.syntax().text_range().start());
19641966 let fmt = format_args::parse(
......@@ -1966,8 +1968,18 @@ impl ExprCollector<'_> {
19661968 fmt_snippet,
19671969 args,
19681970 is_direct_literal,
1969 |name| {
1971 |name, range| {
19701972 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 }
19711983 if !hygiene.is_root() {
19721984 self.body.expr_hygiene.insert(expr_id, hygiene);
19731985 }
......@@ -2139,7 +2151,7 @@ impl ExprCollector<'_> {
21392151 self.source_map
21402152 .template_map
21412153 .get_or_insert_with(Default::default)
2142 .0
2154 .format_args_to_captures
21432155 .insert(idx, (hygiene, mappings));
21442156 idx
21452157 }
src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs+7-3
......@@ -6,7 +6,7 @@ use syntax::{
66 ast::{self, HasName, IsString},
77 AstNode, AstPtr, AstToken, T,
88};
9use tt::{TextRange, TextSize};
9use tt::TextRange;
1010
1111use crate::{
1212 body::lower::{ExprCollector, FxIndexSet},
......@@ -224,7 +224,7 @@ impl ExprCollector<'_> {
224224 TextRange::new(
225225 inner_span.start.try_into().unwrap(),
226226 inner_span.end.try_into().unwrap(),
227 ) - TextSize::from(str_style.map(|it| it + 1).unwrap_or(0) as u32 + 1)
227 )
228228 })
229229 };
230230 for piece in unverified_pieces {
......@@ -268,7 +268,11 @@ impl ExprCollector<'_> {
268268 Expr::InlineAsm(InlineAsm { operands: operands.into_boxed_slice(), options }),
269269 syntax_ptr,
270270 );
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);
272276 idx
273277 }
274278}
src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs+1
......@@ -685,6 +685,7 @@ impl Printer<'_> {
685685 self.print_binding(*id);
686686 if let Some(pat) = subpat {
687687 self.whitespace();
688 w!(self, "@ ");
688689 self.print_pat(*pat);
689690 }
690691 }
src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs+18
......@@ -426,3 +426,21 @@ fn f() {
426426 "should have a binding for `B`",
427427 );
428428}
429
430#[test]
431fn regression_pretty_print_bind_pat() {
432 let (db, body, owner) = lower(
433 r#"
434fn 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 @@
11//! Parses `format_args` input.
22
3use either::Either;
34use hir_expand::name::Name;
45use intern::Symbol;
56use rustc_parse_format as parse;
......@@ -7,7 +8,7 @@ use span::SyntaxContextId;
78use stdx::TupleExt;
89use syntax::{
910 ast::{self, IsString},
10 TextRange, TextSize,
11 TextRange,
1112};
1213
1314use crate::hir::ExprId;
......@@ -33,7 +34,7 @@ pub enum FormatArgsPiece {
3334 Placeholder(FormatPlaceholder),
3435}
3536
36#[derive(Copy, Debug, Clone, PartialEq, Eq)]
37#[derive(Debug, Clone, PartialEq, Eq)]
3738pub struct FormatPlaceholder {
3839 /// Index into [`FormatArgs::arguments`].
3940 pub argument: FormatArgPosition,
......@@ -45,11 +46,11 @@ pub struct FormatPlaceholder {
4546 pub format_options: FormatOptions,
4647}
4748
48#[derive(Copy, Debug, Clone, PartialEq, Eq)]
49#[derive(Debug, Clone, PartialEq, Eq)]
4950pub struct FormatArgPosition {
5051 /// Which argument this position refers to (Ok),
5152 /// or would've referred to if it existed (Err).
52 pub index: Result<usize, usize>,
53 pub index: Result<usize, Either<usize, Name>>,
5354 /// What kind of position this is. See [`FormatArgPositionKind`].
5455 pub kind: FormatArgPositionKind,
5556 /// The span of the name or number.
......@@ -88,7 +89,7 @@ pub enum FormatTrait {
8889 UpperHex,
8990}
9091
91#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
92#[derive(Clone, Default, Debug, PartialEq, Eq)]
9293pub struct FormatOptions {
9394 /// The width. E.g. `{:5}` or `{:width$}`.
9495 pub width: Option<FormatCount>,
......@@ -133,7 +134,7 @@ pub enum FormatAlignment {
133134 Center,
134135}
135136
136#[derive(Copy, Clone, Debug, PartialEq, Eq)]
137#[derive(Clone, Debug, PartialEq, Eq)]
137138pub enum FormatCount {
138139 /// `{:5}` or `{:.5}`
139140 Literal(usize),
......@@ -173,7 +174,7 @@ pub(crate) fn parse(
173174 fmt_snippet: Option<String>,
174175 mut args: FormatArgumentsCollector,
175176 is_direct_literal: bool,
176 mut synth: impl FnMut(Name) -> ExprId,
177 mut synth: impl FnMut(Name, Option<TextRange>) -> ExprId,
177178 mut record_usage: impl FnMut(Name, Option<TextRange>),
178179 call_ctx: SyntaxContextId,
179180) -> FormatArgs {
......@@ -192,7 +193,6 @@ pub(crate) fn parse(
192193 }
193194 None => None,
194195 };
195
196196 let mut parser =
197197 parse::Parser::new(&text, str_style, fmt_snippet, false, parse::ParseMode::Format);
198198
......@@ -217,7 +217,6 @@ pub(crate) fn parse(
217217 let to_span = |inner_span: parse::InnerSpan| {
218218 is_source_literal.then(|| {
219219 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)
221220 })
222221 };
223222
......@@ -245,8 +244,8 @@ pub(crate) fn parse(
245244 Ok(index)
246245 } else {
247246 // 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))
250249 }
251250 }
252251 ArgRef::Name(name, span) => {
......@@ -265,14 +264,17 @@ pub(crate) fn parse(
265264 // For the moment capturing variables from format strings expanded from macros is
266265 // disabled (see RFC #2795)
267266 // 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 }))
268277 }
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 }))
276278 }
277279 }
278280 };
src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs+68-56
......@@ -16,7 +16,7 @@ use syntax::ast;
1616
1717use crate::{
1818 db::DefDatabase,
19 per_ns::PerNs,
19 per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem},
2020 visibility::{Visibility, VisibilityExplicitness},
2121 AdtId, BuiltinType, ConstId, ExternCrateId, FxIndexMap, HasModule, ImplId, LocalModuleId,
2222 Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId,
......@@ -80,9 +80,9 @@ pub struct ItemScope {
8080 /// Defs visible in this scope. This includes `declarations`, but also
8181 /// imports. The imports belong to this module and can be resolved by using them on
8282 /// 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>,
8686 unresolved: FxHashSet<Name>,
8787
8888 /// The defs declared in this scope. Each def has a single scope where it is
......@@ -92,7 +92,7 @@ pub struct ItemScope {
9292 impls: Vec<ImplId>,
9393 unnamed_consts: Vec<ConstId>,
9494 /// Traits imported via `use Trait as _;`.
95 unnamed_trait_imports: FxHashMap<TraitId, (Visibility, Option<ImportId>)>,
95 unnamed_trait_imports: FxHashMap<TraitId, Item<()>>,
9696
9797 // the resolutions of the imports of this scope
9898 use_imports_types: FxHashMap<ImportOrExternCrate, ImportOrDef>,
......@@ -187,7 +187,7 @@ impl ItemScope {
187187 import = i;
188188 }
189189 ImportOrDef::Def(ModuleDefId::MacroId(def)) => {
190 res.macros = Some((def, Visibility::Public, None));
190 res.macros = Some(Item { def, vis: Visibility::Public, import: None });
191191 break;
192192 }
193193 _ => break,
......@@ -203,7 +203,7 @@ impl ItemScope {
203203 import = i;
204204 }
205205 ImportOrDef::Def(def) => {
206 res.types = Some((def, Visibility::Public, None));
206 res.types = Some(Item { def, vis: Visibility::Public, import: None });
207207 break;
208208 }
209209 _ => break,
......@@ -219,7 +219,7 @@ impl ItemScope {
219219 import = i;
220220 }
221221 ImportOrDef::Def(def) => {
222 res.values = Some((def, Visibility::Public, None));
222 res.values = Some(Item { def, vis: Visibility::Public, import: None });
223223 break;
224224 }
225225 _ => break,
......@@ -253,8 +253,8 @@ impl ItemScope {
253253 }
254254
255255 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)),
258258 _ => None,
259259 })
260260 }
......@@ -283,20 +283,20 @@ impl ItemScope {
283283 }
284284
285285 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))
287287 }
288288
289289 /// XXX: this is O(N) rather than O(1), try to not introduce new usages.
290290 pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility, /*declared*/ bool)> {
291291 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()))
294294 }),
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()))
297297 }),
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()))
300300 }),
301301 }
302302 }
......@@ -311,22 +311,34 @@ impl ItemScope {
311311 ItemInNs::Macros(def) => self
312312 .macros
313313 .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 ))
316320 })
317321 .find_map(|(a, b, c)| cb(a, b, c)),
318322 ItemInNs::Types(def) => self
319323 .types
320324 .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 ))
323331 })
324332 .find_map(|(a, b, c)| cb(a, b, c)),
325333 ItemInNs::Values(def) => self
326334 .values
327335 .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 ))
330342 })
331343 .find_map(|(a, b, c)| cb(a, b, c)),
332344 }
......@@ -335,7 +347,7 @@ impl ItemScope {
335347 pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
336348 self.types
337349 .values()
338 .filter_map(|&(def, _, _)| match def {
350 .filter_map(|def| match def.def {
339351 ModuleDefId::TraitId(t) => Some(t),
340352 _ => None,
341353 })
......@@ -344,13 +356,13 @@ impl ItemScope {
344356
345357 pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
346358 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_)| {
348360 (
349361 None,
350362 PerNs::types(
351363 ModuleDefId::TraitId(*tr),
352 *vis,
353 i.map(ImportOrExternCrate::Import),
364 trait_.vis,
365 trait_.import.map(ImportOrExternCrate::Import),
354366 ),
355367 )
356368 }),
......@@ -464,12 +476,12 @@ impl ItemScope {
464476
465477 // FIXME: This is only used in collection, we should move the relevant parts of it out of ItemScope
466478 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)
468480 }
469481
470482 pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
471483 // FIXME: import
472 self.unnamed_trait_imports.insert(tr, (vis, None));
484 self.unnamed_trait_imports.insert(tr, Item { def: (), vis, import: None });
473485 }
474486
475487 pub(crate) fn push_res_with_import(
......@@ -502,7 +514,7 @@ impl ItemScope {
502514 }
503515 None | Some(ImportType::Glob(_)) => None,
504516 };
505 let prev = std::mem::replace(&mut fld.2, import);
517 let prev = std::mem::replace(&mut fld.import, import);
506518 if let Some(import) = import {
507519 self.use_imports_types.insert(
508520 import,
......@@ -513,7 +525,7 @@ impl ItemScope {
513525 Some(ImportOrExternCrate::ExternCrate(import)) => {
514526 ImportOrDef::ExternCrate(import)
515527 }
516 None => ImportOrDef::Def(fld.0),
528 None => ImportOrDef::Def(fld.def),
517529 },
518530 );
519531 }
......@@ -540,7 +552,7 @@ impl ItemScope {
540552 }
541553 None | Some(ImportType::Glob(_)) => None,
542554 };
543 let prev = std::mem::replace(&mut fld.2, import);
555 let prev = std::mem::replace(&mut fld.import, import);
544556 if let Some(import) = import {
545557 self.use_imports_types.insert(
546558 import,
......@@ -551,7 +563,7 @@ impl ItemScope {
551563 Some(ImportOrExternCrate::ExternCrate(import)) => {
552564 ImportOrDef::ExternCrate(import)
553565 }
554 None => ImportOrDef::Def(fld.0),
566 None => ImportOrDef::Def(fld.def),
555567 },
556568 );
557569 }
......@@ -579,13 +591,13 @@ impl ItemScope {
579591 Some(ImportType::Import(import)) => Some(import),
580592 _ => None,
581593 };
582 let prev = std::mem::replace(&mut fld.2, import);
594 let prev = std::mem::replace(&mut fld.import, import);
583595 if let Some(import) = import {
584596 self.use_imports_values.insert(
585597 import,
586598 match prev {
587599 Some(import) => ImportOrDef::Import(import),
588 None => ImportOrDef::Def(fld.0),
600 None => ImportOrDef::Def(fld.def),
589601 },
590602 );
591603 }
......@@ -599,13 +611,13 @@ impl ItemScope {
599611 Some(ImportType::Import(import)) => Some(import),
600612 _ => None,
601613 };
602 let prev = std::mem::replace(&mut fld.2, import);
614 let prev = std::mem::replace(&mut fld.import, import);
603615 if let Some(import) = import {
604616 self.use_imports_values.insert(
605617 import,
606618 match prev {
607619 Some(import) => ImportOrDef::Import(import),
608 None => ImportOrDef::Def(fld.0),
620 None => ImportOrDef::Def(fld.def),
609621 },
610622 );
611623 }
......@@ -631,13 +643,13 @@ impl ItemScope {
631643 Some(ImportType::Import(import)) => Some(import),
632644 _ => None,
633645 };
634 let prev = std::mem::replace(&mut fld.2, import);
646 let prev = std::mem::replace(&mut fld.import, import);
635647 if let Some(import) = import {
636648 self.use_imports_macros.insert(
637649 import,
638650 match prev {
639651 Some(import) => ImportOrDef::Import(import),
640 None => ImportOrDef::Def(fld.0.into()),
652 None => ImportOrDef::Def(fld.def.into()),
641653 },
642654 );
643655 }
......@@ -651,13 +663,13 @@ impl ItemScope {
651663 Some(ImportType::Import(import)) => Some(import),
652664 _ => None,
653665 };
654 let prev = std::mem::replace(&mut fld.2, import);
666 let prev = std::mem::replace(&mut fld.import, import);
655667 if let Some(import) = import {
656668 self.use_imports_macros.insert(
657669 import,
658670 match prev {
659671 Some(import) => ImportOrDef::Import(import),
660 None => ImportOrDef::Def(fld.0.into()),
672 None => ImportOrDef::Def(fld.def.into()),
661673 },
662674 );
663675 }
......@@ -680,19 +692,19 @@ impl ItemScope {
680692 pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) {
681693 self.types
682694 .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))
686698 .for_each(|vis| {
687699 *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit)
688700 });
689701
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()) {
692704 continue;
693705 }
694706
695 *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit);
707 mac.vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit);
696708 }
697709 }
698710
......@@ -707,23 +719,23 @@ impl ItemScope {
707719 name.map_or("_".to_owned(), |name| name.display(db, Edition::LATEST).to_string())
708720 );
709721
710 if let Some((.., i)) = def.types {
722 if let Some(Item { import, .. }) = def.types {
711723 buf.push_str(" t");
712 match i {
724 match import {
713725 Some(ImportOrExternCrate::Import(_)) => buf.push('i'),
714726 Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'),
715727 None => (),
716728 }
717729 }
718 if let Some((.., i)) = def.values {
730 if let Some(Item { import, .. }) = def.values {
719731 buf.push_str(" v");
720 if i.is_some() {
732 if import.is_some() {
721733 buf.push('i');
722734 }
723735 }
724 if let Some((.., i)) = def.macros {
736 if let Some(Item { import, .. }) = def.macros {
725737 buf.push_str(" m");
726 if i.is_some() {
738 if import.is_some() {
727739 buf.push('i');
728740 }
729741 }
......@@ -781,19 +793,19 @@ impl ItemScope {
781793 pub(crate) fn update_visibility_types(&mut self, name: &Name, vis: Visibility) {
782794 let res =
783795 self.types.get_mut(name).expect("tried to update visibility of non-existent type");
784 res.1 = vis;
796 res.vis = vis;
785797 }
786798
787799 pub(crate) fn update_visibility_values(&mut self, name: &Name, vis: Visibility) {
788800 let res =
789801 self.values.get_mut(name).expect("tried to update visibility of non-existent value");
790 res.1 = vis;
802 res.vis = vis;
791803 }
792804
793805 pub(crate) fn update_visibility_macros(&mut self, name: &Name, vis: Visibility) {
794806 let res =
795807 self.macros.get_mut(name).expect("tried to update visibility of non-existent macro");
796 res.1 = vis;
808 res.vis = vis;
797809 }
798810}
799811
src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs+28-28
......@@ -44,7 +44,7 @@ use crate::{
4444 ResolveMode,
4545 },
4646 path::{ImportAlias, ModPath, PathKind},
47 per_ns::PerNs,
47 per_ns::{Item, PerNs},
4848 tt,
4949 visibility::{RawVisibility, Visibility},
5050 AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantLoc,
......@@ -523,7 +523,7 @@ impl DefCollector<'_> {
523523 self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
524524
525525 match per_ns.types {
526 Some((ModuleDefId::ModuleId(m), _, import)) => {
526 Some(Item { def: ModuleDefId::ModuleId(m), import, .. }) => {
527527 // FIXME: This should specifically look for a glob import somehow and record that here
528528 self.def_map.prelude = Some((
529529 m,
......@@ -1069,9 +1069,9 @@ impl DefCollector<'_> {
10691069 //
10701070 // This has been historically allowed, but may be not allowed in future
10711071 // 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() {
10731073 let is_extern_crate_reimport_without_prefix = || {
1074 let Some(ImportOrExternCrate::ExternCrate(_)) = it else {
1074 let Some(ImportOrExternCrate::ExternCrate(_)) = def.import else {
10751075 return false;
10761076 };
10771077 let Some(ImportType::Import(id)) = def_import_type else {
......@@ -1086,16 +1086,16 @@ impl DefCollector<'_> {
10861086 path.segments().len() < 2
10871087 };
10881088 if is_extern_crate_reimport_without_prefix() {
1089 *v = vis;
1089 def.vis = vis;
10901090 } 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);
10921092 }
10931093 }
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);
10961096 }
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);
10991099 }
11001100
11011101 let mut changed = false;
......@@ -1106,12 +1106,12 @@ impl DefCollector<'_> {
11061106 // Multiple globs may import the same item and they may override visibility from
11071107 // previously resolved globs. Handle overrides here and leave the rest to
11081108 // `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
11121112 && 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)
11151115 {
11161116 changed = true;
11171117 // This import is being handled here, don't pass it down to
......@@ -1119,41 +1119,41 @@ impl DefCollector<'_> {
11191119 defs.types = None;
11201120 self.def_map.modules[module_id]
11211121 .scope
1122 .update_visibility_types(name, def_vis);
1122 .update_visibility_types(name, def.vis);
11231123 }
11241124 }
11251125 }
11261126
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
11301130 && 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)
11331133 {
11341134 changed = true;
11351135 // See comment above.
11361136 defs.values = None;
11371137 self.def_map.modules[module_id]
11381138 .scope
1139 .update_visibility_values(name, def_vis);
1139 .update_visibility_values(name, def.vis);
11401140 }
11411141 }
11421142 }
11431143
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
11471147 && 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)
11501150 {
11511151 changed = true;
11521152 // See comment above.
11531153 defs.macros = None;
11541154 self.def_map.modules[module_id]
11551155 .scope
1156 .update_visibility_macros(name, def_vis);
1156 .update_visibility_macros(name, def.vis);
11571157 }
11581158 }
11591159 }
src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs+6-6
......@@ -67,8 +67,8 @@ impl PerNs {
6767 db: &dyn DefDatabase,
6868 expected: Option<MacroSubNs>,
6969 ) -> 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);
7272 sub_namespace_match(Some(this), expected)
7373 });
7474
......@@ -411,7 +411,7 @@ impl DefMap {
411411 original_module: LocalModuleId,
412412 ) -> ResolvePathResult {
413413 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() {
415415 Some(r) => r,
416416 None => {
417417 // we still have path segments left, but the path so far
......@@ -424,7 +424,7 @@ impl DefMap {
424424 };
425425 // resolve segment in curr
426426
427 curr_per_ns = match curr {
427 curr_per_ns = match curr.def {
428428 ModuleDefId::ModuleId(module) => {
429429 if module.krate != self.krate {
430430 let path = ModPath::from_segments(
......@@ -492,7 +492,7 @@ impl DefMap {
492492 Some(res) => res,
493493 None => {
494494 return ResolvePathResult::new(
495 PerNs::types(e.into(), vis, imp),
495 PerNs::types(e.into(), curr.vis, curr.import),
496496 ReachedFixedPoint::Yes,
497497 Some(i),
498498 false,
......@@ -510,7 +510,7 @@ impl DefMap {
510510 );
511511
512512 return ResolvePathResult::new(
513 PerNs::types(s, vis, imp),
513 PerNs::types(s, curr.vis, curr.import),
514514 ReachedFixedPoint::Yes,
515515 Some(i),
516516 false,
src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs+1-1
......@@ -331,7 +331,7 @@ pub type Ty = ();
331331 }
332332
333333 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() {
335335 ModuleDefId::FunctionId(f) => _ = db.function_data(f),
336336 ModuleDefId::AdtId(adt) => match adt {
337337 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! {
2828 }
2929}
3030
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
32pub struct Item<Def, Import = ImportId> {
33 pub def: Def,
34 pub vis: Visibility,
35 pub import: Option<Import>,
36}
37
38pub type TypesItem = Item<ModuleDefId, ImportOrExternCrate>;
39pub type ValuesItem = Item<ModuleDefId>;
40pub type MacrosItem = Item<MacroId>;
41
3142#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
3243pub 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>,
3647}
3748
3849impl PerNs {
......@@ -48,29 +59,33 @@ impl PerNs {
4859 PerNs { types: None, values: None, macros: None }
4960 }
5061
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 }
5364 }
5465
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 }
5768 }
5869
5970 pub fn both(
6071 types: ModuleDefId,
6172 values: ModuleDefId,
62 v: Visibility,
63 i: Option<ImportOrExternCrate>,
73 vis: Visibility,
74 import: Option<ImportOrExternCrate>,
6475 ) -> PerNs {
6576 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 }),
6883 macros: None,
6984 }
7085 }
7186
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 }) }
7489 }
7590
7691 pub fn is_none(&self) -> bool {
......@@ -82,43 +97,43 @@ impl PerNs {
8297 }
8398
8499 pub fn take_types(self) -> Option<ModuleDefId> {
85 self.types.map(|it| it.0)
100 self.types.map(|it| it.def)
86101 }
87102
88 pub fn take_types_full(self) -> Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)> {
103 pub fn take_types_full(self) -> Option<TypesItem> {
89104 self.types
90105 }
91106
92107 pub fn take_values(self) -> Option<ModuleDefId> {
93 self.values.map(|it| it.0)
108 self.values.map(|it| it.def)
94109 }
95110
96111 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))
98113 }
99114
100115 pub fn take_macros(self) -> Option<MacroId> {
101 self.macros.map(|it| it.0)
116 self.macros.map(|it| it.def)
102117 }
103118
104119 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))
106121 }
107122
108123 pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
109124 let _p = tracing::info_span!("PerNs::filter_visibility").entered();
110125 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)),
114129 }
115130 }
116131
117132 pub fn with_visibility(self, vis: Visibility) -> PerNs {
118133 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 }),
122137 }
123138 }
124139
......@@ -141,15 +156,17 @@ impl PerNs {
141156 pub fn iter_items(self) -> impl Iterator<Item = (ItemInNs, Option<ImportOrExternCrate>)> {
142157 let _p = tracing::info_span!("PerNs::iter_items").entered();
143158 self.types
144 .map(|it| (ItemInNs::Types(it.0), it.2))
159 .map(|it| (ItemInNs::Types(it.def), it.import))
145160 .into_iter()
146161 .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 }),
149165 )
150166 .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 }),
153170 )
154171 }
155172}
src/tools/rust-analyzer/crates/hir-def/src/resolver.rs+12-12
......@@ -933,8 +933,8 @@ impl ModuleItemMap {
933933 Some(ResolveValueResult::ValueNs(value, import))
934934 }
935935 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 {
938938 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
939939 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
940940 ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
......@@ -948,7 +948,7 @@ impl ModuleItemMap {
948948 | ModuleDefId::MacroId(_)
949949 | ModuleDefId::StaticId(_) => return None,
950950 };
951 Some(ResolveValueResult::Partial(ty, idx, import))
951 Some(ResolveValueResult::Partial(ty, idx, def.import))
952952 }
953953 }
954954 }
......@@ -986,8 +986,8 @@ fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> {
986986}
987987
988988fn 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 {
991991 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
992992 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
993993
......@@ -1003,7 +1003,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
10031003 | ModuleDefId::StaticId(_)
10041004 | ModuleDefId::ModuleId(_) => return None,
10051005 };
1006 Some((res, import))
1006 Some((res, def.import))
10071007}
10081008
10091009#[derive(Default)]
......@@ -1019,14 +1019,14 @@ impl ScopeNames {
10191019 }
10201020 }
10211021 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))
10241024 }
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))
10271027 }
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)))
10301030 }
10311031 if def.is_none() {
10321032 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 {
153153/// This expands the given macro call, but with different arguments. This is
154154/// used for completion, where we want to see what 'would happen' if we insert a
155155/// token. The `token_to_map` mapped down into the expansion, with the mapped
156/// token returned.
156/// token(s) returned with their priority.
157157pub fn expand_speculative(
158158 db: &dyn ExpandDatabase,
159159 actual_macro_call: MacroCallId,
160160 speculative_args: &SyntaxNode,
161161 token_to_map: SyntaxToken,
162) -> Option<(SyntaxNode, SyntaxToken)> {
162) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> {
163163 let loc = db.lookup_intern_macro_call(actual_macro_call);
164164 let (_, _, span) = db.macro_arg_considering_derives(actual_macro_call, &loc.kind);
165165
......@@ -303,17 +303,19 @@ pub fn expand_speculative(
303303 token_tree_to_syntax_node(&speculative_expansion.value, expand_to, loc.def.edition);
304304
305305 let syntax_node = node.syntax_node();
306 let (token, _) = rev_tmap
306 let token = rev_tmap
307307 .ranges_with_span(span_map.span_for_range(token_to_map.text_range()))
308308 .filter_map(|(range, ctx)| syntax_node.covering_element(range).into_token().zip(Some(ctx)))
309 .min_by_key(|(t, ctx)| {
309 .map(|(t, ctx)| {
310310 // prefer tokens of the same kind and text, as well as non opaque marked ones
311311 // Note the inversion of the score here, as we want to prefer the first token in case
312312 // of all tokens having the same score
313 ctx.is_opaque(db) as u8
313 let ranking = ctx.is_opaque(db) as u8
314314 + 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();
317319 Some((node.syntax_node(), token))
318320}
319321
src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs+1-10
......@@ -22,7 +22,6 @@ use hir_def::{
2222
2323use crate::{
2424 db::{HirDatabase, InternedCoroutine},
25 display::HirDisplay,
2625 from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
2726 generics::generics,
2827 make_binders, make_single_type_binders,
......@@ -823,13 +822,12 @@ pub(crate) fn impl_datum_query(
823822 let _p = tracing::info_span!("impl_datum_query").entered();
824823 debug!("impl_datum {:?}", impl_id);
825824 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_)
827826}
828827
829828fn impl_def_datum(
830829 db: &dyn HirDatabase,
831830 krate: CrateId,
832 chalk_id: ImplId,
833831 impl_id: hir_def::ImplId,
834832) -> Arc<ImplDatum> {
835833 let trait_ref = db
......@@ -850,13 +848,6 @@ fn impl_def_datum(
850848 };
851849 let where_clauses = convert_where_clauses(db, impl_id.into(), &bound_vars);
852850 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 );
860851
861852 let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive };
862853
src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs+11-2
......@@ -193,10 +193,19 @@ impl<'a> UnsafeVisitor<'a> {
193193 self.resolver.reset_to_guard(guard);
194194 }
195195 Expr::Ref { expr, rawness: Rawness::RawPtr, mutability: _ } => {
196 if let Expr::Path(_) = self.body.exprs[*expr] {
196 match self.body.exprs[*expr] {
197197 // Do not report unsafe for `addr_of[_mut]!(EXTERN_OR_MUT_STATIC)`,
198198 // 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 _ => (),
200209 }
201210 }
202211 Expr::MethodCall { .. } => {
src/tools/rust-analyzer/crates/hir/src/diagnostics.rs+14-7
......@@ -262,7 +262,7 @@ pub struct UnresolvedAssocItem {
262262
263263#[derive(Debug)]
264264pub 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>)>,
266266}
267267
268268#[derive(Debug)]
......@@ -550,11 +550,10 @@ impl AnyDiagnostic {
550550 source_map: &hir_def::body::BodySourceMap,
551551 ) -> Option<AnyDiagnostic> {
552552 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()
557554 };
555 let pat_syntax =
556 |pat| source_map.pat_syntax(pat).inspect_err(|_| stdx::never!("synthetic syntax")).ok();
558557 let expr_or_pat_syntax = |id| match id {
559558 ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(|it| it.map(AstPtr::wrap_left)),
560559 ExprOrPatId::PatId(pat) => pat_syntax(pat),
......@@ -626,8 +625,16 @@ impl AnyDiagnostic {
626625 UnresolvedAssocItem { expr_or_pat }.into()
627626 }
628627 &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()
631638 }
632639 &InferenceDiagnostic::BreakOutsideOfLoop { expr, is_break, bad_value_break } => {
633640 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 {
31053105}
31063106
31073107impl ItemInNs {
3108 pub fn as_module_def(self) -> Option<ModuleDef> {
3108 pub fn into_module_def(self) -> ModuleDef {
31093109 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),
31123112 }
31133113 }
31143114
src/tools/rust-analyzer/crates/hir/src/semantics.rs+28-15
......@@ -38,9 +38,9 @@ use span::{AstIdMap, EditionedFileId, FileId, HirFileIdRepr, SyntaxContextId};
3838use stdx::TupleExt;
3939use syntax::{
4040 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,
4444};
4545use triomphe::Arc;
4646
......@@ -571,7 +571,7 @@ impl<'db> SemanticsImpl<'db> {
571571 actual_macro_call: &ast::MacroCall,
572572 speculative_args: &ast::TokenTree,
573573 token_to_map: SyntaxToken,
574 ) -> Option<(SyntaxNode, SyntaxToken)> {
574 ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> {
575575 let SourceAnalyzer { file_id, resolver, .. } =
576576 self.analyze_no_infer(actual_macro_call.syntax())?;
577577 let macro_call = InFile::new(file_id, actual_macro_call);
......@@ -592,7 +592,7 @@ impl<'db> SemanticsImpl<'db> {
592592 macro_file: MacroFileId,
593593 speculative_args: &SyntaxNode,
594594 token_to_map: SyntaxToken,
595 ) -> Option<(SyntaxNode, SyntaxToken)> {
595 ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> {
596596 hir_expand::db::expand_speculative(
597597 self.db.upcast(),
598598 macro_file.macro_call_id,
......@@ -608,7 +608,7 @@ impl<'db> SemanticsImpl<'db> {
608608 actual_macro_call: &ast::Item,
609609 speculative_args: &ast::Item,
610610 token_to_map: SyntaxToken,
611 ) -> Option<(SyntaxNode, SyntaxToken)> {
611 ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> {
612612 let macro_call = self.wrap_node_infile(actual_macro_call.clone());
613613 let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(macro_call.as_ref()))?;
614614 hir_expand::db::expand_speculative(
......@@ -624,7 +624,7 @@ impl<'db> SemanticsImpl<'db> {
624624 actual_macro_call: &ast::Attr,
625625 speculative_args: &ast::Attr,
626626 token_to_map: SyntaxToken,
627 ) -> Option<(SyntaxNode, SyntaxToken)> {
627 ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> {
628628 let attr = self.wrap_node_infile(actual_macro_call.clone());
629629 let adt = actual_macro_call.syntax().parent().and_then(ast::Adt::cast)?;
630630 let macro_call_id = self.with_ctx(|ctx| {
......@@ -643,8 +643,7 @@ impl<'db> SemanticsImpl<'db> {
643643 &self,
644644 string: &ast::String,
645645 ) -> 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();
648647 let token = self.wrap_token_infile(string.syntax().clone()).into_real_file().ok()?;
649648 self.descend_into_macros_breakable(token, |token, _| {
650649 (|| {
......@@ -658,7 +657,7 @@ impl<'db> SemanticsImpl<'db> {
658657 let format_args = self.wrap_node_infile(format_args);
659658 let res = source_analyzer
660659 .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)))
662661 .collect();
663662 Some(res)
664663 } else {
......@@ -672,7 +671,7 @@ impl<'db> SemanticsImpl<'db> {
672671 .iter()
673672 .map(|&(range, index)| {
674673 (
675 range + quote.end(),
674 range + string_start,
676675 Some(Either::Right(InlineAsmOperand { owner, expr, index })),
677676 )
678677 })
......@@ -690,17 +689,16 @@ impl<'db> SemanticsImpl<'db> {
690689 original_token: SyntaxToken,
691690 offset: TextSize,
692691 ) -> 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();
694693 let original_token = self.wrap_token_infile(original_token).into_real_file().ok()?;
695 let quote = original_string.open_quote_text_range()?;
696694 self.descend_into_macros_breakable(original_token, |token, _| {
697695 (|| {
698696 let token = token.value;
699697 self.resolve_offset_in_format_args(
700698 ast::String::cast(token)?,
701 offset.checked_sub(quote.end())?,
699 offset.checked_sub(string_start)?,
702700 )
703 .map(|(range, res)| (range + quote.end(), res))
701 .map(|(range, res)| (range + string_start, res))
704702 })()
705703 .map_or(ControlFlow::Continue(()), ControlFlow::Break)
706704 })
......@@ -1542,6 +1540,21 @@ impl<'db> SemanticsImpl<'db> {
15421540 Some(items.iter_items().map(|(item, _)| item.into()))
15431541 }
15441542
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
15451558 fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> {
15461559 self.analyze(record_lit.syntax())?.resolve_variant(self.db, record_lit)
15471560 }
src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs+5
......@@ -3,6 +3,7 @@
33use hir::{FileRange, Semantics};
44use ide_db::EditionedFileId;
55use ide_db::{label::Label, FileId, RootDatabase};
6use syntax::Edition;
67use syntax::{
78 algo::{self, find_node_at_offset, find_node_at_range},
89 AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange,
......@@ -94,6 +95,10 @@ impl<'a> AssistContext<'a> {
9495 self.frange.file_id
9596 }
9697
98 pub(crate) fn edition(&self) -> Edition {
99 self.frange.file_id.edition()
100 }
101
97102 pub(crate) fn has_empty_selection(&self) -> bool {
98103 self.trimmed_range.is_empty()
99104 }
src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs+67-74
......@@ -1,10 +1,12 @@
1use ide_db::text_edit::TextRange;
21use ide_db::{
32 assists::{AssistId, AssistKind},
43 defs::Definition,
5 search::{FileReference, SearchScope, UsageSearchResult},
4 search::{FileReference, SearchScope},
5 syntax_helpers::suggest_name,
6 text_edit::TextRange,
67};
78use itertools::Itertools;
9use syntax::SmolStr;
810use syntax::{
911 ast::{self, make, AstNode, FieldExpr, HasName, IdentPat},
1012 ted,
......@@ -122,33 +124,43 @@ fn collect_data(ident_pat: IdentPat, ctx: &AssistContext<'_>) -> Option<TupleDat
122124 return None;
123125 }
124126
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| {
128128 Definition::Local(def)
129129 .usages(&ctx.sema)
130130 .in_scope(&SearchScope::single_file(ctx.file_id()))
131131 .all()
132 .iter()
133 .next()
134 .map(|(_, refs)| refs.to_vec())
132135 });
133136
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 })
136159 .collect::<Vec<_>>();
137160
138161 Some(TupleData { ident_pat, ref_type, field_names, usages })
139162}
140163
141fn 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
152164enum RefType {
153165 ReadOnly,
154166 Mutable,
......@@ -157,7 +169,7 @@ struct TupleData {
157169 ident_pat: IdentPat,
158170 ref_type: Option<RefType>,
159171 field_names: Vec<String>,
160 usages: Option<UsageSearchResult>,
172 usages: Option<Vec<FileReference>>,
161173}
162174fn edit_tuple_assignment(
163175 ctx: &AssistContext<'_>,
......@@ -213,42 +225,23 @@ fn edit_tuple_usages(
213225 ctx: &AssistContext<'_>,
214226 in_sub_pattern: bool,
215227) -> 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)
252245}
253246fn edit_tuple_usage(
254247 ctx: &AssistContext<'_>,
......@@ -1769,14 +1762,14 @@ struct S4 {
17691762}
17701763
17711764fn 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);
17731766 let v: i32 = *_0; // deref, no parens
17741767 let v: &i32 = _0; // no deref, no parens, remove `&`
17751768 f1(*_0); // deref, no parens
17761769 f2(_0); // `&*` -> cancel out -> no deref, no parens
17771770 // https://github.com/rust-lang/rust-analyzer/issues/1109#issuecomment-658868639
17781771 // 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
17801773 (*_0).do_stuff(); // deref, parens
17811774 let v: i32 = (*_2)?; // deref, parens
17821775 let v: i32 = _3[0]; // no deref, no parens
......@@ -1815,8 +1808,8 @@ impl S {
18151808}
18161809
18171810fn main() {
1818 let ($0_0, _1) = &(S,2);
1819 let s = _0.f();
1811 let ($0s, _1) = &(S,2);
1812 let s = s.f();
18201813}
18211814 "#,
18221815 )
......@@ -1845,8 +1838,8 @@ impl S {
18451838}
18461839
18471840fn main() {
1848 let ($0_0, _1) = &(S,2);
1849 let s = (*_0).f();
1841 let ($0s, _1) = &(S,2);
1842 let s = (*s).f();
18501843}
18511844 "#,
18521845 )
......@@ -1882,8 +1875,8 @@ impl T for &S {
18821875}
18831876
18841877fn main() {
1885 let ($0_0, _1) = &(S,2);
1886 let s = (*_0).f();
1878 let ($0s, _1) = &(S,2);
1879 let s = (*s).f();
18871880}
18881881 "#,
18891882 )
......@@ -1923,8 +1916,8 @@ impl T for &S {
19231916}
19241917
19251918fn main() {
1926 let ($0_0, _1) = &(S,2);
1927 let s = (*_0).f();
1919 let ($0s, _1) = &(S,2);
1920 let s = (*s).f();
19281921}
19291922 "#,
19301923 )
......@@ -1951,8 +1944,8 @@ impl S {
19511944 fn do_stuff(&self) -> i32 { 42 }
19521945}
19531946fn 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();
19561949}
19571950 "#,
19581951 )
......@@ -1973,7 +1966,7 @@ fn main() {
19731966 // `t.0` gets auto-refed -> no deref needed -> no parens
19741967 let v = t.0.do_stuff(); // no deref, no parens
19751968 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`
19771970 let v = t.1.do_stuff(); // deref, parens
19781971}
19791972 "#,
......@@ -1984,13 +1977,13 @@ impl S {
19841977 fn do_stuff(&self) -> i32 { 42 }
19851978}
19861979fn 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
19891982 // `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
19941987}
19951988 "#,
19961989 )
src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs+168-15
......@@ -1,5 +1,8 @@
11use hir::{HirDisplay, TypeInfo};
2use ide_db::{assists::GroupLabel, syntax_helpers::suggest_name};
2use ide_db::{
3 assists::GroupLabel,
4 syntax_helpers::{suggest_name, LexedStr},
5};
36use syntax::{
47 ast::{
58 self, edit::IndentLevel, edit_in_place::Indent, make, syntax_factory::SyntaxFactory,
......@@ -320,24 +323,58 @@ impl ExtractionKind {
320323 ctx: &AssistContext<'_>,
321324 to_extract: &ast::Expr,
322325 ) -> (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());
332336 }
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)
333343 };
334344
335345 let var_name = match self {
336 ExtractionKind::Variable => var_name,
346 ExtractionKind::Variable => var_name.to_lowercase(),
337347 ExtractionKind::Constant | ExtractionKind::Static => var_name.to_uppercase(),
338348 };
339349
340 (var_name, expr_replace)
350 (var_name, to_extract.syntax().clone())
351 }
352}
353
354fn 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,
341378 }
342379}
343380
......@@ -493,7 +530,7 @@ fn main() {
493530"#,
494531 r#"
495532fn main() {
496 let $0var_name = "hello";
533 let $0hello = "hello";
497534}
498535"#,
499536 "Extract into variable",
......@@ -588,7 +625,7 @@ fn main() {
588625"#,
589626 r#"
590627fn main() {
591 const $0VAR_NAME: &str = "hello";
628 const $0HELLO: &str = "hello";
592629}
593630"#,
594631 "Extract into constant",
......@@ -683,7 +720,7 @@ fn main() {
683720"#,
684721 r#"
685722fn main() {
686 static $0VAR_NAME: &str = "hello";
723 static $0HELLO: &str = "hello";
687724}
688725"#,
689726 "Extract into static",
......@@ -2479,4 +2516,120 @@ fn foo() {
24792516 "Extract into variable",
24802517 );
24812518 }
2519
2520 #[test]
2521 fn extract_string_literal() {
2522 check_assist_by_label(
2523 extract_variable,
2524 r#"
2525struct Entry(&str);
2526fn foo() {
2527 let entry = Entry($0"Hello"$0);
2528}
2529"#,
2530 r#"
2531struct Entry(&str);
2532fn 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#"
2543struct Entry(&str);
2544fn foo() {
2545 let entry = Entry($0"Hello"$0);
2546}
2547"#,
2548 r#"
2549struct Entry(&str);
2550fn 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#"
2561struct Entry(&str);
2562fn foo() {
2563 let entry = Entry($0"Hello"$0);
2564}
2565"#,
2566 r#"
2567struct Entry(&str);
2568fn 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#"
2584struct Entry { message: &str }
2585fn foo() {
2586 let entry = Entry { message: $0"Hello"$0 };
2587}
2588"#,
2589 r#"
2590struct Entry { message: &str }
2591fn 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#"
2602struct Entry { message: &str }
2603fn foo() {
2604 let entry = Entry { message: $0"Hello"$0 };
2605}
2606"#,
2607 r#"
2608struct Entry { message: &str }
2609fn 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#"
2620struct Entry { message: &str }
2621fn foo() {
2622 let entry = Entry { message: $0"Hello"$0 };
2623}
2624"#,
2625 r#"
2626struct Entry { message: &str }
2627fn foo() {
2628 static $0HELLO: &str = "Hello";
2629 let entry = Entry { message: HELLO };
2630}
2631"#,
2632 "Extract into static",
2633 );
2634 }
24822635}
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
8686}
8787
8888fn 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)
9090}
9191
9292#[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
5151 let candidate = import_assets.import_candidate();
5252 let qualify_candidate = match syntax_under_caret.clone() {
5353 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() => {
5555 cov_mark::hit!(qualify_path_qualifier_start);
5656 let path = ast::Path::cast(syntax_under_caret)?;
5757 let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?);
......@@ -219,11 +219,9 @@ fn find_trait_method(
219219}
220220
221221fn 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() {
225223 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),
227225 }
228226}
229227
......@@ -247,7 +245,7 @@ fn label(
247245 let import_path = &import.import_path;
248246
249247 match candidate {
250 ImportCandidate::Path(candidate) if candidate.qualifier.is_none() => {
248 ImportCandidate::Path(candidate) if candidate.qualifier.is_empty() => {
251249 format!("Qualify as `{}`", import_path.display(db, edition))
252250 }
253251 _ => 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(
7878 NameToImport::exact_case_sensitive(path.segments().last()?.to_string()),
7979 items_locator::AssocSearchMode::Exclude,
8080 )
81 .filter_map(|item| match item.as_module_def()? {
81 .filter_map(|item| match item.into_module_def() {
8282 ModuleDef::Trait(trait_) => Some(trait_),
8383 _ => None,
8484 })
src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs+18-25
......@@ -12,13 +12,15 @@ use syntax::{
1212
1313use crate::{AssistContext, Assists};
1414
15// FIXME: This ought to be a diagnostic lint.
16
1517// Assist: unnecessary_async
1618//
1719// Removes the `async` mark from functions which have no `.await` in their body.
1820// Looks for calls to the functions and removes the `.await` on the call site.
1921//
2022// ```
21// pub async f$0n foo() {}
23// pub asy$0nc fn foo() {}
2224// pub async fn bar() { foo().await }
2325// ```
2426// ->
......@@ -29,15 +31,11 @@ use crate::{AssistContext, Assists};
2931pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
3032 let function: ast::Fn = ctx.find_node_at_offset()?;
3133
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()) {
3737 return None;
3838 }
39 // Do nothing if the function isn't async.
40 function.async_token()?;
4139 // Do nothing if the function has an `await` expression in its body.
4240 if function.body()?.syntax().descendants().find_map(ast::AwaitExpr::cast).is_some() {
4341 return None;
......@@ -138,27 +136,22 @@ mod tests {
138136
139137 #[test]
140138 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() {}")
142140 }
143141
144142 #[test]
145143 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() {}")
152145 }
153146
154147 #[test]
155148 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() }")
157150 }
158151
159152 #[test]
160153 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 }")
162155 }
163156
164157 #[test]
......@@ -167,7 +160,7 @@ mod tests {
167160 unnecessary_async,
168161 r#"
169162pub async fn f4() { }
170pub async f$0n f2() { }
163pub asy$0nc fn f2() { }
171164pub async fn f() { f2().await }
172165pub async fn f3() { f2().await }"#,
173166 r#"
......@@ -184,7 +177,7 @@ pub async fn f3() { f2() }"#,
184177 unnecessary_async,
185178 r#"
186179pub async fn f4() { }
187mod a { pub async f$0n f2() { } }
180mod a { pub asy$0nc fn f2() { } }
188181pub async fn f() { a::f2().await }
189182pub async fn f3() { a::f2().await }"#,
190183 r#"
......@@ -202,7 +195,7 @@ pub async fn f3() { a::f2() }"#,
202195 // Ensure that it is the first await on the 3rd line that is removed
203196 r#"
204197pub async fn f() { f2().await }
205pub async f$0n f2() -> i32 { 1 }
198pub asy$0nc fn f2() -> i32 { 1 }
206199pub async fn f3() { f4(f2().await).await }
207200pub async fn f4(i: i32) { }"#,
208201 r#"
......@@ -220,7 +213,7 @@ pub async fn f4(i: i32) { }"#,
220213 // Ensure that it is the second await on the 3rd line that is removed
221214 r#"
222215pub async fn f() { f2().await }
223pub async f$0n f2(i: i32) { }
216pub async$0 fn f2(i: i32) { }
224217pub async fn f3() { f2(f4().await).await }
225218pub async fn f4() -> i32 { 1 }"#,
226219 r#"
......@@ -237,7 +230,7 @@ pub async fn f4() -> i32 { 1 }"#,
237230 unnecessary_async,
238231 r#"
239232pub struct S { }
240impl S { pub async f$0n f2(&self) { } }
233impl S { pub async$0 fn f2(&self) { } }
241234pub async fn f(s: &S) { s.f2().await }"#,
242235 r#"
243236pub struct S { }
......@@ -250,13 +243,13 @@ pub async fn f(s: &S) { s.f2() }"#,
250243 fn does_not_apply_on_function_with_a_nested_await_expr() {
251244 check_assist_not_applicable(
252245 unnecessary_async,
253 "async f$0n f() { if true { loop { f2().await } } }",
246 "async$0 fn f() { if true { loop { f2().await } } }",
254247 )
255248 }
256249
257250 #[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() }")
260253 }
261254
262255 #[test]
src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type.rs+1-1
......@@ -198,7 +198,7 @@ fn wrapper_alias(
198198 );
199199
200200 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() {
202202 hir::ModuleDef::TypeAlias(alias) => {
203203 let enum_ty = alias.ty(ctx.db()).as_adt()?.as_enum()?;
204204 (&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() {
32803280 check_doc_test(
32813281 "unnecessary_async",
32823282 r#####"
3283pub async f$0n foo() {}
3283pub asy$0nc fn foo() {}
32843284pub async fn bar() { foo().await }
32853285"#####,
32863286 r#####"
src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs+25-25
......@@ -205,7 +205,7 @@ impl S {
205205fn foo(s: S) { s.$0 }
206206"#,
207207 expect![[r#"
208 fd foo u32
208 fd foo u32
209209 me bar() fn(&self)
210210 "#]],
211211 );
......@@ -259,7 +259,7 @@ impl S {
259259"#,
260260 expect![[r#"
261261 fd the_field (u32,)
262 me foo() fn(self)
262 me foo() fn(self)
263263 "#]],
264264 )
265265 }
......@@ -275,7 +275,7 @@ impl A {
275275"#,
276276 expect![[r#"
277277 fd the_field (u32, i32)
278 me foo() fn(&self)
278 me foo() fn(&self)
279279 "#]],
280280 )
281281 }
......@@ -536,7 +536,7 @@ impl A {
536536}
537537 "#,
538538 expect![[r#"
539 fd pub_field u32
539 fd pub_field u32
540540 me pub_method() fn(&self)
541541 "#]],
542542 )
......@@ -550,7 +550,7 @@ union U { field: u8, other: u16 }
550550fn foo(u: U) { u.$0 }
551551"#,
552552 expect![[r#"
553 fd field u8
553 fd field u8
554554 fd other u16
555555 "#]],
556556 );
......@@ -725,8 +725,8 @@ fn test(a: A) {
725725}
726726"#,
727727 expect![[r#"
728 fd another u32
729 fd field u8
728 fd another u32
729 fd field u8
730730 me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
731731 "#]],
732732 );
......@@ -748,8 +748,8 @@ fn test(a: A) {
748748}
749749"#,
750750 expect![[r#"
751 fd 0 u8
752 fd 1 u32
751 fd 0 u8
752 fd 1 u32
753753 me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
754754 "#]],
755755 );
......@@ -770,8 +770,8 @@ fn test(a: A) {
770770}
771771"#,
772772 expect![[r#"
773 fd 0 u8
774 fd 1 u32
773 fd 0 u8
774 fd 1 u32
775775 me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
776776 "#]],
777777 );
......@@ -964,12 +964,12 @@ struct Foo { field: i32 }
964964
965965impl Foo { fn foo(&self) { $0 } }"#,
966966 expect![[r#"
967 fd self.field i32
967 fd self.field i32
968968 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
973973 "#]],
974974 );
975975 check(
......@@ -978,12 +978,12 @@ struct Foo(i32);
978978
979979impl Foo { fn foo(&mut self) { $0 } }"#,
980980 expect![[r#"
981 fd self.0 i32
981 fd self.0 i32
982982 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
987987 "#]],
988988 );
989989 }
......@@ -1106,7 +1106,7 @@ fn test(a: A) {
11061106}
11071107"#,
11081108 expect![[r#"
1109 fd 0 u8
1109 fd 0 u8
11101110 me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
11111111 "#]],
11121112 );
......@@ -1162,7 +1162,7 @@ impl<F: core::ops::Deref<Target = impl Bar>> Foo<F> {
11621162}
11631163"#,
11641164 expect![[r#"
1165 fd foo &u8
1165 fd foo &u8
11661166 me foobar() fn(&self)
11671167 "#]],
11681168 );
......@@ -1199,8 +1199,8 @@ impl<B: Bar, F: core::ops::Deref<Target = B>> Foo<F> {
11991199}
12001200"#,
12011201 expect![[r#"
1202 fd foo &u8
1203 "#]],
1202 fd foo &u8
1203 "#]],
12041204 );
12051205 }
12061206
src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs+15-15
......@@ -537,10 +537,10 @@ impl Test for T {
537537}
538538",
539539 expect![[r#"
540 sp Self T
541 st T T
540 sp Self T
541 st T T
542542 tt Test
543 bt u32 u32
543 bt u32 u32
544544 "#]],
545545 );
546546
......@@ -646,10 +646,10 @@ impl Test for T {
646646}
647647",
648648 expect![[r#"
649 sp Self T
650 st T T
649 sp Self T
650 st T T
651651 tt Test
652 bt u32 u32
652 bt u32 u32
653653 "#]],
654654 );
655655
......@@ -663,10 +663,10 @@ impl Test for T {
663663}
664664",
665665 expect![[r#"
666 sp Self T
667 st T T
666 sp Self T
667 st T T
668668 tt Test
669 bt u32 u32
669 bt u32 u32
670670 "#]],
671671 );
672672
......@@ -682,10 +682,10 @@ impl Test for T {
682682}
683683",
684684 expect![[r#"
685 sp Self T
686 st T T
685 sp Self T
686 st T T
687687 tt Test
688 bt u32 u32
688 bt u32 u32
689689 "#]],
690690 );
691691
......@@ -730,10 +730,10 @@ impl Test for T {
730730}
731731",
732732 expect![[r#"
733 sp Self T
734 st T T
733 sp Self T
734 st T T
735735 tt Test
736 bt u32 u32
736 bt u32 u32
737737 "#]],
738738 );
739739
src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs+39-39
......@@ -78,19 +78,19 @@ fn foo(a: A) { a.$0 }
7878"#,
7979 expect![[r#"
8080 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 {}
9494 "#]],
9595 );
9696
......@@ -105,19 +105,19 @@ fn foo() {
105105"#,
106106 expect![[r#"
107107 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 {}
121121 "#]],
122122 );
123123 }
......@@ -134,19 +134,19 @@ fn foo(a: A) { a.$0 }
134134"#,
135135 expect![[r#"
136136 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 {}
150150 "#]],
151151 );
152152 }
src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs+55-55
......@@ -423,21 +423,21 @@ fn main() {
423423}
424424"#,
425425 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 {}
441441 "#]],
442442 );
443443 }
......@@ -456,19 +456,19 @@ fn main() {
456456}
457457"#,
458458 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 {}
472472 "#]],
473473 );
474474 }
......@@ -483,18 +483,18 @@ fn main() {
483483}
484484"#,
485485 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 {}
498498 "#]],
499499 )
500500 }
......@@ -509,21 +509,21 @@ fn main() {
509509}
510510"#,
511511 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 {}
527527 "#]],
528528 );
529529 }
src/tools/rust-analyzer/crates/ide-completion/src/context.rs+2-2
......@@ -718,7 +718,7 @@ impl<'a> CompletionContext<'a> {
718718 expected: (expected_type, expected_name),
719719 qualifier_ctx,
720720 token,
721 offset,
721 original_offset,
722722 } = expand_and_analyze(
723723 &sema,
724724 original_file.syntax().clone(),
......@@ -728,7 +728,7 @@ impl<'a> CompletionContext<'a> {
728728 )?;
729729
730730 // 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)?;
732732
733733 let krate = scope.krate();
734734 let module = scope.module();
src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs+438-288
......@@ -22,10 +22,14 @@ use crate::context::{
2222 COMPLETION_MARKER,
2323};
2424
25#[derive(Debug)]
2526struct ExpansionResult {
2627 original_file: SyntaxNode,
2728 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,
2933 fake_ident_token: SyntaxToken,
3034 derive_ctx: Option<(SyntaxNode, SyntaxNode, TextSize, ast::Attr)>,
3135}
......@@ -36,7 +40,8 @@ pub(super) struct AnalysisResult {
3640 pub(super) qualifier_ctx: QualifierCtx,
3741 /// the original token of the expanded file
3842 pub(super) token: SyntaxToken,
39 pub(super) offset: TextSize,
43 /// The offset in the original file.
44 pub(super) original_offset: TextSize,
4045}
4146
4247pub(super) fn expand_and_analyze(
......@@ -54,226 +59,344 @@ pub(super) fn expand_and_analyze(
5459 // make the offset point to the start of the original token, as that is what the
5560 // intermediate offsets calculated in expansion always points to
5661 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 });
5978
6079 // 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()?;
6382
6483 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 }
6685 })
6786}
6887
6988/// Expand attributes and macro calls at the current cursor position for both the original file
7089/// and fake file repeatedly. As soon as one of the two expansions fail we stop so the original
7190/// 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.
72116fn expand(
73117 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,
78122 relative_offset: TextSize,
79) -> ExpansionResult {
123) -> Option<ExpansionResult> {
80124 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(),
90151 ),
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;
122208 }
123 // exactly one expansion failed, inconsistent state so stop expanding completely
124 _ => break 'expansion,
125209 }
210 // exactly one expansion failed, inconsistent state so stop expanding completely
211 _ => break 'ancestors,
126212 }
213 }
127214
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 };
165244
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 });
183271 }
272 }
184273
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;
217328 }
218329 }
219330 }
220331 }
221 // at this point we won't have any more successful expansions, so stop
222 break 'expansion;
223332 }
333 // at this point we won't have any more successful expansions, so stop
334 return None;
335 }
224336
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());
234345
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();
243375
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 {
256379 // offset outside of bounds from the original expansion,
257380 // stop here to prevent problems from happening
258 break 'expansion;
381 return None;
259382 }
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)
270395 }
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,
274399 }
275
276 ExpansionResult { original_file, speculative_file, offset, fake_ident_token, derive_ctx }
277400}
278401
279402/// Fill the completion context, this is what does semantic reasoning about the surrounding context
......@@ -285,8 +408,14 @@ fn analyze(
285408 self_token: &SyntaxToken,
286409) -> Option<(CompletionAnalysis, (Option<Type>, Option<ast::NameOrNameRef>), QualifierCtx)> {
287410 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;
290419
291420 // Overwrite the path kind for derives
292421 if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx {
......@@ -294,7 +423,8 @@ fn analyze(
294423 find_node_at_offset(&file_with_fake_ident, offset)
295424 {
296425 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)?;
298428 if let NameRefKind::Path(path_ctx) = &mut nameref_ctx.kind {
299429 path_ctx.kind = PathKind::Derive {
300430 existing_derives: sema
......@@ -314,7 +444,7 @@ fn analyze(
314444 return None;
315445 }
316446
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 {
318448 let analysis = if let Some(original) = ast::String::cast(original_token.clone()) {
319449 CompletionAnalysis::String { original, expanded: ast::String::cast(self_token.clone()) }
320450 } else {
......@@ -350,8 +480,13 @@ fn analyze(
350480 }
351481 ast::NameLike::NameRef(name_ref) => {
352482 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 )?;
355490
356491 if let NameRefContext {
357492 kind:
......@@ -636,9 +771,10 @@ fn classify_name_ref(
636771 sema: &Semantics<'_, RootDatabase>,
637772 original_file: &SyntaxNode,
638773 name_ref: ast::NameRef,
774 original_offset: TextSize,
639775 parent: SyntaxNode,
640776) -> 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);
642778
643779 let make_res = |kind| (NameRefContext { nameref: nameref.clone(), kind }, Default::default());
644780
......@@ -760,7 +896,7 @@ fn classify_name_ref(
760896 // We do not want to generate path completions when we are sandwiched between an item decl signature and its body.
761897 // ex. trait Foo $0 {}
762898 // 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
764900 // expression or an item list.
765901 // The following code checks if the body is missing, if it is we either cut off the body
766902 // from the item or it was missing in the first place
......@@ -1088,15 +1224,10 @@ fn classify_name_ref(
10881224 PathKind::Type { location: location.unwrap_or(TypeLocation::Other) }
10891225 };
10901226
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()?;
10951229 let kind = match_ast! {
10961230 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()),
11001231 ast::ItemList(_) => PathKind::Item { kind: ItemListKind::Module },
11011232 ast::AssocItemList(_) => PathKind::Item { kind: match parent.parent() {
11021233 Some(it) => match_ast! {
......@@ -1126,6 +1257,23 @@ fn classify_name_ref(
11261257 };
11271258 Some(kind)
11281259 };
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 };
11291277 let make_path_kind_attr = |meta: ast::Meta| {
11301278 let attr = meta.parent_attr()?;
11311279 let kind = attr.kind();
......@@ -1153,94 +1301,98 @@ fn classify_name_ref(
11531301
11541302 // Infer the path kind
11551303 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 }
11751309
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 }
11771331
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()));
11961333
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()));
12111362
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 }
12331385 }
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 }
12441396 }
12451397 };
12461398
......@@ -1320,9 +1472,7 @@ fn classify_name_ref(
13201472 }
13211473 })
13221474 }
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),
13261476 _ => None,
13271477 };
13281478 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::{
1010};
1111use itertools::Itertools;
1212use smallvec::SmallVec;
13use stdx::{impl_from, never};
13use stdx::{format_to, impl_from, never};
1414use syntax::{format_smolstr, Edition, SmolStr, TextRange, TextSize};
1515
1616use crate::{
......@@ -27,10 +27,7 @@ use crate::{
2727#[non_exhaustive]
2828pub struct CompletionItem {
2929 /// 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,
3431
3532 /// Range of identifier that is being completed.
3633 ///
......@@ -89,11 +86,23 @@ pub struct CompletionItem {
8986 pub import_to_add: SmallVec<[(String, String); 1]>,
9087}
9188
89#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
90pub 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}
9298// We use custom debug for CompletionItem to make snapshot tests more readable.
9399impl fmt::Debug for CompletionItem {
94100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95101 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);
97106 if self.text_edit.len() == 1 {
98107 let atom = self.text_edit.iter().next().unwrap();
99108 s.field("delete", &atom.delete);
......@@ -102,7 +111,7 @@ impl fmt::Debug for CompletionItem {
102111 s.field("text_edit", &self.text_edit);
103112 }
104113 s.field("kind", &self.kind);
105 if self.lookup() != self.label {
114 if self.lookup() != self.label.primary {
106115 s.field("lookup", &self.lookup());
107116 }
108117 if let Some(detail) = &self.detail {
......@@ -434,7 +443,7 @@ impl CompletionItem {
434443
435444 self.ref_match.map(|(mutability, offset)| {
436445 (
437 format!("&{}{}", mutability.as_keyword_for_ref(), self.label),
446 format!("&{}{}", mutability.as_keyword_for_ref(), self.label.primary),
438447 ide_db::text_edit::Indel::insert(
439448 offset,
440449 format!("&{}", mutability.as_keyword_for_ref()),
......@@ -488,13 +497,13 @@ impl Builder {
488497 let _p = tracing::info_span!("item::Builder::build").entered();
489498
490499 let label = self.label;
491 let mut label_detail = None;
492500 let mut lookup = self.lookup.unwrap_or_else(|| label.clone());
493501 let insert_text = self.insert_text.unwrap_or_else(|| label.to_string());
494502
503 let mut detail_left = None;
495504 if !self.doc_aliases.is_empty() {
496505 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})"));
498507 let lookup_doc_aliases = self
499508 .doc_aliases
500509 .iter()
......@@ -516,16 +525,20 @@ impl Builder {
516525 }
517526 if let [import_edit] = &*self.imports_to_add {
518527 // 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 { " " },
522533 import_edit.import_path.display(db, self.edition)
523 ));
534 );
524535 } 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 );
529542 }
530543
531544 let text_edit = match self.text_edit {
......@@ -546,8 +559,11 @@ impl Builder {
546559
547560 CompletionItem {
548561 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 },
551567 text_edit,
552568 is_snippet: self.is_snippet,
553569 detail: self.detail,
src/tools/rust-analyzer/crates/ide-completion/src/render.rs+322-218
......@@ -748,9 +748,9 @@ mod tests {
748748 let tag = it.kind.tag();
749749 let relevance = display_relevance(it.relevance);
750750 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(),
754754 ));
755755
756756 if let Some((label, _indel, relevance)) = it.ref_match() {
......@@ -812,13 +812,13 @@ fn main() {
812812}
813813"#,
814814 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]
822822 "#]],
823823 );
824824 }
......@@ -852,11 +852,11 @@ fn main() {
852852}
853853"#,
854854 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]
860860 "#]],
861861 );
862862 }
......@@ -888,13 +888,13 @@ fn main() {
888888}
889889"#,
890890 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]
898898 "#]],
899899 );
900900 }
......@@ -926,11 +926,11 @@ fn main() {
926926}
927927"#,
928928 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 []
934934 "#]],
935935 );
936936 }
......@@ -958,11 +958,11 @@ fn main() {
958958}
959959"#,
960960 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]
966966 "#]],
967967 );
968968 }
......@@ -990,11 +990,11 @@ fn main() {
990990}
991991"#,
992992 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]
998998 "#]],
999999 );
10001000 }
......@@ -1022,11 +1022,11 @@ fn main() {
10221022}
10231023"#,
10241024 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]
10301030 "#]],
10311031 );
10321032 }
......@@ -1058,7 +1058,7 @@ fn main() {
10581058
10591059"#,
10601060 expect![[r#"
1061 me Function []
1061 me Function fn(&self, i32) -> bool []
10621062 "#]],
10631063 );
10641064 }
......@@ -1081,14 +1081,14 @@ fn func(input: Struct) { }
10811081
10821082"#,
10831083 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) []
10921092 "#]],
10931093 );
10941094 }
......@@ -1109,13 +1109,13 @@ fn main() {
11091109}
11101110"#,
11111111 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) []
11191119 "#]],
11201120 );
11211121 }
......@@ -1133,6 +1133,10 @@ fn main() { Foo::Fo$0 }
11331133 [
11341134 CompletionItem {
11351135 label: "Foo {…}",
1136 detail_left: None,
1137 detail_right: Some(
1138 "Foo { x: i32, y: i32 }",
1139 ),
11361140 source_range: 54..56,
11371141 delete: 54..56,
11381142 insert: "Foo { x: ${1:()}, y: ${2:()} }$0",
......@@ -1161,6 +1165,10 @@ fn main() { Foo::Fo$0 }
11611165 [
11621166 CompletionItem {
11631167 label: "Foo(…)",
1168 detail_left: None,
1169 detail_right: Some(
1170 "Foo(i32, i32)",
1171 ),
11641172 source_range: 46..48,
11651173 delete: 46..48,
11661174 insert: "Foo(${1:()}, ${2:()})$0",
......@@ -1189,6 +1197,10 @@ fn main() { fo$0 }
11891197 [
11901198 CompletionItem {
11911199 label: "foo(…)",
1200 detail_left: None,
1201 detail_right: Some(
1202 "fn(u32, u32, T) -> (u32, T)",
1203 ),
11921204 source_range: 68..70,
11931205 delete: 68..70,
11941206 insert: "foo(${1:a}, ${2:b}, ${3:t})$0",
......@@ -1201,6 +1213,10 @@ fn main() { fo$0 }
12011213 },
12021214 CompletionItem {
12031215 label: "main()",
1216 detail_left: None,
1217 detail_right: Some(
1218 "fn()",
1219 ),
12041220 source_range: 68..70,
12051221 delete: 68..70,
12061222 insert: "main();$0",
......@@ -1228,6 +1244,10 @@ fn main() { Foo::Fo$0 }
12281244 [
12291245 CompletionItem {
12301246 label: "Foo",
1247 detail_left: None,
1248 detail_right: Some(
1249 "Foo",
1250 ),
12311251 source_range: 35..37,
12321252 delete: 35..37,
12331253 insert: "Foo$0",
......@@ -1260,6 +1280,10 @@ fn main() { let _: m::Spam = S$0 }
12601280 [
12611281 CompletionItem {
12621282 label: "main()",
1283 detail_left: None,
1284 detail_right: Some(
1285 "fn()",
1286 ),
12631287 source_range: 75..76,
12641288 delete: 75..76,
12651289 insert: "main();$0",
......@@ -1271,6 +1295,8 @@ fn main() { let _: m::Spam = S$0 }
12711295 },
12721296 CompletionItem {
12731297 label: "m",
1298 detail_left: None,
1299 detail_right: None,
12741300 source_range: 75..76,
12751301 delete: 75..76,
12761302 insert: "m",
......@@ -1280,6 +1306,10 @@ fn main() { let _: m::Spam = S$0 }
12801306 },
12811307 CompletionItem {
12821308 label: "m::Spam::Bar(…)",
1309 detail_left: None,
1310 detail_right: Some(
1311 "m::Spam::Bar(i32)",
1312 ),
12831313 source_range: 75..76,
12841314 delete: 75..76,
12851315 insert: "m::Spam::Bar(${1:()})$0",
......@@ -1305,6 +1335,10 @@ fn main() { let _: m::Spam = S$0 }
13051335 },
13061336 CompletionItem {
13071337 label: "m::Spam::Foo",
1338 detail_left: None,
1339 detail_right: Some(
1340 "m::Spam::Foo",
1341 ),
13081342 source_range: 75..76,
13091343 delete: 75..76,
13101344 insert: "m::Spam::Foo$0",
......@@ -1347,6 +1381,10 @@ fn main() { som$0 }
13471381 [
13481382 CompletionItem {
13491383 label: "main()",
1384 detail_left: None,
1385 detail_right: Some(
1386 "fn()",
1387 ),
13501388 source_range: 56..59,
13511389 delete: 56..59,
13521390 insert: "main();$0",
......@@ -1358,6 +1396,10 @@ fn main() { som$0 }
13581396 },
13591397 CompletionItem {
13601398 label: "something_deprecated()",
1399 detail_left: None,
1400 detail_right: Some(
1401 "fn()",
1402 ),
13611403 source_range: 56..59,
13621404 delete: 56..59,
13631405 insert: "something_deprecated();$0",
......@@ -1382,6 +1424,10 @@ fn foo() { A { the$0 } }
13821424 [
13831425 CompletionItem {
13841426 label: "the_field",
1427 detail_left: None,
1428 detail_right: Some(
1429 "u32",
1430 ),
13851431 source_range: 57..60,
13861432 delete: 57..60,
13871433 insert: "the_field",
......@@ -1429,6 +1475,10 @@ impl S {
14291475 [
14301476 CompletionItem {
14311477 label: "bar()",
1478 detail_left: None,
1479 detail_right: Some(
1480 "fn(self)",
1481 ),
14321482 source_range: 94..94,
14331483 delete: 94..94,
14341484 insert: "bar();$0",
......@@ -1460,6 +1510,10 @@ impl S {
14601510 },
14611511 CompletionItem {
14621512 label: "foo",
1513 detail_left: None,
1514 detail_right: Some(
1515 "{unknown}",
1516 ),
14631517 source_range: 94..94,
14641518 delete: 94..94,
14651519 insert: "foo",
......@@ -1498,6 +1552,8 @@ use self::E::*;
14981552 [
14991553 CompletionItem {
15001554 label: "my",
1555 detail_left: None,
1556 detail_right: None,
15011557 source_range: 10..12,
15021558 delete: 10..12,
15031559 insert: "my",
......@@ -1510,6 +1566,10 @@ use self::E::*;
15101566 },
15111567 CompletionItem {
15121568 label: "V",
1569 detail_left: None,
1570 detail_right: Some(
1571 "V",
1572 ),
15131573 source_range: 10..12,
15141574 delete: 10..12,
15151575 insert: "V$0",
......@@ -1524,6 +1584,10 @@ use self::E::*;
15241584 },
15251585 CompletionItem {
15261586 label: "E",
1587 detail_left: None,
1588 detail_right: Some(
1589 "E",
1590 ),
15271591 source_range: 10..12,
15281592 delete: 10..12,
15291593 insert: "E",
......@@ -1556,6 +1620,10 @@ fn foo(s: S) { s.$0 }
15561620 [
15571621 CompletionItem {
15581622 label: "the_method()",
1623 detail_left: None,
1624 detail_right: Some(
1625 "fn(&self)",
1626 ),
15591627 source_range: 81..81,
15601628 delete: 81..81,
15611629 insert: "the_method();$0",
......@@ -1729,9 +1797,9 @@ fn test(bar: u32) { }
17291797fn foo(s: S) { test(s.$0) }
17301798"#,
17311799 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 []
17351803 "#]],
17361804 );
17371805 }
......@@ -1745,9 +1813,9 @@ struct B { x: (), y: f32, bar: u32 }
17451813fn foo(a: A) { B { bar: a.$0 }; }
17461814"#,
17471815 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 []
17511819 "#]],
17521820 )
17531821 }
......@@ -1768,6 +1836,10 @@ fn f() -> i32 {
17681836 [
17691837 CompletionItem {
17701838 label: "0",
1839 detail_left: None,
1840 detail_right: Some(
1841 "i32",
1842 ),
17711843 source_range: 56..57,
17721844 delete: 56..57,
17731845 insert: "0",
......@@ -1804,9 +1876,9 @@ fn f(foo: i64) { }
18041876fn foo(a: A) { B { bar: f(a.$0) }; }
18051877"#,
18061878 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 []
18101882 "#]],
18111883 );
18121884 check_relevance(
......@@ -1817,9 +1889,9 @@ fn f(foo: i64) { }
18171889fn foo(a: A) { f(B { bar: a.$0 }); }
18181890"#,
18191891 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 []
18231895 "#]],
18241896 );
18251897 }
......@@ -1832,13 +1904,13 @@ struct WorldSnapshot { _f: () };
18321904fn go(world: &WorldSnapshot) { go(w$0) }
18331905"#,
18341906 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: () } []
18381910 st &WorldSnapshot {…} [type]
1839 st WorldSnapshot []
1911 st WorldSnapshot WorldSnapshot []
18401912 st &WorldSnapshot [type]
1841 fn go(…) []
1913 fn go(…) fn(&WorldSnapshot) []
18421914 "#]],
18431915 );
18441916 }
......@@ -1852,9 +1924,9 @@ struct Foo;
18521924fn f(foo: &Foo) { f(foo, w$0) }
18531925"#,
18541926 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) []
18581930 "#]],
18591931 );
18601932 }
......@@ -1869,12 +1941,12 @@ fn bar() -> u8 { 0 }
18691941fn f() { A { bar: b$0 }; }
18701942"#,
18711943 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() []
18781950 "#]],
18791951 );
18801952 }
......@@ -1895,9 +1967,9 @@ fn f() {
18951967}
18961968"#,
18971969 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 []
19011973 "#]],
19021974 );
19031975 }
......@@ -1916,7 +1988,7 @@ fn f() {
19161988}
19171989"#,
19181990 expect![[r#"
1919 me aaa() [name]
1991 me aaa() fn(&self) -> u64 [name]
19201992 "#]],
19211993 );
19221994 }
......@@ -1934,14 +2006,14 @@ fn main() {
19342006}
19352007 "#,
19362008 expect![[r#"
1937 lc s [name+local]
2009 lc s S [name+local]
19382010 lc &mut s [type+name+local]
1939 st S []
2011 st S S []
19402012 st &mut S [type]
1941 st S []
2013 st S S []
19422014 st &mut S [type]
1943 fn foo(…) []
1944 fn main() []
2015 fn foo(…) fn(&mut S) []
2016 fn main() fn() []
19452017 "#]],
19462018 );
19472019 check_relevance(
......@@ -1954,13 +2026,13 @@ fn main() {
19542026}
19552027 "#,
19562028 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() []
19642036 "#]],
19652037 );
19662038 check_relevance(
......@@ -1973,13 +2045,13 @@ fn main() {
19732045}
19742046 "#,
19752047 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() []
19832055 "#]],
19842056 );
19852057 }
......@@ -2010,19 +2082,19 @@ fn main() {
20102082}
20112083 "#,
20122084 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]
20162088 lc &t [type+local]
2017 st S []
2089 st S S []
20182090 st &S [type]
2019 st S []
2091 st S S []
20202092 st &S [type]
2021 st T []
2093 st T T []
20222094 st &T [type]
2023 fn foo(…) []
2024 fn main() []
2025 md core []
2095 fn foo(…) fn(&S) []
2096 fn main() fn() []
2097 md core []
20262098 "#]],
20272099 )
20282100 }
......@@ -2059,19 +2131,19 @@ fn main() {
20592131}
20602132 "#,
20612133 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]
20652137 lc &mut t [type+local]
2066 st S []
2138 st S S []
20672139 st &mut S [type]
2068 st S []
2140 st S S []
20692141 st &mut S [type]
2070 st T []
2142 st T T []
20712143 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 []
20752147 "#]],
20762148 )
20772149 }
......@@ -2087,9 +2159,9 @@ fn foo(bar: u32) {
20872159}
20882160"#,
20892161 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) []
20932165 "#]],
20942166 );
20952167 }
......@@ -2105,13 +2177,13 @@ fn foo() {
21052177fn bar(t: Foo) {}
21062178"#,
21072179 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() []
21152187 "#]],
21162188 );
21172189 }
......@@ -2127,14 +2199,14 @@ fn foo() {
21272199fn bar(t: &Foo) {}
21282200"#,
21292201 expect![[r#"
2130 ev Foo::A []
2202 ev Foo::A Foo::A []
21312203 ev &Foo::A [type]
2132 ev Foo::B []
2204 ev Foo::B Foo::B []
21332205 ev &Foo::B [type]
2134 en Foo []
2206 en Foo Foo []
21352207 en &Foo [type]
2136 fn bar(…) []
2137 fn foo() []
2208 fn bar(…) fn(&Foo) []
2209 fn foo() fn() []
21382210 "#]],
21392211 );
21402212 }
......@@ -2163,18 +2235,18 @@ fn main() {
21632235}
21642236"#,
21652237 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 []
21682240 st &S [type]
2169 st S []
2241 st S S []
21702242 st &S [type]
2171 st T []
2243 st T T []
21722244 st &T [type]
2173 fn bar() []
2245 fn bar() fn() -> T []
21742246 fn &bar() [type]
2175 fn foo(…) []
2176 fn main() []
2177 md core []
2247 fn foo(…) fn(&S) []
2248 fn main() fn() []
2249 md core []
21782250 "#]],
21792251 )
21802252 }
......@@ -2191,7 +2263,7 @@ impl Sub for u32 {}
21912263fn foo(a: u32) { a.$0 }
21922264"#,
21932265 expect![[r#"
2194 me sub(…) (as Sub) [op_method]
2266 me sub(…) fn(self, Self) -> Self [op_method]
21952267 "#]],
21962268 );
21972269 check_relevance(
......@@ -2212,9 +2284,9 @@ fn main() {
22122284}
22132285"#,
22142286 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]
22182290 "#]],
22192291 );
22202292 }
......@@ -2238,9 +2310,9 @@ fn test() {
22382310}
22392311"#,
22402312 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]
22442316 "#]],
22452317 );
22462318 }
......@@ -2384,12 +2456,12 @@ fn test() {
23842456 // Constructor
23852457 // Others
23862458 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]
23932465 "#]],
23942466 );
23952467
......@@ -2420,14 +2492,14 @@ fn test() {
24202492}
24212493 "#,
24222494 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 "#]],
24312503 );
24322504 }
24332505
......@@ -2456,13 +2528,13 @@ fn test() {
24562528}
24572529 "#,
24582530 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]
24662538 "#]],
24672539 );
24682540 }
......@@ -2484,6 +2556,10 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
24842556 [
24852557 CompletionItem {
24862558 label: "baz()",
2559 detail_left: None,
2560 detail_right: Some(
2561 "fn(&self) -> u32",
2562 ),
24872563 source_range: 109..110,
24882564 delete: 109..110,
24892565 insert: "baz()$0",
......@@ -2513,6 +2589,10 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
25132589 },
25142590 CompletionItem {
25152591 label: "bar",
2592 detail_left: None,
2593 detail_right: Some(
2594 "u32",
2595 ),
25162596 source_range: 109..110,
25172597 delete: 109..110,
25182598 insert: "bar",
......@@ -2524,6 +2604,10 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
25242604 },
25252605 CompletionItem {
25262606 label: "qux",
2607 detail_left: None,
2608 detail_right: Some(
2609 "fn()",
2610 ),
25272611 source_range: 109..110,
25282612 text_edit: TextEdit {
25292613 indels: [
......@@ -2562,6 +2646,10 @@ fn foo() {
25622646 [
25632647 CompletionItem {
25642648 label: "field",
2649 detail_left: None,
2650 detail_right: Some(
2651 "fn()",
2652 ),
25652653 source_range: 76..78,
25662654 delete: 76..78,
25672655 insert: "field",
......@@ -2610,6 +2698,10 @@ fn main() {
26102698 [
26112699 CompletionItem {
26122700 label: "foo()",
2701 detail_left: None,
2702 detail_right: Some(
2703 "fn() -> S",
2704 ),
26132705 source_range: 95..95,
26142706 delete: 95..95,
26152707 insert: "foo()$0",
......@@ -2661,15 +2753,15 @@ fn foo() {
26612753}
26622754"#,
26632755 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> []
26732765 "#]],
26742766 );
26752767 }
......@@ -2697,20 +2789,20 @@ fn main() {
26972789 "#,
26982790 &[CompletionItemKind::Snippet, CompletionItemKind::SymbolKind(SymbolKind::Method)],
26992791 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 []
27142806 "#]],
27152807 );
27162808 }
......@@ -2730,19 +2822,19 @@ fn main() {
27302822 "#,
27312823 &[CompletionItemKind::Snippet, CompletionItemKind::SymbolKind(SymbolKind::Method)],
27322824 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 []
27462838 "#]],
27472839 );
27482840 }
......@@ -2765,12 +2857,12 @@ fn f() {
27652857}
27662858"#,
27672859 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]
27742866 "#]],
27752867 );
27762868 }
......@@ -2979,6 +3071,12 @@ fn main() {
29793071 [
29803072 CompletionItem {
29813073 label: "flush()",
3074 detail_left: Some(
3075 "(as Write)",
3076 ),
3077 detail_right: Some(
3078 "fn(&self)",
3079 ),
29823080 source_range: 193..193,
29833081 delete: 193..193,
29843082 insert: "flush();$0",
......@@ -3006,6 +3104,12 @@ fn main() {
30063104 },
30073105 CompletionItem {
30083106 label: "write()",
3107 detail_left: Some(
3108 "(as Write)",
3109 ),
3110 detail_right: Some(
3111 "fn(&self)",
3112 ),
30093113 source_range: 193..193,
30103114 delete: 193..193,
30113115 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(
118118 let items = get_all_items(config, ra_fixture, trigger_character);
119119 items
120120 .into_iter()
121 .filter(|it| it.kind != CompletionItemKind::BuiltinType || it.label == "u32")
121 .filter(|it| it.kind != CompletionItemKind::BuiltinType || it.label.primary == "u32")
122122 .filter(|it| include_keywords || it.kind != CompletionItemKind::Keyword)
123123 .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 })
125131 .collect()
126132}
127133
......@@ -173,27 +179,30 @@ fn render_completion_list(completions: Vec<CompletionItem>) -> String {
173179 let label_width = completions
174180 .iter()
175181 .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
178187 })
179188 .max()
180 .unwrap_or_default()
181 .min(22);
189 .unwrap_or_default();
182190 completions
183191 .into_iter()
184192 .map(|it| {
185193 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}");
190197 }
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,
195204 );
196 format_to!(buf, "{:width$} {}", "", detail, width = width);
205 format_to!(buf, "{:pad_with$}{detail_right}", "",);
197206 }
198207 if it.deprecated {
199208 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);
3333 at cold
3434 at deny(…)
3535 at deprecated
36 at derive macro derive
36 at derive macro derive
3737 at derive(…)
3838 at doc = "…"
3939 at doc(alias = "…")
......@@ -367,9 +367,9 @@ struct Foo;
367367 at cfg_attr(…)
368368 at deny(…)
369369 at deprecated
370 at derive macro derive
370 at derive macro derive
371371 at derive(…)
372 at derive_const macro derive_const
372 at derive_const macro derive_const
373373 at doc = "…"
374374 at doc(alias = "…")
375375 at doc(hidden)
......@@ -790,10 +790,10 @@ mod derive {
790790#[derive($0)] struct Test;
791791"#,
792792 expect![[r#"
793 de Clone macro Clone
793 de Clone macro Clone
794794 de Clone, Copy
795 de Default macro Default
796 de PartialEq macro PartialEq
795 de Default macro Default
796 de PartialEq macro PartialEq
797797 de PartialEq, Eq
798798 de PartialEq, Eq, PartialOrd, Ord
799799 de PartialEq, PartialOrd
......@@ -812,9 +812,9 @@ mod derive {
812812#[derive(serde::Serialize, PartialEq, $0)] struct Test;
813813"#,
814814 expect![[r#"
815 de Clone macro Clone
815 de Clone macro Clone
816816 de Clone, Copy
817 de Default macro Default
817 de Default macro Default
818818 de Eq
819819 de Eq, PartialOrd, Ord
820820 de PartialOrd
......@@ -833,9 +833,9 @@ mod derive {
833833#[derive($0 serde::Serialize, PartialEq)] struct Test;
834834"#,
835835 expect![[r#"
836 de Clone macro Clone
836 de Clone macro Clone
837837 de Clone, Copy
838 de Default macro Default
838 de Default macro Default
839839 de Eq
840840 de Eq, PartialOrd, Ord
841841 de PartialOrd
......@@ -854,9 +854,9 @@ mod derive {
854854#[derive(PartialEq, Eq, Or$0)] struct Test;
855855"#,
856856 expect![[r#"
857 de Clone macro Clone
857 de Clone macro Clone
858858 de Clone, Copy
859 de Default macro Default
859 de Default macro Default
860860 de PartialOrd
861861 de PartialOrd, Ord
862862 md core
src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs+266-196
......@@ -26,22 +26,22 @@ fn baz() {
2626 "#,
2727 // This should not contain `FooDesc {…}`.
2828 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
3535 md _69latrick
3636 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
4545 kw crate::
4646 kw false
4747 kw for
......@@ -76,14 +76,14 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
7676}
7777"#,
7878 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
8787 kw crate::
8888 kw false
8989 kw for
......@@ -122,25 +122,25 @@ impl Unit {
122122"#,
123123 // `self` is in here twice, once as the module, once as the local
124124 expect![[r#"
125 ct CONST Unit
125 ct CONST Unit
126126 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
133133 md module
134134 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
140140 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
144144 kw async
145145 kw const
146146 kw crate::
......@@ -187,19 +187,19 @@ impl Unit {
187187}
188188"#,
189189 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
194194 md module
195195 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
200200 tt Trait
201 un Union Union
202 ev TupleV(…) TupleV(u32)
201 un Union Union
202 ev TupleV(…) TupleV(u32)
203203 ?? Unresolved
204204 "#]],
205205 );
......@@ -216,8 +216,8 @@ fn complete_in_block() {
216216 }
217217"#,
218218 expect![[r#"
219 fn foo() fn()
220 bt u32 u32
219 fn foo() fn()
220 bt u32 u32
221221 kw async
222222 kw const
223223 kw crate::
......@@ -264,8 +264,8 @@ fn complete_after_if_expr() {
264264 }
265265"#,
266266 expect![[r#"
267 fn foo() fn()
268 bt u32 u32
267 fn foo() fn()
268 bt u32 u32
269269 kw async
270270 kw const
271271 kw crate::
......@@ -313,8 +313,8 @@ fn complete_in_match_arm() {
313313 }
314314"#,
315315 expect![[r#"
316 fn foo() fn()
317 bt u32 u32
316 fn foo() fn()
317 bt u32 u32
318318 kw crate::
319319 kw false
320320 kw for
......@@ -337,8 +337,8 @@ fn completes_in_loop_ctx() {
337337 check_empty(
338338 r"fn my() { loop { $0 } }",
339339 expect![[r#"
340 fn my() fn()
341 bt u32 u32
340 fn my() fn()
341 bt u32 u32
342342 kw async
343343 kw break
344344 kw const
......@@ -376,22 +376,22 @@ fn completes_in_loop_ctx() {
376376 check_empty(
377377 r"fn my() { loop { foo.$0 } }",
378378 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 {}
395395 "#]],
396396 );
397397}
......@@ -401,8 +401,8 @@ fn completes_in_let_initializer() {
401401 check_empty(
402402 r#"fn main() { let _ = $0 }"#,
403403 expect![[r#"
404 fn main() fn()
405 bt u32 u32
404 fn main() fn()
405 bt u32 u32
406406 kw crate::
407407 kw false
408408 kw for
......@@ -434,9 +434,9 @@ fn foo() {
434434}
435435"#,
436436 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
440440 kw crate::
441441 kw false
442442 kw for
......@@ -469,9 +469,9 @@ fn foo() {
469469}
470470"#,
471471 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
475475 kw crate::
476476 kw false
477477 kw for
......@@ -499,10 +499,10 @@ fn quux(x: i32) {
499499}
500500"#,
501501 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
506506 kw crate::
507507 kw false
508508 kw for
......@@ -526,10 +526,10 @@ fn quux(x: i32) {
526526}
527527",
528528 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
533533 kw crate::
534534 kw false
535535 kw for
......@@ -554,11 +554,11 @@ fn quux(x: i32) {
554554}
555555"#,
556556 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
562562 kw crate::
563563 kw false
564564 kw for
......@@ -590,12 +590,12 @@ fn func() {
590590}
591591"#,
592592 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 = ()
596596 ev RecordV {…} RecordV { field: u32 }
597 ev TupleV(…) TupleV(u32)
598 ev UnitV UnitV
597 ev TupleV(…) TupleV(u32)
598 ev UnitV UnitV
599599 "#]],
600600 );
601601}
......@@ -633,7 +633,7 @@ fn func() {
633633"#,
634634 expect![[r#"
635635 fn variant fn() -> Enum
636 ev Variant Variant
636 ev Variant Variant
637637 "#]],
638638 );
639639}
......@@ -650,8 +650,8 @@ fn main() {
650650}
651651",
652652 expect![[r#"
653 fn foo() fn() -> impl Trait<U>
654 fn main() fn()
653 fn foo() fn() -> impl Trait<U>
654 fn main() fn()
655655 tt Trait
656656 "#]],
657657 );
......@@ -670,9 +670,9 @@ fn main() {
670670}
671671"#,
672672 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()
676676 tt Trait
677677 "#]],
678678 );
......@@ -692,9 +692,9 @@ fn main() {
692692 Foo::$0
693693}
694694",
695 expect![[r"
695 expect![[r#"
696696 fn bar(…) fn(impl Trait<U>)
697 "]],
697 "#]],
698698 );
699699}
700700
......@@ -712,7 +712,7 @@ fn main() {
712712}
713713"#,
714714 expect![[r#"
715 fn test() fn() -> Zulu
715 fn test() fn() -> Zulu
716716 ex Zulu
717717 ex Zulu::test()
718718 "#]],
......@@ -736,11 +736,11 @@ fn brr() {
736736}
737737"#,
738738 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
742742 st YoloVariant {…} YoloVariant { f: usize }
743 bt u32 u32
743 bt u32 u32
744744 kw crate::
745745 kw false
746746 kw for
......@@ -801,8 +801,8 @@ fn else_completion_after_if() {
801801fn foo() { if foo {} $0 }
802802"#,
803803 expect![[r#"
804 fn foo() fn()
805 bt u32 u32
804 fn foo() fn()
805 bt u32 u32
806806 kw async
807807 kw const
808808 kw crate::
......@@ -842,8 +842,8 @@ fn foo() { if foo {} $0 }
842842fn foo() { if foo {} el$0 }
843843"#,
844844 expect![[r#"
845 fn foo() fn()
846 bt u32 u32
845 fn foo() fn()
846 bt u32 u32
847847 kw async
848848 kw const
849849 kw crate::
......@@ -883,8 +883,8 @@ fn foo() { if foo {} el$0 }
883883fn foo() { bar(if foo {} $0) }
884884"#,
885885 expect![[r#"
886 fn foo() fn()
887 bt u32 u32
886 fn foo() fn()
887 bt u32 u32
888888 kw crate::
889889 kw else
890890 kw else if
......@@ -907,8 +907,8 @@ fn foo() { bar(if foo {} $0) }
907907fn foo() { bar(if foo {} el$0) }
908908"#,
909909 expect![[r#"
910 fn foo() fn()
911 bt u32 u32
910 fn foo() fn()
911 bt u32 u32
912912 kw crate::
913913 kw else
914914 kw else if
......@@ -931,8 +931,8 @@ fn foo() { bar(if foo {} el$0) }
931931fn foo() { if foo {} $0 let x = 92; }
932932"#,
933933 expect![[r#"
934 fn foo() fn()
935 bt u32 u32
934 fn foo() fn()
935 bt u32 u32
936936 kw async
937937 kw const
938938 kw crate::
......@@ -972,8 +972,8 @@ fn foo() { if foo {} $0 let x = 92; }
972972fn foo() { if foo {} el$0 let x = 92; }
973973"#,
974974 expect![[r#"
975 fn foo() fn()
976 bt u32 u32
975 fn foo() fn()
976 bt u32 u32
977977 kw async
978978 kw const
979979 kw crate::
......@@ -1013,8 +1013,8 @@ fn foo() { if foo {} el$0 let x = 92; }
10131013fn foo() { if foo {} el$0 { let x = 92; } }
10141014"#,
10151015 expect![[r#"
1016 fn foo() fn()
1017 bt u32 u32
1016 fn foo() fn()
1017 bt u32 u32
10181018 kw async
10191019 kw const
10201020 kw crate::
......@@ -1065,9 +1065,9 @@ fn main() {
10651065pub struct UnstableThisShouldNotBeListed;
10661066"#,
10671067 expect![[r#"
1068 fn main() fn()
1068 fn main() fn()
10691069 md std
1070 bt u32 u32
1070 bt u32 u32
10711071 kw async
10721072 kw const
10731073 kw crate::
......@@ -1117,10 +1117,10 @@ fn main() {
11171117pub struct UnstableButWeAreOnNightlyAnyway;
11181118"#,
11191119 expect![[r#"
1120 fn main() fn()
1120 fn main() fn()
11211121 md std
11221122 st UnstableButWeAreOnNightlyAnyway UnstableButWeAreOnNightlyAnyway
1123 bt u32 u32
1123 bt u32 u32
11241124 kw async
11251125 kw const
11261126 kw crate::
......@@ -1170,17 +1170,17 @@ fn main() {
11701170}
11711171"#,
11721172 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 {}
11841184 "#]],
11851185 );
11861186 check_empty(
......@@ -1196,17 +1196,17 @@ fn main() {
11961196}
11971197"#,
11981198 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 {}
12101210 "#]],
12111211 );
12121212}
......@@ -1226,17 +1226,17 @@ fn main() {
12261226}
12271227"#,
12281228 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 {}
12401240 "#]],
12411241 );
12421242 check_empty(
......@@ -1252,17 +1252,17 @@ fn main() {
12521252}
12531253"#,
12541254 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 {}
12661266 "#]],
12671267 );
12681268 check_empty(
......@@ -1278,17 +1278,17 @@ fn main() {
12781278}
12791279"#,
12801280 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 {}
12921292 "#]],
12931293 );
12941294 check_empty(
......@@ -1304,19 +1304,89 @@ fn main() {
13041304}
13051305"#,
13061306 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]
1325fn macro_that_ignores_completion_marker() {
1326 check(
1327 r#"
1328macro_rules! helper {
1329 ($v:ident) => {};
1330}
1331
1332macro_rules! m {
1333 ($v:ident) => {{
1334 helper!($v);
1335 $v
1336 }};
1337}
1338
1339fn 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
13201390 "#]],
13211391 );
13221392}
src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs+74-32
......@@ -139,9 +139,9 @@ fn main() {
139139}
140140"#,
141141 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
145145 st Rcar (use dep::some_module::Rcar) Rcar
146146 "#]],
147147 );
......@@ -165,11 +165,11 @@ fn main() {
165165}
166166"#,
167167 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
173173 st Rcar (use dep::some_module::Rcar) Rcar
174174 "#]],
175175 );
......@@ -193,7 +193,7 @@ fn main() {
193193}
194194"#,
195195 expect![[r#"
196 ct RC (use dep::RC) ()
196 ct RC (use dep::RC) ()
197197 ct RC (use dep::some_module::RC) ()
198198 "#]],
199199 );
......@@ -227,7 +227,7 @@ fn main() {
227227}
228228"#,
229229 expect![[r#"
230 st ThirdStruct (use dep::some_module::ThirdStruct) ThirdStruct
230 st ThirdStruct (use dep::some_module::ThirdStruct) ThirdStruct
231231 st AfterThirdStruct (use dep::some_module::AfterThirdStruct) AfterThirdStruct
232232 st ThiiiiiirdStruct (use dep::some_module::ThiiiiiirdStruct) ThiiiiiirdStruct
233233 "#]],
......@@ -263,8 +263,8 @@ fn trait_function_fuzzy_completion() {
263263 check(
264264 fixture,
265265 expect![[r#"
266 fn weird_function() (use dep::test_mod::TestTrait) fn()
267 "#]],
266 fn weird_function() (use dep::test_mod::TestTrait) fn()
267 "#]],
268268 );
269269
270270 check_edit(
......@@ -356,8 +356,8 @@ fn trait_method_fuzzy_completion() {
356356 check(
357357 fixture,
358358 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 "#]],
361361 );
362362
363363 check_edit(
......@@ -401,8 +401,8 @@ fn main() {
401401 check(
402402 fixture,
403403 expect![[r#"
404 me some_method() (use foo::TestTrait) fn(&self)
405 "#]],
404 me some_method() (use foo::TestTrait) fn(&self)
405 "#]],
406406 );
407407
408408 check_edit(
......@@ -448,8 +448,8 @@ fn main() {
448448 check(
449449 fixture,
450450 expect![[r#"
451 me some_method() (use foo::TestTrait) fn(&self)
452 "#]],
451 me some_method() (use foo::TestTrait) fn(&self)
452 "#]],
453453 );
454454
455455 check_edit(
......@@ -496,8 +496,8 @@ fn completion<T: Wrapper>(whatever: T) {
496496 check(
497497 fixture,
498498 expect![[r#"
499 me not_in_scope() (use foo::NotInScope) fn(&self)
500 "#]],
499 me not_in_scope() (use foo::NotInScope) fn(&self)
500 "#]],
501501 );
502502
503503 check_edit(
......@@ -539,8 +539,8 @@ fn main() {
539539 check(
540540 fixture,
541541 expect![[r#"
542 me into() (use test_trait::TestInto) fn(self) -> T
543 "#]],
542 me into() (use test_trait::TestInto) fn(self) -> T
543 "#]],
544544 );
545545}
546546
......@@ -568,8 +568,8 @@ fn main() {
568568 check(
569569 fixture,
570570 expect![[r#"
571 fn random_method() (use dep::test_mod::TestTrait) fn()
572 "#]],
571 fn random_method() (use dep::test_mod::TestTrait) fn()
572 "#]],
573573 );
574574
575575 check_edit(
......@@ -737,8 +737,8 @@ fn main() {
737737}
738738 "#,
739739 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 "#]],
742742 );
743743
744744 check(
......@@ -767,8 +767,8 @@ fn main() {
767767}
768768"#,
769769 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
772772 me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
773773 "#]],
774774 );
......@@ -1117,7 +1117,7 @@ fn main() {
11171117 tes$0
11181118}"#,
11191119 expect![[r#"
1120 ct TEST_CONST (use foo::TEST_CONST) usize
1120 ct TEST_CONST (use foo::TEST_CONST) usize
11211121 fn test_function() (use foo::test_function) fn() -> i32
11221122 "#]],
11231123 );
......@@ -1175,8 +1175,8 @@ fn main() {
11751175}
11761176"#,
11771177 expect![[r#"
1178 fn some_fn() (use m::some_fn) fn() -> i32
1179 "#]],
1178 fn some_fn() (use m::some_fn) fn() -> i32
1179 "#]],
11801180 );
11811181}
11821182
......@@ -1691,7 +1691,7 @@ fn function() {
16911691 expect![[r#"
16921692 st FooStruct (use outer::FooStruct) BarStruct
16931693 md foo (use outer::foo)
1694 fn foo_fun() (use outer::foo_fun) fn()
1694 fn foo_fun() (use outer::foo_fun) fn()
16951695 "#]],
16961696 );
16971697}
......@@ -1720,3 +1720,45 @@ fn function() {
17201720 "#]],
17211721 );
17221722}
1723
1724#[test]
1725fn 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
1749pub mod intrinsics {
1750 extern "rust-intrinsic" {
1751 pub fn transmute<Src, Dst>(src: Src) -> Dst;
1752 }
1753}
1754pub mod mem {
1755 pub use crate::intrinsics::transmute;
1756}
1757//- /main.rs crate:main deps:core
1758fn 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) {}
140140 expect![[r#"
141141 st Bar
142142 bn Bar { bar }: Bar
143 bn Bar {…} Bar { bar$1 }: Bar$0
143 bn Bar {…} Bar { bar$1 }: Bar$0
144144 kw mut
145145 kw ref
146146 "#]],
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() {
2020impl Tra$0
2121"#,
2222 expect![[r#"
23 en Enum Enum
23 en Enum Enum
2424 ma makro!(…) macro_rules! makro
2525 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
2929 tt Trait
30 un Union Union
31 bt u32 u32
30 un Union Union
31 bt u32 u32
3232 kw crate::
3333 kw self::
3434 "#]],
......@@ -42,15 +42,15 @@ fn target_type_in_trait_impl_block() {
4242impl Trait for Str$0
4343"#,
4444 expect![[r#"
45 en Enum Enum
45 en Enum Enum
4646 ma makro!(…) macro_rules! makro
4747 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
5151 tt Trait
52 un Union Union
53 bt u32 u32
52 un Union Union
53 bt u32 u32
5454 kw crate::
5555 kw self::
5656 "#]],
src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs+9-9
......@@ -13,7 +13,7 @@ fn in_mod_item_list() {
1313 check(
1414 r#"mod tests { $0 }"#,
1515 expect![[r#"
16 ma makro!(…) macro_rules! makro
16 ma makro!(…) macro_rules! makro
1717 kw async
1818 kw const
1919 kw crate::
......@@ -46,7 +46,7 @@ fn in_source_file_item_list() {
4646 check(
4747 r#"$0"#,
4848 expect![[r#"
49 ma makro!(…) macro_rules! makro
49 ma makro!(…) macro_rules! makro
5050 md module
5151 kw async
5252 kw const
......@@ -79,7 +79,7 @@ fn in_item_list_after_attr() {
7979 check(
8080 r#"#[attr] $0"#,
8181 expect![[r#"
82 ma makro!(…) macro_rules! makro
82 ma makro!(…) macro_rules! makro
8383 md module
8484 kw async
8585 kw const
......@@ -182,7 +182,7 @@ fn in_impl_assoc_item_list() {
182182 check(
183183 r#"impl Struct { $0 }"#,
184184 expect![[r#"
185 ma makro!(…) macro_rules! makro
185 ma makro!(…) macro_rules! makro
186186 md module
187187 kw async
188188 kw const
......@@ -202,7 +202,7 @@ fn in_impl_assoc_item_list_after_attr() {
202202 check(
203203 r#"impl Struct { #[attr] $0 }"#,
204204 expect![[r#"
205 ma makro!(…) macro_rules! makro
205 ma makro!(…) macro_rules! makro
206206 md module
207207 kw async
208208 kw const
......@@ -315,7 +315,7 @@ impl Test for () {
315315 fn async fn function2()
316316 fn fn function1()
317317 fn fn function2()
318 ma makro!(…) macro_rules! makro
318 ma makro!(…) macro_rules! makro
319319 md module
320320 ta type Type1 =
321321 kw crate::
......@@ -381,7 +381,7 @@ fn after_unit_struct() {
381381 check(
382382 r#"struct S; f$0"#,
383383 expect![[r#"
384 ma makro!(…) macro_rules! makro
384 ma makro!(…) macro_rules! makro
385385 md module
386386 kw async
387387 kw const
......@@ -503,7 +503,7 @@ fn inside_extern_blocks() {
503503 check(
504504 r#"extern { $0 }"#,
505505 expect![[r#"
506 ma makro!(…) macro_rules! makro
506 ma makro!(…) macro_rules! makro
507507 md module
508508 kw crate::
509509 kw fn
......@@ -520,7 +520,7 @@ fn inside_extern_blocks() {
520520 check(
521521 r#"unsafe extern { $0 }"#,
522522 expect![[r#"
523 ma makro!(…) macro_rules! makro
523 ma makro!(…) macro_rules! makro
524524 md module
525525 kw crate::
526526 kw fn
src/tools/rust-analyzer/crates/ide-completion/src/tests/pattern.rs+35-35
......@@ -122,15 +122,15 @@ fn foo() {
122122 expect![[r#"
123123 ct CONST
124124 en Enum
125 ma makro!(…) macro_rules! makro
125 ma makro!(…) macro_rules! makro
126126 md module
127127 st Record
128128 st Tuple
129129 st Unit
130130 ev TupleV
131131 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
134134 kw mut
135135 kw ref
136136 "#]],
......@@ -151,15 +151,15 @@ fn foo() {
151151"#,
152152 expect![[r#"
153153 en SingleVariantEnum
154 ma makro!(…) macro_rules! makro
154 ma makro!(…) macro_rules! makro
155155 md module
156156 st Record
157157 st Tuple
158158 st Unit
159159 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
163163 kw mut
164164 kw ref
165165 "#]],
......@@ -174,13 +174,13 @@ fn foo(a$0) {
174174}
175175"#,
176176 expect![[r#"
177 ma makro!(…) macro_rules! makro
177 ma makro!(…) macro_rules! makro
178178 md module
179179 st Record
180180 st Tuple
181181 st Unit
182182 bn Record {…} Record { field$1 }: Record$0
183 bn Tuple(…) Tuple($1): Tuple$0
183 bn Tuple(…) Tuple($1): Tuple$0
184184 kw mut
185185 kw ref
186186 "#]],
......@@ -191,13 +191,13 @@ fn foo(a$0: Tuple) {
191191}
192192"#,
193193 expect![[r#"
194 ma makro!(…) macro_rules! makro
194 ma makro!(…) macro_rules! makro
195195 md module
196196 st Record
197197 st Tuple
198198 st Unit
199199 bn Record {…} Record { field$1 }$0
200 bn Tuple(…) Tuple($1)$0
200 bn Tuple(…) Tuple($1)$0
201201 bn tuple
202202 kw mut
203203 kw ref
......@@ -240,7 +240,7 @@ fn foo() {
240240 expect![[r#"
241241 en E
242242 ma m!(…) macro_rules! m
243 bn E::X E::X$0
243 bn E::X E::X$0
244244 kw mut
245245 kw ref
246246 "#]],
......@@ -268,7 +268,7 @@ fn outer() {
268268 st Record
269269 st Tuple
270270 bn Record {…} Record { field$1, .. }$0
271 bn Tuple(…) Tuple($1, ..)$0
271 bn Tuple(…) Tuple($1, ..)$0
272272 kw mut
273273 kw ref
274274 "#]],
......@@ -291,7 +291,7 @@ impl Foo {
291291 expect![[r#"
292292 sp Self
293293 st Foo
294 bn Foo(…) Foo($1)$0
294 bn Foo(…) Foo($1)$0
295295 bn Self(…) Self($1)$0
296296 kw mut
297297 kw ref
......@@ -315,8 +315,8 @@ fn func() {
315315 expect![[r#"
316316 ct ASSOC_CONST const ASSOC_CONST: ()
317317 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
320320 "#]],
321321 );
322322}
......@@ -332,7 +332,7 @@ fn outer(Foo { bar: $0 }: Foo) {}
332332 expect![[r#"
333333 st Bar
334334 st Foo
335 bn Bar(…) Bar($1)$0
335 bn Bar(…) Bar($1)$0
336336 bn Foo {…} Foo { bar$1 }$0
337337 kw mut
338338 kw ref
......@@ -395,7 +395,7 @@ fn foo($0) {}
395395 expect![[r#"
396396 st Bar
397397 st Foo
398 bn Bar(…) Bar($1): Bar$0
398 bn Bar(…) Bar($1): Bar$0
399399 bn Foo {…} Foo { bar$1 }: Foo$0
400400 kw mut
401401 kw ref
......@@ -416,7 +416,7 @@ fn foo() {
416416 expect![[r#"
417417 st Bar
418418 st Foo
419 bn Bar(…) Bar($1)$0
419 bn Bar(…) Bar($1)$0
420420 bn Foo {…} Foo { bar$1 }$0
421421 kw mut
422422 kw ref
......@@ -436,7 +436,7 @@ fn foo() {
436436}
437437"#,
438438 expect![[r#"
439 st Bar Bar
439 st Bar Bar
440440 kw crate::
441441 kw self::
442442 "#]],
......@@ -451,7 +451,7 @@ fn foo() {
451451}
452452"#,
453453 expect![[r#"
454 st Foo Foo
454 st Foo Foo
455455 kw crate::
456456 kw self::
457457 "#]],
......@@ -535,10 +535,10 @@ fn foo() {
535535"#,
536536 expect![[r#"
537537 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
540540 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
542542 kw mut
543543 kw ref
544544 "#]],
......@@ -559,10 +559,10 @@ fn foo() {
559559}
560560"#,
561561 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
564564 bn struct {…} r#struct { r#type$1 }$0
565 bn type r#type$0
565 bn type r#type$0
566566 "#]],
567567 );
568568}
......@@ -672,8 +672,8 @@ impl Ty {
672672 st Ty
673673 bn &mut self
674674 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
677677 bn mut self
678678 bn self
679679 kw mut
......@@ -693,8 +693,8 @@ impl Ty {
693693 st Ty
694694 bn &mut self
695695 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
698698 bn mut self
699699 bn self
700700 kw mut
......@@ -714,8 +714,8 @@ impl Ty {
714714 st Ty
715715 bn &mut self
716716 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
719719 bn mut self
720720 bn self
721721 kw mut
......@@ -734,7 +734,7 @@ impl Ty {
734734 sp Self
735735 st Ty
736736 bn Self(…) Self($1): Self$0
737 bn Ty(…) Ty($1): Ty$0
737 bn Ty(…) Ty($1): Ty$0
738738 kw mut
739739 kw ref
740740 "#]],
......@@ -763,7 +763,7 @@ fn f(x: EnumAlias<u8>) {
763763"#,
764764 expect![[r#"
765765 bn Tuple(…) Tuple($1)$0
766 bn Unit Unit$0
766 bn Unit Unit$0
767767 "#]],
768768 );
769769}
src/tools/rust-analyzer/crates/ide-completion/src/tests/predicate.rs+21-21
......@@ -16,16 +16,16 @@ fn predicate_start() {
1616struct Foo<'lt, T, const C: usize> where $0 {}
1717"#,
1818 expect![[r#"
19 en Enum Enum
19 en Enum Enum
2020 ma makro!(…) macro_rules! makro
2121 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
2626 tt Trait
27 un Union Union
28 bt u32 u32
27 un Union Union
28 bt u32 u32
2929 kw crate::
3030 kw self::
3131 "#]],
......@@ -89,16 +89,16 @@ fn param_list_for_for_pred() {
8989struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
9090"#,
9191 expect![[r#"
92 en Enum Enum
92 en Enum Enum
9393 ma makro!(…) macro_rules! makro
9494 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
9999 tt Trait
100 un Union Union
101 bt u32 u32
100 un Union Union
101 bt u32 u32
102102 kw crate::
103103 kw self::
104104 "#]],
......@@ -114,16 +114,16 @@ impl Record {
114114}
115115"#,
116116 expect![[r#"
117 en Enum Enum
117 en Enum Enum
118118 ma makro!(…) macro_rules! makro
119119 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
124124 tt Trait
125 un Union Union
126 bt u32 u32
125 un Union Union
126 bt u32 u32
127127 kw crate::
128128 kw self::
129129 "#]],
src/tools/rust-analyzer/crates/ide-completion/src/tests/proc_macros.rs+52-52
......@@ -24,19 +24,19 @@ fn main() {
2424}
2525"#,
2626 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 {}
4040 "#]],
4141 )
4242}
......@@ -57,19 +57,19 @@ fn main() {
5757}
5858"#,
5959 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 {}
7373 "#]],
7474 )
7575}
......@@ -92,19 +92,19 @@ impl Foo {
9292fn main() {}
9393"#,
9494 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 {}
108108 "#]],
109109 )
110110}
......@@ -127,19 +127,19 @@ impl Foo {
127127fn main() {}
128128"#,
129129 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 {}
143143 "#]],
144144 )
145145}
src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs+24-24
......@@ -70,8 +70,8 @@ fn foo(baz: Baz) {
7070 ev Ok
7171 bn Baz::Bar Baz::Bar$0
7272 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
7575 kw mut
7676 kw ref
7777 "#]],
......@@ -91,20 +91,20 @@ fn foo(baz: Baz) {
9191}
9292 "#,
9393 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 "#]],
108108 );
109109}
110110
......@@ -184,14 +184,14 @@ fn main() {
184184"#,
185185 expect![[r#"
186186 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
190190 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 }
193193 tt Default
194 bt u32 u32
194 bt u32 u32
195195 kw crate::
196196 kw self::
197197 ex Foo::default()
......@@ -238,8 +238,8 @@ fn main() {
238238"#,
239239 expect![[r#"
240240 fd ..Default::default()
241 fd foo1 u32
242 fd foo2 u32
241 fd foo1 u32
242 fd foo2 u32
243243 "#]],
244244 );
245245}
src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs+82-83
......@@ -87,7 +87,7 @@ pub mod prelude {
8787 expect![[r#"
8888 md std
8989 st Option Option
90 bt u32 u32
90 bt u32 u32
9191 "#]],
9292 );
9393}
......@@ -113,10 +113,10 @@ mod macros {
113113}
114114"#,
115115 expect![[r#"
116 fn f() fn()
116 fn f() fn()
117117 ma concat!(…) macro_rules! concat
118118 md std
119 bt u32 u32
119 bt u32 u32
120120 "#]],
121121 );
122122}
......@@ -146,7 +146,7 @@ pub mod prelude {
146146 md core
147147 md std
148148 st String String
149 bt u32 u32
149 bt u32 u32
150150 "#]],
151151 );
152152}
......@@ -174,7 +174,7 @@ pub mod prelude {
174174 expect![[r#"
175175 fn f() fn()
176176 md std
177 bt u32 u32
177 bt u32 u32
178178 "#]],
179179 );
180180}
......@@ -226,9 +226,9 @@ impl S {
226226fn foo() { let _ = lib::S::$0 }
227227"#,
228228 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
232232 "#]],
233233 );
234234}
......@@ -317,14 +317,14 @@ trait Sub: Super {
317317fn foo<T: Sub>() { T::$0 }
318318"#,
319319 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)
326326 ta SubTy (as Sub) type SubTy
327 ta Ty (as Super) type Ty
327 ta Ty (as Super) type Ty
328328 "#]],
329329 );
330330}
......@@ -357,14 +357,14 @@ impl<T> Sub for Wrap<T> {
357357}
358358"#,
359359 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)
366366 ta SubTy (as Sub) type SubTy
367 ta Ty (as Super) type Ty
367 ta Ty (as Super) type Ty
368368 "#]],
369369 );
370370}
......@@ -381,9 +381,9 @@ impl T { fn bar() {} }
381381fn main() { T::$0; }
382382"#,
383383 expect![[r#"
384 fn bar() fn()
385 fn foo() fn()
386 "#]],
384 fn bar() fn()
385 fn foo() fn()
386 "#]],
387387 );
388388}
389389
......@@ -397,7 +397,7 @@ macro_rules! foo { () => {} }
397397fn main() { let _ = crate::$0 }
398398"#,
399399 expect![[r#"
400 fn main() fn()
400 fn main() fn()
401401 ma foo!(…) macro_rules! foo
402402 "#]],
403403 );
......@@ -447,9 +447,9 @@ mod p {
447447}
448448"#,
449449 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
453453 "#]],
454454 );
455455
......@@ -495,9 +495,9 @@ fn main() { m!(self::f$0); }
495495fn foo() {}
496496"#,
497497 expect![[r#"
498 fn foo() fn()
499 fn main() fn()
500 "#]],
498 fn foo() fn()
499 fn main() fn()
500 "#]],
501501 );
502502}
503503
......@@ -513,9 +513,9 @@ mod m {
513513}
514514"#,
515515 expect![[r#"
516 fn z() fn()
517 md z
518 "#]],
516 fn z() fn()
517 md z
518 "#]],
519519 );
520520}
521521
......@@ -534,8 +534,8 @@ fn foo() {
534534}
535535"#,
536536 expect![[r#"
537 fn new() fn() -> HashMap<K, V, RandomState>
538 "#]],
537 fn new() fn() -> HashMap<K, V, RandomState>
538 "#]],
539539 );
540540}
541541
......@@ -557,8 +557,8 @@ impl Foo {
557557"#,
558558 expect![[r#"
559559 me foo(…) fn(self)
560 ev Bar Bar
561 ev Baz Baz
560 ev Bar Bar
561 ev Baz Baz
562562 "#]],
563563 );
564564}
......@@ -578,9 +578,9 @@ fn foo(self) {
578578}
579579"#,
580580 expect![[r#"
581 ev Bar Bar
582 ev Baz Baz
583 "#]],
581 ev Bar Bar
582 ev Baz Baz
583 "#]],
584584 );
585585
586586 check_no_kw(
......@@ -598,8 +598,8 @@ enum Foo {
598598}
599599"#,
600600 expect![[r#"
601 ev Baz Baz
602 "#]],
601 ev Baz Baz
602 "#]],
603603 );
604604}
605605
......@@ -623,9 +623,9 @@ impl u8 {
623623}
624624"#,
625625 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 "#]],
629629 );
630630}
631631
......@@ -643,8 +643,8 @@ fn main() {
643643}
644644"#,
645645 expect![[r#"
646 ev Bar Bar
647 "#]],
646 ev Bar Bar
647 "#]],
648648 );
649649}
650650
......@@ -723,7 +723,7 @@ fn bar() -> Bar {
723723}
724724"#,
725725 expect![[r#"
726 fn bar() fn()
726 fn bar() fn()
727727 fn foo() (as Foo) fn() -> Self
728728 ex Bar
729729 ex bar()
......@@ -787,7 +787,7 @@ fn main() {
787787}
788788"#,
789789 expect![[r#"
790 me by_macro() (as MyTrait) fn(&self)
790 me by_macro() (as MyTrait) fn(&self)
791791 me not_by_macro() (as MyTrait) fn(&self)
792792 "#]],
793793 )
......@@ -827,7 +827,7 @@ fn main() {
827827}
828828"#,
829829 expect![[r#"
830 me by_macro() (as MyTrait) fn(&self)
830 me by_macro() (as MyTrait) fn(&self)
831831 me not_by_macro() (as MyTrait) fn(&self)
832832 "#]],
833833 )
......@@ -885,10 +885,10 @@ fn main() {
885885}
886886"#,
887887 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
892892 "#]],
893893 )
894894}
......@@ -1014,7 +1014,7 @@ fn here_we_go() {
10141014}
10151015"#,
10161016 expect![[r#"
1017 fn here_we_go() fn()
1017 fn here_we_go() fn()
10181018 st Foo (alias Bar) Foo
10191019 bt u32 u32
10201020 kw async
......@@ -1064,9 +1064,9 @@ fn here_we_go() {
10641064}
10651065"#,
10661066 expect![[r#"
1067 fn here_we_go() fn()
1067 fn here_we_go() fn()
10681068 st Foo (alias Bar, Qux, Baz) Foo
1069 bt u32 u32
1069 bt u32 u32
10701070 kw async
10711071 kw const
10721072 kw crate::
......@@ -1160,20 +1160,20 @@ fn here_we_go() {
11601160}
11611161"#,
11621162 expect![[r#"
1163 fd bar u8
1163 fd bar u8
11641164 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 {}
11771177 "#]],
11781178 );
11791179}
......@@ -1189,7 +1189,7 @@ fn bar() { qu$0 }
11891189 expect![[r#"
11901190 fn bar() fn()
11911191 fn foo() (alias qux) fn()
1192 bt u32 u32
1192 bt u32 u32
11931193 kw async
11941194 kw const
11951195 kw crate::
......@@ -1277,10 +1277,10 @@ fn here_we_go() {
12771277}
12781278"#,
12791279 expect![[r#"
1280 fn here_we_go() fn()
1280 fn here_we_go() fn()
12811281 md foo
12821282 st Bar (alias Qux) (use foo::Bar) Bar
1283 bt u32 u32
1283 bt u32 u32
12841284 kw crate::
12851285 kw false
12861286 kw for
......@@ -1315,10 +1315,9 @@ use krate::e;
13151315fn main() {
13161316 e::$0
13171317}"#,
1318 expect![
1319 "fn i_am_public() fn()
1320"
1321 ],
1318 expect![[r#"
1319 fn i_am_public() fn()
1320 "#]],
13221321 )
13231322}
13241323
......@@ -1444,8 +1443,8 @@ fn foo() {
14441443"#,
14451444 Some('_'),
14461445 expect![[r#"
1447 fn foo() fn()
1448 bt u32 u32
1446 fn foo() fn()
1447 bt u32 u32
14491448 kw async
14501449 kw const
14511450 kw crate::
......@@ -1498,7 +1497,7 @@ fn foo(_: a_$0) { }
14981497"#,
14991498 Some('_'),
15001499 expect![[r#"
1501 bt u32 u32
1500 bt u32 u32
15021501 kw crate::
15031502 kw self::
15041503 "#]],
......@@ -1512,7 +1511,7 @@ fn foo<T>() {
15121511 Some('_'),
15131512 expect![[r#"
15141513 tp T
1515 bt u32 u32
1514 bt u32 u32
15161515 kw crate::
15171516 kw self::
15181517 "#]],
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> {
1717}
1818"#,
1919 expect![[r#"
20 en Enum Enum
20 en Enum Enum
2121 ma makro!(…) macro_rules! makro
2222 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
2828 tt Trait
2929 tp T
30 un Union Union
31 bt u32 u32
30 un Union Union
31 bt u32 u32
3232 kw crate::
3333 kw self::
3434 "#]],
......@@ -42,18 +42,18 @@ fn tuple_struct_field() {
4242struct Foo<'lt, T, const C: usize>(f$0);
4343"#,
4444 expect![[r#"
45 en Enum Enum
46 ma makro!(…) macro_rules! makro
45 en Enum Enum
46 ma makro!(…) macro_rules! makro
4747 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
5353 tt Trait
5454 tp T
55 un Union Union
56 bt u32 u32
55 un Union Union
56 bt u32 u32
5757 kw crate::
5858 kw pub
5959 kw pub(crate)
......@@ -70,16 +70,16 @@ fn fn_return_type() {
7070fn x<'lt, T, const C: usize>() -> $0
7171"#,
7272 expect![[r#"
73 en Enum Enum
73 en Enum Enum
7474 ma makro!(…) macro_rules! makro
7575 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
7979 tt Trait
8080 tp T
81 un Union Union
82 bt u32 u32
81 un Union Union
82 bt u32 u32
8383 kw crate::
8484 kw self::
8585 "#]],
......@@ -100,15 +100,15 @@ fn foo() -> B$0 {
100100}
101101"#,
102102 expect![[r#"
103 en Enum Enum
103 en Enum Enum
104104 ma makro!(…) macro_rules! makro
105105 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
109109 tt Trait
110 un Union Union
111 bt u32 u32
110 un Union Union
111 bt u32 u32
112112 it ()
113113 kw crate::
114114 kw self::
......@@ -124,16 +124,16 @@ struct Foo<T>(T);
124124const FOO: $0 = Foo(2);
125125"#,
126126 expect![[r#"
127 en Enum Enum
127 en Enum Enum
128128 ma makro!(…) macro_rules! makro
129129 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
134134 tt Trait
135 un Union Union
136 bt u32 u32
135 un Union Union
136 bt u32 u32
137137 it Foo<i32>
138138 kw crate::
139139 kw self::
......@@ -151,15 +151,15 @@ fn f2() {
151151}
152152"#,
153153 expect![[r#"
154 en Enum Enum
154 en Enum Enum
155155 ma makro!(…) macro_rules! makro
156156 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
160160 tt Trait
161 un Union Union
162 bt u32 u32
161 un Union Union
162 bt u32 u32
163163 it i32
164164 kw crate::
165165 kw self::
......@@ -179,15 +179,15 @@ fn f2() {
179179}
180180"#,
181181 expect![[r#"
182 en Enum Enum
182 en Enum Enum
183183 ma makro!(…) macro_rules! makro
184184 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
188188 tt Trait
189 un Union Union
190 bt u32 u32
189 un Union Union
190 bt u32 u32
191191 it u64
192192 kw crate::
193193 kw self::
......@@ -204,15 +204,15 @@ fn f2(x: u64) -> $0 {
204204}
205205"#,
206206 expect![[r#"
207 en Enum Enum
207 en Enum Enum
208208 ma makro!(…) macro_rules! makro
209209 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
213213 tt Trait
214 un Union Union
215 bt u32 u32
214 un Union Union
215 bt u32 u32
216216 it u64
217217 kw crate::
218218 kw self::
......@@ -230,15 +230,15 @@ fn f2(x: $0) {
230230}
231231"#,
232232 expect![[r#"
233 en Enum Enum
233 en Enum Enum
234234 ma makro!(…) macro_rules! makro
235235 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
239239 tt Trait
240 un Union Union
241 bt u32 u32
240 un Union Union
241 bt u32 u32
242242 it i32
243243 kw crate::
244244 kw self::
......@@ -262,17 +262,17 @@ fn foo<'lt, T, const C: usize>() {
262262}
263263"#,
264264 expect![[r#"
265 en Enum Enum
266 ma makro!(…) macro_rules! makro
265 en Enum Enum
266 ma makro!(…) macro_rules! makro
267267 md a
268268 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
272272 tt Trait
273273 tp T
274 un Union Union
275 bt u32 u32
274 un Union Union
275 bt u32 u32
276276 it a::Foo<a::Foo<i32>>
277277 kw crate::
278278 kw self::
......@@ -291,17 +291,17 @@ fn foo<'lt, T, const C: usize>() {
291291}
292292"#,
293293 expect![[r#"
294 en Enum Enum
294 en Enum Enum
295295 ma makro!(…) macro_rules! makro
296296 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
301301 tt Trait
302302 tp T
303 un Union Union
304 bt u32 u32
303 un Union Union
304 bt u32 u32
305305 it Foo<i32>
306306 kw crate::
307307 kw self::
......@@ -319,16 +319,16 @@ fn foo<'lt, T, const C: usize>() {
319319}
320320"#,
321321 expect![[r#"
322 en Enum Enum
322 en Enum Enum
323323 ma makro!(…) macro_rules! makro
324324 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
328328 tt Trait
329329 tp T
330 un Union Union
331 bt u32 u32
330 un Union Union
331 bt u32 u32
332332 kw crate::
333333 kw self::
334334 "#]],
......@@ -341,14 +341,14 @@ fn foo<'lt, T, const C: usize>() {
341341}
342342"#,
343343 expect![[r#"
344 en Enum Enum
344 en Enum Enum
345345 ma makro!(…) macro_rules! makro
346346 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
350350 tt Trait
351 un Union Union
351 un Union Union
352352 "#]],
353353 );
354354}
......@@ -368,7 +368,7 @@ trait Trait2: Trait1 {
368368fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
369369"#,
370370 expect![[r#"
371 ta Foo = (as Trait2) type Foo
371 ta Foo = (as Trait2) type Foo
372372 ta Super = (as Trait1) type Super
373373 "#]],
374374 );
......@@ -384,18 +384,18 @@ trait Trait2<T>: Trait1 {
384384fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
385385"#,
386386 expect![[r#"
387 en Enum Enum
387 en Enum Enum
388388 ma makro!(…) macro_rules! makro
389389 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
393393 tt Trait
394394 tt Trait1
395395 tt Trait2
396396 tp T
397 un Union Union
398 bt u32 u32
397 un Union Union
398 bt u32 u32
399399 kw crate::
400400 kw self::
401401 "#]],
......@@ -409,15 +409,15 @@ trait Trait2<T> {
409409fn foo<'lt, T: Trait2<self::$0>, const CONST_PARAM: usize>(_: T) {}
410410 "#,
411411 expect![[r#"
412 en Enum Enum
412 en Enum Enum
413413 ma makro!(…) macro_rules! makro
414414 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
418418 tt Trait
419419 tt Trait2
420 un Union Union
420 un Union Union
421421 "#]],
422422 );
423423}
......@@ -434,18 +434,18 @@ trait Tr<T> {
434434impl Tr<$0
435435 "#,
436436 expect![[r#"
437 en Enum Enum
437 en Enum Enum
438438 ma makro!(…) macro_rules! makro
439439 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
445445 tt Tr
446446 tt Trait
447 un Union Union
448 bt u32 u32
447 un Union Union
448 bt u32 u32
449449 kw crate::
450450 kw self::
451451 "#]],
......@@ -481,16 +481,16 @@ trait MyTrait<T, U> {
481481fn f(t: impl MyTrait<u$0
482482"#,
483483 expect![[r#"
484 en Enum Enum
484 en Enum Enum
485485 ma makro!(…) macro_rules! makro
486486 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
490490 tt MyTrait
491491 tt Trait
492 un Union Union
493 bt u32 u32
492 un Union Union
493 bt u32 u32
494494 kw crate::
495495 kw self::
496496 "#]],
......@@ -506,16 +506,16 @@ trait MyTrait<T, U> {
506506fn f(t: impl MyTrait<u8, u$0
507507"#,
508508 expect![[r#"
509 en Enum Enum
509 en Enum Enum
510510 ma makro!(…) macro_rules! makro
511511 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
515515 tt MyTrait
516516 tt Trait
517 un Union Union
518 bt u32 u32
517 un Union Union
518 bt u32 u32
519519 kw crate::
520520 kw self::
521521 "#]],
......@@ -549,16 +549,16 @@ trait MyTrait<T, U = u8> {
549549fn f(t: impl MyTrait<u$0
550550"#,
551551 expect![[r#"
552 en Enum Enum
552 en Enum Enum
553553 ma makro!(…) macro_rules! makro
554554 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
558558 tt MyTrait
559559 tt Trait
560 un Union Union
561 bt u32 u32
560 un Union Union
561 bt u32 u32
562562 kw crate::
563563 kw self::
564564 "#]],
......@@ -574,18 +574,18 @@ trait MyTrait<T, U = u8> {
574574fn f(t: impl MyTrait<u8, u$0
575575"#,
576576 expect![[r#"
577 en Enum Enum
578 ma makro!(…) macro_rules! makro
577 en Enum Enum
578 ma makro!(…) macro_rules! makro
579579 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
583583 tt MyTrait
584584 tt Trait
585585 ta Item1 = (as MyTrait) type Item1
586586 ta Item2 = (as MyTrait) type Item2
587 un Union Union
588 bt u32 u32
587 un Union Union
588 bt u32 u32
589589 kw crate::
590590 kw self::
591591 "#]],
......@@ -619,16 +619,16 @@ trait MyTrait {
619619fn f(t: impl MyTrait<Item1 = $0
620620"#,
621621 expect![[r#"
622 en Enum Enum
622 en Enum Enum
623623 ma makro!(…) macro_rules! makro
624624 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
628628 tt MyTrait
629629 tt Trait
630 un Union Union
631 bt u32 u32
630 un Union Union
631 bt u32 u32
632632 kw crate::
633633 kw self::
634634 "#]],
......@@ -644,16 +644,16 @@ trait MyTrait {
644644fn f(t: impl MyTrait<Item1 = u8, Item2 = $0
645645"#,
646646 expect![[r#"
647 en Enum Enum
647 en Enum Enum
648648 ma makro!(…) macro_rules! makro
649649 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
653653 tt MyTrait
654654 tt Trait
655 un Union Union
656 bt u32 u32
655 un Union Union
656 bt u32 u32
657657 kw crate::
658658 kw self::
659659 "#]],
......@@ -668,7 +668,7 @@ trait MyTrait {
668668fn f(t: impl MyTrait<C = $0
669669"#,
670670 expect![[r#"
671 ct CONST Unit
671 ct CONST Unit
672672 ma makro!(…) macro_rules! makro
673673 kw crate::
674674 kw self::
......@@ -691,9 +691,9 @@ pub struct S;
691691"#,
692692 expect![[r#"
693693 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
697697 kw crate::
698698 kw self::
699699 "#]],
......@@ -716,10 +716,10 @@ pub struct S;
716716"#,
717717 expect![[r#"
718718 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
723723 kw crate::
724724 kw self::
725725 "#]],
......@@ -739,16 +739,16 @@ fn completes_const_and_type_generics_separately() {
739739 }
740740 "#,
741741 expect![[r#"
742 en Enum Enum
742 en Enum Enum
743743 ma makro!(…) macro_rules! makro
744744 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
749749 tt Trait
750 un Union Union
751 bt u32 u32
750 un Union Union
751 bt u32 u32
752752 kw crate::
753753 kw self::
754754 "#]],
......@@ -766,8 +766,8 @@ fn completes_const_and_type_generics_separately() {
766766 }
767767 "#,
768768 expect![[r#"
769 ct CONST Unit
770 ct X usize
769 ct CONST Unit
770 ct X usize
771771 ma makro!(…) macro_rules! makro
772772 kw crate::
773773 kw self::
......@@ -785,16 +785,16 @@ fn completes_const_and_type_generics_separately() {
785785 }
786786 "#,
787787 expect![[r#"
788 en Enum Enum
788 en Enum Enum
789789 ma makro!(…) macro_rules! makro
790790 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
795795 tt Trait
796 un Union Union
797 bt u32 u32
796 un Union Union
797 bt u32 u32
798798 kw crate::
799799 kw self::
800800 "#]],
......@@ -809,8 +809,8 @@ fn completes_const_and_type_generics_separately() {
809809 }
810810 "#,
811811 expect![[r#"
812 ct CONST Unit
813 ct X usize
812 ct CONST Unit
813 ct X usize
814814 ma makro!(…) macro_rules! makro
815815 kw crate::
816816 kw self::
......@@ -828,17 +828,17 @@ fn completes_const_and_type_generics_separately() {
828828 fn foo(_: impl Bar<Baz<F$0, 0> = ()>) {}
829829 "#,
830830 expect![[r#"
831 en Enum Enum
831 en Enum Enum
832832 ma makro!(…) macro_rules! makro
833833 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
838838 tt Bar
839839 tt Trait
840 un Union Union
841 bt u32 u32
840 un Union Union
841 bt u32 u32
842842 kw crate::
843843 kw self::
844844 "#]],
......@@ -853,8 +853,8 @@ fn completes_const_and_type_generics_separately() {
853853 fn foo<T: Bar<Baz<(), $0> = ()>>() {}
854854 "#,
855855 expect![[r#"
856 ct CONST Unit
857 ct X usize
856 ct CONST Unit
857 ct X usize
858858 ma makro!(…) macro_rules! makro
859859 kw crate::
860860 kw self::
......@@ -871,8 +871,8 @@ fn completes_const_and_type_generics_separately() {
871871 }
872872 "#,
873873 expect![[r#"
874 ct CONST Unit
875 ct X usize
874 ct CONST Unit
875 ct X usize
876876 ma makro!(…) macro_rules! makro
877877 kw crate::
878878 kw self::
......@@ -890,8 +890,8 @@ fn completes_const_and_type_generics_separately() {
890890 }
891891 "#,
892892 expect![[r#"
893 ct CONST Unit
894 ct X usize
893 ct CONST Unit
894 ct X usize
895895 ma makro!(…) macro_rules! makro
896896 kw crate::
897897 kw self::
......@@ -908,8 +908,8 @@ fn completes_const_and_type_generics_separately() {
908908 }
909909 "#,
910910 expect![[r#"
911 ct CONST Unit
912 ct X usize
911 ct CONST Unit
912 ct X usize
913913 ma makro!(…) macro_rules! makro
914914 kw crate::
915915 kw self::
......@@ -924,8 +924,8 @@ fn completes_const_and_type_generics_separately() {
924924 impl Foo<(), $0> for () {}
925925 "#,
926926 expect![[r#"
927 ct CONST Unit
928 ct X usize
927 ct CONST Unit
928 ct X usize
929929 ma makro!(…) macro_rules! makro
930930 kw crate::
931931 kw self::
......@@ -942,8 +942,8 @@ fn completes_const_and_type_generics_separately() {
942942 fn foo<T: Bar<X$0, ()>>() {}
943943 "#,
944944 expect![[r#"
945 ct CONST Unit
946 ct X usize
945 ct CONST Unit
946 ct X usize
947947 ma makro!(…) macro_rules! makro
948948 kw crate::
949949 kw self::
......@@ -957,7 +957,7 @@ struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
957957fn foo<'a>() { S::<F$0, _>; }
958958 "#,
959959 expect![[r#"
960 ct CONST Unit
960 ct CONST Unit
961961 ma makro!(…) macro_rules! makro
962962 kw crate::
963963 kw self::
......@@ -970,7 +970,7 @@ struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
970970fn foo<'a>() { S::<'static, 'static, F$0, _>; }
971971 "#,
972972 expect![[r#"
973 ct CONST Unit
973 ct CONST Unit
974974 ma makro!(…) macro_rules! makro
975975 kw crate::
976976 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};
9292"#,
9393 expect![[r#"
9494 md foo
95 st S S
95 st S S
9696 "#]],
9797 );
9898}
......@@ -179,7 +179,7 @@ struct Bar;
179179"#,
180180 expect![[r#"
181181 ma foo macro_rules! foo_
182 st Foo Foo
182 st Foo Foo
183183 "#]],
184184 );
185185}
......@@ -203,8 +203,8 @@ impl Foo {
203203"#,
204204 expect![[r#"
205205 ev RecordVariant RecordVariant
206 ev TupleVariant TupleVariant
207 ev UnitVariant UnitVariant
206 ev TupleVariant TupleVariant
207 ev UnitVariant UnitVariant
208208 "#]],
209209 );
210210}
......@@ -257,7 +257,7 @@ mod a {
257257}
258258"#,
259259 expect![[r#"
260 ct A usize
260 ct A usize
261261 md b
262262 kw super::
263263 "#]],
......@@ -450,9 +450,9 @@ pub fn foo() {}
450450marco_rules! m { () => {} }
451451"#,
452452 expect![[r#"
453 fn foo fn()
453 fn foo fn()
454454 md simd
455 st S S
455 st S S
456456 "#]],
457457 );
458458}
src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs+97-116
......@@ -2,10 +2,10 @@
22
33use hir::{
44 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,
66 SemanticsScope, Trait, TyFingerprint, Type,
77};
8use itertools::{EitherOrBoth, Itertools};
8use itertools::Itertools;
99use rustc_hash::{FxHashMap, FxHashSet};
1010use syntax::{
1111 ast::{self, make, HasName},
......@@ -13,7 +13,6 @@ use syntax::{
1313};
1414
1515use crate::{
16 helpers::item_name,
1716 items_locator::{self, AssocSearchMode, DEFAULT_QUERY_SEARCH_LIMIT},
1817 FxIndexSet, RootDatabase,
1918};
......@@ -52,7 +51,7 @@ pub struct TraitImportCandidate {
5251#[derive(Debug)]
5352pub struct PathImportCandidate {
5453 /// Optional qualifier before name.
55 pub qualifier: Option<Vec<SmolStr>>,
54 pub qualifier: Vec<SmolStr>,
5655 /// The name the item (struct, trait, enum, etc.) should have.
5756 pub name: NameToImport,
5857}
......@@ -264,7 +263,6 @@ impl ImportAssets {
264263 Some(it) => it,
265264 None => return <FxIndexSet<_>>::default().into_iter(),
266265 };
267
268266 let krate = self.module_with_candidate.krate();
269267 let scope_definitions = self.scope_definitions(sema);
270268 let mod_path = |item| {
......@@ -279,11 +277,14 @@ impl ImportAssets {
279277 };
280278
281279 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 ),
287288 ImportCandidate::TraitAssocItem(trait_candidate)
288289 | ImportCandidate::TraitMethod(trait_candidate) => trait_applicable_items(
289290 sema,
......@@ -315,6 +316,7 @@ impl ImportAssets {
315316
316317fn path_applicable_imports(
317318 sema: &Semantics<'_, RootDatabase>,
319 scope: &SemanticsScope<'_>,
318320 current_crate: Crate,
319321 path_candidate: &PathImportCandidate,
320322 mod_path: impl Fn(ItemInNs) -> Option<ModPath> + Copy,
......@@ -322,8 +324,8 @@ fn path_applicable_imports(
322324) -> FxIndexSet<LocatedImport> {
323325 let _p = tracing::info_span!("ImportAssets::path_applicable_imports").entered();
324326
325 match &path_candidate.qualifier {
326 None => {
327 match &*path_candidate.qualifier {
328 [] => {
327329 items_locator::items_with_name(
328330 sema,
329331 current_crate,
......@@ -348,89 +350,107 @@ fn path_applicable_imports(
348350 .take(DEFAULT_QUERY_SEARCH_LIMIT.inner())
349351 .collect()
350352 }
351 Some(qualifier) => items_locator::items_with_name(
353 [first_qsegment, qualifier_rest @ ..] => items_locator::items_with_name(
352354 sema,
353355 current_crate,
354 path_candidate.name.clone(),
355 AssocSearchMode::Include,
356 NameToImport::Exact(first_qsegment.to_string(), true),
357 AssocSearchMode::Exclude,
356358 )
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 })
358370 .take(DEFAULT_QUERY_SEARCH_LIMIT.inner())
359371 .collect(),
360372 }
361373}
362374
363375fn import_for_item(
364 db: &RootDatabase,
376 sema: &Semantics<'_, RootDatabase>,
377 scope: &SemanticsScope<'_>,
365378 mod_path: impl Fn(ItemInNs) -> Option<ModPath>,
379 candidate: &NameToImport,
380 resolved_qualifier: ItemInNs,
366381 unresolved_qualifier: &[SmolStr],
367 original_item: ItemInNs,
368382 scope_filter: impl Fn(ItemInNs) -> bool,
369383) -> Option<LocatedImport> {
370384 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);
374385
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,
383397 }
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;
403398 }
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 }
414399
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,
423403 }
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))
426416 }
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;
429430 }
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;
432448 }
433 _ => return None,
449 Some(LocatedImport::new(
450 import_path_candidate.clone(),
451 resolved_qualifier,
452 assoc_to_item(assoc),
453 ))
434454 })
435455}
436456
......@@ -453,45 +473,6 @@ fn item_for_path_search_assoc(db: &RootDatabase, assoc_item: AssocItem) -> Optio
453473 })
454474}
455475
456fn 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
474fn 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
495476fn trait_applicable_items(
496477 sema: &Semantics<'_, RootDatabase>,
497478 current_crate: Crate,
......@@ -703,7 +684,7 @@ impl ImportCandidate {
703684 return None;
704685 }
705686 Some(ImportCandidate::Path(PathImportCandidate {
706 qualifier: None,
687 qualifier: vec![],
707688 name: NameToImport::exact_case_sensitive(name.to_string()),
708689 }))
709690 }
......@@ -730,7 +711,7 @@ fn path_import_candidate(
730711 .segments()
731712 .map(|seg| seg.name_ref().map(|name| SmolStr::new(name.text())))
732713 .collect::<Option<Vec<_>>>()?;
733 ImportCandidate::Path(PathImportCandidate { qualifier: Some(qualifier), name })
714 ImportCandidate::Path(PathImportCandidate { qualifier, name })
734715 } else {
735716 return None;
736717 }
......@@ -754,10 +735,10 @@ fn path_import_candidate(
754735 }
755736 Some(_) => return None,
756737 },
757 None => ImportCandidate::Path(PathImportCandidate { qualifier: None, name }),
738 None => ImportCandidate::Path(PathImportCandidate { qualifier: vec![], name }),
758739 })
759740}
760741
761742fn 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)
763744}
src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs+55-4
......@@ -3,10 +3,14 @@
33//! The main reason for this module to exist is the fact that project's items and dependencies' items
44//! are located in different caches, with different APIs.
55use either::Either;
6use hir::{import_map, Crate, ItemInNs, Semantics};
6use hir::{import_map, Crate, ItemInNs, Module, Semantics};
77use limit::Limit;
88
9use crate::{imports::import_assets::NameToImport, symbol_index, RootDatabase};
9use crate::{
10 imports::import_assets::NameToImport,
11 symbol_index::{self, SymbolsDatabase as _},
12 RootDatabase,
13};
1014
1115/// A value to use, when uncertain which limit to pick.
1216pub static DEFAULT_QUERY_SEARCH_LIMIT: Limit = Limit::new(100);
......@@ -20,8 +24,7 @@ pub fn items_with_name<'a>(
2024 name: NameToImport,
2125 assoc_item_search: AssocSearchMode,
2226) -> 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()))
2528 .entered();
2629
2730 let prefix = matches!(name, NameToImport::Prefix(..));
......@@ -66,6 +69,54 @@ pub fn items_with_name<'a>(
6669 find_items(sema, krate, local_query, external_query)
6770}
6871
72/// Searches for importable items with the given name in the crate and its dependencies.
73pub 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
69120fn find_items<'a>(
70121 sema: &'a Semantics<'_, RootDatabase>,
71122 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
377377 return None;
378378 }
379379 name
380 } else if let Some(inner_ty) = ty.remove_ref() {
381 return name_of_type(&inner_ty, db, edition);
380382 } else {
381383 return None;
382384 };
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs+16
......@@ -778,4 +778,20 @@ fn bar(mut v: Union2) {
778778 "#,
779779 )
780780 }
781
782 #[test]
783 fn raw_ref_reborrow_is_safe() {
784 check_diagnostics(
785 r#"
786fn 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 }
781797}
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
9090 make::ty("()")
9191 };
9292
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 {
9496 return None;
9597 }
9698
......@@ -501,4 +503,19 @@ fn main() {}
501503 "#,
502504 )
503505 }
506
507 #[test]
508 fn regression_18683() {
509 check_diagnostics(
510 r#"
511struct S;
512impl S {
513 fn f(self) {
514 self.self
515 // ^^^^ error: no field `self` on type `S`
516 }
517}
518 "#,
519 );
520 }
504521}
src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_ident.rs+8-8
......@@ -7,20 +7,19 @@ pub(crate) fn unresolved_ident(
77 ctx: &DiagnosticsContext<'_>,
88 d: &hir::UnresolvedIdent,
99) -> 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()
1717}
1818
1919#[cfg(test)]
2020mod tests {
2121 use crate::tests::check_diagnostics;
2222
23 // FIXME: This should show a diagnostic
2423 #[test]
2524 fn feature() {
2625 check_diagnostics(
......@@ -28,6 +27,7 @@ mod tests {
2827//- minicore: fmt
2928fn main() {
3029 format_args!("{unresolved}");
30 // ^^^^^^^^^^ error: no such value in this scope
3131}
3232"#,
3333 )
src/tools/rust-analyzer/crates/ide/src/runnables.rs+3-16
......@@ -16,7 +16,7 @@ use ide_db::{
1616};
1717use itertools::Itertools;
1818use span::{Edition, TextSize};
19use stdx::{always, format_to};
19use stdx::format_to;
2020use syntax::{
2121 ast::{self, AstNode},
2222 SmolStr, SyntaxNode, ToSmolStr,
......@@ -130,14 +130,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
130130 // In case an expansion creates multiple runnables we want to name them to avoid emitting a bunch of equally named runnables.
131131 let mut in_macro_expansion = FxHashMap::<hir::HirFileId, Vec<Runnable>>::default();
132132 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) {
141134 if let Some(def) = def {
142135 let file_id = match def {
143136 Definition::Module(it) => {
......@@ -161,13 +154,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
161154 Definition::SelfType(impl_) => runnable_impl(&sema, &impl_),
162155 _ => None,
163156 };
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));
171158 if let Definition::SelfType(impl_) = def {
172159 impl_.items(db).into_iter().for_each(|assoc| {
173160 let runnable = match assoc {
src/tools/rust-analyzer/crates/ide/src/typing.rs+19
......@@ -174,6 +174,9 @@ fn on_delimited_node_typed(
174174 kinds: &[fn(SyntaxKind) -> bool],
175175) -> Option<TextEdit> {
176176 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 }
177180 let (filter, node) = t
178181 .parent_ancestors()
179182 .take_while(|n| n.text_range().start() == offset)
......@@ -1091,6 +1094,22 @@ fn f() {
10911094 );
10921095 }
10931096
1097 #[test]
1098 fn preceding_whitespace_is_significant_for_closing_brackets() {
1099 type_char_noop(
1100 '(',
1101 r#"
1102fn f() { a.b$0if true {} }
1103"#,
1104 );
1105 type_char_noop(
1106 '(',
1107 r#"
1108fn f() { foo$0{} }
1109"#,
1110 );
1111 }
1112
10941113 #[test]
10951114 fn adds_closing_parenthesis_for_pat() {
10961115 type_char(
src/tools/rust-analyzer/crates/load-cargo/src/lib.rs+1-1
......@@ -487,7 +487,7 @@ impl ProcMacroExpander for Expander {
487487 match self.0.expand(
488488 subtree,
489489 attrs,
490 env.clone(),
490 env.clone().into(),
491491 def_site,
492492 call_site,
493493 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
7272 // macro_rules! ()
7373 // macro_rules! []
7474 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 }
7788 }
7889
7990 m.abandon(p);
......@@ -410,8 +421,7 @@ fn fn_(p: &mut Parser<'_>, m: Marker) {
410421}
411422
412423fn 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![!]));
415425 match macro_call_after_excl(p) {
416426 BlockLike::Block => (),
417427 BlockLike::NotBlock => {
src/tools/rust-analyzer/crates/parser/src/tests/top_entries.rs+14-16
......@@ -30,22 +30,20 @@ fn source_file() {
3030 TopEntryPoint::SourceFile,
3131 "@error@",
3232 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 "#]],
4947 );
5048}
5149
src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs+4
......@@ -775,6 +775,10 @@ mod err {
775775 run_and_expect_errors("test_data/parser/inline/err/missing_fn_param_type.rs");
776776 }
777777 #[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]
778782 fn pointer_type_no_mutability() {
779783 run_and_expect_errors("test_data/parser/inline/err/pointer_type_no_mutability.rs");
780784 }
src/tools/rust-analyzer/crates/parser/test_data/parser/err/0002_duplicate_shebang.rast+6-12
......@@ -10,20 +10,20 @@ SOURCE_FILE
1010 USE_KW "use"
1111 ERROR
1212 SLASH "/"
13 MACRO_CALL
13 ERROR
1414 PATH
1515 PATH_SEGMENT
1616 NAME_REF
1717 IDENT "bin"
1818 ERROR
1919 SLASH "/"
20 MACRO_CALL
20 ERROR
2121 PATH
2222 PATH_SEGMENT
2323 NAME_REF
2424 IDENT "env"
2525 WHITESPACE " "
26 MACRO_CALL
26 ERROR
2727 PATH
2828 PATH_SEGMENT
2929 NAME_REF
......@@ -33,13 +33,7 @@ error 23: expected `[`
3333error 23: expected an item
3434error 27: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
3535error 28: expected SEMICOLON
36error 31: expected BANG
37error 31: expected `{`, `[`, `(`
38error 31: expected SEMICOLON
3936error 31: expected an item
40error 35: expected BANG
41error 35: expected `{`, `[`, `(`
42error 35: expected SEMICOLON
43error 41: expected BANG
44error 41: expected `{`, `[`, `(`
45error 41: expected SEMICOLON
37error 31: expected an item
38error 35: expected an item
39error 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
1414 WHITESPACE "\n"
1515 R_CURLY "}"
1616 WHITESPACE "\n\n"
17 MACRO_CALL
17 ERROR
1818 PATH
1919 PATH_SEGMENT
2020 NAME_REF
2121 IDENT "bar"
22 TOKEN_TREE
23 L_PAREN "("
24 R_PAREN ")"
22 ERROR
23 L_PAREN "("
24 ERROR
25 R_PAREN ")"
2526 WHITESPACE " "
2627 ERROR
2728 L_CURLY "{"
......@@ -75,6 +76,7 @@ SOURCE_FILE
7576 WHITESPACE "\n"
7677 R_CURLY "}"
7778 WHITESPACE "\n"
78error 17: expected BANG
79error 19: expected SEMICOLON
79error 17: expected an item
80error 17: expected an item
81error 18: expected an item
8082error 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
4646 ERROR
4747 AT "@"
4848 WHITESPACE " "
49 MACRO_CALL
49 ERROR
5050 PATH
5151 PATH_SEGMENT
5252 NAME_REF
......@@ -72,9 +72,7 @@ error 67: expected R_ANGLE
7272error 67: expected R_PAREN
7373error 67: expected SEMICOLON
7474error 67: expected an item
75error 72: expected BANG
76error 72: expected `{`, `[`, `(`
77error 72: expected SEMICOLON
75error 72: expected an item
7876error 72: expected an item
7977error 73: expected an item
8078error 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
2626 ERROR
2727 FN_KW "fn"
2828 WHITESPACE " "
29 MACRO_CALL
29 ERROR
3030 PATH
3131 PATH_SEGMENT
3232 NAME_REF
3333 IDENT "bar"
34 TOKEN_TREE
35 L_PAREN "("
36 R_PAREN ")"
34 ERROR
35 L_PAREN "("
36 ERROR
37 R_PAREN ")"
3738 WHITESPACE " "
3839 ERROR
3940 L_CURLY "{"
......@@ -43,6 +44,7 @@ error 6: expected fn, trait or impl
4344error 38: expected a name
4445error 40: missing type for `const` or `static`
4546error 40: expected SEMICOLON
46error 44: expected BANG
47error 46: expected SEMICOLON
47error 44: expected an item
48error 44: expected an item
49error 45: expected an item
4850error 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
1212 ERROR
1313 USE_KW "use"
1414 WHITESPACE " "
15 MACRO_CALL
15 ERROR
1616 PATH
1717 PATH_SEGMENT
1818 NAME_REF
1919 IDENT "std"
20 ERROR
2021 SEMICOLON ";"
2122 WHITESPACE "\n"
2223error 8: expected R_ANGLE
2324error 8: expected type
2425error 11: expected `{`
25error 15: expected BANG
26error 15: expected `{`, `[`, `(`
26error 15: expected an item
27error 15: expected an item
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_fn.rast+4-8
......@@ -1,5 +1,5 @@
11SOURCE_FILE
2 MACRO_CALL
2 ERROR
33 PATH
44 PATH_SEGMENT
55 NAME_REF
......@@ -22,7 +22,7 @@ SOURCE_FILE
2222 ERROR
2323 ASYNC_KW "async"
2424 WHITESPACE " "
25 MACRO_CALL
25 ERROR
2626 PATH
2727 PATH_SEGMENT
2828 NAME_REF
......@@ -42,10 +42,6 @@ SOURCE_FILE
4242 L_CURLY "{"
4343 R_CURLY "}"
4444 WHITESPACE "\n"
45error 3: expected BANG
46error 3: expected `{`, `[`, `(`
47error 3: expected SEMICOLON
45error 3: expected an item
4846error 24: expected fn, trait or impl
49error 28: expected BANG
50error 28: expected `{`, `[`, `(`
51error 28: expected SEMICOLON
47error 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 @@
1SOURCE_FILE
2 ERROR
3 PATH
4 PATH_SEGMENT
5 NAME_REF
6 IDENT "foo"
7 WHITESPACE "\n"
8error 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 @@
1foo
src/tools/rust-analyzer/crates/paths/Cargo.toml+1-2
......@@ -14,10 +14,9 @@ doctest = false
1414
1515[dependencies]
1616camino.workspace = true
17serde = { workspace = true, optional = true }
1817
1918[features]
20serde1 = ["camino/serde1", "dep:serde"]
19serde1 = ["camino/serde1"]
2120
2221[lints]
2322workspace = true
src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml+4-5
......@@ -14,6 +14,7 @@ doctest = false
1414
1515[dependencies]
1616serde.workspace = true
17serde_derive.workspace = true
1718serde_json = { workspace = true, features = ["unbounded_depth"] }
1819tracing.workspace = true
1920rustc-hash.workspace = true
......@@ -23,11 +24,9 @@ indexmap.workspace = true
2324paths = { workspace = true, features = ["serde1"] }
2425tt.workspace = true
2526stdx.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
28span.workspace = true
29# only here due to the `Env` newtype :/
30base-db.workspace = true
27# span = {workspace = true, default-features = false} does not work
28span = { path = "../span", version = "0.0.0", default-features = false}
29
3130intern.workspace = true
3231
3332[lints]
src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs+2-3
......@@ -9,7 +9,6 @@ pub mod json;
99pub mod msg;
1010mod process;
1111
12use base_db::Env;
1312use paths::{AbsPath, AbsPathBuf};
1413use span::Span;
1514use std::{fmt, io, sync::Arc};
......@@ -148,7 +147,7 @@ impl ProcMacro {
148147 &self,
149148 subtree: &tt::Subtree<Span>,
150149 attr: Option<&tt::Subtree<Span>>,
151 env: Env,
150 env: Vec<(String, String)>,
152151 def_site: Span,
153152 call_site: Span,
154153 mixed_site: Span,
......@@ -179,7 +178,7 @@ impl ProcMacro {
179178 },
180179 },
181180 lib: self.dylib_path.to_path_buf().into(),
182 env: env.into(),
181 env,
183182 current_dir,
184183 };
185184
src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs+3-2
......@@ -4,7 +4,8 @@ pub(crate) mod flat;
44use std::io::{self, BufRead, Write};
55
66use paths::Utf8PathBuf;
7use serde::{de::DeserializeOwned, Deserialize, Serialize};
7use serde::de::DeserializeOwned;
8use serde_derive::{Deserialize, Serialize};
89
910use crate::ProcMacroKind;
1011
......@@ -123,7 +124,7 @@ impl ExpnGlobals {
123124 }
124125}
125126
126pub trait Message: Serialize + DeserializeOwned {
127pub trait Message: serde::Serialize + DeserializeOwned {
127128 fn read<R: BufRead>(
128129 from_proto: ProtocolRead<R>,
129130 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;
3939
4040use intern::Symbol;
4141use rustc_hash::FxHashMap;
42use serde::{Deserialize, Serialize};
42use serde_derive::{Deserialize, Serialize};
4343use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange};
4444
45use crate::msg::EXTENDED_LEAF_DATA;
45use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA};
4646
4747pub type SpanDataIndexMap =
4848 indexmap::IndexSet<Span, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
......@@ -145,7 +145,11 @@ impl FlatTree {
145145 w.write(subtree);
146146
147147 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 },
149153 literal: if version >= EXTENDED_LEAF_DATA {
150154 write_vec(w.literal, LiteralRepr::write_with_kind)
151155 } else {
......@@ -179,7 +183,11 @@ impl FlatTree {
179183 w.write(subtree);
180184
181185 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 },
183191 literal: if version >= EXTENDED_LEAF_DATA {
184192 write_vec(w.literal, LiteralRepr::write_with_kind)
185193 } else {
......@@ -202,7 +210,11 @@ impl FlatTree {
202210 span_data_table: &SpanDataIndexMap,
203211 ) -> tt::Subtree<Span> {
204212 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 },
206218 literal: if version >= EXTENDED_LEAF_DATA {
207219 read_vec(self.literal, LiteralRepr::read_with_kind)
208220 } else {
......@@ -224,7 +236,11 @@ impl FlatTree {
224236
225237 pub fn to_subtree_unresolved(self, version: u32) -> tt::Subtree<TokenId> {
226238 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 },
228244 literal: if version >= EXTENDED_LEAF_DATA {
229245 read_vec(self.literal, LiteralRepr::read_with_kind)
230246 } else {
......@@ -257,7 +273,26 @@ fn write_vec<T, F: Fn(T) -> [u32; N], const N: usize>(xs: Vec<T>, f: F) -> Vec<u
257273}
258274
259275impl 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] {
261296 let kind = match self.kind {
262297 tt::DelimiterKind::Invisible => 0,
263298 tt::DelimiterKind::Parenthesis => 1,
......@@ -266,7 +301,7 @@ impl SubtreeRepr {
266301 };
267302 [self.open.0, self.close.0, kind, self.tt[0], self.tt[1]]
268303 }
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 {
270305 let kind = match kind {
271306 0 => tt::DelimiterKind::Invisible,
272307 1 => tt::DelimiterKind::Parenthesis,
src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs+6-23
......@@ -56,25 +56,8 @@ impl ProcMacroProcessSrv {
5656 match srv.version_check() {
5757 Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new(
5858 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."
7861 ),
7962 )),
8063 Ok(v) => {
......@@ -89,10 +72,10 @@ impl ProcMacroProcessSrv {
8972 tracing::info!("Proc-macro server span mode: {:?}", srv.mode);
9073 Ok(srv)
9174 }
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 }
9679 }
9780 }
9881
src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml+2-2
......@@ -21,8 +21,8 @@ stdx.workspace = true
2121tt.workspace = true
2222syntax-bridge.workspace = true
2323paths.workspace = true
24base-db.workspace = true
25span.workspace = true
24# span = {workspace = true, default-features = false} does not work
25span = { path = "../span", version = "0.0.0", default-features = false}
2626proc-macro-api.workspace = true
2727intern.workspace = true
2828
src/tools/rust-analyzer/crates/project-model/Cargo.toml+1
......@@ -19,6 +19,7 @@ rustc-hash.workspace = true
1919semver.workspace = true
2020serde_json.workspace = true
2121serde.workspace = true
22serde_derive.workspace = true
2223tracing.workspace = true
2324triomphe.workspace = true
2425la-arena.workspace = true
src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs+1-1
......@@ -15,7 +15,7 @@ use itertools::Itertools;
1515use la_arena::ArenaMap;
1616use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
1717use rustc_hash::{FxHashMap, FxHashSet};
18use serde::Deserialize;
18use serde::Deserialize as _;
1919use toolchain::Tool;
2020
2121use crate::{
src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs+1-1
......@@ -8,7 +8,7 @@ use cargo_metadata::{CargoOpt, MetadataCommand};
88use la_arena::{Arena, Idx};
99use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
1010use rustc_hash::{FxHashMap, FxHashSet};
11use serde::Deserialize;
11use serde_derive::Deserialize;
1212use serde_json::from_value;
1313use span::Edition;
1414use toolchain::Tool;
src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml+1-1
......@@ -20,7 +20,7 @@ parking_lot = "0.12.1"
2020rustc-hash = "2.0.0"
2121smallvec = "1.0.0"
2222oorandom = "11"
23triomphe = "0.1.11"
23triomphe.workspace = true
2424itertools.workspace = true
2525
2626ra-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
3636rustc-hash.workspace = true
3737serde_json = { workspace = true, features = ["preserve_order"] }
3838serde.workspace = true
39serde_derive.workspace = true
3940tenthash = "0.4.0"
4041num_cpus = "1.15.0"
4142mimalloc = { 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! {
644644 /// Aliased as `"checkOnSave.targets"`.
645645 check_targets | checkOnSave_targets | checkOnSave_target: Option<CheckOnSaveTargets> = None,
646646 /// 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.
648649 check_workspace: bool = true,
649650
650651 /// 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;
33
44use std::mem;
55
6use cargo_metadata::PackageId;
67use ide::FileId;
78use ide_db::FxHashMap;
89use itertools::Itertools;
......@@ -13,7 +14,8 @@ use triomphe::Arc;
1314
1415use crate::{global_state::GlobalStateSnapshot, lsp, lsp_ext, main_loop::DiagnosticsTaskKind};
1516
16pub(crate) type CheckFixes = Arc<IntMap<usize, IntMap<FileId, Vec<Fix>>>>;
17pub(crate) type CheckFixes =
18 Arc<IntMap<usize, FxHashMap<Option<Arc<PackageId>>, IntMap<FileId, Vec<Fix>>>>>;
1719
1820#[derive(Debug, Default, Clone)]
1921pub struct DiagnosticsMapConfig {
......@@ -31,7 +33,10 @@ pub(crate) struct DiagnosticCollection {
3133 pub(crate) native_syntax: IntMap<FileId, (DiagnosticsGeneration, Vec<lsp_types::Diagnostic>)>,
3234 pub(crate) native_semantic: IntMap<FileId, (DiagnosticsGeneration, Vec<lsp_types::Diagnostic>)>,
3335 // 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 >,
3540 pub(crate) check_fixes: CheckFixes,
3641 changes: IntSet<FileId>,
3742 /// Counter for supplying a new generation number for diagnostics.
......@@ -50,18 +55,37 @@ pub(crate) struct Fix {
5055
5156impl DiagnosticCollection {
5257 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();
5864 }
5965 }
6066
6167 pub(crate) fn clear_check_all(&mut self) {
6268 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 }
6589 }
6690
6791 pub(crate) fn clear_native_for(&mut self, file_id: FileId) {
......@@ -73,11 +97,19 @@ impl DiagnosticCollection {
7397 pub(crate) fn add_check_diagnostic(
7498 &mut self,
7599 flycheck_id: usize,
100 package_id: &Option<Arc<PackageId>>,
76101 file_id: FileId,
77102 diagnostic: lsp_types::Diagnostic,
78103 fix: Option<Box<Fix>>,
79104 ) {
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();
81113 for existing_diagnostic in diagnostics.iter() {
82114 if are_diagnostics_equal(existing_diagnostic, &diagnostic) {
83115 return;
......@@ -86,7 +118,14 @@ impl DiagnosticCollection {
86118
87119 if let Some(fix) = fix {
88120 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);
90129 }
91130 diagnostics.push(diagnostic);
92131 self.changes.insert(file_id);
......@@ -135,7 +174,12 @@ impl DiagnosticCollection {
135174 ) -> impl Iterator<Item = &lsp_types::Diagnostic> {
136175 let native_syntax = self.native_syntax.get(&file_id).into_iter().flat_map(|(_, d)| d);
137176 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();
139183 native_syntax.chain(native_semantic).chain(check)
140184 }
141185
src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs+81-39
......@@ -1,17 +1,20 @@
11//! Flycheck provides the functionality needed to run `cargo check` to provide
22//! LSP diagnostics based on the output of the command.
33
4use std::{fmt, io, process::Command, time::Duration};
4use std::{fmt, io, mem, process::Command, time::Duration};
55
6use cargo_metadata::PackageId;
67use crossbeam_channel::{select_biased, unbounded, Receiver, Sender};
78use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
89use rustc_hash::FxHashMap;
9use serde::Deserialize;
10use serde::Deserialize as _;
11use serde_derive::Deserialize;
1012
1113pub(crate) use cargo_metadata::diagnostic::{
1214 Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan,
1315};
1416use toolchain::Tool;
17use triomphe::Arc;
1518
1619use crate::command::{CommandHandle, ParseFromLine};
1720
......@@ -150,10 +153,19 @@ impl FlycheckHandle {
150153
151154pub(crate) enum FlycheckMessage {
152155 /// 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 },
154162
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 },
157169
158170 /// Request check progress notification to client
159171 Progress {
......@@ -166,15 +178,18 @@ pub(crate) enum FlycheckMessage {
166178impl fmt::Debug for FlycheckMessage {
167179 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168180 match self {
169 FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => f
181 FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic, package_id } => f
170182 .debug_struct("AddDiagnostic")
171183 .field("id", id)
172184 .field("workspace_root", workspace_root)
185 .field("package_id", package_id)
173186 .field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code))
174187 .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(),
178193 FlycheckMessage::Progress { id, progress } => {
179194 f.debug_struct("Progress").field("id", id).field("progress", progress).finish()
180195 }
......@@ -200,12 +215,13 @@ enum StateChange {
200215struct FlycheckActor {
201216 /// The workspace id of this flycheck instance.
202217 id: usize,
218
203219 sender: Sender<FlycheckMessage>,
204220 config: FlycheckConfig,
205221 manifest_path: Option<AbsPathBuf>,
206222 /// Either the workspace root of the workspace we are flychecking,
207223 /// or the project root of the project.
208 root: AbsPathBuf,
224 root: Arc<AbsPathBuf>,
209225 sysroot_root: Option<AbsPathBuf>,
210226 /// CargoHandle exists to wrap around the communication needed to be able to
211227 /// run `cargo check` without blocking. Currently the Rust standard library
......@@ -215,8 +231,13 @@ struct FlycheckActor {
215231 command_handle: Option<CommandHandle<CargoCheckMessage>>,
216232 /// The receiver side of the channel mentioned above.
217233 command_receiver: Option<Receiver<CargoCheckMessage>>,
234 package_status: FxHashMap<Arc<PackageId>, DiagnosticReceived>,
235}
218236
219 status: FlycheckStatus,
237#[derive(PartialEq, Eq, Copy, Clone, Debug)]
238enum DiagnosticReceived {
239 Yes,
240 No,
220241}
221242
222243#[allow(clippy::large_enum_variant)]
......@@ -225,13 +246,6 @@ enum Event {
225246 CheckEvent(Option<CargoCheckMessage>),
226247}
227248
228#[derive(PartialEq)]
229enum FlycheckStatus {
230 Started,
231 DiagnosticSent,
232 Finished,
233}
234
235249pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file";
236250
237251impl FlycheckActor {
......@@ -249,11 +263,11 @@ impl FlycheckActor {
249263 sender,
250264 config,
251265 sysroot_root,
252 root: workspace_root,
266 root: Arc::new(workspace_root),
253267 manifest_path,
254268 command_handle: None,
255269 command_receiver: None,
256 status: FlycheckStatus::Finished,
270 package_status: FxHashMap::default(),
257271 }
258272 }
259273
......@@ -306,13 +320,11 @@ impl FlycheckActor {
306320 self.command_handle = Some(command_handle);
307321 self.command_receiver = Some(receiver);
308322 self.report_progress(Progress::DidStart);
309 self.status = FlycheckStatus::Started;
310323 }
311324 Err(error) => {
312325 self.report_progress(Progress::DidFailToRestart(format!(
313326 "Failed to run the following command: {formatted_command} error={error}"
314327 )));
315 self.status = FlycheckStatus::Finished;
316328 }
317329 }
318330 }
......@@ -332,37 +344,62 @@ impl FlycheckActor {
332344 error
333345 );
334346 }
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 }
337363 }
364
338365 self.report_progress(Progress::DidFinish(res));
339 self.status = FlycheckStatus::Finished;
340366 }
341367 Event::CheckEvent(Some(message)) => match message {
342368 CargoCheckMessage::CompilerArtifact(msg) => {
343369 tracing::trace!(
344370 flycheck_id = self.id,
345371 artifact = msg.target.name,
372 package_id = msg.package_id.repr,
346373 "artifact received"
347374 );
348375 self.report_progress(Progress::DidCheckCrate(msg.target.name));
376 self.package_status
377 .entry(Arc::new(msg.package_id))
378 .or_insert(DiagnosticReceived::No);
349379 }
350
351 CargoCheckMessage::Diagnostic(msg) => {
380 CargoCheckMessage::Diagnostic { diagnostic, package_id } => {
352381 tracing::trace!(
353382 flycheck_id = self.id,
354 message = msg.message,
383 message = diagnostic.message,
384 package_id = package_id.as_ref().map(|it| &it.repr),
355385 "diagnostic received"
356386 );
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 }
359396 }
360397 self.send(FlycheckMessage::AddDiagnostic {
361398 id: self.id,
399 package_id,
362400 workspace_root: self.root.clone(),
363 diagnostic: msg,
401 diagnostic,
364402 });
365 self.status = FlycheckStatus::DiagnosticSent;
366403 }
367404 },
368405 }
......@@ -380,7 +417,7 @@ impl FlycheckActor {
380417 command_handle.cancel();
381418 self.command_receiver.take();
382419 self.report_progress(Progress::DidCancel);
383 self.status = FlycheckStatus::Finished;
420 self.package_status.clear();
384421 }
385422 }
386423
......@@ -400,7 +437,7 @@ impl FlycheckActor {
400437 cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(sysroot_root));
401438 }
402439 cmd.arg(command);
403 cmd.current_dir(&self.root);
440 cmd.current_dir(&*self.root);
404441
405442 match package {
406443 Some(pkg) => cmd.arg("-p").arg(pkg),
......@@ -442,11 +479,11 @@ impl FlycheckActor {
442479
443480 match invocation_strategy {
444481 InvocationStrategy::Once => {
445 cmd.current_dir(&self.root);
482 cmd.current_dir(&*self.root);
446483 }
447484 InvocationStrategy::PerWorkspace => {
448485 // FIXME: cmd.current_dir(&affected_workspace);
449 cmd.current_dir(&self.root);
486 cmd.current_dir(&*self.root);
450487 }
451488 }
452489
......@@ -486,7 +523,7 @@ impl FlycheckActor {
486523#[allow(clippy::large_enum_variant)]
487524enum CargoCheckMessage {
488525 CompilerArtifact(cargo_metadata::Artifact),
489 Diagnostic(Diagnostic),
526 Diagnostic { diagnostic: Diagnostic, package_id: Option<Arc<PackageId>> },
490527}
491528
492529impl ParseFromLine for CargoCheckMessage {
......@@ -501,11 +538,16 @@ impl ParseFromLine for CargoCheckMessage {
501538 Some(CargoCheckMessage::CompilerArtifact(artifact))
502539 }
503540 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 })
505545 }
506546 _ => None,
507547 },
508 JsonMessage::Rustc(message) => Some(CargoCheckMessage::Diagnostic(message)),
548 JsonMessage::Rustc(message) => {
549 Some(CargoCheckMessage::Diagnostic { diagnostic: message, package_id: None })
550 }
509551 };
510552 }
511553
src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs+6-2
......@@ -92,7 +92,7 @@ pub(crate) struct GlobalState {
9292
9393 // status
9494 pub(crate) shutdown_requested: bool,
95 pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>,
95 pub(crate) last_reported_status: lsp_ext::ServerStatusParams,
9696
9797 // proc macros
9898 pub(crate) proc_macro_clients: Arc<[anyhow::Result<ProcMacroServer>]>,
......@@ -238,7 +238,11 @@ impl GlobalState {
238238 mem_docs: MemDocs::default(),
239239 semantic_tokens_cache: Arc::new(Default::default()),
240240 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 },
242246 source_root_config: SourceRootConfig::default(),
243247 local_roots_parent_map: Arc::new(FxHashMap::default()),
244248 config_errors: Default::default(),
src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs+1-1
......@@ -126,7 +126,7 @@ impl RequestDispatcher<'_> {
126126
127127 /// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not
128128 /// 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>(
130130 &mut self,
131131 f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>,
132132 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(
189189 if !state.config.check_on_save(Some(sr)) || run_flycheck(state, vfs_path) {
190190 return Ok(());
191191 }
192 } else if state.config.check_on_save(None) {
192 } else if state.config.check_on_save(None) && state.config.flycheck_workspace(None) {
193193 // No specific flycheck was triggered, so let's trigger all of them.
194194 for flycheck in state.flycheck.iter() {
195195 flycheck.restart_workspace(None);
......@@ -293,7 +293,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
293293 let file_id = state.vfs.read().0.file_id(&vfs_path);
294294 if let Some(file_id) = file_id {
295295 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);
297297 let mut updated = false;
298298 let task = move || -> std::result::Result<(), ide::Cancelled> {
299299 // 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 {
375375 let saved_file = vfs_path.as_path().map(|p| p.to_owned());
376376
377377 // Find and trigger corresponding flychecks
378 for flycheck in world.flycheck.iter() {
378 'flychecks: for flycheck in world.flycheck.iter() {
379379 for (id, package) in workspace_ids.clone() {
380380 if id == flycheck.id() {
381381 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))
386387 }
387 continue;
388 continue 'flychecks;
388389 }
389390 }
390391 }
391392 // No specific flycheck was triggered, so let's trigger all of them.
392 if !updated {
393 if !updated && may_flycheck_workspace {
393394 for flycheck in world.flycheck.iter() {
394395 flycheck.restart_workspace(saved_file.clone());
395396 }
......@@ -432,8 +433,10 @@ pub(crate) fn handle_run_flycheck(
432433 }
433434 }
434435 // 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 }
437440 }
438441 Ok(())
439442}
src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs+19-9
......@@ -481,27 +481,28 @@ pub(crate) fn handle_document_diagnostics(
481481 snap: GlobalStateSnapshot,
482482 params: lsp_types::DocumentDiagnosticParams,
483483) -> anyhow::Result<lsp_types::DocumentDiagnosticReportResult> {
484 const EMPTY: lsp_types::DocumentDiagnosticReportResult =
484 let empty = || {
485485 lsp_types::DocumentDiagnosticReportResult::Report(
486486 lsp_types::DocumentDiagnosticReport::Full(
487487 lsp_types::RelatedFullDocumentDiagnosticReport {
488488 related_documents: None,
489489 full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport {
490 result_id: None,
490 result_id: Some("rust-analyzer".to_owned()),
491491 items: vec![],
492492 },
493493 },
494494 ),
495 );
495 )
496 };
496497
497498 let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
498499 let source_root = snap.analysis.source_root_id(file_id)?;
499500 if !snap.analysis.is_local_source_root(source_root)? {
500 return Ok(EMPTY);
501 return Ok(empty());
501502 }
502503 let config = snap.config.diagnostics(Some(source_root));
503504 if !config.enabled {
504 return Ok(EMPTY);
505 return Ok(empty());
505506 }
506507 let line_index = snap.file_line_index(file_id)?;
507508 let supports_related = snap.config.text_document_diagnostic_related_document_support();
......@@ -529,7 +530,7 @@ pub(crate) fn handle_document_diagnostics(
529530 Ok(lsp_types::DocumentDiagnosticReportResult::Report(
530531 lsp_types::DocumentDiagnosticReport::Full(lsp_types::RelatedFullDocumentDiagnosticReport {
531532 full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport {
532 result_id: None,
533 result_id: Some("rust-analyzer".to_owned()),
533534 items: diagnostics.collect(),
534535 },
535536 related_documents: related_documents.is_empty().not().then(|| {
......@@ -539,7 +540,10 @@ pub(crate) fn handle_document_diagnostics(
539540 (
540541 to_proto::url(&snap, id),
541542 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 },
543547 ),
544548 )
545549 })
......@@ -1144,7 +1148,7 @@ pub(crate) fn handle_completion_resolve(
11441148 let Some(corresponding_completion) = completions.into_iter().find(|completion_item| {
11451149 // Avoid computing hashes for items that obviously do not match
11461150 // 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())
11481152 && resolve_data_hash == completion_item_hash(completion_item, resolve_data.for_ref)
11491153 }) else {
11501154 return Ok(original_completion);
......@@ -1441,7 +1445,13 @@ pub(crate) fn handle_code_action(
14411445 }
14421446
14431447 // 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 {
14451455 // FIXME: this mapping is awkward and shouldn't exist. Refactor
14461456 // `snap.check_fixes` to not convert to LSP prematurely.
14471457 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;
114114 u8::from(item.deprecated),
115115 u8::from(item.trigger_call_info),
116116 ]);
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 {
119122 hasher.update(label_detail);
120123 }
121124 // 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 {
823823#[derive(Debug, Serialize, Deserialize)]
824824pub struct CompletionResolveData {
825825 pub position: lsp_types::TextDocumentPositionParams,
826 #[serde(skip_serializing_if = "Vec::is_empty", default)]
826827 pub imports: Vec<CompletionImport>,
828 #[serde(skip_serializing_if = "Option::is_none", default)]
827829 pub version: Option<i32>,
830 #[serde(skip_serializing_if = "Option::is_none", default)]
828831 pub trigger_character: Option<char>,
829832 pub for_ref: bool,
830833 pub hash: String,
......@@ -836,6 +839,7 @@ pub struct InlayHintResolveData {
836839 // This is a string instead of a u64 as javascript can't represent u64 fully
837840 pub hash: String,
838841 pub resolve_range: lsp_types::Range,
842 #[serde(skip_serializing_if = "Option::is_none", default)]
839843 pub version: Option<i32>,
840844}
841845
src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs+33-23
......@@ -2,6 +2,7 @@
22use std::{
33 iter::once,
44 mem,
5 ops::Not as _,
56 sync::atomic::{AtomicU32, Ordering},
67};
78
......@@ -353,14 +354,17 @@ fn completion_item(
353354 };
354355
355356 let mut lsp_item = lsp_types::CompletionItem {
356 label: item.label.to_string(),
357 label: item.label.primary.to_string(),
357358 detail,
358359 filter_text,
359360 kind: Some(completion_item_kind(item.kind)),
360361 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),
362366 documentation,
363 deprecated: Some(item.deprecated),
367 deprecated: item.deprecated.then_some(item.deprecated),
364368 tags,
365369 command,
366370 insert_text_format,
......@@ -368,15 +372,17 @@ fn completion_item(
368372 };
369373
370374 if config.completion_label_details_support() {
375 let has_label_details =
376 item.label.detail_left.is_some() || item.label.detail_right.is_some();
371377 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 {
374380 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(),
377383 });
378384 }
379 } else if let Some(label_detail) = &item.label_detail {
385 } else if let Some(label_detail) = &item.label.detail_left {
380386 lsp_item.label.push_str(label_detail.as_str());
381387 }
382388
......@@ -1578,22 +1584,26 @@ pub(crate) fn code_lens(
15781584 };
15791585
15801586 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 }
15961605 }
1606
15971607 if lens_config.interpret {
15981608 let command = command::interpret_single(&r);
15991609 acc.push(lsp_types::CodeLens {
src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs+17-9
......@@ -408,7 +408,10 @@ impl GlobalState {
408408 if self.is_quiescent() {
409409 let became_quiescent = !was_quiescent;
410410 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 {
412415 // Project has loaded properly, kick off initial flycheck
413416 self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None));
414417 }
......@@ -656,8 +659,8 @@ impl GlobalState {
656659
657660 fn update_status_or_notify(&mut self) {
658661 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();
661664
662665 if self.config.server_status_notification() {
663666 self.send_notification::<lsp_ext::ServerStatusNotification>(status);
......@@ -715,6 +718,7 @@ impl GlobalState {
715718 error!("FetchWorkspaceError: {e}");
716719 }
717720 self.wants_to_switch = Some("fetched workspace".to_owned());
721 self.diagnostics.clear_check_all();
718722 (Progress::End, None)
719723 }
720724 };
......@@ -956,7 +960,7 @@ impl GlobalState {
956960
957961 fn handle_flycheck_msg(&mut self, message: FlycheckMessage) {
958962 match message {
959 FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => {
963 FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic, package_id } => {
960964 let snap = self.snapshot();
961965 let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
962966 &self.config.diagnostics_map(None),
......@@ -968,6 +972,7 @@ impl GlobalState {
968972 match url_to_file_id(&self.vfs.read().0, &diag.url) {
969973 Ok(file_id) => self.diagnostics.add_check_diagnostic(
970974 id,
975 &package_id,
971976 file_id,
972977 diag.diagnostic,
973978 diag.fix,
......@@ -981,9 +986,12 @@ impl GlobalState {
981986 };
982987 }
983988 }
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 }
987995 FlycheckMessage::Progress { id, progress } => {
988996 let (state, message) = match progress {
989997 flycheck::Progress::DidStart => (Progress::Begin, None),
......@@ -1090,12 +1098,12 @@ impl GlobalState {
10901098 .on_latency_sensitive::<NO_RETRY, lsp_request::SemanticTokensRangeRequest>(handlers::handle_semantic_tokens_range)
10911099 // FIXME: Some of these NO_RETRY could be retries if the file they are interested didn't change.
10921100 // 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(
10941102 lsp_types::DocumentDiagnosticReport::Full(
10951103 lsp_types::RelatedFullDocumentDiagnosticReport {
10961104 related_documents: None,
10971105 full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport {
1098 result_id: None,
1106 result_id: Some("rust-analyzer".to_owned()),
10991107 items: vec![],
11001108 },
11011109 },
src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs-1
......@@ -70,7 +70,6 @@ impl GlobalState {
7070 /// are ready to do semantic work.
7171 pub(crate) fn is_quiescent(&self) -> bool {
7272 self.vfs_done
73 && self.last_reported_status.is_some()
7473 && !self.fetch_workspaces_queue.op_in_progress()
7574 && !self.fetch_build_data_queue.op_in_progress()
7675 && !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;
55
66use crossbeam_channel::Sender;
77use paths::AbsPath;
8use serde::Deserialize;
8use serde::Deserialize as _;
9use serde_derive::Deserialize;
910use toolchain::Tool;
1011
1112use crate::{
src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs+1-1
......@@ -54,7 +54,7 @@ where
5454 fn on_event(&self, _event: &Event<'_>, _ctx: Context<'_, S>) {}
5555
5656 fn on_close(&self, id: Id, ctx: Context<'_, S>) {
57 #[derive(serde::Serialize)]
57 #[derive(serde_derive::Serialize)]
5858 struct JsonDataInner {
5959 name: &'static str,
6060 elapsed_ms: u128,
src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs+9-30
......@@ -1,7 +1,7 @@
11use std::{
22 cell::{Cell, RefCell},
33 env, fs,
4 sync::{Once, OnceLock},
4 sync::Once,
55 time::Duration,
66};
77
......@@ -141,34 +141,15 @@ impl Project<'_> {
141141 /// file in the config dir after server is run, something where our naive approach comes short.
142142 /// Using a `prelock` allows us to force a lock when we know we need it.
143143 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(());
145145
146146 let config_dir_guard = if config_lock {
147147 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)
172153 })
173154 } else {
174155 None
......@@ -311,14 +292,12 @@ pub(crate) struct Server {
311292 client: Connection,
312293 /// XXX: remove the tempdir last
313294 dir: TestDir,
314 #[allow(dyn_drop)]
315 _config_dir_guard: Option<(MutexGuard<'static, ()>, Box<dyn Drop>)>,
295 _config_dir_guard: Option<(MutexGuard<'static, ()>, TestDir)>,
316296}
317297
318298impl Server {
319 #[allow(dyn_drop)]
320299 fn new(
321 config_dir_guard: Option<(MutexGuard<'static, ()>, Box<dyn Drop>)>,
300 config_dir_guard: Option<(MutexGuard<'static, ()>, TestDir)>,
322301 dir: TestDir,
323302 config: Config,
324303 ) -> Server {
src/tools/rust-analyzer/crates/span/Cargo.toml+4-1
......@@ -12,7 +12,7 @@ authors.workspace = true
1212
1313[dependencies]
1414la-arena.workspace = true
15ra-salsa.workspace = true
15ra-salsa = { workspace = true, optional = true }
1616rustc-hash.workspace = true
1717hashbrown.workspace = true
1818text-size.workspace = true
......@@ -22,5 +22,8 @@ vfs.workspace = true
2222syntax.workspace = true
2323stdx.workspace = true
2424
25[features]
26default = ["ra-salsa"]
27
2528[lints]
2629workspace = true
src/tools/rust-analyzer/crates/span/src/hygiene.rs+5
......@@ -21,6 +21,9 @@
2121//! `ExpnData::call_site` in rustc, [`MacroCallLoc::call_site`] in rust-analyzer.
2222use std::fmt;
2323
24#[cfg(not(feature = "ra-salsa"))]
25use crate::InternId;
26#[cfg(feature = "ra-salsa")]
2427use ra_salsa::{InternId, InternValue};
2528
2629use crate::MacroCallId;
......@@ -39,6 +42,7 @@ impl fmt::Debug for SyntaxContextId {
3942 }
4043}
4144
45#[cfg(feature = "ra-salsa")]
4246impl ra_salsa::InternKey for SyntaxContextId {
4347 fn from_intern_id(v: ra_salsa::InternId) -> Self {
4448 SyntaxContextId(v)
......@@ -92,6 +96,7 @@ pub struct SyntaxContextData {
9296 pub opaque_and_semitransparent: SyntaxContextId,
9397}
9498
99#[cfg(feature = "ra-salsa")]
95100impl InternValue for SyntaxContextData {
96101 type Key = (SyntaxContextId, Option<MacroCallId>, Transparency);
97102
src/tools/rust-analyzer/crates/span/src/lib.rs+72-1
......@@ -1,6 +1,7 @@
11//! File and span related types.
22use std::fmt::{self, Write};
33
4#[cfg(feature = "ra-salsa")]
45use ra_salsa::InternId;
56
67mod ast_id;
......@@ -261,8 +262,9 @@ pub struct MacroFileId {
261262/// `MacroCallId` identifies a particular macro invocation, like
262263/// `println!("Hello, {}", world)`.
263264#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
264pub struct MacroCallId(ra_salsa::InternId);
265pub struct MacroCallId(InternId);
265266
267#[cfg(feature = "ra-salsa")]
266268impl ra_salsa::InternKey for MacroCallId {
267269 fn from_intern_id(v: ra_salsa::InternId) -> Self {
268270 MacroCallId(v)
......@@ -355,3 +357,72 @@ impl HirFileId {
355357 }
356358 }
357359}
360
361#[cfg(not(feature = "ra-salsa"))]
362mod 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"))]
428use intern_id_proxy::InternId;
src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml+2-1
......@@ -21,7 +21,8 @@ syntax.workspace = true
2121parser.workspace = true
2222tt.workspace = true
2323stdx.workspace = true
24span.workspace = true
24# span = {workspace = true, default-features = false} does not work
25span = { path = "../span", version = "0.0.0", default-features = false}
2526intern.workspace = true
2627
2728[dev-dependencies]
src/tools/rust-analyzer/crates/syntax/rust.ungram+1-1
......@@ -414,7 +414,7 @@ AsmClobberAbi = 'clobber_abi' '(' ('@string' (',' '@string')* ','?) ')'
414414// option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw"
415415AsmOption = 'pure' | 'nomem' | 'readonly' | 'preserves_flags' | 'noreturn' | 'nostack' | 'att_syntax' | 'raw' | 'may_unwind'
416416// options := "options(" option *("," option) [","] ")"
417AsmOptions = 'options' '(' AsmOption *(',' AsmOption) ','? ')'
417AsmOptions = 'options' '(' (AsmOption (',' AsmOption)*) ','? ')'
418418AsmLabel = 'label' BlockExpr
419419AsmSym = 'sym' Path
420420AsmConst = 'const' Expr
src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs-2
......@@ -211,8 +211,6 @@ pub struct AsmOptions {
211211 pub(crate) syntax: SyntaxNode,
212212}
213213impl AsmOptions {
214 #[inline]
215 pub fn asm_option(&self) -> Option<AsmOption> { support::child(&self.syntax) }
216214 #[inline]
217215 pub fn asm_options(&self) -> AstChildren<AsmOption> { support::children(&self.syntax) }
218216 #[inline]
src/tools/rust-analyzer/docs/dev/lsp-extensions.md+1-1
......@@ -1,5 +1,5 @@
11<!---
2lsp/ext.rs hash: 14b7fb1309f5bb00
2lsp/ext.rs hash: 9790509d87670c22
33
44If you need to change the above hash to make the test pass, please check if you
55need 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"`.
270270+
271271--
272272Whether `--workspace` should be passed to `cargo check`.
273If false, `-p <package>` will be passed instead.
273If false, `-p <package>` will be passed instead if applicable. In case it is not, no
274check will be performed.
274275--
275276[[rust-analyzer.completion.addSemicolonToUnit]]rust-analyzer.completion.addSemicolonToUnit (default: `true`)::
276277+
src/tools/rust-analyzer/editors/code/package.json+1-1
......@@ -1098,7 +1098,7 @@
10981098 "title": "check",
10991099 "properties": {
11001100 "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.",
11021102 "default": true,
11031103 "type": "boolean"
11041104 }
src/tools/rust-analyzer/editors/code/src/ctx.ts+2
......@@ -347,6 +347,8 @@ export class Ctx implements RustAnalyzerExtensionApi {
347347 }
348348 log.info("Disposing language client");
349349 this.updateCommands("disable");
350 // we give the server 100ms to stop gracefully
351 await this.client?.stop(100).catch((_) => {});
350352 await this.disposeClient();
351353 }
352354
src/tools/rust-analyzer/lib/lsp-server/Cargo.toml+3-2
......@@ -1,6 +1,6 @@
11[package]
22name = "lsp-server"
3version = "0.7.7"
3version = "0.7.8"
44description = "Generic LSP server scaffold."
55license = "MIT OR Apache-2.0"
66repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server"
......@@ -9,7 +9,8 @@ edition = "2021"
99[dependencies]
1010log = "0.4.17"
1111serde_json = "1.0.108"
12serde = { version = "1.0.192", features = ["derive"] }
12serde = { version = "1.0.216" }
13serde_derive = { version = "1.0.216" }
1314crossbeam-channel.workspace = true
1415
1516[dev-dependencies]
src/tools/rust-analyzer/lib/lsp-server/src/msg.rs+5-4
......@@ -3,7 +3,8 @@ use std::{
33 io::{self, BufRead, Write},
44};
55
6use serde::{de::DeserializeOwned, Deserialize, Serialize};
6use serde::de::DeserializeOwned;
7use serde_derive::{Deserialize, Serialize};
78
89use crate::error::ExtractError;
910
......@@ -196,7 +197,7 @@ impl Message {
196197}
197198
198199impl 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 {
200201 Response { id, result: Some(serde_json::to_value(result).unwrap()), error: None }
201202 }
202203 pub fn new_err(id: RequestId, code: i32, message: String) -> Response {
......@@ -206,7 +207,7 @@ impl Response {
206207}
207208
208209impl 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 {
210211 Request { id, method, params: serde_json::to_value(params).unwrap() }
211212 }
212213 pub fn extract<P: DeserializeOwned>(
......@@ -231,7 +232,7 @@ impl Request {
231232}
232233
233234impl Notification {
234 pub fn new(method: String, params: impl Serialize) -> Notification {
235 pub fn new(method: String, params: impl serde::Serialize) -> Notification {
235236 Notification { method, params: serde_json::to_value(params).unwrap() }
236237 }
237238 pub fn extract<P: DeserializeOwned>(
src/tools/rust-analyzer/lib/lsp-server/src/req_queue.rs+1-3
......@@ -1,7 +1,5 @@
11use std::collections::HashMap;
22
3use serde::Serialize;
4
53use crate::{ErrorCode, Request, RequestId, Response, ResponseError};
64
75/// Manages the set of pending requests, both incoming and outgoing.
......@@ -56,7 +54,7 @@ impl<I> Incoming<I> {
5654}
5755
5856impl<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 {
6058 let id = RequestId::from(self.next_id);
6159 self.pending.insert(id.clone(), data);
6260 self.next_id += 1;
src/tools/rust-analyzer/rust-version+1-1
......@@ -1 +1 @@
15a6036a1802262f8cf02192b02026688d396f1d7
10eca4dd3205a01dba4bd7b7c140ec370aff03440
src/tools/rust-analyzer/xtask/Cargo.toml+2-1
......@@ -16,7 +16,8 @@ xflags = "0.3.0"
1616time = { version = "0.3", default-features = false }
1717zip = { version = "0.6", default-features = false, features = ["deflate", "time"] }
1818stdx.workspace = true
19proc-macro2 = "1.0.47"
19# https://github.com/dtolnay/proc-macro2/issues/475
20proc-macro2 = "=1.0.86"
2021quote = "1.0.20"
2122ungrammar = "1.16.1"
2223either.workspace = true