Auto merge of #58361 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 16 pull requests Successful merges: - #57259 (Update reference of rlibc crate to compiler-builtins crate) - #57740 (Use `to_ne_bytes` for converting IPv4Addr to octets) - #57926 (Tiny expansion to docs for `core::convert`.) - #58157 (Add Cargo.lock automatically adding message) - #58203 (rustdoc: display sugared return types for async functions) - #58243 (Add trait alias support in rustdoc) - #58262 (Add #[must_use] message to Fn* traits) - #58295 (std::sys::unix::stdio: explain why we do into_raw) - #58297 (Cleanup JS a bit) - #58317 (Some writing improvement, conciseness of intro) - #58324 (miri: give non-generic functions a stable address) - #58332 (operand-to-place copies should never be overlapping) - #58345 (When there are multiple filenames, print what got interpreted as filenames) - #58346 (rpath computation: explain why we pop()) - #58350 (Fix failing tidy (line endings on Windows)) - #58352 (miri value visitor: use `?` in macro) Failed merges: r? @ghost
This commit is contained in:
commit
3d845e131f
25 changed files with 307 additions and 103 deletions
|
@ -1,3 +1,5 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.0.3"
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d663113d1d9fbd35f1145c29f6080a6350b7f419
|
||||
Subproject commit bd2778f304989ee52be8201504d6ec621dd60ca9
|
|
@ -1,9 +1,8 @@
|
|||
# Unstable features
|
||||
|
||||
Rustdoc is under active development, and like the Rust compiler, some features are only available
|
||||
on the nightly releases. Some of these are new and need some more testing before they're able to get
|
||||
released to the world at large, and some of them are tied to features in the Rust compiler that are
|
||||
themselves unstable. Several features here require a matching `#![feature(...)]` attribute to
|
||||
on nightly releases. Some of these features are new and need some more testing before they're able to be
|
||||
released to the world at large, and some of them are tied to features in the Rust compiler that are unstable. Several features here require a matching `#![feature(...)]` attribute to
|
||||
enable, and thus are more fully documented in the [Unstable Book]. Those sections will link over
|
||||
there as necessary.
|
||||
|
||||
|
@ -428,4 +427,4 @@ $ rustdoc src/lib.rs --test -Z unstable-options --persist-doctests target/rustdo
|
|||
|
||||
This flag allows you to keep doctest executables around after they're compiled or run.
|
||||
Usually, rustdoc will immediately discard a compiled doctest after it's been tested, but
|
||||
with this option, you can keep those binaries around for farther testing.
|
||||
with this option, you can keep those binaries around for farther testing.
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
//! [`TryFrom<T>`][`TryFrom`] rather than [`Into<U>`][`Into`] or [`TryInto<U>`][`TryInto`],
|
||||
//! as [`From`] and [`TryFrom`] provide greater flexibility and offer
|
||||
//! equivalent [`Into`] or [`TryInto`] implementations for free, thanks to a
|
||||
//! blanket implementation in the standard library.
|
||||
//! blanket implementation in the standard library. However, there are some cases
|
||||
//! where this is not possible, such as creating conversions into a type defined
|
||||
//! outside your library, so implementing [`Into`] instead of [`From`] is
|
||||
//! sometimes necessary.
|
||||
//!
|
||||
//! # Generic Implementations
|
||||
//!
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
//! often generated by LLVM. Additionally, this library can make explicit
|
||||
//! calls to these functions. Their signatures are the same as found in C.
|
||||
//! These functions are often provided by the system libc, but can also be
|
||||
//! provided by the [rlibc crate](https://crates.io/crates/rlibc).
|
||||
//! provided by the [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
|
||||
//!
|
||||
//! * `rust_begin_panic` - This function takes four arguments, a
|
||||
//! `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
label="expected an `Fn<{Args}>` closure, found `{Self}`",
|
||||
)]
|
||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use]
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
pub trait Fn<Args> : FnMut<Args> {
|
||||
/// Performs the call operation.
|
||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
||||
|
@ -141,7 +141,7 @@ pub trait Fn<Args> : FnMut<Args> {
|
|||
label="expected an `FnMut<{Args}>` closure, found `{Self}`",
|
||||
)]
|
||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use]
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
pub trait FnMut<Args> : FnOnce<Args> {
|
||||
/// Performs the call operation.
|
||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
||||
|
@ -220,7 +220,7 @@ pub trait FnMut<Args> : FnOnce<Args> {
|
|||
label="expected an `FnOnce<{Args}>` closure, found `{Self}`",
|
||||
)]
|
||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use]
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
pub trait FnOnce<Args> {
|
||||
/// The returned type after the call operator is used.
|
||||
#[stable(feature = "fn_once_output", since = "1.12.0")]
|
||||
|
|
|
@ -27,7 +27,7 @@ pub use self::pointer::{Pointer, PointerArithmetic};
|
|||
use std::fmt;
|
||||
use crate::mir;
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::ty::{self, TyCtxt, Instance};
|
||||
use crate::ty::{self, TyCtxt, Instance, subst::UnpackedKind};
|
||||
use crate::ty::layout::{self, Size};
|
||||
use std::io;
|
||||
use crate::rustc_serialize::{Encoder, Decodable, Encodable};
|
||||
|
@ -318,14 +318,29 @@ impl<'tcx> AllocMap<'tcx> {
|
|||
id
|
||||
}
|
||||
|
||||
/// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
|
||||
/// by the linker and functions can be duplicated across crates.
|
||||
/// We thus generate a new `AllocId` for every mention of a function. This means that
|
||||
/// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
|
||||
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId {
|
||||
let id = self.reserve();
|
||||
self.id_to_kind.insert(id, AllocKind::Function(instance));
|
||||
id
|
||||
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
|
||||
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
|
||||
// duplicated across crates.
|
||||
// We thus generate a new `AllocId` for every mention of a function. This means that
|
||||
// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
|
||||
// However, formatting code relies on function identity (see #58320), so we only do
|
||||
// this for generic functions. Lifetime parameters are ignored.
|
||||
let is_generic = instance.substs.into_iter().any(|kind| {
|
||||
match kind.unpack() {
|
||||
UnpackedKind::Lifetime(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
});
|
||||
if is_generic {
|
||||
// Get a fresh ID
|
||||
let id = self.reserve();
|
||||
self.id_to_kind.insert(id, AllocKind::Function(instance));
|
||||
id
|
||||
} else {
|
||||
// Deduplicate
|
||||
self.intern(AllocKind::Function(instance))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `None` in case the `AllocId` is dangling. An `EvalContext` can still have a
|
||||
|
|
|
@ -101,9 +101,9 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
|
|||
|
||||
let cwd = env::current_dir().unwrap();
|
||||
let mut lib = fs::canonicalize(&cwd.join(lib)).unwrap_or_else(|_| cwd.join(lib));
|
||||
lib.pop();
|
||||
lib.pop(); // strip filename
|
||||
let mut output = cwd.join(&config.out_filename);
|
||||
output.pop();
|
||||
output.pop(); // strip filename
|
||||
let output = fs::canonicalize(&output).unwrap_or(output);
|
||||
let relative = path_relative_from(&lib, &output).unwrap_or_else(||
|
||||
panic!("couldn't create relative path from {:?} to {:?}", output, lib));
|
||||
|
|
|
@ -838,7 +838,15 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||
early_error(sopts.error_format, "no input filename given");
|
||||
}
|
||||
1 => panic!("make_input should have provided valid inputs"),
|
||||
_ => early_error(sopts.error_format, "multiple input filenames provided"),
|
||||
_ =>
|
||||
early_error(
|
||||
sopts.error_format,
|
||||
&format!(
|
||||
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
|
||||
matches.free[0],
|
||||
matches.free[1],
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -823,6 +823,8 @@ where
|
|||
let src = match self.try_read_immediate(src)? {
|
||||
Ok(src_val) => {
|
||||
// Yay, we got a value that we can write directly.
|
||||
// FIXME: Add a check to make sure that if `src` is indirect,
|
||||
// it does not overlap with `dest`.
|
||||
return self.write_immediate_no_validate(src_val, dest);
|
||||
}
|
||||
Err(mplace) => mplace,
|
||||
|
@ -836,7 +838,8 @@ where
|
|||
self.memory.copy(
|
||||
src_ptr, src_align,
|
||||
dest_ptr, dest_align,
|
||||
dest.layout.size, false
|
||||
dest.layout.size,
|
||||
/*nonoverlapping*/ true,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -125,14 +125,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
|
|||
}
|
||||
|
||||
macro_rules! make_value_visitor {
|
||||
($visitor_trait_name:ident, $($mutability:ident)*) => {
|
||||
($visitor_trait_name:ident, $($mutability:ident)?) => {
|
||||
// How to traverse a value and what to do when we are at the leaves.
|
||||
pub trait $visitor_trait_name<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Sized {
|
||||
type V: Value<'a, 'mir, 'tcx, M>;
|
||||
|
||||
/// The visitor must have an `EvalContext` in it.
|
||||
fn ecx(&$($mutability)* self)
|
||||
-> &$($mutability)* EvalContext<'a, 'mir, 'tcx, M>;
|
||||
fn ecx(&$($mutability)? self)
|
||||
-> &$($mutability)? EvalContext<'a, 'mir, 'tcx, M>;
|
||||
|
||||
// Recursive actions, ready to be overloaded.
|
||||
/// Visit the given value, dispatching as appropriate to more specialized visitors.
|
||||
|
|
|
@ -517,6 +517,7 @@ pub enum ItemEnum {
|
|||
StaticItem(Static),
|
||||
ConstantItem(Constant),
|
||||
TraitItem(Trait),
|
||||
TraitAliasItem(TraitAlias),
|
||||
ImplItem(Impl),
|
||||
/// A method signature only. Used for required methods in traits (ie,
|
||||
/// non-default-methods).
|
||||
|
@ -554,6 +555,7 @@ impl ItemEnum {
|
|||
ItemEnum::TyMethodItem(ref i) => &i.generics,
|
||||
ItemEnum::MethodItem(ref i) => &i.generics,
|
||||
ItemEnum::ForeignFunctionItem(ref f) => &f.generics,
|
||||
ItemEnum::TraitAliasItem(ref ta) => &ta.generics,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
@ -603,6 +605,7 @@ impl Clean<Item> for doctree::Module {
|
|||
items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
|
||||
items.extend(self.macros.iter().map(|x| x.clean(cx)));
|
||||
items.extend(self.proc_macros.iter().map(|x| x.clean(cx)));
|
||||
items.extend(self.trait_aliases.iter().map(|x| x.clean(cx)));
|
||||
|
||||
// determine if we should display the inner contents or
|
||||
// the outer `mod` item for the source code.
|
||||
|
@ -1724,6 +1727,30 @@ impl FnDecl {
|
|||
pub fn self_type(&self) -> Option<SelfTy> {
|
||||
self.inputs.values.get(0).and_then(|v| v.to_self())
|
||||
}
|
||||
|
||||
/// Returns the sugared return type for an async function.
|
||||
///
|
||||
/// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
|
||||
/// will return `i32`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if the return type does not match the expected sugaring for async
|
||||
/// functions.
|
||||
pub fn sugared_async_return_type(&self) -> FunctionRetTy {
|
||||
match &self.output {
|
||||
FunctionRetTy::Return(Type::ImplTrait(bounds)) => {
|
||||
match &bounds[0] {
|
||||
GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
|
||||
let bindings = trait_.bindings().unwrap();
|
||||
FunctionRetTy::Return(bindings[0].ty.clone())
|
||||
}
|
||||
_ => panic!("unexpected desugaring of async function"),
|
||||
}
|
||||
}
|
||||
_ => panic!("unexpected desugaring of async function"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
|
@ -1885,13 +1912,38 @@ impl Clean<Item> for doctree::Trait {
|
|||
items: self.items.clean(cx),
|
||||
generics: self.generics.clean(cx),
|
||||
bounds: self.bounds.clean(cx),
|
||||
is_spotlight: is_spotlight,
|
||||
is_spotlight,
|
||||
is_auto: self.is_auto.clean(cx),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct TraitAlias {
|
||||
pub generics: Generics,
|
||||
pub bounds: Vec<GenericBound>,
|
||||
}
|
||||
|
||||
impl Clean<Item> for doctree::TraitAlias {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
let attrs = self.attrs.clean(cx);
|
||||
Item {
|
||||
name: Some(self.name.clean(cx)),
|
||||
attrs,
|
||||
source: self.whence.clean(cx),
|
||||
def_id: cx.tcx.hir().local_def_id(self.id),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
inner: TraitAliasItem(TraitAlias {
|
||||
generics: self.generics.clean(cx),
|
||||
bounds: self.bounds.clean(cx),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<bool> for hir::IsAuto {
|
||||
fn clean(&self, _: &DocContext) -> bool {
|
||||
match *self {
|
||||
|
@ -2223,6 +2275,7 @@ pub enum TypeKind {
|
|||
Macro,
|
||||
Attr,
|
||||
Derive,
|
||||
TraitAlias,
|
||||
}
|
||||
|
||||
pub trait GetDefId {
|
||||
|
@ -2282,6 +2335,21 @@ impl Type {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bindings(&self) -> Option<&[TypeBinding]> {
|
||||
match *self {
|
||||
ResolvedPath { ref path, .. } => {
|
||||
path.segments.last().and_then(|seg| {
|
||||
if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
|
||||
Some(&**bindings)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GetDefId for Type {
|
||||
|
@ -3819,10 +3887,9 @@ pub fn register_def(cx: &DocContext, def: Def) -> DefId {
|
|||
MacroKind::Derive => (i, TypeKind::Derive),
|
||||
MacroKind::ProcMacroStub => unreachable!(),
|
||||
},
|
||||
Def::TraitAlias(i) => (i, TypeKind::TraitAlias),
|
||||
Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
|
||||
Def::SelfTy(_, Some(impl_def_id)) => {
|
||||
return impl_def_id
|
||||
}
|
||||
Def::SelfTy(_, Some(impl_def_id)) => return impl_def_id,
|
||||
_ => return def.def_id()
|
||||
};
|
||||
if did.is_local() { return did }
|
||||
|
|
|
@ -38,6 +38,7 @@ pub struct Module {
|
|||
pub foreigns: Vec<hir::ForeignMod>,
|
||||
pub macros: Vec<Macro>,
|
||||
pub proc_macros: Vec<ProcMacro>,
|
||||
pub trait_aliases: Vec<TraitAlias>,
|
||||
pub is_crate: bool,
|
||||
}
|
||||
|
||||
|
@ -53,21 +54,22 @@ impl Module {
|
|||
where_inner: syntax_pos::DUMMY_SP,
|
||||
attrs : hir::HirVec::new(),
|
||||
extern_crates: Vec::new(),
|
||||
imports : Vec::new(),
|
||||
structs : Vec::new(),
|
||||
unions : Vec::new(),
|
||||
enums : Vec::new(),
|
||||
fns : Vec::new(),
|
||||
mods : Vec::new(),
|
||||
typedefs : Vec::new(),
|
||||
existentials: Vec::new(),
|
||||
statics : Vec::new(),
|
||||
constants : Vec::new(),
|
||||
traits : Vec::new(),
|
||||
impls : Vec::new(),
|
||||
foreigns : Vec::new(),
|
||||
macros : Vec::new(),
|
||||
proc_macros: Vec::new(),
|
||||
imports : Vec::new(),
|
||||
structs : Vec::new(),
|
||||
unions : Vec::new(),
|
||||
enums : Vec::new(),
|
||||
fns : Vec::new(),
|
||||
mods : Vec::new(),
|
||||
typedefs : Vec::new(),
|
||||
existentials: Vec::new(),
|
||||
statics : Vec::new(),
|
||||
constants : Vec::new(),
|
||||
traits : Vec::new(),
|
||||
impls : Vec::new(),
|
||||
foreigns : Vec::new(),
|
||||
macros : Vec::new(),
|
||||
proc_macros: Vec::new(),
|
||||
trait_aliases: Vec::new(),
|
||||
is_crate : false,
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +210,18 @@ pub struct Trait {
|
|||
pub depr: Option<attr::Deprecation>,
|
||||
}
|
||||
|
||||
pub struct TraitAlias {
|
||||
pub name: Name,
|
||||
pub generics: hir::Generics,
|
||||
pub bounds: hir::HirVec<hir::GenericBound>,
|
||||
pub attrs: hir::HirVec<ast::Attribute>,
|
||||
pub id: ast::NodeId,
|
||||
pub whence: Span,
|
||||
pub vis: hir::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub depr: Option<attr::Deprecation>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Impl {
|
||||
pub unsafety: hir::Unsafety,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//! assume that HTML output is desired, although it may be possible to redesign
|
||||
//! them in the future to instead emit any format desired.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
|
@ -44,14 +45,16 @@ pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]);
|
|||
pub struct CommaSep<'a, T: 'a>(pub &'a [T]);
|
||||
pub struct AbiSpace(pub Abi);
|
||||
|
||||
/// Wrapper struct for properly emitting a method declaration.
|
||||
pub struct Method<'a> {
|
||||
/// Wrapper struct for properly emitting a function or method declaration.
|
||||
pub struct Function<'a> {
|
||||
/// The declaration to emit.
|
||||
pub decl: &'a clean::FnDecl,
|
||||
/// The length of the function's "name", used to determine line-wrapping.
|
||||
pub name_len: usize,
|
||||
/// The number of spaces to indent each successive line with, if line-wrapping is necessary.
|
||||
pub indent: usize,
|
||||
/// Whether the function is async or not.
|
||||
pub asyncness: hir::IsAsync,
|
||||
}
|
||||
|
||||
/// Wrapper struct for emitting a where clause from Generics.
|
||||
|
@ -829,9 +832,9 @@ impl fmt::Display for clean::FnDecl {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for Method<'a> {
|
||||
impl<'a> fmt::Display for Function<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let &Method { decl, name_len, indent } = self;
|
||||
let &Function { decl, name_len, indent, asyncness } = self;
|
||||
let amp = if f.alternate() { "&" } else { "&" };
|
||||
let mut args = String::new();
|
||||
let mut args_plain = String::new();
|
||||
|
@ -891,11 +894,17 @@ impl<'a> fmt::Display for Method<'a> {
|
|||
args_plain.push_str(", ...");
|
||||
}
|
||||
|
||||
let arrow_plain = format!("{:#}", decl.output);
|
||||
let arrow = if f.alternate() {
|
||||
format!("{:#}", decl.output)
|
||||
let output = if let hir::IsAsync::Async = asyncness {
|
||||
Cow::Owned(decl.sugared_async_return_type())
|
||||
} else {
|
||||
decl.output.to_string()
|
||||
Cow::Borrowed(&decl.output)
|
||||
};
|
||||
|
||||
let arrow_plain = format!("{:#}", &output);
|
||||
let arrow = if f.alternate() {
|
||||
format!("{:#}", &output)
|
||||
} else {
|
||||
output.to_string()
|
||||
};
|
||||
|
||||
let pad = " ".repeat(name_len);
|
||||
|
|
|
@ -42,6 +42,7 @@ pub enum ItemType {
|
|||
Existential = 22,
|
||||
ProcAttribute = 23,
|
||||
ProcDerive = 24,
|
||||
TraitAlias = 25,
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,6 +87,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
|
|||
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
|
||||
clean::ForeignTypeItem => ItemType::ForeignType,
|
||||
clean::KeywordItem(..) => ItemType::Keyword,
|
||||
clean::TraitAliasItem(..) => ItemType::TraitAlias,
|
||||
clean::ProcMacroItem(ref mac) => match mac.kind {
|
||||
MacroKind::Bang => ItemType::Macro,
|
||||
MacroKind::Attr => ItemType::ProcAttribute,
|
||||
|
@ -100,20 +102,21 @@ impl<'a> From<&'a clean::Item> for ItemType {
|
|||
impl From<clean::TypeKind> for ItemType {
|
||||
fn from(kind: clean::TypeKind) -> ItemType {
|
||||
match kind {
|
||||
clean::TypeKind::Struct => ItemType::Struct,
|
||||
clean::TypeKind::Union => ItemType::Union,
|
||||
clean::TypeKind::Enum => ItemType::Enum,
|
||||
clean::TypeKind::Function => ItemType::Function,
|
||||
clean::TypeKind::Trait => ItemType::Trait,
|
||||
clean::TypeKind::Module => ItemType::Module,
|
||||
clean::TypeKind::Static => ItemType::Static,
|
||||
clean::TypeKind::Const => ItemType::Constant,
|
||||
clean::TypeKind::Variant => ItemType::Variant,
|
||||
clean::TypeKind::Typedef => ItemType::Typedef,
|
||||
clean::TypeKind::Foreign => ItemType::ForeignType,
|
||||
clean::TypeKind::Macro => ItemType::Macro,
|
||||
clean::TypeKind::Attr => ItemType::ProcAttribute,
|
||||
clean::TypeKind::Derive => ItemType::ProcDerive,
|
||||
clean::TypeKind::Struct => ItemType::Struct,
|
||||
clean::TypeKind::Union => ItemType::Union,
|
||||
clean::TypeKind::Enum => ItemType::Enum,
|
||||
clean::TypeKind::Function => ItemType::Function,
|
||||
clean::TypeKind::Trait => ItemType::Trait,
|
||||
clean::TypeKind::Module => ItemType::Module,
|
||||
clean::TypeKind::Static => ItemType::Static,
|
||||
clean::TypeKind::Const => ItemType::Constant,
|
||||
clean::TypeKind::Variant => ItemType::Variant,
|
||||
clean::TypeKind::Typedef => ItemType::Typedef,
|
||||
clean::TypeKind::Foreign => ItemType::ForeignType,
|
||||
clean::TypeKind::Macro => ItemType::Macro,
|
||||
clean::TypeKind::Attr => ItemType::ProcAttribute,
|
||||
clean::TypeKind::Derive => ItemType::ProcDerive,
|
||||
clean::TypeKind::TraitAlias => ItemType::TraitAlias,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,6 +149,7 @@ impl ItemType {
|
|||
ItemType::Existential => "existential",
|
||||
ItemType::ProcAttribute => "attr",
|
||||
ItemType::ProcDerive => "derive",
|
||||
ItemType::TraitAlias => "traitalias",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +164,7 @@ impl ItemType {
|
|||
ItemType::Primitive |
|
||||
ItemType::AssociatedType |
|
||||
ItemType::Existential |
|
||||
ItemType::TraitAlias |
|
||||
ItemType::ForeignType => NameSpace::Type,
|
||||
|
||||
ItemType::ExternCrate |
|
||||
|
|
|
@ -62,7 +62,7 @@ use fold::DocFolder;
|
|||
use html::escape::Escape;
|
||||
use html::format::{AsyncSpace, ConstnessSpace};
|
||||
use html::format::{GenericBounds, WhereClause, href, AbiSpace};
|
||||
use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
|
||||
use html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
|
||||
use html::format::fmt_impl_for_trait_page;
|
||||
use html::item_type::ItemType;
|
||||
use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, ErrorCodes, IdMap};
|
||||
|
@ -1836,6 +1836,7 @@ struct AllTypes {
|
|||
keywords: FxHashSet<ItemEntry>,
|
||||
attributes: FxHashSet<ItemEntry>,
|
||||
derives: FxHashSet<ItemEntry>,
|
||||
trait_aliases: FxHashSet<ItemEntry>,
|
||||
}
|
||||
|
||||
impl AllTypes {
|
||||
|
@ -1856,6 +1857,7 @@ impl AllTypes {
|
|||
keywords: new_set(100),
|
||||
attributes: new_set(100),
|
||||
derives: new_set(100),
|
||||
trait_aliases: new_set(100),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1879,6 +1881,7 @@ impl AllTypes {
|
|||
ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::ProcAttribute => self.attributes.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::ProcDerive => self.derives.insert(ItemEntry::new(new_url, name)),
|
||||
ItemType::TraitAlias => self.trait_aliases.insert(ItemEntry::new(new_url, name)),
|
||||
_ => true,
|
||||
};
|
||||
}
|
||||
|
@ -1922,6 +1925,7 @@ impl fmt::Display for AllTypes {
|
|||
print_entries(f, &self.derives, "Derive Macros", "derives")?;
|
||||
print_entries(f, &self.functions, "Functions", "functions")?;
|
||||
print_entries(f, &self.typedefs, "Typedefs", "typedefs")?;
|
||||
print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?;
|
||||
print_entries(f, &self.existentials, "Existentials", "existentials")?;
|
||||
print_entries(f, &self.statics, "Statics", "statics")?;
|
||||
print_entries(f, &self.constants, "Constants", "constants")
|
||||
|
@ -2419,6 +2423,7 @@ impl<'a> fmt::Display for Item<'a> {
|
|||
clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
|
||||
clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
|
||||
clean::ExistentialItem(..) => write!(fmt, "Existential Type ")?,
|
||||
clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?,
|
||||
_ => {
|
||||
// We don't generate pages for any other type.
|
||||
unreachable!();
|
||||
|
@ -2457,6 +2462,7 @@ impl<'a> fmt::Display for Item<'a> {
|
|||
clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
|
||||
clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k),
|
||||
clean::ExistentialItem(ref e, _) => item_existential(fmt, self.cx, self.item, e),
|
||||
clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta),
|
||||
_ => {
|
||||
// We don't generate pages for any other type.
|
||||
unreachable!();
|
||||
|
@ -2977,10 +2983,11 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
|||
name = it.name.as_ref().unwrap(),
|
||||
generics = f.generics,
|
||||
where_clause = WhereClause { gens: &f.generics, indent: 0, end_newline: true },
|
||||
decl = Method {
|
||||
decl = Function {
|
||||
decl: &f.decl,
|
||||
name_len,
|
||||
indent: 0,
|
||||
asyncness: f.header.asyncness,
|
||||
})?;
|
||||
document(w, cx, it)
|
||||
}
|
||||
|
@ -3014,23 +3021,17 @@ fn render_impls(cx: &Context, w: &mut fmt::Formatter,
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn bounds(t_bounds: &[clean::GenericBound]) -> String {
|
||||
fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool) -> String {
|
||||
let mut bounds = String::new();
|
||||
let mut bounds_plain = String::new();
|
||||
if !t_bounds.is_empty() {
|
||||
if !bounds.is_empty() {
|
||||
bounds.push(' ');
|
||||
bounds_plain.push(' ');
|
||||
if !trait_alias {
|
||||
bounds.push_str(": ");
|
||||
}
|
||||
bounds.push_str(": ");
|
||||
bounds_plain.push_str(": ");
|
||||
for (i, p) in t_bounds.iter().enumerate() {
|
||||
if i > 0 {
|
||||
bounds.push_str(" + ");
|
||||
bounds_plain.push_str(" + ");
|
||||
}
|
||||
bounds.push_str(&(*p).to_string());
|
||||
bounds_plain.push_str(&format!("{:#}", *p));
|
||||
}
|
||||
}
|
||||
bounds
|
||||
|
@ -3050,7 +3051,7 @@ fn item_trait(
|
|||
it: &clean::Item,
|
||||
t: &clean::Trait,
|
||||
) -> fmt::Result {
|
||||
let bounds = bounds(&t.bounds);
|
||||
let bounds = bounds(&t.bounds, false);
|
||||
let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
|
||||
let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
|
||||
let required = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>();
|
||||
|
@ -3424,10 +3425,11 @@ fn render_assoc_item(w: &mut fmt::Formatter,
|
|||
href = href,
|
||||
name = name,
|
||||
generics = *g,
|
||||
decl = Method {
|
||||
decl = Function {
|
||||
decl: d,
|
||||
name_len: head_len,
|
||||
indent,
|
||||
asyncness: header.asyncness,
|
||||
},
|
||||
where_clause = WhereClause {
|
||||
gens: g,
|
||||
|
@ -4280,7 +4282,26 @@ fn item_existential(
|
|||
it.name.as_ref().unwrap(),
|
||||
t.generics,
|
||||
where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true },
|
||||
bounds = bounds(&t.bounds))?;
|
||||
bounds = bounds(&t.bounds, false))?;
|
||||
|
||||
document(w, cx, it)?;
|
||||
|
||||
// Render any items associated directly to this alias, as otherwise they
|
||||
// won't be visible anywhere in the docs. It would be nice to also show
|
||||
// associated items from the aliased type (see discussion in #32077), but
|
||||
// we need #14072 to make sense of the generics.
|
||||
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
|
||||
}
|
||||
|
||||
fn item_trait_alias(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
t: &clean::TraitAlias) -> fmt::Result {
|
||||
write!(w, "<pre class='rust trait-alias'>")?;
|
||||
render_attributes(w, it)?;
|
||||
write!(w, "trait {}{}{} = {};</pre>",
|
||||
it.name.as_ref().unwrap(),
|
||||
t.generics,
|
||||
WhereClause { gens: &t.generics, indent: 0, end_newline: true },
|
||||
bounds(&t.bounds, true))?;
|
||||
|
||||
document(w, cx, it)?;
|
||||
|
||||
|
@ -4844,6 +4865,7 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
|
|||
ItemType::Existential => ("existentials", "Existentials"),
|
||||
ItemType::ProcAttribute => ("attributes", "Attribute Macros"),
|
||||
ItemType::ProcDerive => ("derives", "Derive Macros"),
|
||||
ItemType::TraitAlias => ("trait-aliases", "Trait aliases"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ if (!DOMTokenList.prototype.remove) {
|
|||
"keyword",
|
||||
"existential",
|
||||
"attr",
|
||||
"derive"];
|
||||
"derive",
|
||||
"traitalias"];
|
||||
|
||||
var search_input = document.getElementsByClassName("search-input")[0];
|
||||
|
||||
|
@ -79,8 +80,6 @@ if (!DOMTokenList.prototype.remove) {
|
|||
// 2 for "In Return Types"
|
||||
var currentTab = 0;
|
||||
|
||||
var themesWidth = null;
|
||||
|
||||
var titleBeforeSearch = document.title;
|
||||
|
||||
function getPageId() {
|
||||
|
@ -240,7 +239,7 @@ if (!DOMTokenList.prototype.remove) {
|
|||
return String.fromCharCode(c);
|
||||
}
|
||||
|
||||
function displayHelp(display, ev) {
|
||||
function displayHelp(display, ev, help) {
|
||||
if (display === true) {
|
||||
if (hasClass(help, "hidden")) {
|
||||
ev.preventDefault();
|
||||
|
@ -258,7 +257,7 @@ if (!DOMTokenList.prototype.remove) {
|
|||
hideModal();
|
||||
var search = document.getElementById("search");
|
||||
if (hasClass(help, "hidden") === false) {
|
||||
displayHelp(false, ev);
|
||||
displayHelp(false, ev, help);
|
||||
} else if (hasClass(search, "hidden") === false) {
|
||||
ev.preventDefault();
|
||||
addClass(search, "hidden");
|
||||
|
@ -289,7 +288,7 @@ if (!DOMTokenList.prototype.remove) {
|
|||
|
||||
case "s":
|
||||
case "S":
|
||||
displayHelp(false, ev);
|
||||
displayHelp(false, ev, help);
|
||||
hideModal();
|
||||
ev.preventDefault();
|
||||
focusSearchBar();
|
||||
|
@ -304,7 +303,7 @@ if (!DOMTokenList.prototype.remove) {
|
|||
case "?":
|
||||
if (ev.shiftKey) {
|
||||
hideModal();
|
||||
displayHelp(true, ev);
|
||||
displayHelp(true, ev, help);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -654,7 +653,7 @@ if (!DOMTokenList.prototype.remove) {
|
|||
return MAX_LEV_DISTANCE + 1;
|
||||
}
|
||||
}
|
||||
return lev_distance;//Math.ceil(total / done);
|
||||
return Math.ceil(total / done);
|
||||
}
|
||||
}
|
||||
return MAX_LEV_DISTANCE + 1;
|
||||
|
@ -1786,6 +1785,7 @@ if (!DOMTokenList.prototype.remove) {
|
|||
block("type", "Type Definitions");
|
||||
block("foreigntype", "Foreign Types");
|
||||
block("keyword", "Keywords");
|
||||
block("traitalias", "Trait Aliases");
|
||||
}
|
||||
|
||||
window.initSidebarItems = initSidebarItems;
|
||||
|
@ -2432,7 +2432,7 @@ if (!DOMTokenList.prototype.remove) {
|
|||
// for vertical layout (column-oriented flex layout for divs caused
|
||||
// errors in mobile browsers).
|
||||
if (e.tagName === "H2" || e.tagName === "H3") {
|
||||
let nextTagName = e.nextElementSibling.tagName;
|
||||
var nextTagName = e.nextElementSibling.tagName;
|
||||
if (nextTagName == "H2" || nextTagName == "H3") {
|
||||
e.nextElementSibling.style.display = "flex";
|
||||
} else {
|
||||
|
|
|
@ -94,6 +94,7 @@ pre {
|
|||
}
|
||||
.content .highlighted a, .content .highlighted span { color: #eee !important; }
|
||||
.content .highlighted.trait { background-color: #013191; }
|
||||
.content .highlighted.traitalias { background-color: #013191; }
|
||||
.content .highlighted.mod,
|
||||
.content .highlighted.externcrate { background-color: #afc6e4; }
|
||||
.content .highlighted.mod { background-color: #803a1b; }
|
||||
|
@ -128,6 +129,7 @@ pre {
|
|||
.content span.externcrate,
|
||||
.content span.mod, .content a.mod, .block a.current.mod { color: #bda000; }
|
||||
.content span.trait, .content a.trait, .block a.current.trait { color: #b78cf2; }
|
||||
.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #b397da; }
|
||||
.content span.fn, .content a.fn, .block a.current.fn,
|
||||
.content span.method, .content a.method, .block a.current.method,
|
||||
.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
|
||||
|
|
|
@ -96,6 +96,7 @@ pre {
|
|||
}
|
||||
.content .highlighted a, .content .highlighted span { color: #000 !important; }
|
||||
.content .highlighted.trait { background-color: #c7b6ff; }
|
||||
.content .highlighted.traitalias { background-color: #c7b6ff; }
|
||||
.content .highlighted.mod,
|
||||
.content .highlighted.externcrate { background-color: #afc6e4; }
|
||||
.content .highlighted.enum { background-color: #b4d1b9; }
|
||||
|
@ -128,6 +129,7 @@ pre {
|
|||
.content span.externcrate,
|
||||
.content span.mod, .content a.mod, .block a.current.mod { color: #4d76ae; }
|
||||
.content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; }
|
||||
.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #6841f1; }
|
||||
.content span.fn, .content a.fn, .block a.current.fn,
|
||||
.content span.method, .content a.method, .block a.current.method,
|
||||
.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
|
||||
|
|
|
@ -224,6 +224,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
|||
| clean::ConstantItem(..)
|
||||
| clean::UnionItem(..)
|
||||
| clean::AssociatedConstItem(..)
|
||||
| clean::TraitAliasItem(..)
|
||||
| clean::ForeignTypeItem => {
|
||||
if i.def_id.is_local() {
|
||||
if !self.access_levels.is_exported(i.def_id) {
|
||||
|
|
|
@ -547,8 +547,19 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
|
|||
};
|
||||
om.traits.push(t);
|
||||
},
|
||||
hir::ItemKind::TraitAlias(..) => {
|
||||
unimplemented!("trait objects are not yet implemented")
|
||||
hir::ItemKind::TraitAlias(ref gen, ref b) => {
|
||||
let t = TraitAlias {
|
||||
name: ident.name,
|
||||
generics: gen.clone(),
|
||||
bounds: b.iter().cloned().collect(),
|
||||
id: item.id,
|
||||
attrs: item.attrs.clone(),
|
||||
whence: item.span,
|
||||
vis: item.vis.clone(),
|
||||
stab: self.stability(item.id),
|
||||
depr: self.deprecation(item.id),
|
||||
};
|
||||
om.trait_aliases.push(t);
|
||||
},
|
||||
|
||||
hir::ItemKind::Impl(unsafety,
|
||||
|
|
|
@ -392,8 +392,7 @@ impl Ipv4Addr {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn octets(&self) -> [u8; 4] {
|
||||
let bits = u32::from_be(self.inner.s_addr);
|
||||
[(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
|
||||
self.inner.s_addr.to_ne_bytes()
|
||||
}
|
||||
|
||||
/// Returns [`true`] for the special 'unspecified' address (0.0.0.0).
|
||||
|
|
|
@ -12,7 +12,7 @@ impl Stdin {
|
|||
pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
|
||||
let fd = FileDesc::new(libc::STDIN_FILENO);
|
||||
let ret = fd.read(data);
|
||||
fd.into_raw();
|
||||
fd.into_raw(); // do not close this FD
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ impl Stdout {
|
|||
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
||||
let fd = FileDesc::new(libc::STDOUT_FILENO);
|
||||
let ret = fd.write(data);
|
||||
fd.into_raw();
|
||||
fd.into_raw(); // do not close this FD
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ impl Stderr {
|
|||
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
||||
let fd = FileDesc::new(libc::STDERR_FILENO);
|
||||
let ret = fd.write(data);
|
||||
fd.into_raw();
|
||||
fd.into_raw(); // do not close this FD
|
||||
ret
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,35 @@
|
|||
// edition:2018
|
||||
// compile-flags:-Z unstable-options
|
||||
|
||||
// FIXME: once `--edition` is stable in rustdoc, remove that `compile-flags` directive
|
||||
|
||||
#![feature(async_await, futures_api)]
|
||||
|
||||
// @has async_fn/struct.S.html
|
||||
// @has - '//code' 'pub async fn f()'
|
||||
pub struct S;
|
||||
// @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option<Foo>'
|
||||
pub async fn foo() -> Option<Foo> {
|
||||
None
|
||||
}
|
||||
|
||||
impl S {
|
||||
// @has async_fn/fn.bar.html '//pre[@class="rust fn"]' 'pub async fn bar(a: i32, b: i32) -> i32'
|
||||
pub async fn bar(a: i32, b: i32) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
// @has async_fn/fn.baz.html '//pre[@class="rust fn"]' 'pub async fn baz<T>(a: T) -> T'
|
||||
pub async fn baz<T>(a: T) -> T {
|
||||
a
|
||||
}
|
||||
|
||||
trait Bar {}
|
||||
|
||||
impl Bar for () {}
|
||||
|
||||
// @has async_fn/fn.quux.html '//pre[@class="rust fn"]' 'pub async fn quux() -> impl Bar'
|
||||
pub async fn quux() -> impl Bar {
|
||||
()
|
||||
}
|
||||
|
||||
// @has async_fn/struct.Foo.html
|
||||
// @matches - '//code' 'pub async fn f\(\)$'
|
||||
pub struct Foo;
|
||||
|
||||
impl Foo {
|
||||
pub async fn f() {}
|
||||
}
|
||||
|
|
21
src/test/rustdoc/trait_alias.rs
Normal file
21
src/test/rustdoc/trait_alias.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
#![feature(trait_alias)]
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
// @has foo/all.html '//a[@href="traitalias.CopyAlias.html"]' 'CopyAlias'
|
||||
// @has foo/all.html '//a[@href="traitalias.Alias2.html"]' 'Alias2'
|
||||
// @has foo/all.html '//a[@href="traitalias.Foo.html"]' 'Foo'
|
||||
|
||||
// @has foo/index.html '//h2[@id="trait-aliases"]' 'Trait aliases'
|
||||
// @has foo/index.html '//a[@class="traitalias"]' 'CopyAlias'
|
||||
// @has foo/index.html '//a[@class="traitalias"]' 'Alias2'
|
||||
// @has foo/index.html '//a[@class="traitalias"]' 'Foo'
|
||||
|
||||
// @has foo/traitalias.CopyAlias.html '//section[@id="main"]/pre' 'trait CopyAlias = Copy;'
|
||||
pub trait CopyAlias = Copy;
|
||||
// @has foo/traitalias.Alias2.html '//section[@id="main"]/pre' 'trait Alias2 = Copy + Debug;'
|
||||
pub trait Alias2 = Copy + Debug;
|
||||
// @has foo/traitalias.Foo.html '//section[@id="main"]/pre' 'trait Foo<T> = Into<T> + Debug;'
|
||||
pub trait Foo<T> = Into<T> + Debug;
|
Loading…
Add table
Add a link
Reference in a new issue