{"id":"3b30689c8d342b2a","repo":"rust-lang/rust","slug":"expected-a-string-literal","errorCode":null,"errorMessage":"Expected a string literal","messagePattern":"Expected a string literal","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"compiler/rustc_macros/src/query.rs","lineNumber":316,"sourceCode":"        eval_always: #eval_always,\n        feedable: #feedable,\n        handle_cycle_error: #handle_cycle_error,\n        no_force: #no_force,\n        no_hash: #no_hash,\n        returns_error_guaranteed: #returns_error_guaranteed,\n        separate_provide_extern: #separate_provide_extern,\n        // tidy-alphabetical-end\n    }\n}\n\nfn doc_comment_from_desc(list: &Punctuated<Expr, token::Comma>) -> Result<Attribute> {\n    use ::syn::*;\n    let mut iter = list.iter();\n    let format_str: String = match iter.next() {\n        Some(&Expr::Lit(ExprLit { lit: Lit::Str(ref lit_str), .. })) => {\n            lit_str.value().replace(\"`{}`\", \"{}\") // We add them later anyways for consistency\n        }\n        _ => return Err(Error::new(list.span(), \"Expected a string literal\")),\n    };\n    let mut fmt_fragments = format_str.split(\"{}\");\n    let mut doc_string = fmt_fragments.next().unwrap().to_string();\n    iter.map(::quote::ToTokens::to_token_stream).zip(fmt_fragments).for_each(\n        |(tts, next_fmt_fragment)| {\n            use ::core::fmt::Write;\n            write!(\n                &mut doc_string,\n                \" `{}` {}\",\n                tts.to_string().replace(\" . \", \".\"),\n                next_fmt_fragment,\n            )\n            .unwrap();\n        },\n    );\n    let doc_string = format!(\"[query description - consider adding a doc-comment!] {doc_string}\");\n    Ok(parse_quote! { #[doc = #doc_string] })\n}","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_macros/src/query.rs#L298-L334","documentation":"Thrown by doc_comment_from_desc (query.rs:309-317) when auto-generating a doc comment for a query that was declared without an explicit doc comment. The function takes the desc block's expression list and requires its first expression to be a string literal (Lit::Str); the match arm at query.rs:312-316 returns Err for anything else. This path is only reached when no /// doc comment is present (query.rs:109-111), because the desc string is used as a fallback description.","triggerScenarios":"Declaring a query without a /// doc comment and giving a desc block whose first expression is not a string literal, e.g. `query foo(k: K) -> V { desc { tcx.foo(k), \"x\" } }` (variable before the format string) or `desc { 42 }`. The first element must be a string literal like `\"{}\"`.","commonSituations":"Adding a new query to rustc and forgetting the doc comment while also writing the desc block in an unusual order; using a non-literal format string (e.g. a const or macro result) as the first desc argument. End users never see this; it is a rustc-internal compile error.","solutions":["Add an explicit /// doc comment above the query, which bypasses the auto-generation path entirely (query.rs:109).","Otherwise ensure the first expression inside the desc { } block is a string literal, e.g. `desc { \"computing {}\", tcx.item_path(key) }`.","Keep format placeholders as `{}` (the code rewrites `` `{}` `` back to `{}` at query.rs:314, so either form works, but it must be a literal)."],"exampleFix":"// before\nquery type_of(key: DefId) -> Ty<'tcx> {\n    desc { tcx.def_path_str(key), \"type of {}\" }\n}\n\n// after\nquery type_of(key: DefId) -> Ty<'tcx> {\n    desc { \"type of {}\", tcx.def_path_str(key) }\n}","handlingStrategy":"type-guard","validationCode":"// The macro only accepts a *literal* string token; never a const, ident, or expr.\n// Good:  #[query(name = \"dep_graph\")]\n// Bad:   const N = \"dep_graph\"; #[query(name = N)]\nfn assert_literal(s: &'static str) -> &'static str { s }","typeGuard":"// Narrow to a compile-time &str literal so non-literal expressions fail to compile\nfn require_str_literal<S: AsRef<str>>(s: S) -> &str { s.as_ref() }","tryCatchPattern":null,"preventionTips":["Always quote the argument passed to the query macro","Never pass a const/ident/expression where a string literal is expected","When copying a query declaration, re-type the string rather than aliasing it"],"tags":["rustc-internals","proc-macro","query-system","compile-error","documentation"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}