rust-lang/rust-analyzer · error · SsrError

Expected {} found {}

Error message

Expected {} found {}

What it means

expect_token consumes the next token from the pattern's token stream and requires its text to equal the expected string (e.g. '(' or ')'). If a token exists but its text differs, this error reports both the expected and found text. It is used by parse_constraint to validate the parentheses around kind(...) and not(...) constraints.

Source

Thrown at crates/ide-ssr/src/parsing.rs:338

            expect_token(tokens, ")")?;
            Ok(Constraint::Kind(NodeKind::from(&t.text)?))
        }
        "not" => {
            expect_token(tokens, "(")?;
            let sub = parse_constraint(tokens)?;
            expect_token(tokens, ")")?;
            Ok(Constraint::Not(Box::new(sub)))
        }
        x => bail!("Unsupported constraint type '{}'", x),
    }
}

fn expect_token(tokens: &mut std::vec::IntoIter<Token>, expected: &str) -> Result<(), SsrError> {
    if let Some(t) = tokens.next() {
        if t.text == expected {
            return Ok(());
        }
        bail!("Expected {} found {}", expected, t.text);
    }
    bail!("Expected {} found end of stream", expected);
}

impl NodeKind {
    fn from(name: &SmolStr) -> Result<NodeKind, SsrError> {
        Ok(match name.as_str() {
            "literal" => NodeKind::Literal,
            _ => bail!("Unknown node kind '{}'", name),
        })
    }
}

impl Placeholder {
    fn new(name: SmolStr, constraints: Vec<Constraint>) -> Self {
        Self {
            stand_in_name: format!("__placeholder_{name}"),
            constraints,

View on GitHub (pinned to e8f7e90aa3)

Solutions

  1. Ensure every constraint argument is fully parenthesized: kind(literal), not(kind(literal))
  2. Compare the 'found' text in the message against your pattern to locate the mismatched character
  3. Balance parentheses when nesting not constraints

Example fix

// before
let pattern = "$x:kind literal";
// after
let pattern = "$x:kind(literal)";
Defensive patterns

Strategy: validation

Validate before calling

fn constraint_parens_balanced(p: &str) -> bool {
    let mut depth = 0i32;
    for c in p.chars() {
        match c {
            '(' => depth += 1,
            ')' => {
                depth -= 1;
                if depth < 0 { return false; }
            }
            _ => {}
        }
    }
    depth == 0
}

Try / catch

match parse_pattern(pattern) {
    Ok(p) => use_pattern(p),
    Err(e) if e.message.starts_with("Expected ") => {
        eprintln!("Constraint parentheses mismatch: {}", e.message);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: kind constraint missing its '(' or ')' but with some other token present instead, e.g. kind literal) or kind(literal, producing 'Expected ( found literal' style messages.

Common situations: Omitting parentheses around kind(...) arguments; stray commas or spaces-as-tokens inside constraint syntax; copy/paste mangling of constraint examples.

Related errors


AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03). Data as JSON: /api/errors/4267c179664e50ad. Report an issue: GitHub.