Auto merge of #51140 - GuillaumeGomez:doc-keyword, r=QuietMisdreavus
rustdoc: introduce the #[doc(keyword="")] attribute for documenting keywords Part of #34601. r? @QuietMisdreavus
This commit is contained in:
@@ -346,15 +346,19 @@ def check_tree_attr(tree, path, attr, pat, regexp):
|
|||||||
def check_tree_text(tree, path, pat, regexp):
|
def check_tree_text(tree, path, pat, regexp):
|
||||||
path = normalize_xpath(path)
|
path = normalize_xpath(path)
|
||||||
ret = False
|
ret = False
|
||||||
for e in tree.findall(path):
|
try:
|
||||||
try:
|
for e in tree.findall(path):
|
||||||
value = flatten(e)
|
try:
|
||||||
except KeyError:
|
value = flatten(e)
|
||||||
continue
|
except KeyError:
|
||||||
else:
|
continue
|
||||||
ret = check_string(value, pat, regexp)
|
else:
|
||||||
if ret:
|
ret = check_string(value, pat, regexp)
|
||||||
break
|
if ret:
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print('Failed to get path "{}"'.format(path))
|
||||||
|
raise e
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use syntax::attr;
|
|||||||
use syntax::codemap::{dummy_spanned, Spanned};
|
use syntax::codemap::{dummy_spanned, Spanned};
|
||||||
use syntax::feature_gate::UnstableFeatures;
|
use syntax::feature_gate::UnstableFeatures;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords::{self, Keyword};
|
||||||
use syntax::symbol::{Symbol, InternedString};
|
use syntax::symbol::{Symbol, InternedString};
|
||||||
use syntax_pos::{self, DUMMY_SP, Pos, FileName};
|
use syntax_pos::{self, DUMMY_SP, Pos, FileName};
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ use std::{mem, slice, vec};
|
|||||||
use std::iter::{FromIterator, once};
|
use std::iter::{FromIterator, once};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
@@ -177,7 +178,7 @@ impl<'a, 'tcx, 'rcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx, 'rcx>
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let ExternalCrate { name, src, primitives, .. } = LOCAL_CRATE.clean(cx);
|
let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx);
|
||||||
{
|
{
|
||||||
let m = match module.inner {
|
let m = match module.inner {
|
||||||
ModuleItem(ref mut m) => m,
|
ModuleItem(ref mut m) => m,
|
||||||
@@ -195,6 +196,18 @@ impl<'a, 'tcx, 'rcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx, 'rcx>
|
|||||||
inner: PrimitiveItem(prim),
|
inner: PrimitiveItem(prim),
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
m.items.extend(keywords.into_iter().map(|(def_id, kw, attrs)| {
|
||||||
|
Item {
|
||||||
|
source: Span::empty(),
|
||||||
|
name: Some(kw.clone()),
|
||||||
|
attrs: attrs,
|
||||||
|
visibility: Some(Public),
|
||||||
|
stability: get_stability(cx, def_id),
|
||||||
|
deprecation: get_deprecation(cx, def_id),
|
||||||
|
def_id,
|
||||||
|
inner: KeywordItem(kw),
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut access_levels = cx.access_levels.borrow_mut();
|
let mut access_levels = cx.access_levels.borrow_mut();
|
||||||
@@ -220,6 +233,7 @@ pub struct ExternalCrate {
|
|||||||
pub src: FileName,
|
pub src: FileName,
|
||||||
pub attrs: Attributes,
|
pub attrs: Attributes,
|
||||||
pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
|
pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
|
||||||
|
pub keywords: Vec<(DefId, String, Attributes)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clean<ExternalCrate> for CrateNum {
|
impl Clean<ExternalCrate> for CrateNum {
|
||||||
@@ -286,11 +300,53 @@ impl Clean<ExternalCrate> for CrateNum {
|
|||||||
.filter_map(as_primitive).collect()
|
.filter_map(as_primitive).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let as_keyword = |def: Def| {
|
||||||
|
if let Def::Mod(def_id) = def {
|
||||||
|
let attrs = cx.tcx.get_attrs(def_id).clean(cx);
|
||||||
|
let mut keyword = None;
|
||||||
|
for attr in attrs.lists("doc") {
|
||||||
|
if let Some(v) = attr.value_str() {
|
||||||
|
if attr.check_name("keyword") {
|
||||||
|
keyword = Keyword::from_str(&v.as_str()).ok()
|
||||||
|
.map(|x| x.name().to_string());
|
||||||
|
if keyword.is_some() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// FIXME: should warn on unknown keywords?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keyword.map(|p| (def_id, p, attrs));
|
||||||
|
}
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let keywords = if root.is_local() {
|
||||||
|
cx.tcx.hir.krate().module.item_ids.iter().filter_map(|&id| {
|
||||||
|
let item = cx.tcx.hir.expect_item(id.id);
|
||||||
|
match item.node {
|
||||||
|
hir::ItemMod(_) => {
|
||||||
|
as_keyword(Def::Mod(cx.tcx.hir.local_def_id(id.id)))
|
||||||
|
}
|
||||||
|
hir::ItemUse(ref path, hir::UseKind::Single)
|
||||||
|
if item.vis == hir::Visibility::Public => {
|
||||||
|
as_keyword(path.def).map(|(_, prim, attrs)| {
|
||||||
|
(cx.tcx.hir.local_def_id(id.id), prim, attrs)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}).collect()
|
||||||
|
} else {
|
||||||
|
cx.tcx.item_children(root).iter().map(|item| item.def)
|
||||||
|
.filter_map(as_keyword).collect()
|
||||||
|
};
|
||||||
|
|
||||||
ExternalCrate {
|
ExternalCrate {
|
||||||
name: cx.tcx.crate_name(*self).to_string(),
|
name: cx.tcx.crate_name(*self).to_string(),
|
||||||
src: krate_src,
|
src: krate_src,
|
||||||
attrs: cx.tcx.get_attrs(root).clean(cx),
|
attrs: cx.tcx.get_attrs(root).clean(cx),
|
||||||
primitives,
|
primitives,
|
||||||
|
keywords,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,6 +453,9 @@ impl Item {
|
|||||||
pub fn is_extern_crate(&self) -> bool {
|
pub fn is_extern_crate(&self) -> bool {
|
||||||
self.type_() == ItemType::ExternCrate
|
self.type_() == ItemType::ExternCrate
|
||||||
}
|
}
|
||||||
|
pub fn is_keyword(&self) -> bool {
|
||||||
|
self.type_() == ItemType::Keyword
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_stripped(&self) -> bool {
|
pub fn is_stripped(&self) -> bool {
|
||||||
match self.inner { StrippedItem(..) => true, _ => false }
|
match self.inner { StrippedItem(..) => true, _ => false }
|
||||||
@@ -475,6 +534,7 @@ pub enum ItemEnum {
|
|||||||
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
|
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
|
||||||
/// An item that has been stripped by a rustdoc pass
|
/// An item that has been stripped by a rustdoc pass
|
||||||
StrippedItem(Box<ItemEnum>),
|
StrippedItem(Box<ItemEnum>),
|
||||||
|
KeywordItem(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemEnum {
|
impl ItemEnum {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ pub enum ItemType {
|
|||||||
AssociatedConst = 18,
|
AssociatedConst = 18,
|
||||||
Union = 19,
|
Union = 19,
|
||||||
ForeignType = 20,
|
ForeignType = 20,
|
||||||
|
Keyword = 21,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ pub enum NameSpace {
|
|||||||
Type,
|
Type,
|
||||||
Value,
|
Value,
|
||||||
Macro,
|
Macro,
|
||||||
|
Keyword,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a clean::Item> for ItemType {
|
impl<'a> From<&'a clean::Item> for ItemType {
|
||||||
@@ -83,6 +85,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
|
|||||||
clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
|
clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
|
||||||
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
|
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
|
||||||
clean::ForeignTypeItem => ItemType::ForeignType,
|
clean::ForeignTypeItem => ItemType::ForeignType,
|
||||||
|
clean::KeywordItem(..) => ItemType::Keyword,
|
||||||
clean::StrippedItem(..) => unreachable!(),
|
clean::StrippedItem(..) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,6 +134,7 @@ impl ItemType {
|
|||||||
ItemType::Constant => "constant",
|
ItemType::Constant => "constant",
|
||||||
ItemType::AssociatedConst => "associatedconstant",
|
ItemType::AssociatedConst => "associatedconstant",
|
||||||
ItemType::ForeignType => "foreigntype",
|
ItemType::ForeignType => "foreigntype",
|
||||||
|
ItemType::Keyword => "keyword",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,6 +163,8 @@ impl ItemType {
|
|||||||
ItemType::AssociatedConst => NameSpace::Value,
|
ItemType::AssociatedConst => NameSpace::Value,
|
||||||
|
|
||||||
ItemType::Macro => NameSpace::Macro,
|
ItemType::Macro => NameSpace::Macro,
|
||||||
|
|
||||||
|
ItemType::Keyword => NameSpace::Keyword,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,6 +178,7 @@ impl fmt::Display for ItemType {
|
|||||||
pub const NAMESPACE_TYPE: &'static str = "t";
|
pub const NAMESPACE_TYPE: &'static str = "t";
|
||||||
pub const NAMESPACE_VALUE: &'static str = "v";
|
pub const NAMESPACE_VALUE: &'static str = "v";
|
||||||
pub const NAMESPACE_MACRO: &'static str = "m";
|
pub const NAMESPACE_MACRO: &'static str = "m";
|
||||||
|
pub const NAMESPACE_KEYWORD: &'static str = "k";
|
||||||
|
|
||||||
impl NameSpace {
|
impl NameSpace {
|
||||||
pub fn to_static_str(&self) -> &'static str {
|
pub fn to_static_str(&self) -> &'static str {
|
||||||
@@ -179,6 +186,7 @@ impl NameSpace {
|
|||||||
NameSpace::Type => NAMESPACE_TYPE,
|
NameSpace::Type => NAMESPACE_TYPE,
|
||||||
NameSpace::Value => NAMESPACE_VALUE,
|
NameSpace::Value => NAMESPACE_VALUE,
|
||||||
NameSpace::Macro => NAMESPACE_MACRO,
|
NameSpace::Macro => NAMESPACE_MACRO,
|
||||||
|
NameSpace::Keyword => NAMESPACE_KEYWORD,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1541,6 +1541,7 @@ struct AllTypes {
|
|||||||
typedefs: HashSet<ItemEntry>,
|
typedefs: HashSet<ItemEntry>,
|
||||||
statics: HashSet<ItemEntry>,
|
statics: HashSet<ItemEntry>,
|
||||||
constants: HashSet<ItemEntry>,
|
constants: HashSet<ItemEntry>,
|
||||||
|
keywords: HashSet<ItemEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AllTypes {
|
impl AllTypes {
|
||||||
@@ -1556,6 +1557,7 @@ impl AllTypes {
|
|||||||
typedefs: HashSet::with_capacity(100),
|
typedefs: HashSet::with_capacity(100),
|
||||||
statics: HashSet::with_capacity(100),
|
statics: HashSet::with_capacity(100),
|
||||||
constants: HashSet::with_capacity(100),
|
constants: HashSet::with_capacity(100),
|
||||||
|
keywords: HashSet::with_capacity(100),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2063,12 +2065,13 @@ impl<'a> fmt::Display for Item<'a> {
|
|||||||
clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?,
|
clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?,
|
||||||
clean::ConstantItem(..) => write!(fmt, "Constant ")?,
|
clean::ConstantItem(..) => write!(fmt, "Constant ")?,
|
||||||
clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
|
clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
|
||||||
|
clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
|
||||||
_ => {
|
_ => {
|
||||||
// We don't generate pages for any other type.
|
// We don't generate pages for any other type.
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !self.item.is_primitive() {
|
if !self.item.is_primitive() && !self.item.is_keyword() {
|
||||||
let cur = &self.cx.current;
|
let cur = &self.cx.current;
|
||||||
let amt = if self.item.is_mod() { cur.len() - 1 } else { cur.len() };
|
let amt = if self.item.is_mod() { cur.len() - 1 } else { cur.len() };
|
||||||
for (i, component) in cur.iter().enumerate().take(amt) {
|
for (i, component) in cur.iter().enumerate().take(amt) {
|
||||||
@@ -2126,6 +2129,7 @@ impl<'a> fmt::Display for Item<'a> {
|
|||||||
item_static(fmt, self.cx, self.item, i),
|
item_static(fmt, self.cx, self.item, i),
|
||||||
clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c),
|
clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c),
|
||||||
clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
|
clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
|
||||||
|
clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k),
|
||||||
_ => {
|
_ => {
|
||||||
// We don't generate pages for any other type.
|
// We don't generate pages for any other type.
|
||||||
unreachable!();
|
unreachable!();
|
||||||
@@ -2353,29 +2357,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||||||
write!(w, "</table>")?;
|
write!(w, "</table>")?;
|
||||||
}
|
}
|
||||||
curty = myty;
|
curty = myty;
|
||||||
let (short, name) = match myty.unwrap() {
|
let (short, name) = item_ty_to_strs(&myty.unwrap());
|
||||||
ItemType::ExternCrate |
|
|
||||||
ItemType::Import => ("reexports", "Re-exports"),
|
|
||||||
ItemType::Module => ("modules", "Modules"),
|
|
||||||
ItemType::Struct => ("structs", "Structs"),
|
|
||||||
ItemType::Union => ("unions", "Unions"),
|
|
||||||
ItemType::Enum => ("enums", "Enums"),
|
|
||||||
ItemType::Function => ("functions", "Functions"),
|
|
||||||
ItemType::Typedef => ("types", "Type Definitions"),
|
|
||||||
ItemType::Static => ("statics", "Statics"),
|
|
||||||
ItemType::Constant => ("constants", "Constants"),
|
|
||||||
ItemType::Trait => ("traits", "Traits"),
|
|
||||||
ItemType::Impl => ("impls", "Implementations"),
|
|
||||||
ItemType::TyMethod => ("tymethods", "Type Methods"),
|
|
||||||
ItemType::Method => ("methods", "Methods"),
|
|
||||||
ItemType::StructField => ("fields", "Struct Fields"),
|
|
||||||
ItemType::Variant => ("variants", "Variants"),
|
|
||||||
ItemType::Macro => ("macros", "Macros"),
|
|
||||||
ItemType::Primitive => ("primitives", "Primitive Types"),
|
|
||||||
ItemType::AssociatedType => ("associated-types", "Associated Types"),
|
|
||||||
ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
|
|
||||||
ItemType::ForeignType => ("foreign-types", "Foreign Types"),
|
|
||||||
};
|
|
||||||
write!(w, "<h2 id='{id}' class='section-header'>\
|
write!(w, "<h2 id='{id}' class='section-header'>\
|
||||||
<a href=\"#{id}\">{name}</a></h2>\n<table>",
|
<a href=\"#{id}\">{name}</a></h2>\n<table>",
|
||||||
id = derive_id(short.to_owned()), name = name)?;
|
id = derive_id(short.to_owned()), name = name)?;
|
||||||
@@ -4360,6 +4342,33 @@ fn sidebar_enum(fmt: &mut fmt::Formatter, it: &clean::Item,
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
|
||||||
|
match *ty {
|
||||||
|
ItemType::ExternCrate |
|
||||||
|
ItemType::Import => ("reexports", "Re-exports"),
|
||||||
|
ItemType::Module => ("modules", "Modules"),
|
||||||
|
ItemType::Struct => ("structs", "Structs"),
|
||||||
|
ItemType::Union => ("unions", "Unions"),
|
||||||
|
ItemType::Enum => ("enums", "Enums"),
|
||||||
|
ItemType::Function => ("functions", "Functions"),
|
||||||
|
ItemType::Typedef => ("types", "Type Definitions"),
|
||||||
|
ItemType::Static => ("statics", "Statics"),
|
||||||
|
ItemType::Constant => ("constants", "Constants"),
|
||||||
|
ItemType::Trait => ("traits", "Traits"),
|
||||||
|
ItemType::Impl => ("impls", "Implementations"),
|
||||||
|
ItemType::TyMethod => ("tymethods", "Type Methods"),
|
||||||
|
ItemType::Method => ("methods", "Methods"),
|
||||||
|
ItemType::StructField => ("fields", "Struct Fields"),
|
||||||
|
ItemType::Variant => ("variants", "Variants"),
|
||||||
|
ItemType::Macro => ("macros", "Macros"),
|
||||||
|
ItemType::Primitive => ("primitives", "Primitive Types"),
|
||||||
|
ItemType::AssociatedType => ("associated-types", "Associated Types"),
|
||||||
|
ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
|
||||||
|
ItemType::ForeignType => ("foreign-types", "Foreign Types"),
|
||||||
|
ItemType::Keyword => ("keywords", "Keywords"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item,
|
fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item,
|
||||||
items: &[clean::Item]) -> fmt::Result {
|
items: &[clean::Item]) -> fmt::Result {
|
||||||
let mut sidebar = String::new();
|
let mut sidebar = String::new();
|
||||||
@@ -4379,29 +4388,7 @@ fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item,
|
|||||||
ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
|
ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
|
||||||
ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
|
ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
|
||||||
if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) {
|
if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) {
|
||||||
let (short, name) = match myty {
|
let (short, name) = item_ty_to_strs(&myty);
|
||||||
ItemType::ExternCrate |
|
|
||||||
ItemType::Import => ("reexports", "Re-exports"),
|
|
||||||
ItemType::Module => ("modules", "Modules"),
|
|
||||||
ItemType::Struct => ("structs", "Structs"),
|
|
||||||
ItemType::Union => ("unions", "Unions"),
|
|
||||||
ItemType::Enum => ("enums", "Enums"),
|
|
||||||
ItemType::Function => ("functions", "Functions"),
|
|
||||||
ItemType::Typedef => ("types", "Type Definitions"),
|
|
||||||
ItemType::Static => ("statics", "Statics"),
|
|
||||||
ItemType::Constant => ("constants", "Constants"),
|
|
||||||
ItemType::Trait => ("traits", "Traits"),
|
|
||||||
ItemType::Impl => ("impls", "Implementations"),
|
|
||||||
ItemType::TyMethod => ("tymethods", "Type Methods"),
|
|
||||||
ItemType::Method => ("methods", "Methods"),
|
|
||||||
ItemType::StructField => ("fields", "Struct Fields"),
|
|
||||||
ItemType::Variant => ("variants", "Variants"),
|
|
||||||
ItemType::Macro => ("macros", "Macros"),
|
|
||||||
ItemType::Primitive => ("primitives", "Primitive Types"),
|
|
||||||
ItemType::AssociatedType => ("associated-types", "Associated Types"),
|
|
||||||
ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
|
|
||||||
ItemType::ForeignType => ("foreign-types", "Foreign Types"),
|
|
||||||
};
|
|
||||||
sidebar.push_str(&format!("<li><a href=\"#{id}\">{name}</a></li>",
|
sidebar.push_str(&format!("<li><a href=\"#{id}\">{name}</a></li>",
|
||||||
id = short,
|
id = short,
|
||||||
name = name));
|
name = name));
|
||||||
@@ -4462,6 +4449,12 @@ fn item_primitive(w: &mut fmt::Formatter, cx: &Context,
|
|||||||
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
|
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn item_keyword(w: &mut fmt::Formatter, cx: &Context,
|
||||||
|
it: &clean::Item,
|
||||||
|
_p: &str) -> fmt::Result {
|
||||||
|
document(w, cx, it)
|
||||||
|
}
|
||||||
|
|
||||||
const BASIC_KEYWORDS: &'static str = "rust, rustlang, rust-lang";
|
const BASIC_KEYWORDS: &'static str = "rust, rustlang, rust-lang";
|
||||||
|
|
||||||
fn make_item_keywords(it: &clean::Item) -> String {
|
fn make_item_keywords(it: &clean::Item) -> String {
|
||||||
|
|||||||
@@ -38,7 +38,8 @@
|
|||||||
"constant",
|
"constant",
|
||||||
"associatedconstant",
|
"associatedconstant",
|
||||||
"union",
|
"union",
|
||||||
"foreigntype"];
|
"foreigntype",
|
||||||
|
"keyword"];
|
||||||
|
|
||||||
var search_input = document.getElementsByClassName('search-input')[0];
|
var search_input = document.getElementsByClassName('search-input')[0];
|
||||||
|
|
||||||
@@ -158,6 +159,7 @@
|
|||||||
|
|
||||||
// used for special search precedence
|
// used for special search precedence
|
||||||
var TY_PRIMITIVE = itemTypes.indexOf("primitive");
|
var TY_PRIMITIVE = itemTypes.indexOf("primitive");
|
||||||
|
var TY_KEYWORD = itemTypes.indexOf("keyword");
|
||||||
|
|
||||||
onEach(document.getElementsByClassName('js-only'), function(e) {
|
onEach(document.getElementsByClassName('js-only'), function(e) {
|
||||||
removeClass(e, 'js-only');
|
removeClass(e, 'js-only');
|
||||||
@@ -530,11 +532,13 @@
|
|||||||
b = bbb.index;
|
b = bbb.index;
|
||||||
if (a !== b) { return a - b; }
|
if (a !== b) { return a - b; }
|
||||||
|
|
||||||
// special precedence for primitive pages
|
// special precedence for primitive and keyword pages
|
||||||
if ((aaa.item.ty === TY_PRIMITIVE) && (bbb.item.ty !== TY_PRIMITIVE)) {
|
if ((aaa.item.ty === TY_PRIMITIVE && bbb.item.ty !== TY_KEYWORD) ||
|
||||||
|
(aaa.item.ty === TY_KEYWORD && bbb.item.ty !== TY_PRIMITIVE)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((bbb.item.ty === TY_PRIMITIVE) && (aaa.item.ty !== TY_PRIMITIVE)) {
|
if ((bbb.item.ty === TY_PRIMITIVE && aaa.item.ty !== TY_PRIMITIVE) ||
|
||||||
|
(bbb.item.ty === TY_KEYWORD && aaa.item.ty !== TY_KEYWORD)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1206,7 +1210,7 @@
|
|||||||
displayPath = item.path + '::';
|
displayPath = item.path + '::';
|
||||||
href = rootPath + item.path.replace(/::/g, '/') + '/' +
|
href = rootPath + item.path.replace(/::/g, '/') + '/' +
|
||||||
name + '/index.html';
|
name + '/index.html';
|
||||||
} else if (type === "primitive") {
|
} else if (type === "primitive" || type === "keyword") {
|
||||||
displayPath = "";
|
displayPath = "";
|
||||||
href = rootPath + item.path.replace(/::/g, '/') +
|
href = rootPath + item.path.replace(/::/g, '/') +
|
||||||
'/' + type + '.' + name + '.html';
|
'/' + type + '.' + name + '.html';
|
||||||
@@ -1700,6 +1704,7 @@
|
|||||||
block("fn", "Functions");
|
block("fn", "Functions");
|
||||||
block("type", "Type Definitions");
|
block("type", "Type Definitions");
|
||||||
block("foreigntype", "Foreign Types");
|
block("foreigntype", "Foreign Types");
|
||||||
|
block("keyword", "Keywords");
|
||||||
}
|
}
|
||||||
|
|
||||||
window.initSidebarItems = initSidebarItems;
|
window.initSidebarItems = initSidebarItems;
|
||||||
|
|||||||
@@ -628,6 +628,11 @@ tr.result span.primitive::after {
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr.result span.keyword::after {
|
||||||
|
content: ' (keyword)';
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
body.blur > :not(#help) {
|
body.blur > :not(#help) {
|
||||||
filter: blur(8px);
|
filter: blur(8px);
|
||||||
-webkit-filter: blur(8px);
|
-webkit-filter: blur(8px);
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ pre {
|
|||||||
.content .highlighted.constant,
|
.content .highlighted.constant,
|
||||||
.content .highlighted.static { background-color: #0063cc; }
|
.content .highlighted.static { background-color: #0063cc; }
|
||||||
.content .highlighted.primitive { background-color: #00708a; }
|
.content .highlighted.primitive { background-color: #00708a; }
|
||||||
|
.content .highlighted.keyword { background-color: #884719; }
|
||||||
|
|
||||||
.content span.enum, .content a.enum, .block a.current.enum { color: #82b089; }
|
.content span.enum, .content a.enum, .block a.current.enum { color: #82b089; }
|
||||||
.content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; }
|
.content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; }
|
||||||
@@ -145,6 +146,7 @@ pre {
|
|||||||
.content span.method, .content a.method, .block a.current.method,
|
.content span.method, .content a.method, .block a.current.method,
|
||||||
.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
|
.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
|
||||||
.content .fnname{ color: #2BAB63; }
|
.content .fnname{ color: #2BAB63; }
|
||||||
|
.content span.keyword, .content a.keyword, .block a.current.keyword { color: #de5249; }
|
||||||
|
|
||||||
pre.rust .comment { color: #8d8d8b; }
|
pre.rust .comment { color: #8d8d8b; }
|
||||||
pre.rust .doccomment { color: #8ca375; }
|
pre.rust .doccomment { color: #8ca375; }
|
||||||
@@ -209,7 +211,7 @@ a.test-arrow {
|
|||||||
color: grey;
|
color: grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.result span.primitive::after {
|
tr.result span.primitive::after, tr.result span.keyword::after {
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ pre {
|
|||||||
.content .highlighted.constant,
|
.content .highlighted.constant,
|
||||||
.content .highlighted.static { background-color: #c3e0ff; }
|
.content .highlighted.static { background-color: #c3e0ff; }
|
||||||
.content .highlighted.primitive { background-color: #9aecff; }
|
.content .highlighted.primitive { background-color: #9aecff; }
|
||||||
|
.content .highlighted.keyword { background-color: #f99650; }
|
||||||
|
|
||||||
.content span.enum, .content a.enum, .block a.current.enum { color: #508157; }
|
.content span.enum, .content a.enum, .block a.current.enum { color: #508157; }
|
||||||
.content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; }
|
.content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; }
|
||||||
@@ -145,6 +146,7 @@ pre {
|
|||||||
.content span.method, .content a.method, .block a.current.method,
|
.content span.method, .content a.method, .block a.current.method,
|
||||||
.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
|
.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
|
||||||
.content .fnname { color: #9a6e31; }
|
.content .fnname { color: #9a6e31; }
|
||||||
|
.content span.keyword, .content a.keyword, .block a.current.keyword { color: #de5249; }
|
||||||
|
|
||||||
pre.rust .comment { color: #8E908C; }
|
pre.rust .comment { color: #8E908C; }
|
||||||
pre.rust .doccomment { color: #4D4D4C; }
|
pre.rust .doccomment { color: #4D4D4C; }
|
||||||
@@ -203,7 +205,7 @@ a.test-arrow {
|
|||||||
color: grey;
|
color: grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.result span.primitive::after {
|
tr.result span.primitive::after, tr.result span.keyword::after {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,6 +126,9 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
|||||||
|
|
||||||
// Associated types are never stripped
|
// Associated types are never stripped
|
||||||
clean::AssociatedTypeItem(..) => {}
|
clean::AssociatedTypeItem(..) => {}
|
||||||
|
|
||||||
|
// Keywords are never stripped
|
||||||
|
clean::KeywordItem(..) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fastreturn = match i.inner {
|
let fastreturn = match i.inner {
|
||||||
|
|||||||
@@ -316,6 +316,7 @@
|
|||||||
#![cfg_attr(test, feature(update_panic_count))]
|
#![cfg_attr(test, feature(update_panic_count))]
|
||||||
#![cfg_attr(windows, feature(used))]
|
#![cfg_attr(windows, feature(used))]
|
||||||
#![feature(doc_alias)]
|
#![feature(doc_alias)]
|
||||||
|
#![feature(doc_keyword)]
|
||||||
#![feature(float_internals)]
|
#![feature(float_internals)]
|
||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
#![cfg_attr(not(stage0), feature(panic_implementation))]
|
#![cfg_attr(not(stage0), feature(panic_implementation))]
|
||||||
|
|||||||
@@ -476,8 +476,12 @@ declare_features! (
|
|||||||
// 'a: { break 'a; }
|
// 'a: { break 'a; }
|
||||||
(active, label_break_value, "1.28.0", Some(48594), None),
|
(active, label_break_value, "1.28.0", Some(48594), None),
|
||||||
|
|
||||||
|
|
||||||
// #[panic_implementation]
|
// #[panic_implementation]
|
||||||
(active, panic_implementation, "1.28.0", Some(44489), None),
|
(active, panic_implementation, "1.28.0", Some(44489), None),
|
||||||
|
|
||||||
|
// #[doc(keyword = "...")]
|
||||||
|
(active, doc_keyword, "1.28.0", Some(51315), None),
|
||||||
);
|
);
|
||||||
|
|
||||||
declare_features! (
|
declare_features! (
|
||||||
@@ -1506,6 +1510,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||||||
gate_feature_post!(&self, doc_alias, attr.span,
|
gate_feature_post!(&self, doc_alias, attr.span,
|
||||||
"#[doc(alias = \"...\")] is experimental"
|
"#[doc(alias = \"...\")] is experimental"
|
||||||
);
|
);
|
||||||
|
} else if content.iter().any(|c| c.check_name("keyword")) {
|
||||||
|
gate_feature_post!(&self, doc_keyword, attr.span,
|
||||||
|
"#[doc(keyword = \"...\")] is experimental"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,6 +311,17 @@ macro_rules! declare_keywords {(
|
|||||||
ident: Ident::with_empty_ctxt(super::Symbol($index))
|
ident: Ident::with_empty_ctxt(super::Symbol($index))
|
||||||
};
|
};
|
||||||
)*
|
)*
|
||||||
|
|
||||||
|
impl ::std::str::FromStr for Keyword {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, ()> {
|
||||||
|
match s {
|
||||||
|
$($string => Ok($konst),)*
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interner {
|
impl Interner {
|
||||||
|
|||||||
24
src/test/rustdoc/keyword.rs
Normal file
24
src/test/rustdoc/keyword.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
#![feature(doc_keyword)]
|
||||||
|
|
||||||
|
// @has foo/index.html '//h2[@id="keywords"]' 'Keywords'
|
||||||
|
// @has foo/index.html '//a[@href="keyword.match.html"]' 'match'
|
||||||
|
// @has foo/keyword.match.html '//a[@class="keyword"]' 'match'
|
||||||
|
// @has foo/keyword.match.html '//section[@id="main"]//div[@class="docblock"]//p' 'this is a test!'
|
||||||
|
// @!has foo/index.html '//a/@href' 'foo/index.html'
|
||||||
|
// @!has foo/foo/index.html
|
||||||
|
// @!has-dir foo/foo
|
||||||
|
#[doc(keyword = "match")]
|
||||||
|
/// this is a test!
|
||||||
|
mod foo{}
|
||||||
13
src/test/ui/feature-gate-doc_keyword.rs
Normal file
13
src/test/ui/feature-gate-doc_keyword.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#[doc(keyword = "match")] //~ ERROR: #[doc(keyword = "...")] is experimental
|
||||||
|
/// wonderful
|
||||||
|
mod foo{}
|
||||||
11
src/test/ui/feature-gate-doc_keyword.stderr
Normal file
11
src/test/ui/feature-gate-doc_keyword.stderr
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
error[E0658]: #[doc(keyword = "...")] is experimental (see issue #51315)
|
||||||
|
--> $DIR/feature-gate-doc_keyword.rs:11:1
|
||||||
|
|
|
||||||
|
LL | #[doc(keyword = "match")] //~ ERROR: #[doc(keyword = "...")] is experimental
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: add #![feature(doc_keyword)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
@@ -231,7 +231,9 @@ function main(argv) {
|
|||||||
finalJS = "";
|
finalJS = "";
|
||||||
|
|
||||||
var arraysToLoad = ["itemTypes"];
|
var arraysToLoad = ["itemTypes"];
|
||||||
var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "TY_PRIMITIVE", "levenshtein_row2"];
|
var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS",
|
||||||
|
"TY_PRIMITIVE", "TY_KEYWORD",
|
||||||
|
"levenshtein_row2"];
|
||||||
// execQuery first parameter is built in getQuery (which takes in the search input).
|
// execQuery first parameter is built in getQuery (which takes in the search input).
|
||||||
// execQuery last parameter is built in buildIndex.
|
// execQuery last parameter is built in buildIndex.
|
||||||
// buildIndex requires the hashmap from search-index.
|
// buildIndex requires the hashmap from search-index.
|
||||||
|
|||||||
Reference in New Issue
Block a user