rust-lang/rust-analyzer · error

unexpected character: `{}`

Error message

unexpected character: `{}`

What it means

Fallback lexer error in ungrammar's `advance`: any character that does not start a known token (identifier char, whitespace, punctuation like `= | ( ) * ? ;`, `'`, etc.) is rejected with this message naming the offending character.

Source

Thrown at lib/ungrammar/src/lexer.rs:114

            }
            TokenKind::Token(buf)
        }
        c if is_ident_char(c) => {
            let mut buf = String::new();
            buf.push(c);
            loop {
                match chars.clone().next() {
                    Some(c) if is_ident_char(c) => {
                        chars.next();
                        buf.push(c);
                    }
                    _ => break,
                }
            }
            TokenKind::Node(buf)
        }
        '\r' => bail!("unexpected `\\r`, only Unix-style line endings allowed"),
        c => bail!("unexpected character: `{}`", c),
    };

    *input = chars.as_str();
    Ok(res)
}

fn is_escapable(c: char) -> bool {
    matches!(c, '\\' | '\'')
}
fn is_whitespace(c: char) -> bool {
    matches!(c, ' ' | '\t' | '\n')
}
fn is_ident_char(c: char) -> bool {
    matches!(c, 'a'..='z' | 'A'..='Z' | '_')
}

View on GitHub (pinned to e8f7e90aa3)

Solutions

  1. Locate the reported character and replace or remove it
  2. Replace smart quotes with plain `'` and non-breaking spaces with regular spaces
  3. Consult ungrammar syntax docs to confirm the construct is supported (nodes, tokens, `=`, `|`, `*`, `?`, `(`, `)`, `;`)
  4. Check for invisible unicode characters with a hex viewer if the character looks correct

Example fix

// before
Expr = “literal”
// after
Expr = 'literal'
Defensive patterns

Strategy: validation

Validate before calling

// spot suspicious characters before parsing
fn has_suspect_chars(src: &str) -> Vec<char> {
    src.chars().filter(|&c| {
        matches!(c, '\u{201c}' | '\u{201d}' | '\u{2018}' | '\u{2019}' | '\u{00a0}')
    }).collect()
}

Try / catch

match ungrammar::Grammar::parse(src) {
    Err(e) if e.to_string().starts_with("unexpected character") => {
        eprintln!("remove the unsupported character: {e}")
    }
    r => r?,
}

Prevention

When it happens

Trigger: A `.ungrammar` file contains a character outside the grammar's alphabet, e.g. `"` quotes, `#` comments, tabs in odd spots (if not treated as whitespace), unicode look-alikes, or stray operators.

Common situations: Copy-pasting grammar snippets from docs/websites (smart quotes, non-breaking spaces); inventing syntax unsupported by ungrammar; typos.

Related errors


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