rust-lang/rust · error · syn::Error
duplicate modifier
Error message
duplicate modifier
What it means
Thrown by the rustc_queries proc-macro (via the try_insert! macro at query.rs:169-176) when the same query modifier name appears more than once inside a query's modifier braces. The rustc compiler declares queries with a fixed set of modifiers (arena_cache, cache_on_disk, depth_limit, desc, eval_always, feedable, handle_cycle_error, no_force, no_hash, separate_provide_extern), each tracked as an Option<Ident>; assigning one twice is a logic error in the query declaration. The span reported is that of the duplicated modifier ident, pointing at the offending token in the query definition.
Source
Thrown at compiler/rustc_macros/src/query.rs:172
let mut arena_cache = None;
let mut cache_on_disk = None;
let mut depth_limit = None;
let mut desc = None;
let mut eval_always = None;
let mut feedable = None;
let mut handle_cycle_error = None;
let mut no_force = None;
let mut no_hash = None;
let mut separate_provide_extern = None;
// tidy-alphabetical-end
while !input.is_empty() {
let modifier: Ident = input.parse()?;
macro_rules! try_insert {
($name:ident = $expr:expr) => {
if $name.is_some() {
return Err(Error::new(modifier.span(), "duplicate modifier"));
}
$name = Some($expr);
};
}
if modifier == "arena_cache" {
try_insert!(arena_cache = modifier);
} else if modifier == "cache_on_disk" {
try_insert!(cache_on_disk = modifier);
} else if modifier == "depth_limit" {
try_insert!(depth_limit = modifier);
} else if modifier == "desc" {
// Parse a description modifier like:
// `desc { "foo {}", tcx.item_path(key) }`
let attr_content;
braced!(attr_content in input);
let expr_list = attr_content.parse_terminated(Expr::parse, Token![,])?;
try_insert!(desc = Desc { modifier, expr_list });View on GitHub (pinned to 22057b88b0)
Solutions
- Inspect the query declaration at the reported span and remove the duplicate modifier keyword so each appears at most once.
- Cross-check the modifier list against the canonical set documented in rustc_middle::query::modifiers (query.rs:136-150) to confirm the intended single usage.
- If you meant two different behaviors, verify the modifier name is correct; consult the modifier docs rather than reusing the same one twice.
Example fix
// before
query type_of(key: DefId) -> Ty<'tcx> {
eval_always
desc { "type of `{}`", tcx.def_path_str(key) }
eval_always
}
// after
query type_of(key: DefId) -> Ty<'tcx> {
eval_always
desc { "type of `{}`", tcx.def_path_str(key) }
} Defensive patterns
Strategy: validation
Validate before calling
// Lint your #[query(...)] modifier list before compiling
use std::collections::HashSet;
fn first_duplicate(mods: &[&str]) -> Option<&str> {
let mut seen = HashSet::new();
for m in mods { if !seen.insert(*m) { return Some(*m); } }
None
}
// assert!(first_duplicate(&["eval_always","anon","eval_always"]).is_none()); Prevention
- Keep all query modifiers in one const slice and diff it in CI before building
- Add a grep-based check that no modifier keyword appears twice inside a single #[query(...)]
- Re-read compiler/rustc_macros/src/query.rs:172 when adding a new modifier to confirm its semantics
When it happens
Trigger: Authoring or editing a query in a rustc_queries! {} invocation (e.g. in compiler/rustc_middle/src/query/system.rs or similar) and listing the same modifier keyword twice in the braces block, e.g. `query foo(key: K) -> V { eval_always, desc {"x"}, eval_always }`. The parser loops over modifiers (query.rs:166) and try_insert! (line 171) rejects the second occurrence because the Option is already Some.
Common situations: Editing the rustc query system during compiler development; merging query declarations where a modifier was copy-pasted; typos that duplicate a flag like no_hash/no_force. Seen only by people hacking on the compiler internals, never by end users compiling normal crates.
Related errors
- unknown query modifier
- Expected a string literal
- attributes not supported on queries
- attributes must be outer attributes (`///`), not inner attri
- {:?} shouldn't exist here
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/db0b1887a1e07e1a.json.
Report an issue: GitHub.