ICE in insert_ast_item when the same crate is declared twice under different names
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 2.9k
- Forks
- 231
- Avg merge
- 20h 2m
- Merged PRs (30d)
- 66
Description
Summary
Declaring the same crate twice under different names is legal Rust, but gccrs ICEs during HIR lowering. Found while working on #4679; it looks related but is a distinct problem, so filing separately.
Reproducer
foo.rs:
#![feature(no_core)]
#![no_core]
v4.rs:
#![feature(no_core)]
#![no_core]
extern crate foo;
extern crate foo as bar;
Build foo to metadata first, then compile v4.rs against it:
gccrs -frust-incomplete-and-experimental-compiler-do-not-use \
-frust-crate=foo -frust-crate-type=rlib \
-frust-metadata-output=foo.rox -c foo.rs -o foo.o
gccrs -frust-incomplete-and-experimental-compiler-do-not-use \
-frust-crate-attr=no_core -frust-crate-attr='feature(no_core)' \
-frust-extern=foo=foo.rox -c v4.rs
The bare snippet on its own won't reproduce it: without a real crate it fails
at "failed to locate crate" before reaching lowering.
Does the code make use of any (1.49) nightly feature ?
- Nightly
Godbolt link
No response
Actual behavior
crab1: internal compiler error: in insert_ast_item, at rust/util/rust-hir-map.cc:1264
0x2bace8b internal_error(char const*, ...)
../../gccrs/gcc/diagnostic-global-context.cc:787
0xb55fab fancy_abort(char const*, int, char const*)
../../gccrs/gcc/diagnostics/context.cc:1813
0x911607 Rust::Analysis::Mappings::insert_ast_item(Rust::AST::Item*)
../../gccrs/gcc/rust/util/rust-hir-map.cc:1264
0xe19a1e Rust::HIR::ASTLoweringItem::translate(Rust::AST::Item&)
../../gccrs/gcc/rust/hir/rust-ast-lower-item.cc:47
0xe0b9d7 Rust::HIR::ASTLowering::go()
../../gccrs/gcc/rust/hir/rust-ast-lower.cc:79
0xe0be55 Rust::HIR::ASTLowering::Resolve(Rust::AST::Crate&)
../../gccrs/gcc/rust/hir/rust-ast-lower.cc:69
0xe19678 Rust::HIR::ASTLoweringItem::visit(Rust::AST::ExternCrate&)
../../gccrs/gcc/rust/hir/rust-ast-lower-item.cc:800
0xe1999b Rust::HIR::ASTLoweringItem::translate(Rust::AST::Item&)
../../gccrs/gcc/rust/hir/rust-ast-lower-item.cc:38
0xe0b9d7 Rust::HIR::ASTLowering::go()
../../gccrs/gcc/rust/hir/rust-ast-lower.cc:79
0xe0be55 Rust::HIR::ASTLowering::Resolve(Rust::AST::Crate&)
../../gccrs/gcc/rust/hir/rust-ast-lower.cc:69
0xd3b90e Rust::Session::compile_crate(char const*)
../../gccrs/gcc/rust/rust-session-manager.cc:785
/home/utkuputku/gsoc/gccrs-build/gcc/crab1 v4.rs -quiet -dumpbase v4.rs -dumpbase-ext .rs -mtune=generic -march=x86-64 -frust-incomplete-and-experimental-compiler-do-not-use -frust-crate-attr=no_core -frust-crate-attr=feature(no_core) -frust-extern=foo=foo.rox -L/home/utkuputku/gsoc/gccrs-build/gcc -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/lib -L/usr/lib -o /tmp/ccYD1yS6.s
ASTLoweringItem::visit (AST::ExternCrate &) at rust-ast-lower-item.cc:800
calls ASTLowering::Resolve on the referenced crate with no guard against it
having already been lowered. Both items name the same crate, so it gets
lowered twice, and the second pass re-inserts NodeIds already present in
ast_item_mappings, tripping the assert at rust-hir-map.cc:1264.
This appears keyed on crate identity rather than binding name, which fits what
I see: extern crate foo; extern crate foo; hits the same assert, while two
items naming different crates do not.
Expected behavior
This should compile. Binding one crate under two names is legal Rust; rustc
1.95.0 accepts it and produces a binary.
GCC Version
gccrs (GCC) 17.0.0 20260630 (experimental)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproducer commands in the issue, then inspect ASTLoweringItem::visit for AST::ExternCrate in rust-ast-lower-item.cc:800 and the assertion in rust-hir-map.cc:1264. Verify behavior with two extern crate declarations naming the same crate and with different crates. Done means the duplicate-name case compiles without an ICE and preserves the expected crate bindings.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100