Skip to content

Extern crate loading improvements#4588

Draft
P-E-P wants to merge 11 commits into
Rust-GCC:masterfrom
P-E-P:typecheck_issue
Draft

Extern crate loading improvements#4588
P-E-P wants to merge 11 commits into
Rust-GCC:masterfrom
P-E-P:typecheck_issue

Conversation

@P-E-P

@P-E-P P-E-P commented Jun 17, 2026

Copy link
Copy Markdown
Member

Extern crates such as core were not loaded correctly. Among the issues:

  • modules were not handled
  • reexported items were not handled

Changes the metadata dump from an HIR dump which does not contain any UseDeclaration to an AST dump. This lead to some problems with crate::XXXX path which were no handled from the external crate's POV. To avoid that we now name resolve the external crates on their own alone and merge them later within the current crate.

We now dump the AST instead of the HIR for metadata for the following reasons:

  • AST dump accuracy is garanteed by proc macros
  • We do not have to lower use declaration to hir

@P-E-P P-E-P mentioned this pull request Jun 23, 2026
@P-E-P P-E-P force-pushed the typecheck_issue branch 7 times, most recently from f3618f5 to cf08c62 Compare June 27, 2026 12:03
@P-E-P P-E-P requested a review from CohenArthur June 29, 2026 11:57
P-E-P added 11 commits June 29, 2026 14:01
The compiler would crash if the file name was requested from the lexer
whilst lexing from a non-file source (mainly string sources). Now return
an empty file name instead.

gcc/rust/ChangeLog:

	* lex/rust-lex.h: Return an empty file name when file is missing.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Modules were not emitted within metadata files, and could not be resolved
upon crate import.

gcc/rust/ChangeLog:

	* metadata/rust-export-metadata.cc (ExportContext::begin_module):
	Add a function to emit the module preamble.
	(ExportContext::end_module): Add function to emit public module brace
	suffix.
	* metadata/rust-export-metadata.h: Add function prototypes.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
HIR does not contain the UseDeclaration but those are required to
resolve some metadata. This commit change the whole metadata export to
use the AST data instead. We could have lowered UseDeclaration to HIR
instead akin to macro export but the AST dump accuracy is already used by
multiple other systems such as proc macro expansion, using it
deduplicates the dumper code used.

gcc/rust/ChangeLog:

	* metadata/rust-export-metadata.cc (ExportContext::emit_trait): Use
	AST node instead.
	(ExportContext::emit_function): Likewise.
	(ExportContext::emit_use_declaration): likewise.
	(ExportContext::begin_module): Likewise.
	(ExportContext::end_module): Likewise.
	(class ExportVisItems): Use DefaultASTVisitor instead.
	(PublicInterface::gather_export_data): Lookup the AST crate and visit
	its items.
	* metadata/rust-export-metadata.h: Update function prototys with AST
	nodes.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Extern crates are exported using their own dump. When resolved, we may
encounter `crate::` path, which point to an item from the extern crate's
root instead of the current crate's root. This means we need the crate
context within the name resolution. We chose to resolve crates
independently because extern crates do not require late name resolution
and keeping them isolated keeps things easy.

gcc/rust/ChangeLog:

	* Make-lang.in: Add a new file with a visitor to collect and load
	extern crates.
	* expand/rust-cfg-strip.cc (CfgStrip::visit): Remove extern crate
	loading from cfgstrip step.
	* resolve/rust-default-resolver.cc (DefaultResolver::visit_extern_crate):
	Do not visit the extern crate. We do not need to resolve it since it is
	already done.
	* resolve/rust-forever-stack.hxx: Do not assign unused result.
	* resolve/rust-name-resolution-context.cc (NameResolutionContext::merge):
	Add a function to merge an extern crate's nr context at some location
	within another name resolution context.
	* resolve/rust-name-resolution-context.h: Add function prototype.
	* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit_extern_crate):
	Do not visit extern crate.
	* rust-session-manager.cc (Session::expansion): Collect extern crates,
	load them and merge them into the main crate.
	(Session::dump_hir_pretty): Change function return type.
	(Session::load_extern_crate): Change return type to collect extern
	crates name resolution context.
	* rust-session-manager.h: Update function prototype.
	* expand/rust-extern-crate-loader.cc: New file.
	* expand/rust-extern-crate-loader.h: New file.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Lang item segment name were made optional because we thought we wouldn't
