{"id":"7e3d10ecb6426454","repo":"rust-lang/rust","slug":"empty-prefix-in-a-simple-import","errorCode":null,"errorMessage":"empty prefix in a simple import","messagePattern":"empty prefix in a simple import","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_ast/src/ast.rs","lineNumber":3377,"sourceCode":"    Glob(Span),\n}\n\n/// A tree of paths sharing common prefixes.\n/// Used in `use` items both at top-level and inside of braces in import groups.\n#[derive(Clone, Encodable, Decodable, Debug, Walkable)]\npub struct UseTree {\n    pub prefix: Path,\n    pub kind: UseTreeKind,\n}\n\nimpl UseTree {\n    /// If the `UseTree` is just an identifier, return that.\n    /// Panics if it's a glob (`*`) or a nested use tree.\n    pub fn ident(&self) -> Ident {\n        match self.kind {\n            UseTreeKind::Simple(Some(rename)) => rename,\n            UseTreeKind::Simple(None) => {\n                self.prefix.segments.last().expect(\"empty prefix in a simple import\").ident\n            }\n            _ => panic!(\"`UseTree::ident` can only be used on a simple import\"),\n        }\n    }\n\n    /// Returns the full span from the start of the path to the\n    /// closing `}` or nested spans, `*` of glob spans or the end of the\n    /// identifier of simple spans.\n    pub fn span(&self) -> Span {\n        self.prefix.span.to(self.hi_span())\n    }\n\n    /// Returns the trailing element's span. So for a nested\n    /// span you get the entire `{}`-block, for a glob you\n    /// get the span of the `*` itself, and for simple use trees\n    /// you get the identifier to rename the import to or the full\n    /// path if no rename is specified.\n    pub fn hi_span(&self) -> Span {","sourceCodeStart":3359,"sourceCodeEnd":3395,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_ast/src/ast.rs#L3359-L3395","documentation":"`.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.","triggerScenarios":"`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`.","commonSituations":"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.","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."],"exampleFix":"// before\nUseTree { prefix: Path { segments: ThinVec::new(), span }, kind: UseTreeKind::Simple(None) }\n\n// after\nUseTree {\n    prefix: Path { segments: thin_vec![PathSegment::ident(ident)], span },\n    kind: UseTreeKind::Simple(None),\n}","handlingStrategy":"validation","validationCode":"if use_tree.kind == UseTreeKind::Simple(None)\n    && use_tree.prefix.segments.is_empty()\n{\n    // refuse to call ident(); construct a fresh Ident or skip\n}","typeGuard":"fn has_simple_ident_prefix(tree: &UseTree) -> bool {\n    matches!(tree.kind, UseTreeKind::Simple(_)) && !tree.prefix.segments.is_empty()\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["rustc","internals","ast","use-tree","invariant"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}