diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 0da42f38251cc..34ff00c448c13 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1274,6 +1274,31 @@ impl LinkCollector<'_, '_> { } } + /// This method checks specifically if a primitive has a potential ambiguity with a local module. + /// Returns `true` if an error was emitted. + fn check_mod_primitive_ambiguity( + &self, + res: &mut Res, + path_str: &str, + disambiguator: Option, + diag_info: &DiagnosticInfo<'_>, + ) -> bool { + if !matches!(res, Res::Primitive(_)) + && let Some(prim) = resolve_primitive(path_str, TypeNS) + { + // `prim@char` + if matches!(disambiguator, Some(Disambiguator::Primitive)) { + *res = prim; + } else { + // `[char]` when a `char` module is in scope + let candidates = &[(*res, res.def_id(self.cx.tcx)), (prim, None)]; + ambiguity_error(self.cx, diag_info, path_str, candidates, true); + return true; + } + } + false + } + fn compute_link( &mut self, mut res: Res, @@ -1286,21 +1311,19 @@ impl LinkCollector<'_, '_> { // Check for a primitive which might conflict with a module // Report the ambiguity and require that the user specify which one they meant. // FIXME: could there ever be a primitive not in the type namespace? - if matches!( - disambiguator, - None | Some(Disambiguator::Namespace(Namespace::TypeNS) | Disambiguator::Primitive) - ) && !matches!(res, Res::Primitive(_)) - && let Some(prim) = resolve_primitive(path_str, TypeNS) - { - // `prim@char` - if matches!(disambiguator, Some(Disambiguator::Primitive)) { - res = prim; - } else { - // `[char]` when a `char` module is in scope - let candidates = &[(res, res.def_id(self.cx.tcx)), (prim, None)]; - ambiguity_error(self.cx, &diag_info, path_str, candidates, true); - return None; + let emitted_error = match disambiguator { + None | Some(Disambiguator::Primitive) => { + self.check_mod_primitive_ambiguity(&mut res, path_str, disambiguator, &diag_info) + } + Some(Disambiguator::Namespace(Namespace::TypeNS)) + if !matches!(res, Res::Def(DefKind::TyAlias, _)) => + { + self.check_mod_primitive_ambiguity(&mut res, path_str, disambiguator, &diag_info) } + _ => false, + }; + if emitted_error { + return None; } match res { diff --git a/tests/rustdoc-ui/intra-doc/type-alias-primitive.rs b/tests/rustdoc-ui/intra-doc/type-alias-primitive.rs new file mode 100644 index 0000000000000..3a0a617a49101 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/type-alias-primitive.rs @@ -0,0 +1,13 @@ +// Ensure that no warning is emitted if the disambiguator is used for type alias. +// Regression test for . + +//@ check-pass + +#![deny(rustdoc::broken_intra_doc_links)] + +pub struct Foo; +#[allow(non_camel_case_types)] +pub type f32 = Foo; + +/// This function returns [`type@f32`]" and not [`prim@f32`]. +pub fn my_fn() -> f32 {} diff --git a/tests/rustdoc/intra-doc/type-alias-primitive.rs b/tests/rustdoc/intra-doc/type-alias-primitive.rs new file mode 100644 index 0000000000000..077cfffb9e2e6 --- /dev/null +++ b/tests/rustdoc/intra-doc/type-alias-primitive.rs @@ -0,0 +1,14 @@ +// Ensure that no warning is emitted if the disambiguator is used for type alias. +// Regression test for . + +#![crate_name = "foo"] + +pub struct Foo; +#[allow(non_camel_case_types)] +pub type f32 = Foo; + +/// This function returns [`type@f32`] and not [bla][`prim@f32`]. +//@ has 'foo/fn.my_fn.html' +//@ has - '//a[@href="type.f32.html"]' "f32" +//@ has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.f32.html"]' "bla" +pub fn my_fn() -> f32 {}