Skip to content

Commit 402d370

Browse files
committed
feat: use doc(cfg)
Gated on feature flag docsrs https://doc.rust-lang.org/rustdoc/unstable-features.html\#doccfg-recording-what-platforms-or-features-are-required-for-code-to-be-present See example for how this works. Use cargo +nightly docsrs to test
1 parent 731685a commit 402d370

File tree

3 files changed

+259
-19
lines changed

3 files changed

+259
-19
lines changed

example/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ unstable-risky-struct = []
1212

1313
[dependencies]
1414
instability = { path = "../" }
15+
16+
[package.metadata.docs.rs]
17+
all-features = true
18+
rustdoc-args = ["--cfg", "docsrs"]

example/src/lib.rs

Lines changed: 251 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,269 @@
1-
#![forbid(unreachable_pub)]
1+
#![cfg_attr(docsrs, feature(doc_cfg))]
2+
#![allow(dead_code)]
23

34
//! This is an example library demonstrating various attributes from the
45
//! stability crate.
56
6-
/// This function does something really risky!
7+
/// A stable type alias
78
///
8-
/// Don't use it yet!
9-
#[instability::unstable(feature = "risky-function", issue = "#101")]
10-
pub fn risky_function() {
9+
/// This type alias is stable
10+
pub type StableTypeAlias = u8;
11+
12+
/// An unstable type alias
13+
///
14+
/// This type alias is unstable
15+
#[instability::unstable(feature = "type-alias")]
16+
pub type UnstableTypeAlias = u8;
17+
18+
/// A stable constant
19+
///
20+
/// This constant is stable
21+
pub const STABLE_CONSTANT: u8 = 42;
22+
23+
/// An unstable constant
24+
///
25+
/// This constant is unstable
26+
#[instability::unstable(feature = "constant")]
27+
pub const UNSTABLE_CONSTANT: u8 = 42;
28+
29+
/// A stable static
30+
///
31+
/// This static is stable
32+
pub static STABLE_STATIC: u8 = 42;
33+
34+
/// An unstable static
35+
///
36+
/// This static is unstable
37+
#[instability::unstable(feature = "static")]
38+
pub static UNSTABLE_STATIC: u8 = 42;
39+
40+
/// A stable function
41+
///
42+
/// This function is stable
43+
pub fn stable_function() {
1144
unimplemented!()
1245
}
1346

14-
/// This struct does something really risky!
47+
/// An unstable function
48+
///
49+
/// This function is unstable
50+
#[instability::unstable(feature = "function")]
51+
pub fn unstable_function() {
52+
unimplemented!()
53+
}
54+
55+
/// A stable struct
56+
///
57+
/// This struct is stable
58+
pub struct StableStruct {
59+
pub x: u8,
60+
}
61+
62+
impl StableStruct {
63+
/// An unstable method
64+
///
65+
/// This method is unstable
66+
#[instability::unstable(feature = "method")]
67+
pub fn unstable_method(&self) {
68+
unimplemented!()
69+
}
70+
71+
/// A stable method
72+
///
73+
/// This method is stable
74+
pub fn stable_method(&self) {
75+
unimplemented!()
76+
}
77+
}
78+
79+
/// An unstable struct
80+
///
81+
/// This struct is unstable
82+
#[instability::unstable(feature = "struct")]
83+
pub struct UnstableStruct {
84+
pub x: u8,
85+
}
86+
87+
impl UnstableStruct {
88+
/// An unstable method
89+
///
90+
/// This method is unstable
91+
#[instability::unstable(feature = "method")]
92+
pub fn unstable_method(&self) {
93+
unimplemented!()
94+
}
95+
96+
/// A stable method
97+
///
98+
/// This method is stable
99+
#[expect(
100+
unreachable_pub,
101+
reason = "The unstable macros cannot make the method pub(crate)"
102+
)]
103+
pub fn stable_method(&self) {
104+
unimplemented!()
105+
}
106+
}
107+
108+
/// An unstable struct with an issue link
15109
///
16-
/// Don't use it yet!
17-
#[instability::unstable(feature = "risky-struct", issue = "#102")]
18-
pub struct RiskyStruct {
110+
/// This struct is unstable and has an issue link.
111+
#[instability::unstable(feature = "struct-with-issue", issue = "#123")]
112+
pub struct UnstableStructWithIssue {
19113
pub x: u8,
20114
}
21115

116+
/// A stable trait
117+
///
118+
/// This trait is stable
119+
pub trait StableTrait {
120+
/// A stable trait method
121+
///
122+
/// This method is stable.
123+
fn stable_trait_method(&self) {
124+
unimplemented!()
125+
}
126+
127+
// Not yet supported
128+
// /// An unstable trait method
129+
// ///
130+
// /// This method is unstable.
131+
// #[instability::unstable(feature = "trait-method")]
132+
// fn unstable_trait_method(&self);
133+
}
134+
135+
/// An unstable trait
136+
///
137+
/// This trait is unstable
138+
#[instability::unstable(feature = "trait")]
139+
pub trait UnstableTrait {
140+
/// A stable trait method
141+
///
142+
/// This method is stable.
143+
fn stable_trait_method(&self) {
144+
unimplemented!()
145+
}
146+
147+
// Not yet supported
148+
// /// An unstable trait method
149+
// ///
150+
// /// This method is not implemented yet.
151+
// #[instability::unstable(feature = "trait-method")]
152+
// fn unstable_trait_method(&self);
153+
}
154+
155+
/// A stable enum
156+
///
157+
/// This enum is stable.
158+
pub enum StableEnum {
159+
/// An enum variant
160+
///
161+
/// This variant is stable.
162+
Variant,
163+
}
164+
165+
/// An unstable enum
166+
///
167+
/// This enum is unstable.
168+
#[instability::unstable(feature = "enum")]
169+
pub enum UnstableEnum {
170+
/// An enum variant
171+
///
172+
/// This variant is stable.
173+
Variant,
174+
// Not yet supported
175+
// /// An unstable enum variant
176+
// ///
177+
// /// This variant is not implemented yet.
178+
// #[instability::unstable(feature = "enum-variant")]
179+
// UnstableVariant,
180+
}
181+
182+
/// A stable module
183+
///
184+
/// This module is stable.
185+
pub mod stable {
186+
/// A stable function
187+
///
188+
/// This function is stable.
189+
pub fn stable_function() {
190+
unimplemented!()
191+
}
192+
193+
/// An unstable function
194+
///
195+
/// This function is unstable.
196+
#[instability::unstable(feature = "function")]
197+
pub fn unstable_function() {
198+
unimplemented!()
199+
}
200+
}
201+
202+
/// An unstable module
203+
///
204+
/// This module is unstable.
205+
#[instability::unstable(feature = "module")]
206+
pub mod unstable {
207+
/// A stable function
208+
///
209+
/// This function is stable.
210+
pub fn stable_function() {
211+
unimplemented!()
212+
}
213+
214+
/// An unstable function
215+
///
216+
/// This function is unstable.
217+
#[instability::unstable(feature = "function")]
218+
pub fn unstable_function() {
219+
unimplemented!()
220+
}
221+
}
222+
223+
/// A private module
224+
///
225+
/// This module is private.
22226
mod private {
23-
/// This function does something really risky!
227+
/// A private function
228+
///
229+
/// This function is private.
230+
pub fn private_function() {
231+
unimplemented!()
232+
}
233+
234+
/// An unstable private function
24235
///
25-
/// Don't use it yet!
26-
#[instability::unstable(feature = "risky-private-function")]
27-
pub fn risky_private_function() {
236+
/// This function is unstable.
237+
#[instability::unstable(feature = "private-function")]
238+
pub fn unstable_private_function() {
28239
unimplemented!()
29240
}
30241
}
31242

32-
#[allow(unused_imports)]
33-
#[instability::unstable(feature = "risky-private-function")]
34-
pub use private::risky_private_function;
243+
/// A stable re-export of a private stable item
244+
///
245+
/// This re-export is stable.
246+
pub use private::private_function as stable_reexport;
247+
248+
/// An unstable re-export of a private stable item
249+
///
250+
/// This re-export is unstable.
251+
#[instability::unstable(feature = "reexport")]
252+
#[expect(unused_imports)]
253+
pub use private::private_function as unstable_reexport;
254+
255+
// This does not work as the unstable_private_function is only public within the crate and cannot
256+
// be re-exported
257+
// /// A stable reexport of a private unstable item
258+
// ///
259+
// /// This export is stable.
260+
// pub use private::unstable_private_function as stable_unstable_reexport;
261+
262+
/// An unstable reexport of a private unstable item
263+
///
264+
/// This export is unstable. The availability section on this will be appended to the availability
265+
/// section of the unstable_private_function, which will look odd. Consider avoiding re-exporting
266+
/// unstable items like this, and instead only mark the re-export itself as unstable.
267+
#[instability::unstable(feature = "reexport")]
268+
#[expect(unused_imports)]
269+
pub use private::unstable_private_function as unstable_unstable_export;

src/unstable.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn unstable_macro(args: TokenStream, input: TokenStream) -> TokenStream {
2626
Item::Const(item_const) => unstable_attribute.expand(item_const),
2727
Item::Static(item_static) => unstable_attribute.expand(item_static),
2828
Item::Use(item_use) => unstable_attribute.expand(item_use),
29-
item => panic!("unsupported item type {item:?}"),
29+
_ => panic!("unsupported item type"),
3030
},
3131
Err(err) => return TokenStream::from(Error::from(err).write_errors()),
3232
}
@@ -75,10 +75,11 @@ impl UnstableAttribute {
7575
hidden_item.set_visibility(parse_quote! { pub(crate) });
7676

7777
TokenStream::from(quote! {
78-
#[cfg(feature = #feature_flag)]
78+
#[cfg(any(doc, feature = #feature_flag))]
79+
#[cfg_attr(docsrs, doc(cfg(feature = #feature_flag)))]
7980
#item
8081

81-
#[cfg(not(feature = #feature_flag))]
82+
#[cfg(not(any(doc, feature = #feature_flag)))]
8283
#[allow(dead_code)]
8384
#hidden_item
8485
})

0 commit comments

Comments
 (0)