rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

Spurious "expected integer or floating pointer number after `-` (rust-analyzer macro-error)" (with reproduction)

Open sourcefrog opened this issue 6 months ago • 8 comments

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".

sourcefrog avatar Jun 13 '25 13:06 sourcefrog

Specifically the problem seems to come from the combination of

  1. Using the JsonSchema derive macro.
  2. 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.

sourcefrog avatar Jun 13 '25 14:06 sourcefrog

Grepping in the r-a codebase the thing that causes that error is concat!().

ChayimFriedman2 avatar Jun 13 '25 14:06 ChayimFriedman2

Likely our () wrapping for expression fragments at fault again

Veykril avatar Jun 13 '25 15:06 Veykril

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.

sourcefrog avatar Jun 13 '25 18:06 sourcefrog

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

sourcefrog avatar Jun 13 '25 18:06 sourcefrog

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.

sourcefrog avatar Jun 15 '25 14:06 sourcefrog

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.

ChayimFriedman2 avatar Jun 15 '25 14:06 ChayimFriedman2

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?

sourcefrog avatar Jun 16 '25 00:06 sourcefrog

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 avatar Sep 04 '25 17:09 lukesandberg

@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.

ChayimFriedman2 avatar Sep 04 '25 17:09 ChayimFriedman2

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

lukesandberg avatar Sep 04 '25 17:09 lukesandberg

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 avatar Sep 04 '25 18:09 ChayimFriedman2

@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.

bgw avatar Sep 04 '25 21:09 bgw

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.

lukesandberg avatar Sep 04 '25 22:09 lukesandberg

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"?

ChayimFriedman2 avatar Sep 04 '25 23:09 ChayimFriedman2

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.

lukesandberg avatar Sep 05 '25 04:09 lukesandberg

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.

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.)

sourcefrog avatar Sep 06 '25 15:09 sourcefrog

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).

ChayimFriedman2 avatar Sep 06 '25 20:09 ChayimFriedman2

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 avatar Sep 13 '25 15:09 sourcefrog

@sourcefrog Could be https://github.com/rust-lang/rust-analyzer/pull/19434.

ChayimFriedman2 avatar Sep 13 '25 19:09 ChayimFriedman2

Yes that looks right!

sourcefrog avatar Sep 13 '25 21:09 sourcefrog