Auto merge of #87269 - GuillaumeGomez:rollup-qukedv0, r=GuillaumeGomez

Rollup of 8 pull requests

Successful merges:

 - #86230 (Add --nocapture option to rustdoc)
 - #87210 (Rustdoc accessibility: make the sidebar headers actual headers)
 - #87227 (Move asm! and global_asm! to core::arch)
 - #87236 (Simplify command-line argument initialization on unix)
 - #87251 (Fix "item info" width)
 - #87256 (Extend HIR-based WF checking to associated type defaults)
 - #87259 (triagebot shortcut config)
 - #87268 (Don't create references to uninitialized data in `List::from_arena`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-07-19 10:10:08 +00:00
commit 8df945c471
35 changed files with 239 additions and 126 deletions

View File

@ -63,17 +63,17 @@ impl<T: Copy> List<T> {
let (layout, _offset) = let (layout, _offset) =
Layout::new::<usize>().extend(Layout::for_value::<[T]>(slice)).unwrap(); Layout::new::<usize>().extend(Layout::for_value::<[T]>(slice)).unwrap();
let mem = arena.dropless.alloc_raw(layout); let mem = arena.dropless.alloc_raw(layout) as *mut List<T>;
unsafe { unsafe {
let result = &mut *(mem as *mut List<T>);
// Write the length // Write the length
result.len = slice.len(); ptr::addr_of_mut!((*mem).len).write(slice.len());
// Write the elements // Write the elements
let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len); ptr::addr_of_mut!((*mem).data)
arena_slice.copy_from_slice(slice); .cast::<T>()
.copy_from_nonoverlapping(slice.as_ptr(), slice.len());
result &mut *mem
} }
} }

View File

@ -121,7 +121,11 @@ fn diagnostic_hir_wf_check<'tcx>(
let ty = match tcx.hir().get(hir_id) { let ty = match tcx.hir().get(hir_id) {
hir::Node::ImplItem(item) => match item.kind { hir::Node::ImplItem(item) => match item.kind {
hir::ImplItemKind::TyAlias(ref ty) => Some(ty), hir::ImplItemKind::TyAlias(ty) => Some(ty),
_ => None,
},
hir::Node::TraitItem(item) => match item.kind {
hir::TraitItemKind::Type(_, ty) => ty,
_ => None, _ => None,
}, },
_ => None, _ => None,

View File

@ -316,5 +316,35 @@ pub mod primitive;
#[unstable(feature = "stdsimd", issue = "48556")] #[unstable(feature = "stdsimd", issue = "48556")]
mod core_arch; mod core_arch;
#[doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")]
#[stable(feature = "simd_arch", since = "1.27.0")] #[stable(feature = "simd_arch", since = "1.27.0")]
pub use core_arch::arch; pub mod arch {
#[stable(feature = "simd_arch", since = "1.27.0")]
pub use crate::core_arch::arch::*;
/// Inline assembly.
///
/// Read the [unstable book] for the usage.
///
/// [unstable book]: ../../unstable-book/library-features/asm.html
#[unstable(
feature = "asm",
issue = "72016",
reason = "inline assembly is not stable enough for use and is subject to change"
)]
#[rustc_builtin_macro]
pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
/// Module-level inline assembly.
#[unstable(
feature = "global_asm",
issue = "35119",
reason = "`global_asm!` is not stable enough for use and is subject to change"
)]
#[rustc_builtin_macro]
pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
}

View File

@ -1312,27 +1312,6 @@ pub(crate) mod builtin {
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }}; ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
} }
/// Inline assembly.
///
/// Read the [unstable book] for the usage.
///
/// [unstable book]: ../unstable-book/library-features/asm.html
#[unstable(
feature = "asm",
issue = "72016",
reason = "inline assembly is not stable enough for use and is subject to change"
)]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! asm {
("assembly template",
$(operands,)*
$(options($(option),*))?
) => {
/* compiler built-in */
};
}
/// LLVM-style inline assembly. /// LLVM-style inline assembly.
/// ///
/// Read the [unstable book] for the usage. /// Read the [unstable book] for the usage.
@ -1355,23 +1334,6 @@ pub(crate) mod builtin {
}; };
} }
/// Module-level inline assembly.
#[unstable(
feature = "global_asm",
issue = "35119",
reason = "`global_asm!` is not stable enough for use and is subject to change"
)]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! global_asm {
("assembly template",
$(operands,)*
$(options($(option),*))?
) => {
/* compiler built-in */
};
}
/// Prints passed tokens into the standard output. /// Prints passed tokens into the standard output.
#[unstable( #[unstable(
feature = "log_syntax", feature = "log_syntax",

