Spurious "expected integer or floating pointer number after `-` (rust-analyzer macro-error)" (with reproduction)
rust-analyzer version: rust-analyzer 1.89.0-nightly (573a015 2025-06-12)
rustc version: rustc 1.89.0-nightly (573a01569 2025-06-12) binary: rustc commit-hash: 573a01569000d395498a5f98f916d6e5305ac81a commit-date: 2025-06-12 host: x86_64-unknown-linux-gnu release: 1.89.0-nightly LLVM version: 20.1.5
editor or extension: Zed 0.190.5 901b05221cf3f1946638c44a81c93cffdaf1cdf5, also reproducible on VS Code 1.100.3 258e40fedc6cb8edf399a463ce3a9d32e7e1f6f3
relevant settings: (eg. client settings, or environment variables like CARGO, RUSTC, RUSTUP_HOME or CARGO_HOME)
repository link (if public, optional): (eg. rust-analyzer) https://github.com/sourcefrog/rust-analyzer-repro (minimized from https://github.com/sourcefrog/cargo-mutants)
code snippet to reproduce:
use schemars::JsonSchema;
use serde::Deserialize;
#[derive(Default, Deserialize, JsonSchema)]
pub struct Config {
/// Pass `--cap-lints` to rustc.
pub cap_lints: bool,
/// Skip calls to functions or methods with these names.
///
/// This is combined with values from the --skip-calls argument.
pub skip_calls: Vec<String>,
/// Use built-in defaults for `skip_calls` in addition to any explicit values.
pub skip_calls_defaults: Option<bool>,
}
errors:
; rust-analyzer diagnostics .
processing crate: rust_analyzer_repro, module: /home/mbp/src/rust-analyzer-repro/src/lib.rs
Error Ra("macro-error", Error) from LineCol { line: 5, col: 4 } to LineCol { line: 5, col: 36 }: expected integer or floating pointer number after '-'
Error Ra("macro-error", Error) from LineCol { line: 5, col: 4 } to LineCol { line: 5, col: 36 }: expected integer or floating pointer number after '-'
Error Ra("macro-error", Error) from LineCol { line: 7, col: 4 } to LineCol { line: 9, col: 68 }: expected integer or floating pointer number after '-'
Error Ra("macro-error", Error) from LineCol { line: 7, col: 4 } to LineCol { line: 9, col: 68 }: expected integer or floating pointer number after '-'
Error Ra("macro-error", Error) from LineCol { line: 11, col: 4 } to LineCol { line: 11, col: 82 }: expected integer or floating pointer number after '-'
Error Ra("macro-error", Error) from LineCol { line: 11, col: 4 } to LineCol { line: 11, col: 82 }: expected integer or floating pointer number after '-'
diagnostic scan complete
Error: diagnostic error detected
Stack backtrace:
0: <anyhow::Error>::msg::<&str>
1: std::sys::backtrace::__rust_begin_short_backtrace::<<stdx::thread::Builder>::spawn<<rust_analyzer::cli::flags::Diagnostics>::run::{closure#0}, core::result::Result<(), anyhow::Error>>::{closure#0}, core::result::Result<(), anyhow::Error>>
2: <<std::thread::Builder>::spawn_unchecked_<<stdx::thread::Builder>::spawn<<rust_analyzer::cli::flags::Diagnostics>::run::{closure#0}, core::result::Result<(), anyhow::Error>>::{closure#0}, core::result::Result<(), anyhow::Error>>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
3: std::sys::pal::unix::thread::Thread::new::thread_start
4: start_thread
at ./nptl/pthread_create.c:442:8
5: __GI___clone3
at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81:0
cargo build doesn't error on this code.
Incidentally there's a typo "floating pointer" rather than "floating point".
Specifically the problem seems to come from the combination of
- Using the
JsonSchemaderive macro. - Having a docstring containing the sequence
--. (jsonschema extracts the docstrings into metadata, like clap does.)
Since it compiles fine I think it's probably a RA bug.
cargo expand seems to show, as you'd expect, that the -- only goes into a quoted string plus the docstring in the output. So, it's a bit surprising that RA is trying to parse it as Rust code. But maybe it's trying to find references to types etc within docstrings.
The problem still reproduces whether I have backticks or not, i.e.
/// A docstring with a -- causes a problem.
/// A docstring with a `--` causes a problem.
Grepping in the r-a codebase the thing that causes that error is concat!().
Likely our () wrapping for expression fragments at fault again
I got a backtrace in case that helps:
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/573a01569000d395498a5f98f916d6e5305ac81a/library/std/src/panicking.rs:697:5
1: core::panicking::panic_fmt
at /rustc/573a01569000d395498a5f98f916d6e5305ac81a/library/core/src/panicking.rs:75:14
2: core::panicking::panic_display
at /rustc/573a01569000d395498a5f98f916d6e5305ac81a/library/core/src/panicking.rs:268:5
3: core::panicking::panic_explicit
at /rustc/573a01569000d395498a5f98f916d6e5305ac81a/library/core/src/panicking.rs:241:5
4: hir_expand::builtin::fn_macro::concat_expand::panic_cold_explicit
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic.rs:88:13
5: hir_expand::builtin::fn_macro::concat_expand
at ./crates/hir-expand/src/builtin/fn_macro.rs:538:29
6: hir_expand::builtin::fn_macro::EagerExpander::expand
at ./crates/hir-expand/src/builtin/fn_macro.rs:95:9
7: hir_expand::db::macro_expand
at ./crates/hir-expand/src/db.rs:648:42
8: hir_expand::db::parse_macro_expansion
at ./crates/hir-expand/src/db.rs:363:62
9: <<DB as hir_expand::db::ExpandDatabase>::parse_macro_expansion::parse_macro_expansion_shim::Configuration_ as salsa::function::Configuration>::execute::inner_
at ./crates/hir-expand/src/db.rs:71:8
10: <<DB as hir_expand::db::ExpandDatabase>::parse_macro_expansion::parse_macro_expansion_shim::Configuration_ as salsa::function::Configuration>::execute
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-macro-rules-0.22.0/src/setup_tracked_fn.rs:207:21
11: salsa::function::execute::<impl salsa::function::IngredientImpl<C>>::execute_query
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/execute.rs:271:25
12: salsa::function::execute::<impl salsa::function::IngredientImpl<C>>::execute
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/execute.rs:44:17
13: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::fetch_cold
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:200:25
14: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::fetch_cold_with_retry
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:88:25
15: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::refresh_memo::{{closure}}
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:47:34
16: core::option::Option<T>::or_else
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1609:21
17: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::refresh_memo
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:47:18
18: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::fetch
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:18:25
19: <DB as hir_expand::db::ExpandDatabase>::parse_macro_expansion::parse_macro_expansion_shim::{{closure}}
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-macro-rules-0.22.0/src/setup_tracked_fn.rs:365:60
20: salsa::attach::Attached::attach
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/attach.rs:89:9
21: salsa::attach::attach::{{closure}}
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/attach.rs:113:15
22: std::thread::local::LocalKey<T>::try_with
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:315:12
23: std::thread::local::LocalKey<T>::with
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:279:20
24: salsa::attach::attach
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/attach.rs:111:14
25: <DB as hir_expand::db::ExpandDatabase>::parse_macro_expansion::parse_macro_expansion_shim
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-macro-rules-0.22.0/src/setup_tracked_fn.rs:357:13
26: <DB as hir_expand::db::ExpandDatabase>::parse_macro_expansion
at ./crates/hir-expand/src/db.rs:52:1
27: hir_def::expr_store::expander::Expander::within_limit
at ./crates/hir-def/src/expr_store/expander.rs:202:22
28: hir_def::expr_store::expander::Expander::enter_expand
at ./crates/hir-def/src/expr_store/expander.rs:96:27
29: hir_def::expr_store::lower::ExprCollector::collect_macro_call
at ./crates/hir-def/src/expr_store/lower.rs:1965:31
30: hir_def::expr_store::lower::ExprCollector::maybe_collect_expr
at ./crates/hir-def/src/expr_store/lower.rs:1437:31
31: hir_def::expr_store::lower::ExprCollector::maybe_collect_expr::{{closure}}
at ./crates/hir-def/src/expr_store/lower.rs:1130:61
32: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:294:21
33: core::iter::traits::iterator::Iterator::find_map::check::{{closure}}
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2914:32
34: core::iter::traits::iterator::Iterator::try_fold
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2426:21
35: core::iter::traits::iterator::Iterator::find_map
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2920:14
36: <core::iter::adapters::filter_map::FilterMap<I,F> as core::iter::traits::iterator::Iterator>::next
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/filter_map.rs:64:19
37: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/spec_from_iter_nested.rs:25:41
38: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/spec_from_iter.rs:34:9
39: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3438:9
40: core::iter::traits::iterator::Iterator::collect
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2027:9
41: alloc::boxed::iter::<impl core::iter::traits::collect::FromIterator<I> for alloc::boxed::Box<[I]>>::from_iter
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed/iter.rs:144:26
42: core::iter::traits::iterator::Iterator::collect
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2027:9
43: hir_def::expr_store::lower::ExprCollector::maybe_collect_expr
at ./crates/hir-def/src/expr_store/lower.rs:1130:84
44: hir_def::expr_store::lower::ExprCollector::collect_expr
at ./crates/hir-def/src/expr_store/lower.rs:1023:14
45: hir_def::expr_store::lower::ExprCollector::collect_expr_opt
at ./crates/hir-def/src/expr_store/lower.rs:2021:32
46: hir_def::expr_store::lower::ExprCollector::collect::{{closure}}
at ./crates/hir-def/src/expr_store/lower.rs:932:22
47: hir_def::expr_store::lower::ExprCollector::with_label_rib
at ./crates/hir-def/src/expr_store/lower.rs:2636:19
48: hir_def::expr_store::lower::ExprCollector::collect
at ./crates/hir-def/src/expr_store/lower.rs:918:14
49: hir_def::expr_store::lower::lower_body
at ./crates/hir-def/src/expr_store/lower.rs:160:31
50: hir_def::expr_store::body::Body::body_with_source_map_query
at ./crates/hir-def/src/expr_store/body.rs:106:13
51: <<DB as hir_def::db::DefDatabase>::body_with_source_map::body_with_source_map_shim::Configuration_ as salsa::function::Configuration>::execute::inner_
at ./crates/hir-def/src/db.rs:274:21
52: <<DB as hir_def::db::DefDatabase>::body_with_source_map::body_with_source_map_shim::Configuration_ as salsa::function::Configuration>::execute
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-macro-rules-0.22.0/src/setup_tracked_fn.rs:207:21
53: salsa::function::execute::<impl salsa::function::IngredientImpl<C>>::execute_query
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/execute.rs:271:25
54: salsa::function::execute::<impl salsa::function::IngredientImpl<C>>::execute
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/execute.rs:44:17
55: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::fetch_cold
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:200:25
56: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::fetch_cold_with_retry
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:88:25
57: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::refresh_memo::{{closure}}
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:47:34
58: core::option::Option<T>::or_else
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1609:21
59: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::refresh_memo
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:47:18
60: salsa::function::fetch::<impl salsa::function::IngredientImpl<C>>::fetch
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/function/fetch.rs:18:25
61: <DB as hir_def::db::DefDatabase>::body_with_source_map::body_with_source_map_shim::{{closure}}
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-macro-rules-0.22.0/src/setup_tracked_fn.rs:365:60
62: salsa::attach::Attached::attach
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/attach.rs:89:9
63: salsa::attach::attach::{{closure}}
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/attach.rs:113:15
64: std::thread::local::LocalKey<T>::try_with
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:315:12
65: std::thread::local::LocalKey<T>::with
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:279:20
66: salsa::attach::attach
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/attach.rs:111:14
67: <DB as hir_def::db::DefDatabase>::body_with_source_map::body_with_source_map_shim
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-macro-rules-0.22.0/src/setup_tracked_fn.rs:357:13
68: <DB as hir_def::db::DefDatabase>::body_with_source_map
at ./crates/hir-def/src/db.rs:104:1
69: hir::DefWithBody::diagnostics
at ./crates/hir/src/lib.rs:1885:37
70: hir::ModuleDef::diagnostics
at ./crates/hir/src/lib.rs:425:21
71: hir::Module::diagnostics
at ./crates/hir/src/lib.rs:735:37
72: hir::DefWithBody::diagnostics
at ./crates/hir/src/lib.rs:1897:60
73: hir::AssocItem::diagnostics
at ./crates/hir/src/lib.rs:3512:41
74: hir::Module::diagnostics
at ./crates/hir/src/lib.rs:916:39
75: hir::DefWithBody::diagnostics
at ./crates/hir/src/lib.rs:1897:60
76: hir::ModuleDef::diagnostics
at ./crates/hir/src/lib.rs:425:21
77: hir::Module::diagnostics
at ./crates/hir/src/lib.rs:735:37
78: ide_diagnostics::semantic_diagnostics
at ./crates/ide-diagnostics/src/lib.rs:400:19
79: ide_diagnostics::full_diagnostics
at ./crates/ide-diagnostics/src/lib.rs:541:16
80: ide::Analysis::full_diagnostics::{{closure}}
at ./crates/ide/src/lib.rs:739:27
81: ide::Analysis::with_db::{{closure}}
at ./crates/ide/src/lib.rs:867:29
82: std::panicking::catch_unwind::do_call
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:589:40
83: __rust_try
84: std::panicking::catch_unwind
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:552:19
85: std::panic::catch_unwind
at /home/mbp/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:359:14
86: salsa::cancelled::Cancelled::catch
at /home/mbp/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/salsa-0.22.0/src/cancelled.rs:34:15
87: ide::Analysis::with_db
at ./crates/ide/src/lib.rs:867:9
88: ide::Analysis::full_diagnostics
at ./crates/ide/src/lib.rs:739:14
89: rust_analyzer::cli::diagnostics::<impl rust_analyzer::cli::flags::Diagnostics>::run_
at ./crates/rust-analyzer/src/cli/diagnostics.rs:71:22
90: rust_analyzer::cli::diagnostics::<impl rust_analyzer::cli::flags::Diagnostics>::run::{{closure}}
at ./crates/rust-analyzer/src/cli/diagnostics.rs:23:24
91: stdx::thread::Builder::spawn::{{closure}}
at ./crates/stdx/src/thread.rs:68:13
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
And it seems to be coming from this concat! call, probably:
https://github.com/GREsau/schemars/blob/e4653c7c738299ca865269970ec1aad6b77f6a01/schemars_derive/src/attr/doc.rs#L5-L37
I poked around but it looks like it'll take more time than I have free at the moment to understand how RA does macro expansion. I don't understand why it is ever treating this text as something that should be parsed. It's only ever inside a docstring or quoted string, as far as I can see.
Without digging deep, I suspect the problem is that r-a adds parentheses in the call to concat!(), causing errors.
This will likely require a big fix, so if you don't want to invest a lot of time in it I suggest you don't try to fix this.
Thanks, I won't claim this.
I tried a couple more things, one of which was to make the proc macro print out what it's getting as input.
From rustc it gets the right doc attribute:
macro called with doc: TokenStream [Punct { ch: ':', spacing: Joint, span: #11 bytes(103..113) }, Punct { ch: ':', spacing: Alone, span: #11 bytes(103..113) }, Ident { ident: "core", span: #11 bytes(103..113) }, Punct { ch: ':', spacing: Joint, span: #11 bytes(103..113) }, Punct { ch: ':', spacing: Alone, span: #11 bytes(103..113) }, Ident { ident: "concat", span: #11 bytes(103..113) }, Punct { ch: '!', spacing: Alone, span: #11 bytes(103..113) }, Group { delimiter: Parenthesis, stream: TokenStream [Literal { kind: Str, symbol: "A docstring with a - causes a problem.", suffix: None, span: #11 bytes(103..113) }], span: #11 bytes(103..113) }]
versus RA
macro called with doc: TokenStream [Punct { ch: ':', spacing: Joint, span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }, Punct { ch: ':', spacing: Alone, span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }, Ident { ident: "core", span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }, Punct { ch: ':', spacing: Joint, span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }, Punct { ch: ':', spacing: Alone, span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }, Ident { ident: "concat", span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }, Punct { ch: '!', spacing: Alone, span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }, Group { delimiter: Parenthesis, stream: TokenStream [Punct { ch: '-', spacing: Alone, span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }, Literal { kind: Str, symbol: " causes a problem.", suffix: None, span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }], span: SpanData { range: 238..264, anchor: SpanAnchor(EditionedFileId(28, Edition2021), 15), ctx: SyntaxContext(87835) } }]
The same problem shows up if I make it an explicit attribute rather than a docstring:
#[doc = "A docstring with a - causes a problem."]
I wonder if there's some code that's trying to interpret or preprocess attributes before they're passed to proc macros?
We ran into the same problem using the inventory::submit macro inside of a proc macro. r-a reported an error but cargo was fine.
The only relevant - character in the expansion appeared to be in this
#[cfg_attr(target_family = "wasm",inventory::__private::attr(any(all(stable,since(1.85)),since(2024-12-18)),link_section = ".init_array",),)]
#[cfg_attr(
any(target_os = "macos", target_os = "ios"),
link_section = "__DATA,__mod_init_func,mod_init_funcs"
)]
#[cfg_attr(windows, link_section = ".CRT$XCU")]
static __CTOR: unsafe extern "C" fn() = __ctor;
We think it was complaining about the 2024-12-18. We were able to workaround by making this expansion conditional using cfg(rust_analyzer) in https://github.com/vercel/next.js/pull/83447
@lukesandberg This - isn't the problem (unless you're compiling for WASM, then maybe) and I'm unable to reproduce the r-a error on your codebase.
We were seeing this when developing on MacOs with the R-A plugins for VsCode/Cursor. Admittedly that - being the problem was a guess, but we only started seeing this error message after adopting inventory in our proc macros, and the PR that makes it conditional appears to resolve it. We are also using the concat! and module_path! macros in our proc macro 'generated code'. So perhaps it is related to one of those?
editor: Cursor 1.5.9 rust-analyzer-version: 0.3.2593 $ rustc --version rustc 1.89.0-nightly (59aa1e873 2025-06-03) $ cargo --version cargo 1.89.0-nightly (64a124607 2025-05-30)
Also the relevant commits are only on the canary branch if perhaps that is the problem
I cannot reproduce the error on VSCode on Windows on the canary branch. So it's either a MacOS-specific problem or a Cursor-specific problem. Since I don't own a Mac system and don't want to download Cursor, I can't help further, but if you can pivot the issue (test on Windows/Linux system or on VSCode, or better, on both) or minimize the issue, perhaps I will be able to help.
@ChayimFriedman2 I've reproduced the issue in https://github.com/vercel/next.js on Debian with neovim. RA is configured using https://github.com/mrcjkb/rustaceanvim.
I isolated the issue to the use of concat! here
https://github.com/vercel/next.js/blob/canary/turbopack/crates/turbo-tasks-macros/src/global_name.rs#L10
our proc-macro uses that to compute a string that we embed in a bunch of places. (so my guess above about inventory was wrong, sorry about that). This lines up more with the investigation above as well.
That is more reasonable, but I still do not understand. First, why did disabling inventory eliminate the issue? Second, why is it problematic? It seems to call concat!() with string literals, stringify!(), and module_path!() only. Do you know which macro causes the error, and can you post the result of "Expand macro recursively"?
first, why did disabling inventory eliminate the issue?
Well it didn't, i just got confused. I think all the issues disappeared when i hit 'rebuild proc macros and build scripts' and just took a really long time to show up even though it appeared that the check action had completed.
Second, why is it problematic? It seems to call concat!() with string literals, stringify!(), and module_path!() only. Do you know which macro causes the error, and can you post the result of "Expand macro recursively"?
Good question. Whenever i expand this macro with R-A it just expands that concat to "" whereas cargo expand shows the expected result like "turbopack-core@turbopack_core::ident::test" So i went and selectively disabled each part of the concat
quote! { concat!(#crate_name, "@", module_path!(), "::", #local_name)}
It turns our that removing #crate_name fixes it
crate_name is a local variable
let crate_name =
std::env::var("CARGO_PKG_NAME").unwrap_or_else(|_| "unknown_crate".to_string());
So that string would tend to have - characters in it, e.g. "turbo-tasks". Is that the culprit here? R-A isn't interpreting the expansion there as a string literal?
Similarly if i replace #crate_name with a literal "foo-bar" that works.
I cannot reproduce the error on VSCode on Windows on the
canarybranch. So it's either a MacOS-specific problem or a Cursor-specific problem. Since I don't own a Mac system and don't want to download Cursor, I can't help further, but if you can pivot the issue (test on Windows/Linux system or on VSCode, or better, on both) or minimize the issue, perhaps I will be able to help.
My original reproduction in https://github.com/rust-lang/rust-analyzer/issues/19993#issue-3143671859 etc was on Linux, and in Zed and VS Code. Also, it seems to be reproducible in the standalone rust-analyzer diagnostics so I don't think the editor matters at all. (Of course it's conceivable there are multiple similar bugs in play.)
Can you dbg!() the tokens global_name() returns and post the result here? It should appear in the Output->rust-analyzer Language Server pane (VSCode).
Actually I no longer see the warning in either my main tree or the isolated reproduction in comment 1 on
rust-analyzer 1.90.0-beta.7 (fb918cec013 2025-08-29)
Is it dependent on the state of the target dir? Or is it maybe just fixed now?
@sourcefrog Could be https://github.com/rust-lang/rust-analyzer/pull/19434.
Yes that looks right!