rust-lang/rust · error · syn::Error
Expected a string literal
Error message
Expected a string literal
What it means
Emitted by doc_comment_from_desc in the rustc_queries! macro. When a query has no explicit doc comment (///), the macro auto-generates one from the desc modifier's expression list. The first expression must be a string literal (a format string like "computes type of {}"). If the first expression is not an Expr::Lit containing a Lit::Str, this error fires at the span of the entire expression list. This only happens when no manual doc comment is provided — if you add ///, doc_comment_from_desc is never called.
Solutions
- Ensure the desc block starts with a string literal: desc { "description for `{}`", key }.
- Alternatively, add a /// doc comment above the query — then desc's format is not inspected for auto-doc generation, though desc still requires a string literal for the query description closure.
- Remember that desc's first element is always a format string; subsequent comma-separated expressions are the format arguments.
Example fix
// before (no doc comment, desc doesn't start with a string literal):
query foo(key: DefId) -> Ty<'tcx> { desc { key, "foo" } }
// after: start with a string literal format string
query foo(key: DefId) -> Ty<'tcx> { desc { "foo for `{}`", key } }
// or add a manual doc comment:
/// Computes foo for the given definition.
query foo(key: DefId) -> Ty<'tcx> { desc { "foo for `{}`", key } } Defensive patterns
Strategy: validation
Validate before calling
// Ensure every desc block starts with a string literal, or add a doc comment.
// Static check in your editor: verify the first token inside desc { } is a "...".
// If you add a /// comment above the query, doc_comment_from_desc is bypassed
// and this error won't fire (though desc still needs a string literal for the description). Try / catch
// Compile-time error from the proc macro — cannot be caught at runtime.
// Fix by making the first element of desc { } a string literal. Prevention
- Always start the desc block with a quoted format string: desc { "description for `{}`", key }.
- If you add a /// doc comment, the auto-generation path is skipped, but still use a string literal.
- Remember the desc format: first element is the format string, rest are comma-separated arguments.
When it happens
Trigger: Writing a query without a /// doc comment where the desc block's first element is not a string literal. For example: desc { 42, key } or desc { tcx.item_name(key), key } or an empty desc { }. The first token must be a quoted string.
Common situations: Writing a desc block that starts with a format_args! macro call or an expression instead of a plain string literal; forgetting the format string and only putting expression arguments.
Related errors
- attributes must be outer attributes (`///`), not inner…
- attributes not supported on queries
- duplicate modifier
- unknown query modifier
- CFG_RELEASE env var
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/3b30689c8d342b2a.
Report an issue: GitHub.
Appendix: source
Thrown at compiler/rustc_macros/src/query.rs:316
eval_always: #eval_always,
feedable: #feedable,
handle_cycle_error: #handle_cycle_error,
no_force: #no_force,
no_hash: #no_hash,
returns_error_guaranteed: #returns_error_guaranteed,
separate_provide_extern: #separate_provide_extern,
// tidy-alphabetical-end
}
}
fn doc_comment_from_desc(list: &Punctuated<Expr, token::Comma>) -> Result<Attribute> {
use ::syn::*;
let mut iter = list.iter();
let format_str: String = match iter.next() {
Some(&Expr::Lit(ExprLit { lit: Lit::Str(ref lit_str), .. })) => {
lit_str.value().replace("`{}`", "{}") // We add them later anyways for consistency
}
_ => return Err(Error::new(list.span(), "Expected a string literal")),
};
let mut fmt_fragments = format_str.split("{}");
let mut doc_string = fmt_fragments.next().unwrap().to_string();
iter.map(::quote::ToTokens::to_token_stream).zip(fmt_fragments).for_each(
|(tts, next_fmt_fragment)| {
use ::core::fmt::Write;
write!(
&mut doc_string,
" `{}` {}",
tts.to_string().replace(" . ", "."),
next_fmt_fragment,
)
.unwrap();
},
);
let doc_string = format!("[query description - consider adding a doc-comment!] {doc_string}");
Ok(parse_quote! { #[doc = #doc_string] })
}View on GitHub (pinned to 7088e4b63a)