Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1f54f71

Browse files
committed
Auto merge of rust-lang#16637 - Veykril:fix-proc-macro-srv-literals, r=Veykril
fix: Fix proc-macro server not accounting for string delimiters correctly Fixes rust-lang/rust-analyzer#16622 Note that this is a bug a in the proc-macro server, so this won't be fixed until the next subtree sync
2 parents 543d7e9 + efa6948 commit 1f54f71

File tree

7 files changed

+89
-58
lines changed

7 files changed

+89
-58
lines changed

crates/proc-macro-api/src/process.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl ProcMacroProcessSrv {
4545
})
4646
};
4747
let mut srv = create_srv(true)?;
48-
tracing::info!("sending version check");
48+
tracing::info!("sending proc-macro server version check");
4949
match srv.version_check() {
5050
Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new(
5151
io::ErrorKind::Other,
@@ -55,14 +55,15 @@ impl ProcMacroProcessSrv {
5555
),
5656
)),
5757
Ok(v) => {
58-
tracing::info!("got version {v}");
58+
tracing::info!("Proc-macro server version: {v}");
5959
srv = create_srv(false)?;
6060
srv.version = v;
61-
if srv.version > RUST_ANALYZER_SPAN_SUPPORT {
61+
if srv.version >= RUST_ANALYZER_SPAN_SUPPORT {
6262
if let Ok(mode) = srv.enable_rust_analyzer_spans() {
6363
srv.mode = mode;
6464
}
6565
}
66+
tracing::info!("Proc-macro server span mode: {:?}", srv.mode);
6667
Ok(srv)
6768
}
6869
Err(e) => {

crates/proc-macro-srv/src/proc_macros.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl ProcMacros {
6464
&bridge::server::SameThread,
6565
S::make_server(call_site, def_site, mixed_site),
6666
parsed_body,
67-
false,
67+
cfg!(debug_assertions),
6868
);
6969
return res
7070
.map(|it| it.into_subtree(call_site))
@@ -75,7 +75,7 @@ impl ProcMacros {
7575
&bridge::server::SameThread,
7676
S::make_server(call_site, def_site, mixed_site),
7777
parsed_body,
78-
false,
78+
cfg!(debug_assertions),
7979
);
8080
return res
8181
.map(|it| it.into_subtree(call_site))
@@ -87,7 +87,7 @@ impl ProcMacros {
8787
S::make_server(call_site, def_site, mixed_site),
8888
parsed_attributes,
8989
parsed_body,
90-
false,
90+
cfg!(debug_assertions),
9191
);
9292
return res
9393
.map(|it| it.into_subtree(call_site))

crates/proc-macro-srv/src/server.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,14 @@ impl<S> LiteralFormatter<S> {
9393
let hashes = get_hashes_str(n);
9494
f(&["br", hashes, "\"", symbol, "\"", hashes, suffix])
9595
}
96-
_ => f(&[symbol, suffix]),
96+
bridge::LitKind::CStr => f(&["c\"", symbol, "\"", suffix]),
97+
bridge::LitKind::CStrRaw(n) => {
98+
let hashes = get_hashes_str(n);
99+
f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
100+
}
101+
bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => {
102+
f(&[symbol, suffix])
103+
}
97104
})
98105
}
99106

crates/proc-macro-srv/src/server/rust_analyzer_span.rs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,33 @@ impl server::FreeFunctions for RaSpanServer {
9797
}
9898

