summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/proc-macro-srv
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/proc-macro-srv')
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs12
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs46
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs85
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs49
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_stream.rs64
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs98
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs26
7 files changed, 228 insertions, 152 deletions
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
index dd05e250c..f20e6832f 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
@@ -11,7 +11,7 @@ use libloading::Library;
use memmap2::Mmap;
use object::Object;
use paths::AbsPath;
-use proc_macro_api::{read_dylib_info, ProcMacroKind};
+use proc_macro_api::{msg::TokenId, read_dylib_info, ProcMacroKind};
const NEW_REGISTRAR_SYMBOL: &str = "_rustc_proc_macro_decls_";
@@ -152,9 +152,15 @@ impl Expander {
macro_name: &str,
macro_body: &crate::tt::Subtree,
attributes: Option<&crate::tt::Subtree>,
+ def_site: TokenId,
+ call_site: TokenId,
+ mixed_site: TokenId,
) -> Result<crate::tt::Subtree, String> {
- let result = self.inner.proc_macros.expand(macro_name, macro_body, attributes);
- result.map_err(|e| e.as_str().unwrap_or_else(|| "<unknown error>".to_string()))
+ let result = self
+ .inner
+ .proc_macros
+ .expand(macro_name, macro_body, attributes, def_site, call_site, mixed_site);
+ result.map_err(|e| e.into_string().unwrap_or_default())
}
pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
index 84bd15efb..56529f71d 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
@@ -10,10 +10,10 @@
//! * By **copying** the whole rustc `lib_proc_macro` code, we are able to build this with `stable`
//! rustc rather than `unstable`. (Although in general ABI compatibility is still an issue)…
-#![cfg(feature = "sysroot-abi")]
+#![cfg(any(feature = "sysroot-abi", rust_analyzer))]
#![feature(proc_macro_internals, proc_macro_diagnostic, proc_macro_span)]
-#![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
-#![allow(unreachable_pub)]
+#![warn(rust_2018_idioms, unused_lifetimes)]
+#![allow(unreachable_pub, internal_features)]
extern crate proc_macro;
@@ -32,11 +32,23 @@ use std::{
};
use proc_macro_api::{
- msg::{self, CURRENT_API_VERSION},
+ msg::{self, ExpnGlobals, TokenId, CURRENT_API_VERSION},
ProcMacroKind,
};
-use ::tt::token_id as tt;
+mod tt {
+ pub use proc_macro_api::msg::TokenId;
+
+ pub use ::tt::*;
+
+ pub type Subtree = ::tt::Subtree<TokenId>;
+ pub type TokenTree = ::tt::TokenTree<TokenId>;
+ pub type Delimiter = ::tt::Delimiter<TokenId>;
+ pub type Leaf = ::tt::Leaf<TokenId>;
+ pub type Literal = ::tt::Literal<TokenId>;
+ pub type Punct = ::tt::Punct<TokenId>;
+ pub type Ident = ::tt::Ident<TokenId>;
+}
// see `build.rs`
include!(concat!(env!("OUT_DIR"), "/rustc_version.rs"));
@@ -70,16 +82,28 @@ impl ProcMacroSrv {
None => None,
};
- let macro_body = task.macro_body.to_subtree(CURRENT_API_VERSION);
- let attributes = task.attributes.map(|it| it.to_subtree(CURRENT_API_VERSION));
+ let ExpnGlobals { def_site, call_site, mixed_site, .. } = task.has_global_spans;
+ let def_site = TokenId(def_site as u32);
+ let call_site = TokenId(call_site as u32);
+ let mixed_site = TokenId(mixed_site as u32);
+
+ let macro_body = task.macro_body.to_subtree_unresolved(CURRENT_API_VERSION);
+ let attributes = task.attributes.map(|it| it.to_subtree_unresolved(CURRENT_API_VERSION));
let result = thread::scope(|s| {
let thread = thread::Builder::new()
.stack_size(EXPANDER_STACK_SIZE)
.name(task.macro_name.clone())
.spawn_scoped(s, || {
expander
- .expand(&task.macro_name, &macro_body, attributes.as_ref())
- .map(|it| msg::FlatTree::new(&it, CURRENT_API_VERSION))
+ .expand(
+ &task.macro_name,
+ &macro_body,
+ attributes.as_ref(),
+ def_site,
+ call_site,
+ mixed_site,
+ )
+ .map(|it| msg::FlatTree::new_raw(&it, CURRENT_API_VERSION))
});
let res = match thread {
Ok(handle) => handle.join(),
@@ -136,8 +160,8 @@ pub struct PanicMessage {
}
impl PanicMessage {
- pub fn as_str(&self) -> Option<String> {
- self.message.clone()
+ pub fn into_string(self) -> Option<String> {
+ self.message
}
}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs
index 3c6f32033..716b85d09 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs
@@ -1,16 +1,17 @@
//! Proc macro ABI
use libloading::Library;
-use proc_macro_api::{ProcMacroKind, RustCInfo};
+use proc_macro::bridge;
+use proc_macro_api::{msg::TokenId, ProcMacroKind, RustCInfo};
use crate::{dylib::LoadProcMacroDylibError, server::SYMBOL_INTERNER, tt};
pub(crate) struct ProcMacros {
- exported_macros: Vec<proc_macro::bridge::client::ProcMacro>,
+ exported_macros: Vec<bridge::client::ProcMacro>,
}
-impl From<proc_macro::bridge::PanicMessage> for crate::PanicMessage {
- fn from(p: proc_macro::bridge::PanicMessage) -> Self {
+impl From<bridge::PanicMessage> for crate::PanicMessage {
+ fn from(p: bridge::PanicMessage) -> Self {
Self { message: p.as_str().map(|s| s.to_string()) }
}
}
@@ -31,9 +32,8 @@ impl ProcMacros {
info: RustCInfo,
) -> Result<ProcMacros, LoadProcMacroDylibError> {
if info.version_string == crate::RUSTC_VERSION_STRING {
- let macros = unsafe {
- lib.get::<&&[proc_macro::bridge::client::ProcMacro]>(symbol_name.as_bytes())
- }?;
+ let macros =
+ unsafe { lib.get::<&&[bridge::client::ProcMacro]>(symbol_name.as_bytes()) }?;
return Ok(Self { exported_macros: macros.to_vec() });
}
@@ -45,6 +45,9 @@ impl ProcMacros {
macro_name: &str,
macro_body: &tt::Subtree,
attributes: Option<&tt::Subtree>,
+ def_site: TokenId,
+ call_site: TokenId,
+ mixed_site: TokenId,
) -> Result<tt::Subtree, crate::PanicMessage> {
let parsed_body = crate::server::TokenStream::with_subtree(macro_body.clone());
@@ -54,58 +57,76 @@ impl ProcMacros {
for proc_macro in &self.exported_macros {
match proc_macro {
- proc_macro::bridge::client::ProcMacro::CustomDerive {
- trait_name, client, ..
- } if *trait_name == macro_name => {
+ bridge::client::ProcMacro::CustomDerive { trait_name, client, .. }
+ if *trait_name == macro_name =>
+ {
let res = client.run(
- &proc_macro::bridge::server::SameThread,
- crate::server::RustAnalyzer { interner: &SYMBOL_INTERNER },
+ &bridge::server::SameThread,
+ crate::server::RustAnalyzer {
+ interner: &SYMBOL_INTERNER,
+ call_site,
+ def_site,
+ mixed_site,
+ },
parsed_body,
- true,
+ false,
);
- return res.map(|it| it.into_subtree()).map_err(crate::PanicMessage::from);
+ return res
+ .map(|it| it.into_subtree(call_site))
+ .map_err(crate::PanicMessage::from);
}
- proc_macro::bridge::client::ProcMacro::Bang { name, client }
- if *name == macro_name =>
- {
+ bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => {
let res = client.run(
- &proc_macro::bridge::server::SameThread,
- crate::server::RustAnalyzer { interner: &SYMBOL_INTERNER },
+ &bridge::server::SameThread,
+ crate::server::RustAnalyzer {
+ interner: &SYMBOL_INTERNER,
+ call_site,
+ def_site,
+ mixed_site,
+ },
parsed_body,
- true,
+ false,
);
- return res.map(|it| it.into_subtree()).map_err(crate::PanicMessage::from);
+ return res
+ .map(|it| it.into_subtree(call_site))
+ .map_err(crate::PanicMessage::from);
}
- proc_macro::bridge::client::ProcMacro::Attr { name, client }
- if *name == macro_name =>
- {
+ bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => {
let res = client.run(
- &proc_macro::bridge::server::SameThread,
- crate::server::RustAnalyzer { interner: &SYMBOL_INTERNER },
+ &bridge::server::SameThread,
+ crate::server::RustAnalyzer {
+ interner: &SYMBOL_INTERNER,
+
+ call_site,
+ def_site,
+ mixed_site,
+ },
parsed_attributes,
parsed_body,
- true,
+ false,
);
- return res.map(|it| it.into_subtree()).map_err(crate::PanicMessage::from);
+ return res
+ .map(|it| it.into_subtree(call_site))
+ .map_err(crate::PanicMessage::from);
}
_ => continue,
}
}
- Err(proc_macro::bridge::PanicMessage::String("Nothing to expand".to_string()).into())
+ Err(bridge::PanicMessage::String("Nothing to expand".to_string()).into())
}
pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
self.exported_macros
.iter()
.map(|proc_macro| match proc_macro {
- proc_macro::bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
+ bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
(trait_name.to_string(), ProcMacroKind::CustomDerive)
}
- proc_macro::bridge::client::ProcMacro::Bang { name, .. } => {
+ bridge::client::ProcMacro::Bang { name, .. } => {
(name.to_string(), ProcMacroKind::FuncLike)
}
- proc_macro::bridge::client::ProcMacro::Attr { name, .. } => {
+ bridge::client::ProcMacro::Attr { name, .. } => {
(name.to_string(), ProcMacroKind::Attr)
}
})
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
index fe18451d3..917d8a6e2 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
@@ -11,6 +11,7 @@
use proc_macro::bridge::{self, server};
mod token_stream;
+use proc_macro_api::msg::TokenId;
pub use token_stream::TokenStream;
use token_stream::TokenStreamBuilder;
@@ -43,6 +44,9 @@ pub struct FreeFunctions;
pub struct RustAnalyzer {
// FIXME: store span information here.
pub(crate) interner: SymbolInternerRef,
+ pub call_site: TokenId,
+ pub def_site: TokenId,
+ pub mixed_site: TokenId,
}
impl server::Types for RustAnalyzer {
@@ -54,6 +58,10 @@ impl server::Types for RustAnalyzer {
}
impl server::FreeFunctions for RustAnalyzer {
+ fn injected_env_var(&mut self, _var: &str) -> Option<String> {
+ None
+ }
+
fn track_env_var(&mut self, _var: &str, _value: Option<&str>) {
// FIXME: track env var accesses
// https://github.com/rust-lang/rust/pull/71858
@@ -69,7 +77,7 @@ impl server::FreeFunctions for RustAnalyzer {
kind: bridge::LitKind::Err,
symbol: Symbol::intern(self.interner, s),
suffix: None,
- span: tt::TokenId::unspecified(),
+ span: self.call_site,
})
}
@@ -83,7 +91,7 @@ impl server::TokenStream for RustAnalyzer {
stream.is_empty()
}
fn from_str(&mut self, src: &str) -> Self::TokenStream {
- src.parse().expect("cannot parse string")
+ Self::TokenStream::from_str(src, self.call_site).expect("cannot parse string")
}
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
stream.to_string()
@@ -280,7 +288,7 @@ impl server::Span for RustAnalyzer {
}
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
// FIXME stub
- tt::TokenId::unspecified()
+ self.call_site
}
/// Recent feature, not yet in the proc_macro
///
@@ -317,15 +325,15 @@ impl server::Span for RustAnalyzer {
}
fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span {
// FIXME handle span
- tt::TokenId::unspecified()
+ self.call_site
}
fn end(&mut self, _self_: Self::Span) -> Self::Span {
- tt::TokenId::unspecified()
+ self.call_site
}
fn start(&mut self, _self_: Self::Span) -> Self::Span {
- tt::TokenId::unspecified()
+ self.call_site
}
fn line(&mut self, _span: Self::Span) -> usize {
@@ -349,9 +357,9 @@ impl server::Symbol for RustAnalyzer {
impl server::Server for RustAnalyzer {
fn globals(&mut self) -> bridge::ExpnGlobals<Self::Span> {
bridge::ExpnGlobals {
- def_site: Span::unspecified(),
- call_site: Span::unspecified(),
- mixed_site: Span::unspecified(),
+ def_site: self.def_site,
+ call_site: self.call_site,
+ mixed_site: self.mixed_site,
}
}
@@ -430,16 +438,16 @@ mod tests {
token_trees: vec![
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
text: "struct".into(),
- span: tt::TokenId::unspecified(),
+ span: tt::TokenId(0),
})),
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
text: "T".into(),
- span: tt::TokenId::unspecified(),
+ span: tt::TokenId(0),
})),
tt::TokenTree::Subtree(tt::Subtree {
delimiter: tt::Delimiter {
- open: tt::TokenId::unspecified(),
- close: tt::TokenId::unspecified(),
+ open: tt::TokenId(0),
+ close: tt::TokenId(0),
kind: tt::DelimiterKind::Brace,
},
token_trees: vec![],
@@ -452,33 +460,32 @@ mod tests {
#[test]
fn test_ra_server_from_str() {
- use std::str::FromStr;
let subtree_paren_a = tt::TokenTree::Subtree(tt::Subtree {
delimiter: tt::Delimiter {
- open: tt::TokenId::unspecified(),
- close: tt::TokenId::unspecified(),
+ open: tt::TokenId(0),
+ close: tt::TokenId(0),
kind: tt::DelimiterKind::Parenthesis,
},
token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
text: "a".into(),
- span: tt::TokenId::unspecified(),
+ span: tt::TokenId(0),
}))],
});
- let t1 = TokenStream::from_str("(a)").unwrap();
+ let t1 = TokenStream::from_str("(a)", tt::TokenId(0)).unwrap();
assert_eq!(t1.token_trees.len(), 1);
assert_eq!(t1.token_trees[0], subtree_paren_a);
- let t2 = TokenStream::from_str("(a);").unwrap();
+ let t2 = TokenStream::from_str("(a);", tt::TokenId(0)).unwrap();
assert_eq!(t2.token_trees.len(), 2);
assert_eq!(t2.token_trees[0], subtree_paren_a);
- let underscore = TokenStream::from_str("_").unwrap();
+ let underscore = TokenStream::from_str("_", tt::TokenId(0)).unwrap();
assert_eq!(
underscore.token_trees[0],
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
text: "_".into(),
- span: tt::TokenId::unspecified(),
+ span: tt::TokenId(0),
}))
);
}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_stream.rs
index 2589d8b64..36be88250 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_stream.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_stream.rs
@@ -1,5 +1,7 @@
//! TokenStream implementation used by sysroot ABI
+use proc_macro_api::msg::TokenId;
+
use crate::tt::{self, TokenTree};
#[derive(Debug, Default, Clone)]
@@ -20,8 +22,15 @@ impl TokenStream {
}
}
- pub(crate) fn into_subtree(self) -> tt::Subtree {
- tt::Subtree { delimiter: tt::Delimiter::UNSPECIFIED, token_trees: self.token_trees }
+ pub(crate) fn into_subtree(self, call_site: TokenId) -> tt::Subtree {
+ tt::Subtree {
+ delimiter: tt::Delimiter {
+ open: call_site,
+ close: call_site,
+ kind: tt::DelimiterKind::Invisible,
+ },
+ token_trees: self.token_trees,
+ }
}
pub(super) fn is_empty(&self) -> bool {
@@ -84,7 +93,7 @@ pub(super) struct TokenStreamBuilder {
/// pub(super)lic implementation details for the `TokenStream` type, such as iterators.
pub(super) mod token_stream {
- use std::str::FromStr;
+ use proc_macro_api::msg::TokenId;
use super::{tt, TokenStream, TokenTree};
@@ -109,14 +118,15 @@ pub(super) mod token_stream {
///
/// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
/// change these errors into `LexError`s later.
- impl FromStr for TokenStream {
- type Err = LexError;
+ #[rustfmt::skip]
+ impl /*FromStr for*/ TokenStream {
+ // type Err = LexError;
- fn from_str(src: &str) -> Result<TokenStream, LexError> {
- let (subtree, _token_map) =
- mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?;
+ pub(crate) fn from_str(src: &str, call_site: TokenId) -> Result<TokenStream, LexError> {
+ let subtree =
+ mbe::parse_to_token_tree_static_span(call_site, src).ok_or("Failed to parse from mbe")?;
- let subtree = subtree_replace_token_ids_with_unspecified(subtree);
+ let subtree = subtree_replace_token_ids_with_call_site(subtree,call_site);
Ok(TokenStream::with_subtree(subtree))
}
}
@@ -127,43 +137,39 @@ pub(super) mod token_stream {
}
}
- fn subtree_replace_token_ids_with_unspecified(subtree: tt::Subtree) -> tt::Subtree {
+ fn subtree_replace_token_ids_with_call_site(
+ subtree: tt::Subtree,
+ call_site: TokenId,
+ ) -> tt::Subtree {
tt::Subtree {
- delimiter: tt::Delimiter {
- open: tt::TokenId::UNSPECIFIED,
- close: tt::TokenId::UNSPECIFIED,
- ..subtree.delimiter
- },
+ delimiter: tt::Delimiter { open: call_site, close: call_site, ..subtree.delimiter },
token_trees: subtree
.token_trees
.into_iter()
- .map(token_tree_replace_token_ids_with_unspecified)
+ .map(|it| token_tree_replace_token_ids_with_call_site(it, call_site))
.collect(),
}
}
- fn token_tree_replace_token_ids_with_unspecified(tt: tt::TokenTree) -> tt::TokenTree {
+ fn token_tree_replace_token_ids_with_call_site(
+ tt: tt::TokenTree,
+ call_site: TokenId,
+ ) -> tt::TokenTree {
match tt {
tt::TokenTree::Leaf(leaf) => {
- tt::TokenTree::Leaf(leaf_replace_token_ids_with_unspecified(leaf))
+ tt::TokenTree::Leaf(leaf_replace_token_ids_with_call_site(leaf, call_site))
}
tt::TokenTree::Subtree(subtree) => {
- tt::TokenTree::Subtree(subtree_replace_token_ids_with_unspecified(subtree))
+ tt::TokenTree::Subtree(subtree_replace_token_ids_with_call_site(subtree, call_site))
}
}
}
- fn leaf_replace_token_ids_with_unspecified(leaf: tt::Leaf) -> tt::Leaf {
+ fn leaf_replace_token_ids_with_call_site(leaf: tt::Leaf, call_site: TokenId) -> tt::Leaf {
match leaf {
- tt::Leaf::Literal(lit) => {
- tt::Leaf::Literal(tt::Literal { span: tt::TokenId::unspecified(), ..lit })
- }
- tt::Leaf::Punct(punct) => {
- tt::Leaf::Punct(tt::Punct { span: tt::TokenId::unspecified(), ..punct })
- }
- tt::Leaf::Ident(ident) => {
- tt::Leaf::Ident(tt::Ident { span: tt::TokenId::unspecified(), ..ident })
- }
+ tt::Leaf::Literal(lit) => tt::Leaf::Literal(tt::Literal { span: call_site, ..lit }),
+ tt::Leaf::Punct(punct) => tt::Leaf::Punct(tt::Punct { span: call_site, ..punct }),
+ tt::Leaf::Ident(ident) => tt::Leaf::Ident(tt::Ident { span: call_site, ..ident }),
}
}
}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
index 04a0ae7bc..b04e3ca19 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
@@ -8,7 +8,7 @@ use expect_test::expect;
#[test]
fn test_derive_empty() {
- assert_expand("DeriveEmpty", r#"struct S;"#, expect!["SUBTREE $$ 4294967295 4294967295"]);
+ assert_expand("DeriveEmpty", r#"struct S;"#, expect!["SUBTREE $$ 1 1"]);
}
#[test]
@@ -17,12 +17,12 @@ fn test_derive_error() {
"DeriveError",
r#"struct S;"#,
expect![[r##"
- SUBTREE $$ 4294967295 4294967295
- IDENT compile_error 4294967295
- PUNCH ! [alone] 4294967295
- SUBTREE () 4294967295 4294967295
- LITERAL "#[derive(DeriveError)] struct S ;" 4294967295
- PUNCH ; [alone] 4294967295"##]],
+ SUBTREE $$ 1 1
+ IDENT compile_error 1
+ PUNCH ! [alone] 1
+ SUBTREE () 1 1
+ LITERAL "#[derive(DeriveError)] struct S ;" 1
+ PUNCH ; [alone] 1"##]],
);
}
@@ -32,14 +32,14 @@ fn test_fn_like_macro_noop() {
"fn_like_noop",
r#"ident, 0, 1, []"#,
expect![[r#"
- SUBTREE $$ 4294967295 4294967295
- IDENT ident 4294967295
- PUNCH , [alone] 4294967295
- LITERAL 0 4294967295
- PUNCH , [alone] 4294967295
- LITERAL 1 4294967295
- PUNCH , [alone] 4294967295
- SUBTREE [] 4294967295 4294967295"#]],
+ SUBTREE $$ 1 1
+ IDENT ident 1
+ PUNCH , [alone] 1
+ LITERAL 0 1
+ PUNCH , [alone] 1
+ LITERAL 1 1
+ PUNCH , [alone] 1
+ SUBTREE [] 1 1"#]],
);
}
@@ -49,10 +49,10 @@ fn test_fn_like_macro_clone_ident_subtree() {
"fn_like_clone_tokens",
r#"ident, []"#,
expect![[r#"
- SUBTREE $$ 4294967295 4294967295
- IDENT ident 4294967295
- PUNCH , [alone] 4294967295
- SUBTREE [] 4294967295 4294967295"#]],
+ SUBTREE $$ 1 1
+ IDENT ident 1
+ PUNCH , [alone] 1
+ SUBTREE [] 1 1"#]],
);
}
@@ -62,8 +62,8 @@ fn test_fn_like_macro_clone_raw_ident() {
"fn_like_clone_tokens",
"r#async",
expect![[r#"
- SUBTREE $$ 4294967295 4294967295
- IDENT r#async 4294967295"#]],
+ SUBTREE $$ 1 1
+ IDENT r#async 1"#]],
);
}
@@ -73,14 +73,14 @@ fn test_fn_like_mk_literals() {
"fn_like_mk_literals",
r#""#,
expect![[r#"
- SUBTREE $$ 4294967295 4294967295
- LITERAL b"byte_string" 4294967295
- LITERAL 'c' 4294967295
- LITERAL "string" 4294967295
- LITERAL 3.14f64 4294967295
- LITERAL 3.14 4294967295
- LITERAL 123i64 4294967295
- LITERAL 123 4294967295"#]],
+ SUBTREE $$ 1 1
+ LITERAL b"byte_string" 1
+ LITERAL 'c' 1
+ LITERAL "string" 1
+ LITERAL 3.14f64 1
+ LITERAL 3.14 1
+ LITERAL 123i64 1
+ LITERAL 123 1"#]],
);
}
@@ -90,9 +90,9 @@ fn test_fn_like_mk_idents() {
"fn_like_mk_idents",
r#""#,
expect![[r#"
- SUBTREE $$ 4294967295 4294967295
- IDENT standard 4294967295
- IDENT r#raw 4294967295"#]],
+ SUBTREE $$ 1 1
+ IDENT standard 1
+ IDENT r#raw 1"#]],
);
}
@@ -102,17 +102,17 @@ fn test_fn_like_macro_clone_literals() {
"fn_like_clone_tokens",
r#"1u16, 2_u32, -4i64, 3.14f32, "hello bridge""#,
expect![[r#"
- SUBTREE $$ 4294967295 4294967295
- LITERAL 1u16 4294967295
- PUNCH , [alone] 4294967295
- LITERAL 2_u32 4294967295
- PUNCH , [alone] 4294967295
- PUNCH - [alone] 4294967295
- LITERAL 4i64 4294967295
- PUNCH , [alone] 4294967295
- LITERAL 3.14f32 4294967295
- PUNCH , [alone] 4294967295
- LITERAL "hello bridge" 4294967295"#]],
+ SUBTREE $$ 1 1
+ LITERAL 1u16 1
+ PUNCH , [alone] 1
+ LITERAL 2_u32 1
+ PUNCH , [alone] 1
+ PUNCH - [alone] 1
+ LITERAL 4i64 1
+ PUNCH , [alone] 1
+ LITERAL 3.14f32 1
+ PUNCH , [alone] 1
+ LITERAL "hello bridge" 1"#]],
);
}
@@ -126,12 +126,12 @@ fn test_attr_macro() {
r#"mod m {}"#,
r#"some arguments"#,
expect![[r##"
- SUBTREE $$ 4294967295 4294967295
- IDENT compile_error 4294967295
- PUNCH ! [alone] 4294967295
- SUBTREE () 4294967295 4294967295
- LITERAL "#[attr_error(some arguments)] mod m {}" 4294967295
- PUNCH ; [alone] 4294967295"##]],
+ SUBTREE $$ 1 1
+ IDENT compile_error 1
+ PUNCH ! [alone] 1
+ SUBTREE () 1 1
+ LITERAL "#[attr_error(some arguments)] mod m {}" 1
+ PUNCH ; [alone] 1"##]],
);
}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
index 49b4d973b..c12096d14 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
@@ -1,18 +1,18 @@
//! utils used in proc-macro tests
use expect_test::Expect;
-use std::str::FromStr;
+use proc_macro_api::msg::TokenId;
use crate::{dylib, proc_macro_test_dylib_path, ProcMacroSrv};
-fn parse_string(code: &str) -> Option<crate::server::TokenStream> {
+fn parse_string(code: &str, call_site: TokenId) -> Option<crate::server::TokenStream> {
// This is a bit strange. We need to parse a string into a token stream into
// order to create a tt::SubTree from it in fixtures. `into_subtree` is
// implemented by all the ABIs we have so we arbitrarily choose one ABI to
// write a `parse_string` function for and use that. The tests don't really
// care which ABI we're using as the `into_subtree` function isn't part of
// the ABI and shouldn't change between ABI versions.
- crate::server::TokenStream::from_str(code).ok()
+ crate::server::TokenStream::from_str(code, call_site).ok()
}
pub fn assert_expand(macro_name: &str, ra_fixture: &str, expect: Expect) {
@@ -24,12 +24,24 @@ pub fn assert_expand_attr(macro_name: &str, ra_fixture: &str, attr_args: &str, e
}
fn assert_expand_impl(macro_name: &str, input: &str, attr: Option<&str>, expect: Expect) {
+ let def_site = TokenId(0);
+ let call_site = TokenId(1);
+ let mixed_site = TokenId(2);
let path = proc_macro_test_dylib_path();
let expander = dylib::Expander::new(&path).unwrap();
- let fixture = parse_string(input).unwrap();
- let attr = attr.map(|attr| parse_string(attr).unwrap().into_subtree());
-
- let res = expander.expand(macro_name, &fixture.into_subtree(), attr.as_ref()).unwrap();
+ let fixture = parse_string(input, call_site).unwrap();
+ let attr = attr.map(|attr| parse_string(attr, call_site).unwrap().into_subtree(call_site));
+
+ let res = expander
+ .expand(
+ macro_name,
+ &fixture.into_subtree(call_site),
+ attr.as_ref(),
+ def_site,
+ call_site,
+ mixed_site,
+ )
+ .unwrap();
expect.assert_eq(&format!("{res:?}"));
}