diff options
| author | bors <bors@rust-lang.org> | 2024-09-22 02:59:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-09-22 02:59:38 +0000 |
| commit | 6ce376774c0bc46ac8be247bca93ff5a1287a8fc (patch) | |
| tree | d3c1b85ae8ad4821a513b99b0d6c2f4fd74d80d7 /compiler | |
| parent | 55043f067dcf7067e7c6ebccf3639af94ff57bda (diff) | |
| parent | a187d0a90c939522e563b122dedef2cb7087f8d0 (diff) | |
| download | rust-6ce376774c0bc46ac8be247bca93ff5a1287a8fc.tar.gz rust-6ce376774c0bc46ac8be247bca93ff5a1287a8fc.zip | |
Auto merge of #130246 - dianne:issue-97589-fix, r=petrochenkov
rustc_expand: remember module `#[path]`s during expansion During invocation collection, if a module item parsed from a `#[path]` attribute needed a second pass after parsing, its path wouldn't get added to the file path stack, so cycle detection broke. This checks the `#[path]` in such cases, so that it gets added appropriately. I think it should work identically to the case for external modules that don't need a second pass, but I'm not 100% sure. Fixes #97589
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_expand/src/expand.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/module.rs | 2 |
2 files changed, 11 insertions, 3 deletions
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 0d56a005f15..84ae351ed72 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -41,7 +41,9 @@ use crate::errors::{ }; use crate::fluent_generated; use crate::mbe::diagnostics::annotate_err_with_kind; -use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod}; +use crate::module::{ + mod_dir_path, mod_file_path_from_attr, parse_external_mod, DirOwnership, ParsedExternalMod, +}; use crate::placeholders::{placeholder, PlaceholderExpander}; macro_rules! ast_fragments { @@ -1202,8 +1204,14 @@ impl InvocationCollectorNode for P<ast::Item> { ecx.current_expansion.dir_ownership, *inline, ); + // If the module was parsed from an external file, recover its path. + // This lets `parse_external_mod` catch cycles if it's self-referential. + let file_path = match inline { + Inline::Yes => None, + Inline::No => mod_file_path_from_attr(ecx.sess, &attrs, &dir_path), + }; node.attrs = attrs; - (None, dir_path, dir_ownership) + (file_path, dir_path, dir_ownership) } ModKind::Unloaded => { // We have an outline `mod foo;` so we need to parse the file. diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 13348376851..27a9a330f3c 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -171,7 +171,7 @@ fn mod_file_path<'a>( /// Derive a submodule path from the first found `#[path = "path_string"]`. /// The provided `dir_path` is joined with the `path_string`. -fn mod_file_path_from_attr( +pub(crate) fn mod_file_path_from_attr( sess: &Session, attrs: &[Attribute], dir_path: &Path, |
