about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-22 02:59:38 +0000
committerbors <bors@rust-lang.org>2024-09-22 02:59:38 +0000
commit6ce376774c0bc46ac8be247bca93ff5a1287a8fc (patch)
treed3c1b85ae8ad4821a513b99b0d6c2f4fd74d80d7
parent55043f067dcf7067e7c6ebccf3639af94ff57bda (diff)
parenta187d0a90c939522e563b122dedef2cb7087f8d0 (diff)
downloadrust-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
-rw-r--r--compiler/rustc_expand/src/expand.rs12
-rw-r--r--compiler/rustc_expand/src/module.rs2
-rw-r--r--tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs6
-rw-r--r--tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.stderr8
-rw-r--r--tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs6
5 files changed, 31 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,
diff --git a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs
new file mode 100644
index 00000000000..ff28548b795
--- /dev/null
+++ b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.rs
@@ -0,0 +1,6 @@
+//@ error-pattern: circular modules
+// Regression test for #97589: a doc-comment on a circular module bypassed cycle detection
+
+#![crate_type = "lib"]
+
+pub mod recursive;
diff --git a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.stderr b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.stderr
new file mode 100644
index 00000000000..02d6406775a
--- /dev/null
+++ b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/circular-module-with-doc-comment-issue-97589.stderr
@@ -0,0 +1,8 @@
+error: circular modules: $DIR/recursive.rs -> $DIR/recursive.rs
+  --> $DIR/recursive.rs:6:1
+   |
+LL | mod recursive;
+   | ^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs
new file mode 100644
index 00000000000..3d758be8c05
--- /dev/null
+++ b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs
@@ -0,0 +1,6 @@
+//@ ignore-test: this is an auxiliary file for circular-module-with-doc-comment-issue-97589.rs
+
+//! this comment caused the circular dependency checker to break
+
+#[path = "recursive.rs"]
+mod recursive;