about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2024-10-03 17:42:08 -0700
committerMichael Howell <michael@notriddle.com>2024-10-03 22:01:23 -0700
commit253fec494fa336ee27c6cb027ffdb3d6e0b632c3 (patch)
treefaffaa3f4bc88db84d31ce789e4b3c977ada7670
parent9ff5fc4ffbbe1e911527aa054e789b05ae55ffcc (diff)
downloadrust-253fec494fa336ee27c6cb027ffdb3d6e0b632c3.tar.gz
rust-253fec494fa336ee27c6cb027ffdb3d6e0b632c3.zip
rustdoc: prevent ctors from resolving
-rw-r--r--compiler/rustc_resolve/src/lib.rs4
-rw-r--r--tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs4
-rw-r--r--tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr6
-rw-r--r--tests/rustdoc-ui/intra-doc/value-ctor.rs35
-rw-r--r--tests/rustdoc-ui/intra-doc/value-ctor.stderr62
5 files changed, 105 insertions, 6 deletions
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index fcbbb523cfc..24a0c252e55 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -2148,7 +2148,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
 
         match self.maybe_resolve_path(&segments, Some(ns), &parent_scope, None) {
             PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()),
-            PathResult::NonModule(path_res) => path_res.full_res(),
+            PathResult::NonModule(path_res) => {
+                path_res.full_res().filter(|res| !matches!(res, Res::Def(DefKind::Ctor(..), _)))
+            }
             PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => {
                 None
             }
diff --git a/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs
index 8142bd83877..f63a9e87497 100644
--- a/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs
+++ b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs
@@ -91,7 +91,7 @@ struct X {
 //~| HELP prefix with `field@`
 
 /// Link to [field@S::A]
-//~^ ERROR incompatible link kind for `S::A`
-//~| NOTE this link resolved
+//~^ ERROR unresolved link to `S::A`
+//~| NOTE this link resolves
 //~| HELP prefix with `variant@`
 pub fn f() {}
diff --git a/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr
index 488120304fd..66b910eed81 100644
--- a/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr
+++ b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr
@@ -160,13 +160,13 @@ help: to link to the field, prefix with `field@`
 LL | /// Link to [field@X::y]
    |              ~~~~~~
 
-error: incompatible link kind for `S::A`
+error: unresolved link to `S::A`
   --> $DIR/disambiguator-mismatch.rs:93:14
    |
 LL | /// Link to [field@S::A]
-   |              ^^^^^^^^^^ this link resolved to a unit variant, which is not a field
+   |              ^^^^^^^^^^ this link resolves to the variant `A`, which is not in the value namespace
    |
-help: to link to the unit variant, prefix with `variant@`
+help: to link to the variant, prefix with `variant@`
    |
 LL | /// Link to [variant@S::A]
    |              ~~~~~~~~
diff --git a/tests/rustdoc-ui/intra-doc/value-ctor.rs b/tests/rustdoc-ui/intra-doc/value-ctor.rs
new file mode 100644
index 00000000000..6f57b7c6f10
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/value-ctor.rs
@@ -0,0 +1,35 @@
+// https://github.com/rust-lang/rust/issues/130591
+#![deny(rustdoc::broken_intra_doc_links)]
+#![crate_name = "foo"]
+
+/// [value@Foo::X] //~ERROR broken
+pub enum Foo {
+    X,
+}
+
+/// [tst][value@MyStruct] //~ERROR broken
+pub struct MyStruct;
+
+pub enum MyEnum {
+    Internals,
+}
+
+pub use MyEnum::*;
+
+/// In this context, [a][type@Internals] is a struct,
+/// while [b][value@Internals] fails. //~ERROR broken
+/// Also, [c][struct@Internals] is a struct,
+/// while [d][variant@Internals] fails. //~ERROR broken
+pub struct Internals {
+    foo: (),
+}
+
+pub mod inside {
+    pub struct Internals2;
+}
+
+use inside::*;
+
+/// In this context, [a][type@Internals2] is an enum,
+/// while [b][value@Internals2] fails. //~ERROR broken
+pub enum Internals2 {}
diff --git a/tests/rustdoc-ui/intra-doc/value-ctor.stderr b/tests/rustdoc-ui/intra-doc/value-ctor.stderr
new file mode 100644
index 00000000000..8d2a6649f4c
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/value-ctor.stderr
@@ -0,0 +1,62 @@
+error: unresolved link to `Foo::X`
+  --> $DIR/value-ctor.rs:5:6
+   |
+LL | /// [value@Foo::X]
+   |      ^^^^^^^^^^^^ this link resolves to the variant `X`, which is not in the value namespace
+   |
+note: the lint level is defined here
+  --> $DIR/value-ctor.rs:2:9
+   |
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: to link to the variant, prefix with `variant@`
+   |
+LL | /// [variant@Foo::X]
+   |      ~~~~~~~~
+
+error: unresolved link to `MyStruct`
+  --> $DIR/value-ctor.rs:10:11
+   |
+LL | /// [tst][value@MyStruct]
+   |           ^^^^^^^^^^^^^^ this link resolves to the struct `MyStruct`, which is not in the value namespace
+   |
+help: to link to the struct, prefix with `struct@`
+   |
+LL | /// [tst][struct@MyStruct]
+   |           ~~~~~~~
+
+error: unresolved link to `Internals`
+  --> $DIR/value-ctor.rs:20:15
+   |
+LL | /// while [b][value@Internals] fails.
+   |               ^^^^^^^^^^^^^^^ this link resolves to the struct `Internals`, which is not in the value namespace
+   |
+help: to link to the struct, prefix with `struct@`
+   |
+LL | /// while [b][struct@Internals] fails.
+   |               ~~~~~~~
+
+error: incompatible link kind for `Internals`
+  --> $DIR/value-ctor.rs:22:15
+   |
+LL | /// while [d][variant@Internals] fails.
+   |               ^^^^^^^^^^^^^^^^^ this link resolved to a struct, which is not a variant
+   |
+help: to link to the struct, prefix with `struct@`
+   |
+LL | /// while [d][struct@Internals] fails.
+   |               ~~~~~~~
+
+error: unresolved link to `Internals2`
+  --> $DIR/value-ctor.rs:34:15
+   |
+LL | /// while [b][value@Internals2] fails.
+   |               ^^^^^^^^^^^^^^^^ this link resolves to the enum `Internals2`, which is not in the value namespace
+   |
+help: to link to the enum, prefix with `enum@`
+   |
+LL | /// while [b][enum@Internals2] fails.
+   |               ~~~~~
+
+error: aborting due to 5 previous errors
+