diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 3b54ffbc3f0..b9d1597c4c6 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -629,6 +629,8 @@ declare_features! ( /// Allows references to types with interior mutability within constants (active, const_refs_to_cell, "1.51.0", Some(80384), None), + /// Allows using `pointer` and `reference` in intra-doc links + (active, intra_doc_pointers, "1.51.0", Some(80896), None), // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 63f95a39084..7b90e5b611c 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -622,6 +622,7 @@ symbols! { intel, into_iter, into_result, + intra_doc_pointers, intrinsics, irrefutable_let_patterns, isa_attribute, diff --git a/src/doc/unstable-book/src/language-features/intra-doc-pointers.md b/src/doc/unstable-book/src/language-features/intra-doc-pointers.md new file mode 100644 index 00000000000..fbc83f4b4f4 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/intra-doc-pointers.md @@ -0,0 +1,15 @@ +# `intra-doc-pointers` + +The tracking issue for this feature is: [#80896] + +[#80896]: https://github.com/rust-lang/rust/issues/80896 + +------------------------ + +Rustdoc does not currently allow disambiguating between `*const` and `*mut`, and +raw pointers in intra-doc links are unstable until it does. + +```rust +#![feature(intra_doc_pointers)] +//! [pointer::add] +``` diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 280984088a9..2694450a520 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -20,8 +20,7 @@ use rustc_session::lint::{ Lint, }; use rustc_span::hygiene::{MacroKind, SyntaxContext}; -use rustc_span::symbol::Ident; -use rustc_span::symbol::Symbol; +use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::DUMMY_SP; use smallvec::{smallvec, SmallVec}; @@ -1195,7 +1194,7 @@ impl LinkCollector<'_, '_> { }; match res { - Res::Primitive(_) => { + Res::Primitive(prim) => { if let Some((kind, id)) = self.kind_side_channel.take() { // We're actually resolving an associated item of a primitive, so we need to // verify the disambiguator (if any) matches the type of the associated item. @@ -1206,6 +1205,29 @@ impl LinkCollector<'_, '_> { // valid omission. See https://github.com/rust-lang/rust/pull/80660#discussion_r551585677 // for discussion on the matter. verify(kind, id)?; + + if prim == PrimitiveType::RawPointer + && !self.cx.tcx.features().intra_doc_pointers + { + let span = super::source_span_for_markdown_range( + cx, + dox, + &ori_link.range, + &item.attrs, + ) + .unwrap_or_else(|| { + span_of_attrs(&item.attrs).unwrap_or(item.source.span()) + }); + + rustc_session::parse::feature_err( + &self.cx.tcx.sess.parse_sess, + sym::intra_doc_pointers, + span, + "linking to associated items of raw pointers is experimental", + ) + .note("rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does") + .emit(); + } } else { match disambiguator { Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => {} @@ -1215,6 +1237,7 @@ impl LinkCollector<'_, '_> { } } } + Some(ItemLink { link: ori_link.link, link_text, did: None, fragment }) } Res::Def(kind, id) => { diff --git a/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.rs b/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.rs new file mode 100644 index 00000000000..3cfac942ca8 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.rs @@ -0,0 +1,6 @@ +//! [pointer::add] +//~^ ERROR: experimental +//! [pointer::wrapping_add] +//~^ ERROR: experimental +//! [pointer] // This is explicitly allowed +//! [reference] // This is explicitly allowed diff --git a/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr b/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr new file mode 100644 index 00000000000..2c946ed48db --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr @@ -0,0 +1,23 @@ +error[E0658]: linking to associated items of raw pointers is experimental + --> $DIR/feature-gate-intra-doc-pointers.rs:1:6 + | +LL | //! [pointer::add] + | ^^^^^^^^^^^^ + | + = note: see issue #80896 for more information + = help: add `#![feature(intra_doc_pointers)]` to the crate attributes to enable + = note: rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does + +error[E0658]: linking to associated items of raw pointers is experimental + --> $DIR/feature-gate-intra-doc-pointers.rs:3:6 + | +LL | //! [pointer::wrapping_add] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #80896 for more information + = help: add `#![feature(intra_doc_pointers)]` to the crate attributes to enable + = note: rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs index 114502b0ddf..6785c4c43f5 100644 --- a/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs +++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs @@ -1,4 +1,5 @@ #![deny(broken_intra_doc_links)] +#![feature(intra_doc_pointers)] // These are links that could reasonably expected to work, but don't. // `[]` isn't supported because it had too many false positives. diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr index ea831e648f6..174758504ae 100644 --- a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr +++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr @@ -1,5 +1,5 @@ error: unresolved link to `T` - --> $DIR/non-path-primitives.rs:11:7 + --> $DIR/non-path-primitives.rs:12:7 | LL | //! [[T]::rotate_left] | ^ no item named `T` in scope @@ -12,7 +12,7 @@ LL | #![deny(broken_intra_doc_links)] = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: unresolved link to `Z` - --> $DIR/non-path-primitives.rs:13:5 + --> $DIR/non-path-primitives.rs:14:5 | LL | //![Z]([T; N]::map) | ^ no item named `Z` in scope @@ -20,7 +20,7 @@ LL | //![Z]([T; N]::map) = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: unresolved link to `Z` - --> $DIR/non-path-primitives.rs:16:6 + --> $DIR/non-path-primitives.rs:17:6 | LL | //! [Z][] | ^ no item named `Z` in scope @@ -28,7 +28,7 @@ LL | //! [Z][] = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: unresolved link to `Z` - --> $DIR/non-path-primitives.rs:18:6 + --> $DIR/non-path-primitives.rs:19:6 | LL | //! [Z]: [T; N]::map | ^ no item named `Z` in scope @@ -36,31 +36,31 @@ LL | //! [Z]: [T; N]::map = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: unresolved link to `unit::eq` - --> $DIR/non-path-primitives.rs:27:6 + --> $DIR/non-path-primitives.rs:28:6 | LL | //! [unit::eq] | ^^^^^^^^ the builtin type `unit` has no associated item named `eq` error: unresolved link to `tuple::eq` - --> $DIR/non-path-primitives.rs:28:6 + --> $DIR/non-path-primitives.rs:29:6 | LL | //! [tuple::eq] | ^^^^^^^^^ the builtin type `tuple` has no associated item named `eq` error: unresolved link to `fn::eq` - --> $DIR/non-path-primitives.rs:29:6 + --> $DIR/non-path-primitives.rs:30:6 | LL | //! [fn::eq] | ^^^^^^ the builtin type `fn` has no associated item named `eq` error: unresolved link to `never::eq` - --> $DIR/non-path-primitives.rs:30:6 + --> $DIR/non-path-primitives.rs:31:6 | LL | //! [never::eq] | ^^^^^^^^^ the builtin type `never` has no associated item named `eq` error: unresolved link to `reference::deref` - --> $DIR/non-path-primitives.rs:34:6 + --> $DIR/non-path-primitives.rs:35:6 | LL | //! [reference::deref] | ^^^^^^^^^^^^^^^^ the builtin type `reference` has no associated item named `deref` diff --git a/src/test/rustdoc/intra-doc/non-path-primitives.rs b/src/test/rustdoc/intra-doc/non-path-primitives.rs index 2c7e7b5c48c..48c667ef2d1 100644 --- a/src/test/rustdoc/intra-doc/non-path-primitives.rs +++ b/src/test/rustdoc/intra-doc/non-path-primitives.rs @@ -1,5 +1,6 @@ // ignore-tidy-linelength #![crate_name = "foo"] +#![feature(intra_doc_pointers)] #![deny(broken_intra_doc_links)] // @has foo/index.html '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'slice::rotate_left' diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 384a291a777..d3a44542759 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -85,7 +85,11 @@ pub fn check( assert!(!lib_features.is_empty()); super::walk_many( - &[&src_path.join("test/ui"), &src_path.join("test/ui-fulldeps")], + &[ + &src_path.join("test/ui"), + &src_path.join("test/ui-fulldeps"), + &src_path.join("test/rustdoc-ui"), + ], &mut |path| super::filter_dirs(path), &mut |entry, contents| { let file = entry.path();