need them once identified. But the lang item name are not fixed, they're
declared within the core crate. This means we couldn't accurately dump
the AST anymore.

gcc/rust/ChangeLog:

	* ast/rust-ast-builder.cc (Builder::type_path_segment): Add segment
	name argument.
	(Builder::type_path_segment_generic): Likewise.
	(Builder::single_generic_type_path): Likewise.
	(Builder::type_path): Likewise.
	* ast/rust-ast-builder.h: Add segment name string to ctor.
	* ast/rust-path.h: Make segment name mandatory.
	* expand/rust-derive-clone.cc (DeriveClone::visit_union): Forward
	segment name.
	* expand/rust-derive-copy.cc: Likewise.
	* expand/rust-derive-eq.cc (DeriveEq::assert_param_is_eq): Likewise.
	* expand/rust-derive-partial-eq.cc: Likewise.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Late name resolution was initially not run on extern crate since the
content within the functions was not used. But function return type is
resolved within the late name resolver hence why we cannot skip it.

gcc/rust/ChangeLog:

	* rust-session-manager.cc (Session::load_extern_crate): Run late name
	resolver on extern crates.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Name resolution on extern crate did merge the name declarations but not
their usage, this lead to return types within functions not being
recognized anymore. We missed the usage binding during the merge
operation.

gcc/rust/ChangeLog:

	* resolve/rust-name-resolution-context.cc (NameResolutionContext::merge):
	Merge nr usage binding when merging nr contexts.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Add a new function to merge one CanonicalPathCtx within another one. This
move broke the references within the path segment. To avoid this breakage
this commit also changes the way parent handle are stored. Instead of
storing a reference to the parent, a record stores the parent's node id.

gcc/rust/ChangeLog:

	* resolve/rust-name-resolution-context.cc (CanonicalPathRecordNormal::as_path):
	Use context and retrieve parent from its node id.
	(CanonicalPathRecordImpl::as_path): Likewise.
	(CanonicalPathRecordTraitImpl::as_path): Likewise.
	(NameResolutionContext::merge): Merge both record map.
	* resolve/rust-name-resolution-context.h: Change parent handle
	representation from reference to node id.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Resolving multiple crates means setting up multiple time the builtin
types. Once those crates are merged within the node resolution means
we get multiple node ids for what should be the same types.
To fix that we assign the same node and hir id for the builtin types,
independently from where they get created.

gcc/rust/ChangeLog:

	* resolve/rust-resolve-builtins.cc (class LangPreludeSingleton): Add a
	singleton to store node and hir ids.
	(setup_lang_prelude): Use the new singleton store.
	(TYPE0): Change reference to singleton.
	(TYPE1): Likewise.
	(setup_type_ctx): Use the new singleton store.
	(find_builtin_node_id): Likewise.
	* rust-session-manager.cc (Session::load_extern_crate): Setup builtin
	types.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Extern block metadata is required to identify intrinsics from an extern
crate.

gcc/rust/ChangeLog:

	* metadata/rust-export-metadata.cc (ExportContext::begin_extern_block):
	Dump the prefix of an extern block.
	(ExportContext::end_extern_block): Likewise with extern block suffix.
	* metadata/rust-export-metadata.h: Add function prototypes.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
We would have to call two functions, one of which could be forgotten,
this would also duplicates the condition. This new interface makes
things a bit simpler.

gcc/rust/ChangeLog:

	* metadata/rust-export-metadata.cc (ExportContext::begin_extern_block):
	Delete function.
	(ExportContext::end_extern_block): Likewise.
	(ExportContext::begin_module): Likewise.
	(ExportContext::end_module): Likewise.
	(ExportContext::emit_extern_block): Merge both begin/end within one
	function that calls the visitor in between.
	(ExportContext::emit_module): Likewise.
	* metadata/rust-export-metadata.h: Update function prototypes.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
@P-E-P P-E-P force-pushed the typecheck_issue branch from 637f3a2 to 9285931 Compare June 29, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant