Change:
I'm probably planning on working on this, I found it while I was working on . The issue is that rustdoc looks up in the value namespace, which returns a Ctor, not a Variant. Turns out giving doc comments unimpeded access to the rustc resolver might not be a perfect idea This seems slightly (but not very) tricky to fix, mainly an ironing out of semantics - do we pretend that in the value namespace doesn't exist? Or do we let you reference it, but taking care not to say that there's a conflict between (the constructor) and (the variant) and that you have to disambiguate it? <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --(current master): <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
i'm not sure why we would want this - you can't document the constructor separately from the variant, so i would expect rustdoc to hide it from intra-doc links
(or alternatively we could make an alias for )
First of all, I can reproduce this problem with a unit-like struct. Second of all, This is an observable fact. To see it, use glob exports. Most crates probably won't do this... but most crates probably won't need disambiguators at all. These things are in the value namespace, and that's a fact that can be observed in the surface language, so we probably shouldn't pretend otherwise.

Discussion:
match self.maybe_resolve_path(&segments, Some(ns), &parent_scope, None) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()), <del> PathResult::NonModule(path_res) => path_res.full_res(), </del> <ins> PathResult::NonModule(path_res) => { path_res.full_res().filter(|res| !matches!(res, Res::Def(DefKind::Ctor(..), _))) } </ins> PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => { None }

//~| HELP prefix with `field@` /// Link to [field@S::A] <del> //~^ ERROR incompatible link kind for `S::A` //~| NOTE this link resolved </del> <ins> //~^ ERROR unresolved link to `S::A` //~| NOTE this link resolves </ins> //~| HELP prefix with `variant@` pub fn f() {}

LL | /// Link to [field@X::y] |              ~~~~~~ <del> error: incompatible link kind for `S::A` </del> <ins> error: unresolved link to `S::A` </ins> --> $DIR/disambiguator-mismatch.rs:93:14 | LL | /// Link to [field@S::A] <del> |              ^^^^^^^^^^ this link resolved to a unit variant, which is not a field </del> <ins> |              ^^^^^^^^^^ this link resolves to the variant `A`, which is not in the value namespace </ins> | <del> help: to link to the unit variant, prefix with `variant@` </del> <ins> help: to link to the variant, prefix with `variant@` </ins> | LL | /// Link to [variant@S::A] |              ~~~~~~~~

<ins> // 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 {} </ins>

<ins> 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 </ins>