9999
let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
100-
let kind = match kind {
101-
LiteralKind::Int { .. } => LitKind::Integer,
102-
LiteralKind::Float { .. } => LitKind::Float,
103-
LiteralKind::Char { .. } => LitKind::Char,
104-
LiteralKind::Byte { .. } => LitKind::Byte,
105-
LiteralKind::Str { .. } => LitKind::Str,
106-
LiteralKind::ByteStr { .. } => LitKind::ByteStr,
107-
LiteralKind::CStr { .. } => LitKind::CStr,
108-
LiteralKind::RawStr { n_hashes } => LitKind::StrRaw(n_hashes.unwrap_or_default()),
109-
LiteralKind::RawByteStr { n_hashes } => {
110-
LitKind::ByteStrRaw(n_hashes.unwrap_or_default())
111-
}
112-
LiteralKind::RawCStr { n_hashes } => LitKind::CStrRaw(n_hashes.unwrap_or_default()),
100+
let (kind, start_offset, end_offset) = match kind {
101+
LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
102+
LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
103+
LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
104+
LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
105+
LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
106+
LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
107+
LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
108+
LiteralKind::RawStr { n_hashes } => (
109+
LitKind::StrRaw(n_hashes.unwrap_or_default()),
110+
2 + n_hashes.unwrap_or_default() as usize,
111+
1 + n_hashes.unwrap_or_default() as usize,
112+
),
113+
LiteralKind::RawByteStr { n_hashes } => (
114+
LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
115+
3 + n_hashes.unwrap_or_default() as usize,
116+
1 + n_hashes.unwrap_or_default() as usize,
117+
),
118+
LiteralKind::RawCStr { n_hashes } => (
119+
LitKind::CStrRaw(n_hashes.unwrap_or_default()),
120+
3 + n_hashes.unwrap_or_default() as usize,
121+
1 + n_hashes.unwrap_or_default() as usize,
122+
),
113123
};
114124

115125
let (lit, suffix) = s.split_at(suffix_start as usize);
126+
let lit = &lit[start_offset..lit.len() - end_offset];
116127
let suffix = match suffix {
117128
"" | "_" => None,
118129
suffix => Some(Symbol::intern(self.interner, suffix)),
@@ -248,12 +259,8 @@ impl server::TokenStream for RaSpanServer {
248259
}
249260
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
250261
bridge::TokenTree::Literal(bridge::Literal {
251-
// FIXME: handle literal kinds
252-
kind: bridge::LitKind::Integer, // dummy
253-
symbol: Symbol::intern(self.interner, &lit.text),
254-
// FIXME: handle suffixes
255-
suffix: None,
256262
span: lit.span,
263+
..server::FreeFunctions::literal_from_str(self, &lit.text).unwrap()
257264
})
258265
}
259266
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => {

crates/proc-macro-srv/src/server/token_id.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -89,22 +89,34 @@ impl server::FreeFunctions for TokenIdServer {
8989
}
9090

9191
let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
92-
let kind = match kind {
93-
LiteralKind::Int { .. } => LitKind::Integer,
94-
LiteralKind::Float { .. } => LitKind::Float,
95-
LiteralKind::Char { .. } => LitKind::Char,
96-
LiteralKind::Byte { .. } => LitKind::Byte,
97-
LiteralKind::Str { .. } => LitKind::Str,
98-
LiteralKind::ByteStr { .. } => LitKind::ByteStr,
99-
LiteralKind::CStr { .. } => LitKind::CStr,
100-
LiteralKind::RawStr { n_hashes } => LitKind::StrRaw(n_hashes.unwrap_or_default()),
101-
LiteralKind::RawByteStr { n_hashes } => {
102-
LitKind::ByteStrRaw(n_hashes.unwrap_or_default())
103-
}
104-
LiteralKind::RawCStr { n_hashes } => LitKind::CStrRaw(n_hashes.unwrap_or_default()),
92+
93+
let (kind, start_offset, end_offset) = match kind {
94+
LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
95+
LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
96+
LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
97+
LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
98+
LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
99+
LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
100+
LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
101+
LiteralKind::RawStr { n_hashes } => (
102+
LitKind::StrRaw(n_hashes.unwrap_or_default()),
103+
2 + n_hashes.unwrap_or_default() as usize,
104+
1 + n_hashes.unwrap_or_default() as usize,
105+
),
106+
LiteralKind::RawByteStr { n_hashes } => (
107+
LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
108+
3 + n_hashes.unwrap_or_default() as usize,
109+
1 + n_hashes.unwrap_or_default() as usize,
110+
),
111+
LiteralKind::RawCStr { n_hashes } => (
112+
LitKind::CStrRaw(n_hashes.unwrap_or_default()),
113+
3 + n_hashes.unwrap_or_default() as usize,
114+
1 + n_hashes.unwrap_or_default() as usize,
115+
),
105116
};
106117

107118
let (lit, suffix) = s.split_at(suffix_start as usize);
119+
let lit = &lit[start_offset..lit.len() - end_offset];
108120
let suffix = match suffix {
109121
"" | "_" => None,
110122
suffix => Some(Symbol::intern(self.interner, suffix)),
@@ -233,12 +245,9 @@ impl server::TokenStream for TokenIdServer {
233245
}
234246
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
235247
bridge::TokenTree::Literal(bridge::Literal {
236-
// FIXME: handle literal kinds
237-
kind: bridge::LitKind::Integer, // dummy
238-
symbol: Symbol::intern(self.interner, &lit.text),
239-
// FIXME: handle suffixes
240-
suffix: None,
241248
span: lit.span,
249+
..server::FreeFunctions::literal_from_str(self, &lit.text)
250+
.unwrap_or_else(|_| panic!("`{}`", lit.text))
242251
})
243252
}
244253
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => {

crates/proc-macro-srv/src/server/token_stream.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,22 +115,17 @@ pub(super) mod token_stream {
115115
}
116116
}
117117

118-
type LexError = String;
119-
120118
/// Attempts to break the string into tokens and parse those tokens into a token stream.
121119
/// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
122120
/// or characters not existing in the language.
123121
/// All tokens in the parsed stream get `Span::call_site()` spans.
124122
///
125123
/// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
126124
/// change these errors into `LexError`s later.
127-
#[rustfmt::skip]
128-
impl<S: tt::Span> /*FromStr for*/ TokenStream<S> {
129-
// type Err = LexError;
130-
131-
pub(crate) fn from_str(src: &str, call_site: S) -> Result<TokenStream<S>, LexError> {
125+
impl<S: tt::Span> TokenStream<S> {
126+
pub(crate) fn from_str(src: &str, call_site: S) -> Result<TokenStream<S>, String> {
132127
let subtree =
133-
mbe::parse_to_token_tree_static_span(call_site, src).ok_or("Failed to parse from mbe")?;
128+
mbe::parse_to_token_tree_static_span(call_site, src).ok_or("lexing error")?;
134129

135130
Ok(TokenStream::with_subtree(subtree))
136131
}

crates/proc-macro-srv/src/tests/mod.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ fn test_fn_like_mk_idents() {
169169
fn test_fn_like_macro_clone_literals() {
170170
assert_expand(
171171
"fn_like_clone_tokens",
172-
r###"1u16, 2_u32, -4i64, 3.14f32, "hello bridge", "suffixed"suffix, r##"raw"##"###,
172+
r###"1u16, 2_u32, -4i64, 3.14f32, "hello bridge", "suffixed"suffix, r##"raw"##, 'a', b'b', c"null""###,
173173
expect![[r###"
174174
SUBTREE $$ 1 1
175175
LITERAL 1u16 1
@@ -181,11 +181,17 @@ fn test_fn_like_macro_clone_literals() {
181181
PUNCH , [alone] 1
182182
LITERAL 3.14f32 1
183183
PUNCH , [alone] 1
184-
LITERAL ""hello bridge"" 1
184+
LITERAL "hello bridge" 1
185185
PUNCH , [alone] 1
186-
LITERAL ""suffixed""suffix 1
186+
LITERAL "suffixed"suffix 1
187187
PUNCH , [alone] 1
188-
LITERAL r##"r##"raw"##"## 1"###]],
188+
LITERAL r##"raw"## 1
189+
PUNCH , [alone] 1
190+
LITERAL 'a' 1
191+
PUNCH , [alone] 1
192+
LITERAL b'b' 1
193+
PUNCH , [alone] 1
194+
LITERAL c"null" 1"###]],
189195
expect![[r###"
190196
SUBTREE $$ SpanData { range: 0..100, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) } SpanData { range: 0..100, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
191197
LITERAL 1u16 SpanData { range: 0..4, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
@@ -197,11 +203,17 @@ fn test_fn_like_macro_clone_literals() {
197203
PUNCH , [alone] SpanData { range: 18..19, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
198204
LITERAL 3.14f32 SpanData { range: 20..27, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
199205
PUNCH , [alone] SpanData { range: 27..28, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
200-
LITERAL ""hello bridge"" SpanData { range: 29..43, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
206+
LITERAL "hello bridge" SpanData { range: 29..43, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
201207
PUNCH , [alone] SpanData { range: 43..44, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
202-
LITERAL ""suffixed""suffix SpanData { range: 45..61, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
208+
LITERAL "suffixed"suffix SpanData { range: 45..61, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
203209
PUNCH , [alone] SpanData { range: 61..62, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
204-
LITERAL r##"r##"raw"##"## SpanData { range: 63..73, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }"###]],
210+
LITERAL r##"raw"## SpanData { range: 63..73, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
211+
PUNCH , [alone] SpanData { range: 73..74, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
212+
LITERAL 'a' SpanData { range: 75..78, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
213+
PUNCH , [alone] SpanData { range: 78..79, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
214+
LITERAL b'b' SpanData { range: 80..84, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
215+
PUNCH , [alone] SpanData { range: 84..85, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }
216+
LITERAL c"null" SpanData { range: 86..93, anchor: SpanAnchor(FileId(42), 2), ctx: SyntaxContextId(0) }"###]],
205217
);
206218
}
207219

0 commit comments

Comments
 (0)