diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 5cac2d1bbe7ee..c228f54217d34 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -138,7 +138,7 @@ impl Cfg {
/// Renders the configuration for human display, as a short HTML description.
pub(crate) fn render_short_html(&self) -> String {
- let mut msg = Html(self).to_string();
+ let mut msg = ShortHtml(self).to_string();
if self.should_capitalize_first_letter() {
if let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) {
msg[i .. i+1].make_ascii_uppercase();
@@ -149,7 +149,13 @@ impl Cfg {
/// Renders the configuration for long display, as a long HTML description.
pub(crate) fn render_long_html(&self) -> String {
- let mut msg = format!("This is supported on {}", Html(self));
+ let on = if self.should_use_with_in_description() {
+ "with"
+ } else {
+ "on"
+ };
+
+ let mut msg = format!("This is supported {} {}", on, Html(self));
if self.should_append_only_to_description() {
msg.push_str(" only");
}
@@ -180,6 +186,13 @@ impl Cfg {
}
}
}
+
+ fn should_use_with_in_description(&self) -> bool {
+ match *self {
+ Cfg::Cfg(ref name, _) if name == &"target_feature" => true,
+ _ => false,
+ }
+ }
}
impl ops::Not for Cfg {
@@ -376,6 +389,8 @@ impl<'a> fmt::Display for Html<'a> {
},
("target_endian", Some(endian)) => return write!(fmt, "{}-endian", endian),
("target_pointer_width", Some(bits)) => return write!(fmt, "{}-bit", bits),
+ ("target_feature", Some(feat)) =>
+ return write!(fmt, "target feature {}
", feat),
_ => "",
};
if !human_readable.is_empty() {
@@ -390,6 +405,19 @@ impl<'a> fmt::Display for Html<'a> {
}
}
+struct ShortHtml<'a>(&'a Cfg);
+
+impl<'a> fmt::Display for ShortHtml<'a> {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ match *self.0 {
+ Cfg::Cfg(ref name, Some(ref vendor)) if name == &"target_feature" => {
+ write!(fmt, "{}
", vendor)
+ },
+ ref cfg => write!(fmt, "{}", Html(cfg)),
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use super::Cfg;
@@ -824,6 +852,10 @@ mod test {
).render_short_html(),
"(Debug-assertions enabled or Windows) and Unix"
);
+ assert_eq!(
+ name_value_cfg("target_feature", "sse2").render_short_html(),
+ "sse2
"
+ );
})
}
@@ -898,6 +930,10 @@ mod test {
"This is supported on (debug-assertions enabled or Windows) and Unix\
only."
);
+ assert_eq!(
+ name_value_cfg("target_feature", "sse2").render_long_html(),
+ "This is supported with target feature sse2
only."
+ );
})
}
}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ff281a53ab7e4..d6897617d556e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -828,6 +828,19 @@ impl Attributes {
})
}).collect();
+ // treat #[target_feature(enable = "feat")] attributes as if they were
+ // #[doc(cfg(target_feature = "feat"))] attributes as well
+ for attr in attrs.lists("target_feature") {
+ if attr.check_name("enable") {
+ if let Some(feat) = attr.value_str() {
+ let meta = attr::mk_name_value_item_str("target_feature".into(), feat);
+ if let Ok(feat_cfg) = Cfg::parse(&meta) {
+ cfg &= feat_cfg;
+ }
+ }
+ }
+ }
+
Attributes {
doc_strings,
other_attrs,
diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs
index 8499e5c741ee0..ea8a13b034beb 100644
--- a/src/test/rustdoc/doc-cfg.rs
+++ b/src/test/rustdoc/doc-cfg.rs
@@ -9,6 +9,7 @@
// except according to those terms.
#![feature(doc_cfg)]
+#![feature(target_feature, cfg_target_feature)]
// @has doc_cfg/struct.Portable.html
// @!has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' ''
@@ -45,3 +46,26 @@ pub mod unix_only {
fn unix_and_arm_only_function() {}
}
}
+
+// tagging a function with `#[target_feature]` creates a doc(cfg(target_feature)) node for that
+// item as well
+
+// the portability header is different on the module view versus the full view
+// @has doc_cfg/index.html
+// @matches - '//*[@class=" module-item"]//*[@class="stab portability"]' '\Aavx\Z'
+
+// @has doc_cfg/fn.uses_target_feature.html
+// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
+// 'This is supported with target feature avx only.'
+#[target_feature(enable = "avx")]
+pub unsafe fn uses_target_feature() {
+ content::should::be::irrelevant();
+}
+
+// @has doc_cfg/fn.uses_cfg_target_feature.html
+// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
+// 'This is supported with target feature avx only.'
+#[doc(cfg(target_feature = "avx"))]
+pub fn uses_cfg_target_feature() {
+ uses_target_feature();
+}