View File

@ -55,11 +55,27 @@ pub use crate::hash::macros::Hash;
#[allow(deprecated)] #[allow(deprecated)]
#[doc(no_inline)] #[doc(no_inline)]
pub use crate::{ pub use crate::{
asm, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
format_args_nl, global_asm, include, include_bytes, include_str, line, llvm_asm, log_syntax, format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path,
module_path, option_env, stringify, trace_macros, option_env, stringify, trace_macros,
}; };
#[unstable(
feature = "asm",
issue = "72016",
reason = "inline assembly is not stable enough for use and is subject to change"
)]
#[doc(no_inline)]
pub use crate::arch::asm;
#[unstable(
feature = "global_asm",
issue = "35119",
reason = "`global_asm!` is not stable enough for use and is subject to change"
)]
#[doc(no_inline)]
pub use crate::arch::global_asm;
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow(deprecated, deprecated_in_future)] #[allow(deprecated, deprecated_in_future)]
#[doc(no_inline)] #[doc(no_inline)]

View File

@ -556,9 +556,9 @@ pub use core::{
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow(deprecated)] #[allow(deprecated)]
pub use core::{ pub use core::{
asm, assert, assert_matches, cfg, column, compile_error, concat, concat_idents, env, file, assert, assert_matches, cfg, column, compile_error, concat, concat_idents, env, file,
format_args, format_args_nl, global_asm, include, include_bytes, include_str, line, llvm_asm, format_args, format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax,
log_syntax, module_path, option_env, stringify, trace_macros, module_path, option_env, stringify, trace_macros,
}; };
#[stable(feature = "core_primitive", since = "1.43.0")] #[stable(feature = "core_primitive", since = "1.43.0")]

View File

@ -39,12 +39,28 @@ pub use crate::result::Result::{self, Err, Ok};
#[allow(deprecated)] #[allow(deprecated)]
#[doc(no_inline)] #[doc(no_inline)]
pub use core::prelude::v1::{ pub use core::prelude::v1::{
asm, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
format_args_nl, global_asm, include, include_bytes, include_str, line, llvm_asm, log_syntax, format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path,
module_path, option_env, stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, option_env, stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq,
PartialEq, PartialOrd, PartialOrd,
}; };
#[unstable(
feature = "asm",
issue = "72016",
reason = "inline assembly is not stable enough for use and is subject to change"
)]
#[doc(no_inline)]
pub use core::prelude::v1::asm;
#[unstable(
feature = "global_asm",
issue = "35119",
reason = "`global_asm!` is not stable enough for use and is subject to change"
)]
#[doc(no_inline)]
pub use core::prelude::v1::global_asm;
// FIXME: Attribute and internal derive macros are not documented because for them rustdoc generates // FIXME: Attribute and internal derive macros are not documented because for them rustdoc generates
// dead links which fail link checker testing. // dead links which fail link checker testing.
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]

View File

