slint-ui/slint · error
an identifier
Error message
an identifier
What it means
This panic fires in `point_span` when the string `p<id>` (e.g. `p3`) fails to lex as a Slint identifier. The function fabricates a fallback `Span` by parsing a synthetic token, and the compiler treats its own ability to parse that token as an invariant.
Solutions
- Ensure the generator runs inside the compiler where `str::parse::<TokenStream>()` is supported (proc-macro runtime available)
- Update proc-macro2/proc-macro dependency; a broken token source usually means a bad proc-macro2 runtime
- Report as a compiler bug — the invariant `p<id>` is always an identifier should hold for every usize
Defensive patterns
Strategy: validation
Validate before calling
assert!(!format!("p{id}").is_empty(), "point_span id must produce a token"); Prevention
- Only call point_span from within the compiler's normal codegen path
- Keep proc-macro2 features enabled in all build targets
- Treat any hit as a compiler bug and file it with the id value
When it happens
Trigger: Calling `point_span` with an id such that `format!("p{id}")` is not a valid identifier token — practically impossible since every usize yields `p` + digits, so a failure would indicate a broken lexer or `proc_macro2` token stream in a non-compiler context (e.g. invoking the generator outside `proc-macro` mode where `parse::<TokenStream>()` on strings is unavailable).
Common situations: Hitting this while porting the slint-sc generator to a context without proc-macro token source support, or a regression in the lexer rejecting digit-suffixed identifiers.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- a setter belongs to a field
- default value requested for unknown struct field
- element without a size
- Global was just valid
- invalid parent reference
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/3f2aad5b9a0da7b3.
Report an issue: GitHub.
Appendix: source
Thrown at internal/compiler/generator/slint_sc.rs:191
let written = elem.debug.first().and_then(|d| d.node.QualifiedName());
match written {
Some(name) => name.text().to_string().trim().to_string(),
None => elem.base_type.to_string(),
}
}
/// The name of a property as the source writes it: `move_declarations` hoists
/// a declaration onto the root element under a name of its own making.
fn source_name(elem: &Element, name: &SmolStr) -> SmolStr {
let moved_from = elem.property_declarations.get(name).and_then(|d| d.moved_from.clone());
moved_from.unwrap_or_else(|| name.clone())
}
/// A span naming point `id`: the span of a token parsed from the text
/// `p<id>`, which `source_text` gives back. Fallback spans can be made in no
/// other way, and the printer is the only reader.
fn point_span(id: usize) -> Span {
let tokens: TokenStream = format!("p{id}").parse().expect("an identifier");
tokens.into_iter().next().expect("one token").span()
}
/// The point a span names, if any.
fn point_id(span: Span) -> Option<usize> {
span.source_text()?.strip_prefix('p')?.parse().ok()
}
/// The tokens as the range of the point, when they are one. See `stamped`.
fn stamped_at(point: Option<Span>, tokens: TokenStream) -> TokenStream {
match point {
Some(span) => stamped(span, tokens),
None => tokens,
}
}
/// The tokens as a point's range: a group without delimiters, which prints
/// as the tokens alone, stamped with the point's span.View on GitHub (pinned to bb937076de)