rust-lang/rust · error
empty prefix in a simple import
Error message
empty prefix in a simple import
What it means
`.expect("empty prefix in a simple import")` is fired by `UseTree::ident()` when a `UseTreeKind::Simple(None)` (no rename) import has a `prefix` `Path` with zero segments. The method assumes a simple import always has at least one path segment to read the trailing ident from; an empty prefix means the `UseTree` was constructed with a malformed (empty) path. It indicates corrupted AST construction, not valid source.
Source
Thrown at compiler/rustc_ast/src/ast.rs:3377
Glob(Span),
}
/// A tree of paths sharing common prefixes.
/// Used in `use` items both at top-level and inside of braces in import groups.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct UseTree {
pub prefix: Path,
pub kind: UseTreeKind,
}
impl UseTree {
/// If the `UseTree` is just an identifier, return that.
/// Panics if it's a glob (`*`) or a nested use tree.
pub fn ident(&self) -> Ident {
match self.kind {
UseTreeKind::Simple(Some(rename)) => rename,
UseTreeKind::Simple(None) => {
self.prefix.segments.last().expect("empty prefix in a simple import").ident
}
_ => panic!("`UseTree::ident` can only be used on a simple import"),
}
}
/// Returns the full span from the start of the path to the
/// closing `}` or nested spans, `*` of glob spans or the end of the
/// identifier of simple spans.
pub fn span(&self) -> Span {
self.prefix.span.to(self.hi_span())
}
/// Returns the trailing element's span. So for a nested
/// span you get the entire `{}`-block, for a glob you
/// get the span of the `*` itself, and for simple use trees
/// you get the identifier to rename the import to or the full
/// path if no rename is specified.
pub fn hi_span(&self) -> Span {View on GitHub (pinned to 22057b88b0)
Solutions
- Ensure any `UseTree` with `UseTreeKind::Simple` is constructed with at least one `Path` segment.
- If you build paths programmatically, assert `!prefix.segments.is_empty()` at construction time.
- Check `ident()` callers — guard with `if !self.prefix.segments.is_empty()` or switch to pattern-matching `UseTreeKind` if empty prefixes are legitimately possible in your context.
Example fix
// before
UseTree { prefix: Path { segments: ThinVec::new(), span }, kind: UseTreeKind::Simple(None) }
// after
UseTree {
prefix: Path { segments: thin_vec![PathSegment::ident(ident)], span },
kind: UseTreeKind::Simple(None),
} Defensive patterns
Strategy: validation
Validate before calling
if use_tree.kind == UseTreeKind::Simple(None)
&& use_tree.prefix.segments.is_empty()
{
// refuse to call ident(); construct a fresh Ident or skip
} Type guard
fn has_simple_ident_prefix(tree: &UseTree) -> bool {
matches!(tree.kind, UseTreeKind::Simple(_)) && !tree.prefix.segments.is_empty()
} Prevention
- Only call `UseTree::ident()` after confirming `prefix.segments` is non-empty.
- Filter glob/nested trees out before processing the Simple(None) case.
- Treat an empty `prefix` as a structural invariant violation upstream, not a normal input.
When it happens
Trigger: `UseTree::ident()` is called on a `UseTree { prefix: Path { segments: [], .. }, kind: UseTreeKind::Simple(None) }`. This happens when AST-building code (macros, `cfg` rewriting, pretty-printing helpers, or `use`-tree visiting) emits a Simple use tree with an empty `Path`.
Common situations: Procedural macros or internal AST rewrites that synthesize `UseTree` values without populating `prefix`. Bugs in macro expansion that drop the path. Refactors that move path construction and forget the trailing segment. Almost never seen from end-user Rust source — only from tools manipulating AST directly.
Related errors
- `UseTree::ident` can only be used on a simple import
- attribute is missing tokens: {self:?}
- if we had an explicit self, we wouldn't be here
- Should be `AttrTokenTree::Delimited`, not delim tokens: {:?}
- cloning statement `NodeId`s is prohibited by default, the vi
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/7e3d10ecb6426454.json.
Report an issue: GitHub.