@ -14,11 +14,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
imp::init(argc, argv) imp::init(argc, argv)
} }
/// One-time global cleanup.
pub unsafe fn cleanup() {
imp::cleanup()
}
/// Returns the command line arguments /// Returns the command line arguments
pub fn args() -> Args { pub fn args() -> Args {
imp::args() imp::args()
@ -82,16 +77,10 @@ mod imp {
use crate::ptr; use crate::ptr;
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering}; use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
use crate::sys_common::mutex::StaticMutex;
static ARGC: AtomicIsize = AtomicIsize::new(0); static ARGC: AtomicIsize = AtomicIsize::new(0);
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut()); static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
// We never call `ENV_LOCK.init()`, so it is UB to attempt to
// acquire this mutex reentrantly!
static LOCK: StaticMutex = StaticMutex::new();
unsafe fn really_init(argc: isize, argv: *const *const u8) { unsafe fn really_init(argc: isize, argv: *const *const u8) {
let _guard = LOCK.lock();
ARGC.store(argc, Ordering::Relaxed); ARGC.store(argc, Ordering::Relaxed);
ARGV.store(argv as *mut _, Ordering::Relaxed); ARGV.store(argv as *mut _, Ordering::Relaxed);
} }
@ -127,21 +116,16 @@ mod imp {
init_wrapper init_wrapper
}; };
pub unsafe fn cleanup() {
let _guard = LOCK.lock();
ARGC.store(0, Ordering::Relaxed);
ARGV.store(ptr::null_mut(), Ordering::Relaxed);
}
pub fn args() -> Args { pub fn args() -> Args {
Args { iter: clone().into_iter() } Args { iter: clone().into_iter() }
} }
fn clone() -> Vec<OsString> { fn clone() -> Vec<OsString> {
unsafe { unsafe {
let _guard = LOCK.lock(); // Load ARGC and ARGV without a lock. If the store to either ARGV or
let argc = ARGC.load(Ordering::Relaxed); // ARGC isn't visible yet, we'll return an empty argument list.
let argv = ARGV.load(Ordering::Relaxed); let argv = ARGV.load(Ordering::Relaxed);
let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
(0..argc) (0..argc)
.map(|i| { .map(|i| {
let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char); let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
@ -159,8 +143,6 @@ mod imp {
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
pub fn cleanup() {}
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub fn args() -> Args { pub fn args() -> Args {
use crate::os::unix::prelude::*; use crate::os::unix::prelude::*;

View File

@ -123,7 +123,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
// SAFETY: must be called only once during runtime cleanup. // SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts. // NOTE: this is not guaranteed to run, for example when the program aborts.
pub unsafe fn cleanup() { pub unsafe fn cleanup() {
args::cleanup();
stack_overflow::cleanup(); stack_overflow::cleanup();
} }

View File

@ -417,3 +417,10 @@ This flag is **deprecated** and **has no effect**.
Rustdoc only supports Rust source code and Markdown input formats. If the Rustdoc only supports Rust source code and Markdown input formats. If the
file ends in `.md` or `.markdown`, `rustdoc` treats it as a Markdown file. file ends in `.md` or `.markdown`, `rustdoc` treats it as a Markdown file.
Otherwise, it assumes that the input file is Rust. Otherwise, it assumes that the input file is Rust.
## `--nocapture`
When this flag is used with `--test`, the output (stdout and stderr) of your tests won't be
captured by rustdoc. Instead, the output will be directed to your terminal,
as if you had run the test executable manually. This is especially useful
for debugging your tests!

View File

@ -156,6 +156,8 @@ crate struct Options {
crate run_check: bool, crate run_check: bool,
/// Whether doctests should emit unused externs /// Whether doctests should emit unused externs
crate json_unused_externs: bool, crate json_unused_externs: bool,
/// Whether to skip capturing stdout and stderr of tests.
crate nocapture: bool,
} }
impl fmt::Debug for Options { impl fmt::Debug for Options {
@ -199,6 +201,7 @@ impl fmt::Debug for Options {
.field("enable-per-target-ignores", &self.enable_per_target_ignores) .field("enable-per-target-ignores", &self.enable_per_target_ignores)
.field("run_check", &self.run_check) .field("run_check", &self.run_check)
.field("no_run", &self.no_run) .field("no_run", &self.no_run)
.field("nocapture", &self.nocapture)
.finish() .finish()
} }
} }
@ -627,6 +630,7 @@ impl Options {
let run_check = matches.opt_present("check"); let run_check = matches.opt_present("check");
let generate_redirect_map = matches.opt_present("generate-redirect-map"); let generate_redirect_map = matches.opt_present("generate-redirect-map");
let show_type_layout = matches.opt_present("show-type-layout"); let show_type_layout = matches.opt_present("show-type-layout");
let nocapture = matches.opt_present("nocapture");
let (lint_opts, describe_lints, lint_cap, _) = let (lint_opts, describe_lints, lint_cap, _) =
get_cmd_lint_options(matches, error_format, &debugging_opts); get_cmd_lint_options(matches, error_format, &debugging_opts);
@ -665,6 +669,7 @@ impl Options {
test_builder, test_builder,
run_check, run_check,
no_run, no_run,
nocapture,
render_options: RenderOptions { render_options: RenderOptions {
output, output,
external_html, external_html,

View File

@ -107,6 +107,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
let mut test_args = options.test_args.clone(); let mut test_args = options.test_args.clone();
let display_warnings = options.display_warnings; let display_warnings = options.display_warnings;
let nocapture = options.nocapture;
let externs = options.externs.clone(); let externs = options.externs.clone();
let json_unused_externs = options.json_unused_externs; let json_unused_externs = options.json_unused_externs;
@ -166,6 +167,9 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
}; };
test_args.insert(0, "rustdoctest".to_string()); test_args.insert(0, "rustdoctest".to_string());
if nocapture {
test_args.push("--nocapture".to_string());
}
test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings))); test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings)));
@ -456,7 +460,16 @@ fn run_test(
cmd.current_dir(run_directory); cmd.current_dir(run_directory);
} }
match cmd.output() { let result = if options.nocapture {
cmd.status().map(|status| process::Output {
status,
stdout: Vec::new(),
stderr: Vec::new(),
})
} else {
cmd.output()
};
match result {
Err(e) => return Err(TestFailure::ExecutionError(e)), Err(e) => return Err(TestFailure::ExecutionError(e)),
Ok(out) => { Ok(out) => {
if should_panic && out.status.success() { if should_panic && out.status.success() {

View File

@ -539,7 +539,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
}; };
let sidebar = if let Some(ref version) = self.cache.crate_version { let sidebar = if let Some(ref version) = self.cache.crate_version {
format!( format!(
"<p class=\"location\">Crate {}</p>\ "<h2 class=\"location\">Crate {}</h2>\
<div class=\"block version\">\ <div class=\"block version\">\
<p>Version {}</p>\ <p>Version {}</p>\
</div>\ </div>\
@ -567,7 +567,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
page.root_path = "./"; page.root_path = "./";
let mut style_files = self.shared.style_files.clone(); let mut style_files = self.shared.style_files.clone();
let sidebar = "<p class=\"location\">Settings</p><div class=\"sidebar-elems\"></div>"; let sidebar = "<h2 class=\"location\">Settings</h2><div class=\"sidebar-elems\"></div>";
style_files.push(StylePath { path: PathBuf::from("settings.css"), disabled: false }); style_files.push(StylePath { path: PathBuf::from("settings.css"), disabled: false });
let v = layout::render( let v = layout::render(
&self.shared.templates, &self.shared.templates,

View File

@ -1654,7 +1654,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
{ {
write!( write!(
buffer, buffer,
"<p class=\"location\">{}{}</p>", "<h2 class=\"location\">{}{}</h2>",
match *it.kind { match *it.kind {
clean::StructItem(..) => "Struct ", clean::StructItem(..) => "Struct ",
clean::TraitItem(..) => "Trait ", clean::TraitItem(..) => "Trait ",
@ -1718,7 +1718,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
// to navigate the documentation (though slightly inefficiently). // to navigate the documentation (though slightly inefficiently).
if !it.is_mod() { if !it.is_mod() {
buffer.write_str("<p class=\"location\">Other items in<br>"); buffer.write_str("<h2 class=\"location\">Other items in<br>");
for (i, name) in cx.current.iter().take(parentlen).enumerate() { for (i, name) in cx.current.iter().take(parentlen).enumerate() {
if i > 0 { if i > 0 {
buffer.write_str("::<wbr>"); buffer.write_str("::<wbr>");
@ -1730,7 +1730,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
*name *name
); );
} }
buffer.write_str("</p>"); buffer.write_str("</h2>");
} }
// Sidebar refers to the enclosing module, not this module. // Sidebar refers to the enclosing module, not this module.
@ -1841,7 +1841,7 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
ret.sort(); ret.sort();
out.push_str( out.push_str(
"<a class=\"sidebar-title\" href=\"#implementations\">Methods</a>\ "<h3 class=\"sidebar-title\"><a href=\"#implementations\">Methods</a></h3>\
<div class=\"sidebar-links\">", <div class=\"sidebar-links\">",
); );
for line in ret { for line in ret {
@ -1906,24 +1906,24 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
if !concrete_format.is_empty() { if !concrete_format.is_empty() {
out.push_str( out.push_str(
"<a class=\"sidebar-title\" href=\"#trait-implementations\">\ "<h3 class=\"sidebar-title\"><a href=\"#trait-implementations\">\
Trait Implementations</a>", Trait Implementations</a></h3>",
); );
write_sidebar_links(out, concrete_format); write_sidebar_links(out, concrete_format);
} }
if !synthetic_format.is_empty() { if !synthetic_format.is_empty() {
out.push_str( out.push_str(
"<a class=\"sidebar-title\" href=\"#synthetic-implementations\">\ "<h3 class=\"sidebar-title\"><a href=\"#synthetic-implementations\">\
Auto Trait Implementations</a>", Auto Trait Implementations</a></h3>",
); );
write_sidebar_links(out, synthetic_format); write_sidebar_links(out, synthetic_format);
} }
if !blanket_format.is_empty() { if !blanket_format.is_empty() {
out.push_str( out.push_str(
"<a class=\"sidebar-title\" href=\"#blanket-implementations\">\ "<h3 class=\"sidebar-title\"><a href=\"#blanket-implementations\">\
Blanket Implementations</a>", Blanket Implementations</a></h3>",
); );
write_sidebar_links(out, blanket_format); write_sidebar_links(out, blanket_format);
} }
@ -1975,7 +1975,7 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
if !ret.is_empty() { if !ret.is_empty() {
write!( write!(
out, out,
"<a class=\"sidebar-title\" href=\"#deref-methods\">Methods from {}&lt;Target={}&gt;</a>", "<h3 class=\"sidebar-title\"><a href=\"#deref-methods\">Methods from {}&lt;Target={}&gt;</a></h3>",
Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(cx))), Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(cx))),
Escape(&format!("{:#}", real_target.print(cx))), Escape(&format!("{:#}", real_target.print(cx))),
); );
@ -1998,7 +1998,7 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
if !fields.is_empty() { if !fields.is_empty() {
if let CtorKind::Fictive = s.struct_type { if let CtorKind::Fictive = s.struct_type {
sidebar.push_str( sidebar.push_str(
"<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\ "<h3 class=\"sidebar-title\"><a href=\"#fields\">Fields</a></h3>\
<div class=\"sidebar-links\">", <div class=\"sidebar-links\">",
); );
@ -2075,8 +2075,8 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
print_sidebar_section( print_sidebar_section(
buf, buf,
&t.items, &t.items,
"<a class=\"sidebar-title\" href=\"#associated-types\">\ "<h3 class=\"sidebar-title\"><a href=\"#associated-types\">\
Associated Types</a><div class=\"sidebar-links\">", Associated Types</a></h3><div class=\"sidebar-links\">",
|m| m.is_associated_type(), |m| m.is_associated_type(),
|out, sym| write!(out, "<a href=\"#associatedtype.{0}\">{0}</a>", sym), |out, sym| write!(out, "<a href=\"#associatedtype.{0}\">{0}</a>", sym),
"</div>", "</div>",
@ -2085,8 +2085,8 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
print_sidebar_section( print_sidebar_section(
buf, buf,
&t.items, &t.items,
"<a class=\"sidebar-title\" href=\"#associated-const\">\ "<h3 class=\"sidebar-title\"><a href=\"#associated-const\">\
Associated Constants</a><div class=\"sidebar-links\">", Associated Constants</a></h3><div class=\"sidebar-links\">",
|m| m.is_associated_const(), |m| m.is_associated_const(),
|out, sym| write!(out, "<a href=\"#associatedconstant.{0}\">{0}</a>", sym), |out, sym| write!(out, "<a href=\"#associatedconstant.{0}\">{0}</a>", sym),
"</div>", "</div>",
@ -2095,8 +2095,8 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
print_sidebar_section( print_sidebar_section(
buf, buf,
&t.items, &t.items,
"<a class=\"sidebar-title\" href=\"#required-methods\">\ "<h3 class=\"sidebar-title\"><a href=\"#required-methods\">\
Required Methods</a><div class=\"sidebar-links\">", Required Methods</a></h3><div class=\"sidebar-links\">",
|m| m.is_ty_method(), |m| m.is_ty_method(),
|out, sym| write!(out, "<a href=\"#tymethod.{0}\">{0}</a>", sym), |out, sym| write!(out, "<a href=\"#tymethod.{0}\">{0}</a>", sym),
"</div>", "</div>",
@ -2105,8 +2105,8 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
print_sidebar_section( print_sidebar_section(
buf, buf,
&t.items, &t.items,
"<a class=\"sidebar-title\" href=\"#provided-methods\">\ "<h3 class=\"sidebar-title\"><a href=\"#provided-methods\">\
Provided Methods</a><div class=\"sidebar-links\">", Provided Methods</a></h3><div class=\"sidebar-links\">",
|m| m.is_method(), |m| m.is_method(),
|out, sym| write!(out, "<a href=\"#method.{0}\">{0}</a>", sym), |out, sym| write!(out, "<a href=\"#method.{0}\">{0}</a>", sym),
"</div>", "</div>",
@ -2128,8 +2128,8 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
if !res.is_empty() { if !res.is_empty() {
res.sort(); res.sort();
buf.push_str( buf.push_str(
"<a class=\"sidebar-title\" href=\"#foreign-impls\">\ "<h3 class=\"sidebar-title\"><a href=\"#foreign-impls\">\
Implementations on Foreign Types</a>\ Implementations on Foreign Types</a></h3>\
<div class=\"sidebar-links\">", <div class=\"sidebar-links\">",
); );
for (name, id) in res.into_iter() { for (name, id) in res.into_iter() {
@ -2141,11 +2141,11 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
sidebar_assoc_items(cx, buf, it); sidebar_assoc_items(cx, buf, it);
buf.push_str("<a class=\"sidebar-title\" href=\"#implementors\">Implementors</a>"); buf.push_str("<h3 class=\"sidebar-title\"><a href=\"#implementors\">Implementors</a></h3>");
if t.is_auto { if t.is_auto {
buf.push_str( buf.push_str(
"<a class=\"sidebar-title\" \ "<h3 class=\"sidebar-title\"><a \
href=\"#synthetic-implementors\">Auto Implementors</a>", href=\"#synthetic-implementors\">Auto Implementors</a></h3>",
); );
} }
@ -2188,7 +2188,7 @@ fn sidebar_union(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, u: &clean
if !fields.is_empty() { if !fields.is_empty() {
sidebar.push_str( sidebar.push_str(
"<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\ "<h3 class=\"sidebar-title\"><a href=\"#fields\">Fields</a></h3>\
<div class=\"sidebar-links\">", <div class=\"sidebar-links\">",
); );
@ -2220,7 +2220,7 @@ fn sidebar_enum(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, e: &clean:
if !variants.is_empty() { if !variants.is_empty() {
variants.sort_unstable(); variants.sort_unstable();
sidebar.push_str(&format!( sidebar.push_str(&format!(
"<a class=\"sidebar-title\" href=\"#variants\">Variants</a>\ "<h3 class=\"sidebar-title\"><a href=\"#variants\">Variants</a></h3>\
<div class=\"sidebar-links\">{}</div>", <div class=\"sidebar-links\">{}</div>",
variants.join(""), variants.join(""),
)); ));

View File

@ -342,6 +342,8 @@ nav.sub {
margin: 30px 10px 20px 10px; margin: 30px 10px 20px 10px;
text-align: center; text-align: center;
word-wrap: break-word; word-wrap: break-word;
font-weight: inherit;
padding: 0;
} }
.sidebar .version { .sidebar .version {
@ -394,6 +396,8 @@ nav.sub {
text-align: center; text-align: center;
font-size: 17px; font-size: 17px;
margin-bottom: 5px; margin-bottom: 5px;
font-weight: inherit;
padding: 0;
} }
.sidebar-links { .sidebar-links {
@ -921,6 +925,9 @@ body.blur > :not(#help) {
padding: 0 20px 20px 17px;; padding: 0 20px 20px 17px;;
} }
.item-info .stab {
display: table;
}
.stab { .stab {
border-width: 1px; border-width: 1px;
border-style: solid; border-style: solid;

View File

@ -604,6 +604,9 @@ fn opts() -> Vec<RustcOptGroup> {
unstable("show-type-layout", |o| { unstable("show-type-layout", |o| {
o.optflagmulti("", "show-type-layout", "Include the memory layout of types in the docs") o.optflagmulti("", "show-type-layout", "Include the memory layout of types in the docs")
}), }),
unstable("nocapture", |o| {
o.optflag("", "nocapture", "Don't capture stdout and stderr of tests")
}),
] ]
} }

View File

@ -136,6 +136,9 @@ crate fn test(mut options: Options) -> Result<(), String> {
find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None); find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None);
options.test_args.insert(0, "rustdoctest".to_string()); options.test_args.insert(0, "rustdoctest".to_string());
if options.nocapture {
options.test_args.push("--nocapture".to_string());
}
test::test_main( test::test_main(
&options.test_args, &options.test_args,
collector.tests, collector.tests,

View File

@ -0,0 +1,7 @@
// This test ensures that the item information don't take 100% of the width if unnecessary.
goto: file://|DOC_PATH|/lib2/struct.Foo.html
// We set a fixed size so there is no chance of "random" resize.
size: (1100, 800)
// We check that ".item-info" is bigger than its content.
assert-css: (".item-info", {"width": "807px"})
assert-css: (".item-info .stab", {"width": "343px"})

View File

@ -13,7 +13,7 @@ click: ".sidebar-menu"
assert-css: (".sidebar-elems", {"display": "block", "left": "-246px"}) assert-css: (".sidebar-elems", {"display": "block", "left": "-246px"})
// Force the sidebar open by focusing a link inside it. // Force the sidebar open by focusing a link inside it.
// This makes it easier for keyboard users to get to it. // This makes it easier for keyboard users to get to it.
focus: ".sidebar-title" focus: ".sidebar-title a"
assert-css: (".sidebar-elems", {"display": "block", "left": "0px"}) assert-css: (".sidebar-elems", {"display": "block", "left": "0px"})
// When we tab out of the sidebar, close it. // When we tab out of the sidebar, close it.
focus: ".search-input" focus: ".search-input"

View File

@ -1,5 +1,7 @@
// ignore-tidy-linelength // ignore-tidy-linelength
#![feature(doc_cfg)]
pub mod module { pub mod module {
pub mod sub_module { pub mod sub_module {
pub mod sub_sub_module { pub mod sub_sub_module {
@ -14,6 +16,7 @@ pub fn foobar() {}
pub type Alias = u32; pub type Alias = u32;
#[doc(cfg(feature = "foo-method"))]
pub struct Foo { pub struct Foo {
pub x: Alias, pub x: Alias,
} }

View File

@ -0,0 +1,12 @@
// check-pass
// compile-flags:--test -Zunstable-options --nocapture
// normalize-stderr-test: "src/test/rustdoc-ui" -> "$$DIR"
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
/// ```compile_fail
/// fn foo() {
/// Input: 123
/// }
/// ```
pub struct Foo;

View File

@ -0,0 +1,18 @@
error: struct literal body without path
--> $DIR/nocapture-fail.rs:8:10
|
LL | fn foo() {
| __________^
LL | | Input: 123
LL | | }
| |_^
|
help: you might have forgotten to add the struct literal inside the block
|
LL | fn foo() { SomeStruct {
LL | Input: 123
LL | } }
|
error: aborting due to previous error

View File

@ -0,0 +1,6 @@
running 1 test
test $DIR/nocapture-fail.rs - Foo (line 7) - compile fail ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

View File

@ -0,0 +1,10 @@
// check-pass
// compile-flags:--test -Zunstable-options --nocapture
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
/// ```
/// println!("hello!");
/// eprintln!("stderr");
/// ```
pub struct Foo;

View File

@ -0,0 +1 @@
stderr

View File

@ -0,0 +1,7 @@
running 1 test
hello!
test $DIR/nocapture.rs - Foo (line 6) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

View File

@ -6,7 +6,7 @@
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)'
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)'
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods"]' 'Methods from Deref<Target=FooJ>' // @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods"]' 'Methods from Deref<Target=FooJ>'
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a'
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b'
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c'

View File

@ -4,6 +4,6 @@
pub struct Foo; pub struct Foo;
// @has foo/struct.Foo.html // @has foo/struct.Foo.html
// @has - '//*[@class="sidebar-title"][@href="#trait-implementations"]' 'Trait Implementations' // @has - '//*[@class="sidebar-title"]/a[@href="#trait-implementations"]' 'Trait Implementations'
// @has - '//*[@class="sidebar-links"]/a' '!Sync' // @has - '//*[@class="sidebar-links"]/a' '!Sync'
impl !Sync for Foo {} impl !Sync for Foo {}

View File

@ -1,13 +1,13 @@
#![crate_name = "foo"] #![crate_name = "foo"]
// @has foo/trait.Foo.html // @has foo/trait.Foo.html
// @has - '//*[@class="sidebar-title"][@href="#required-methods"]' 'Required Methods' // @has - '//*[@class="sidebar-title"]/a[@href="#required-methods"]' 'Required Methods'
// @has - '//*[@class="sidebar-links"]/a' 'bar' // @has - '//*[@class="sidebar-links"]/a' 'bar'
// @has - '//*[@class="sidebar-title"][@href="#provided-methods"]' 'Provided Methods' // @has - '//*[@class="sidebar-title"]/a[@href="#provided-methods"]' 'Provided Methods'
// @has - '//*[@class="sidebar-links"]/a' 'foo' // @has - '//*[@class="sidebar-links"]/a' 'foo'
// @has - '//*[@class="sidebar-title"][@href="#associated-const"]' 'Associated Constants' // @has - '//*[@class="sidebar-title"]/a[@href="#associated-const"]' 'Associated Constants'
// @has - '//*[@class="sidebar-links"]/a' 'BAR' // @has - '//*[@class="sidebar-links"]/a' 'BAR'
// @has - '//*[@class="sidebar-title"][@href="#associated-types"]' 'Associated Types' // @has - '//*[@class="sidebar-title"]/a[@href="#associated-types"]' 'Associated Types'
// @has - '//*[@class="sidebar-links"]/a' 'Output' // @has - '//*[@class="sidebar-links"]/a' 'Output'
pub trait Foo { pub trait Foo {
const BAR: u32 = 0; const BAR: u32 = 0;
@ -18,7 +18,7 @@ pub trait Foo {
} }
// @has foo/struct.Bar.html // @has foo/struct.Bar.html
// @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields' // @has - '//*[@class="sidebar-title"]/a[@href="#fields"]' 'Fields'
// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f"]' 'f' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f"]' 'f'
// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.u"]' 'u' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.u"]' 'u'
// @!has - '//*[@class="sidebar-links"]/a' 'waza' // @!has - '//*[@class="sidebar-links"]/a' 'waza'
@ -29,7 +29,7 @@ pub struct Bar {
} }
// @has foo/enum.En.html // @has foo/enum.En.html
// @has - '//*[@class="sidebar-title"][@href="#variants"]' 'Variants' // @has - '//*[@class="sidebar-title"]/a[@href="#variants"]' 'Variants'
// @has - '//*[@class="sidebar-links"]/a' 'foo' // @has - '//*[@class="sidebar-links"]/a' 'foo'
// @has - '//*[@class="sidebar-links"]/a' 'bar' // @has - '//*[@class="sidebar-links"]/a' 'bar'
pub enum En { pub enum En {
@ -38,7 +38,7 @@ pub enum En {
} }
// @has foo/union.MyUnion.html // @has foo/union.MyUnion.html
// @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields' // @has - '//*[@class="sidebar-title"]/a[@href="#fields"]' 'Fields'
// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f1"]' 'f1' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f1"]' 'f1'
// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f2"]' 'f2' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f2"]' 'f2'
// @!has - '//*[@class="sidebar-links"]/a' 'waza' // @!has - '//*[@class="sidebar-links"]/a' 'waza'

View File

@ -3,7 +3,7 @@
#![crate_name = "foo"] #![crate_name = "foo"]
// @has foo/trait.Foo.html // @has foo/trait.Foo.html
// @has - '//*[@class="sidebar-title"][@href="#foreign-impls"]' 'Implementations on Foreign Types' // @has - '//*[@class="sidebar-title"]/a[@href="#foreign-impls"]' 'Implementations on Foreign Types'
// @has - '//h2[@id="foreign-impls"]' 'Implementations on Foreign Types' // @has - '//h2[@id="foreign-impls"]' 'Implementations on Foreign Types'
// @has - '//*[@class="sidebar-links"]/a[@href="#impl-Foo-for-u32"]' 'u32' // @has - '//*[@class="sidebar-links"]/a[@href="#impl-Foo-for-u32"]' 'u32'
// @has - '//div[@id="impl-Foo-for-u32"]//code' 'impl Foo for u32' // @has - '//div[@id="impl-Foo-for-u32"]//code' 'impl Foo for u32'

View File

@ -12,7 +12,7 @@ impl MyStruct {
// @has - '//*[@class="impl has-srclink"]//code' 'impl MyAlias' // @has - '//*[@class="impl has-srclink"]//code' 'impl MyAlias'
// @has - '//*[@class="impl has-srclink"]//code' 'impl MyTrait for MyAlias' // @has - '//*[@class="impl has-srclink"]//code' 'impl MyTrait for MyAlias'
// @has - 'Alias docstring' // @has - 'Alias docstring'
// @has - '//*[@class="sidebar"]//p[@class="location"]' 'Type Definition MyAlias' // @has - '//*[@class="sidebar"]//*[@class="location"]' 'Type Definition MyAlias'
// @has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods' // @has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods'
// @has - '//*[@class="sidebar"]//a[@href="#trait-implementations"]' 'Trait Implementations' // @has - '//*[@class="sidebar"]//a[@href="#trait-implementations"]' 'Trait Implementations'
/// Alias docstring /// Alias docstring

View File

@ -1,8 +1,8 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/defaults-wf.rs:7:5 --> $DIR/defaults-wf.rs:7:15
| |
LL | type Ty = Vec<[u8]>; LL | type Ty = Vec<[u8]>;
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ^^^^^^^^^ doesn't have a size known at compile-time
| |
::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
| |

View File

@ -8,7 +8,7 @@ struct IsCopy<T:Copy> { x: T }
trait SomeTrait { trait SomeTrait {
type Type1; type Type1;
type Type2 = IsCopy<Self::Type1>; type Type2 = (IsCopy<Self::Type1>, bool);
//~^ ERROR E0277 //~^ ERROR E0277
} }

View File

@ -1,11 +1,11 @@
error[E0277]: the trait bound `<Self as SomeTrait>::Type1: Copy` is not satisfied error[E0277]: the trait bound `<Self as SomeTrait>::Type1: Copy` is not satisfied
--> $DIR/wf-trait-associated-type-trait.rs:11:5 --> $DIR/wf-trait-associated-type-trait.rs:11:19
| |
LL | struct IsCopy<T:Copy> { x: T } LL | struct IsCopy<T:Copy> { x: T }
| ---- required by this bound in `IsCopy` | ---- required by this bound in `IsCopy`
... ...
LL | type Type2 = IsCopy<Self::Type1>; LL | type Type2 = (IsCopy<Self::Type1>, bool);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `<Self as SomeTrait>::Type1` | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `<Self as SomeTrait>::Type1`
| |
help: consider further restricting the associated type help: consider further restricting the associated type
| |

View File

@ -117,3 +117,5 @@ format = "rustc"
project-name = "Rust" project-name = "Rust"
changelog-path = "RELEASES.md" changelog-path = "RELEASES.md"
changelog-branch = "master" changelog-branch = "master"
[shortcut]