diff --git a/Cargo.lock b/Cargo.lock index 5609125c7f081..7be90aaf9e6fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -998,9 +998,9 @@ dependencies = [ [[package]] name = "expect-test" -version = "0.1.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e383741ea1982866572109d1a8c807bd36aad91fca701489fdca56ef92b3b8" +checksum = "ceb96f3eaa0d4e8769c52dacfd4eb60183b817ed2f176171b3c691d5022b0f2e" dependencies = [ "difference", "once_cell", diff --git a/README.md b/README.md index 095ffdd04b982..a7e23d8ac2caa 100644 --- a/README.md +++ b/README.md @@ -211,11 +211,17 @@ fetch snapshots, and an OS that can execute the available snapshot binaries. Snapshot binaries are currently built and tested on several platforms: -| Platform / Architecture | x86 | x86_64 | -|----------------------------|-----|--------| -| Windows (7, 8, 10, ...) | ✓ | ✓ | -| Linux (2.6.18 or later) | ✓ | ✓ | -| macOS (10.7 Lion or later) | ✓ | ✓ | +| Platform / Architecture | x86 | x86_64 | +|---------------------------------------------|-----|--------| +| Windows (7, 8, 10, ...) | ✓ | ✓ | +| Linux (kernel 2.6.32, glibc 2.11 or later) | ✓ | ✓ | +| macOS (10.7 Lion or later) | (\*) | ✓ | + +(\*): Apple dropped support for running 32-bit binaries starting from macOS 10.15 and iOS 11. +Due to this decision from Apple, the targets are no longer useful to our users. +Please read [our blog post][macx32] for more info. + +[macx32]: https://blog.rust-lang.org/2020/01/03/reducing-support-for-32-bit-apple-targets.html You may find that other platforms work, but these are our officially supported build environments that are most likely to work. diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index bfcf979d12548..270c8250e1981 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1668,7 +1668,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( // FIXME: Order dependent, applies to the following objects. Where should it be placed? // Try to strip as much out of the generated object by removing unused // sections if possible. See more comments in linker.rs - if sess.opts.cg.link_dead_code != Some(true) { + if !sess.link_dead_code() { let keep_metadata = crate_type == CrateType::Dylib; cmd.gc_sections(keep_metadata); } diff --git a/compiler/rustc_error_codes/src/error_codes/E0764.md b/compiler/rustc_error_codes/src/error_codes/E0764.md index e9061f988ac59..0a2e2290e77c2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0764.md +++ b/compiler/rustc_error_codes/src/error_codes/E0764.md @@ -1,12 +1,4 @@ -Mutable references (`&mut`) can only be used in constant functions, not statics -or constants. This limitation exists to prevent the creation of constants that -have a mutable reference in their final value. If you had a constant of `&mut -i32` type, you could modify the value through that reference, making the -constant essentially mutable. While there could be a more fine-grained scheme -in the future that allows mutable references if they are not "leaked" to the -final value, a more conservative approach was chosen for now. `const fn` do not -have this problem, as the borrow checker will prevent the `const fn` from -returning new mutable references. +A mutable reference was used in a constant. Erroneous code example: @@ -19,6 +11,18 @@ fn main() { } ``` +Mutable references (`&mut`) can only be used in constant functions, not statics +or constants. This limitation exists to prevent the creation of constants that +have a mutable reference in their final value. If you had a constant of +`&mut i32` type, you could modify the value through that reference, making the +constant essentially mutable. + +While there could be a more fine-grained scheme in the future that allows +mutable references if they are not "leaked" to the final value, a more +conservative approach was chosen for now. `const fn` do not have this problem, +as the borrow checker will prevent the `const fn` from returning new mutable +references. + Remember: you cannot use a function call inside a constant or static. However, you can totally use it in constant functions: diff --git a/compiler/rustc_error_codes/src/error_codes/E0769.md b/compiler/rustc_error_codes/src/error_codes/E0769.md index d1995be9899b1..4a3b674b05896 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0769.md +++ b/compiler/rustc_error_codes/src/error_codes/E0769.md @@ -1,5 +1,5 @@ -A tuple struct or tuple variant was used in a pattern as if it were a -struct or struct variant. +A tuple struct or tuple variant was used in a pattern as if it were a struct or +struct variant. Erroneous code example: @@ -7,9 +7,13 @@ Erroneous code example: enum E { A(i32), } + let e = E::A(42); + match e { - E::A { number } => println!("{}", x), + E::A { number } => { // error! + println!("{}", number); + } } ``` @@ -21,12 +25,14 @@ To fix this error, you can use the tuple pattern: # } # let e = E::A(42); match e { - E::A(number) => println!("{}", number), + E::A(number) => { // ok! + println!("{}", number); + } } ``` -Alternatively, you can also use the struct pattern by using the correct -field names and binding them to new identifiers: +Alternatively, you can also use the struct pattern by using the correct field +names and binding them to new identifiers: ``` # enum E { @@ -34,6 +40,8 @@ field names and binding them to new identifiers: # } # let e = E::A(42); match e { - E::A { 0: number } => println!("{}", number), + E::A { 0: number } => { // ok! + println!("{}", number); + } } ``` diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml index 390a21a501cb8..12101776de25f 100644 --- a/compiler/rustc_lexer/Cargo.toml +++ b/compiler/rustc_lexer/Cargo.toml @@ -20,4 +20,4 @@ doctest = false unicode-xid = "0.2.0" [dev-dependencies] -expect-test = "0.1" +expect-test = "1.0" diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 245e07d096eb9..79e2c5aac2385 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -85,7 +85,7 @@ impl<'tcx> MonoItem<'tcx> { .debugging_opts .inline_in_all_cgus .unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No) - && tcx.sess.opts.cg.link_dead_code != Some(true); + && !tcx.sess.link_dead_code(); match *self { MonoItem::Fn(ref instance) => { diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 82c649b8f543b..ece8da7e51e34 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -55,7 +55,7 @@ impl GenericArg<'tcx> { /// that appear in `self`, it does not descend into the fields of /// structs or variants. For example: /// - /// ```notrust + /// ```text /// isize => { isize } /// Foo> => { Foo>, Bar, isize } /// [isize] => { [isize], isize } @@ -80,7 +80,7 @@ impl<'tcx> super::TyS<'tcx> { /// that appear in `self`, it does not descend into the fields of /// structs or variants. For example: /// - /// ```notrust + /// ```text /// isize => { isize } /// Foo> => { Foo>, Bar, isize } /// [isize] => { [isize], isize } diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs index 5747c016357a9..b45fe0ee010f9 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs @@ -190,7 +190,7 @@ pub fn partition<'tcx>( // Next we try to make as many symbols "internal" as possible, so LLVM has // more freedom to optimize. - if tcx.sess.opts.cg.link_dead_code != Some(true) { + if !tcx.sess.link_dead_code() { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols"); partitioner.internalize_symbols(tcx, &mut post_inlining, inlining_map); } @@ -327,7 +327,7 @@ fn collect_and_partition_mono_items<'tcx>( } } None => { - if tcx.sess.opts.cg.link_dead_code == Some(true) { + if tcx.sess.link_dead_code() { MonoItemCollectionMode::Eager } else { MonoItemCollectionMode::Lazy diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index c4ef35bc30c70..1131f00cb425e 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -27,7 +27,7 @@ pub struct UnmatchedBrace { pub candidate_span: Option, } -pub struct StringReader<'a> { +crate struct StringReader<'a> { sess: &'a ParseSess, /// Initial position, read-only. start_pos: BytePos, @@ -41,7 +41,7 @@ pub struct StringReader<'a> { } impl<'a> StringReader<'a> { - pub fn new( + crate fn new( sess: &'a ParseSess, source_file: Lrc, override_span: Option, @@ -66,7 +66,7 @@ impl<'a> StringReader<'a> { } /// Returns the next token, including trivia like whitespace or comments. - pub fn next_token(&mut self) -> Token { + fn next_token(&mut self) -> Token { let start_src_index = self.src_index(self.pos); let text: &str = &self.src[start_src_index..self.end_src_index]; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 1808a0ca59bea..0a2a535598a2f 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1718,20 +1718,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { ); } - // `-Z instrument-coverage` implies: - // * `-Z symbol-mangling-version=v0` - to ensure consistent and reversible name mangling. - // Note, LLVM coverage tools can analyze coverage over multiple runs, including some - // changes to source code; so mangled names must be consistent across compilations. - // * `-C link-dead-code` - so unexecuted code is still counted as zero, rather than be - // optimized out. Note that instrumenting dead code can be explicitly disabled with: - // `-Z instrument-coverage -C link-dead-code=no`. + // `-Z instrument-coverage` implies `-Z symbol-mangling-version=v0` - to ensure consistent + // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over + // multiple runs, including some changes to source code; so mangled names must be consistent + // across compilations. debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0; - if cg.link_dead_code == None { - // FIXME(richkadel): Investigate if the `instrument-coverage` implementation can - // inject ["zero counters"](https://llvm.org/docs/CoverageMappingFormat.html#counter) - // in the coverage map when "dead code" is removed, rather than forcing `link-dead-code`. - cg.link_dead_code = Some(true); - } } if !cg.embed_bitcode { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 82330d9a5331a..ee30c16108a0c 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -885,9 +885,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "instrument the generated code to support LLVM source-based code coverage \ reports (note, the compiler build config must include `profiler = true`, \ and is mutually exclusive with `-C profile-generate`/`-C profile-use`); \ - implies `-C link-dead-code` (unless explicitly disabled)` and \ - `-Z symbol-mangling-version=v0`; and disables/overrides some optimization \ - options (default: no)"), + implies `-C link-dead-code` (unless targeting MSVC, or explicitly disabled) \ + and `-Z symbol-mangling-version=v0`; disables/overrides some Rust \ + optimizations (default: no)"), instrument_mcount: bool = (false, parse_bool, [TRACKED], "insert function instrument code for mcount-based tracing (default: no)"), keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 53c3e4df9761e..db2059251c0c8 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1024,6 +1024,40 @@ impl Session { || self.opts.debugging_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY) } + pub fn link_dead_code(&self) -> bool { + match self.opts.cg.link_dead_code { + Some(explicitly_set) => explicitly_set, + None => { + self.opts.debugging_opts.instrument_coverage + && !self.target.target.options.is_like_msvc + // Issue #76038: (rustc `-Clink-dead-code` causes MSVC linker to produce invalid + // binaries when LLVM InstrProf counters are enabled). As described by this issue, + // the "link dead code" option produces incorrect binaries when compiled and linked + // under MSVC. The resulting Rust programs typically crash with a segmentation + // fault, or produce an empty "*.profraw" file (profiling counter results normally + // generated during program exit). + // + // If not targeting MSVC, `-Z instrument-coverage` implies `-C link-dead-code`, so + // unexecuted code is still counted as zero, rather than be optimized out. Note that + // instrumenting dead code can be explicitly disabled with: + // + // `-Z instrument-coverage -C link-dead-code=no`. + // + // FIXME(richkadel): Investigate if `instrument-coverage` implementation can inject + // [zero counters](https://llvm.org/docs/CoverageMappingFormat.html#counter) in the + // coverage map when "dead code" is removed, rather than forcing `link-dead-code`. + // This may not be possible, however, if (as it seems to appear) the "dead code" + // that would otherwise not be linked is only identified as "dead" by the native + // linker. If that's the case, I believe it is too late for the Rust compiler to + // leverage any information it might be able to get from the linker regarding what + // code is dead, to be able to add those counters. + // + // On the other hand, if any Rust compiler passes are optimizing out dead code blocks + // we should inject "zero" counters for those code regions. + } + } + } + pub fn mark_attr_known(&self, attr: &Attribute) { self.known_attrs.lock().mark(attr) } @@ -1432,20 +1466,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { ); } - // FIXME(richkadel): See `src/test/run-make-fulldeps/instrument-coverage/Makefile`. After - // compiling with `-Zinstrument-coverage`, the resulting binary generates a segfault during - // the program's exit process (likely while attempting to generate the coverage stats in - // the "*.profraw" file). An investigation to resolve the problem on Windows is ongoing, - // but until this is resolved, the option is disabled on Windows, and the test is skipped - // when targeting `MSVC`. - if sess.opts.debugging_opts.instrument_coverage && sess.target.target.options.is_like_msvc { - sess.warn( - "Rust source-based code coverage instrumentation (with `-Z instrument-coverage`) \ - is not yet supported on Windows when targeting MSVC. The resulting binaries will \ - still be instrumented for experimentation purposes, but may not execute correctly.", - ); - } - const ASAN_SUPPORTED_TARGETS: &[&str] = &[ "aarch64-fuchsia", "aarch64-unknown-linux-gnu", diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index c654dade2abd4..b478a1d15c506 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -400,6 +400,13 @@ impl Span { span.with_lo(span.hi) } + #[inline] + /// Returns true if hi == lo + pub fn is_empty(&self) -> bool { + let span = self.data(); + span.hi == span.lo + } + /// Returns `self` if `self` is not the dummy span, and `other` otherwise. pub fn substitute_dummy(self, other: Span) -> Span { if self.is_dummy() { other } else { self } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 7c656db22ed8c..37596b8ef6fca 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -487,6 +487,15 @@ impl SourceMap { } } + /// Returns a new `Span` covering the start and end `BytePos`s of the file containing the given + /// `pos`. This can be used to quickly determine if another `BytePos` or `Span` is from the same + /// file. + pub fn lookup_file_span(&self, pos: BytePos) -> Span { + let idx = self.lookup_source_file_idx(pos); + let SourceFile { start_pos, end_pos, .. } = *(*self.files.borrow().source_files)[idx]; + Span::with_root_ctxt(start_pos, end_pos) + } + /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If /// there are gaps between LHS and RHS, the resulting union will cross these gaps. /// For this to work, diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 51c233a21f1a4..e7260f3956c38 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -217,7 +217,7 @@ impl Cow<'_, B> { /// assert!(!bull.is_borrowed()); /// ``` #[unstable(feature = "cow_is_borrowed", issue = "65143")] - pub fn is_borrowed(&self) -> bool { + pub const fn is_borrowed(&self) -> bool { match *self { Borrowed(_) => true, Owned(_) => false, @@ -239,7 +239,7 @@ impl Cow<'_, B> { /// assert!(!bull.is_owned()); /// ``` #[unstable(feature = "cow_is_borrowed", issue = "65143")] - pub fn is_owned(&self) -> bool { + pub const fn is_owned(&self) -> bool { !self.is_borrowed() } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index dde442aa7b52d..3953c73319fe4 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -356,9 +356,8 @@ impl Ordering { /// ``` #[inline] #[must_use] - #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn reverse(self) -> Ordering { + pub fn reverse(self) -> Ordering { match self { Less => Greater, Equal => Equal, @@ -395,9 +394,8 @@ impl Ordering { /// ``` #[inline] #[must_use] - #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")] #[stable(feature = "ordering_chaining", since = "1.17.0")] - pub const fn then(self, other: Ordering) -> Ordering { + pub fn then(self, other: Ordering) -> Ordering { match self { Equal => other, _ => self, diff --git a/library/std/src/env.rs b/library/std/src/env.rs index d38911ba0db90..970dea6b2991b 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -68,10 +68,9 @@ pub fn set_current_dir>(path: P) -> io::Result<()> { /// An iterator over a snapshot of the environment variables of this process. /// -/// This structure is created by the [`std::env::vars`] function. See its -/// documentation for more. +/// This structure is created by [`env::vars()`]. See its documentation for more. /// -/// [`std::env::vars`]: vars +/// [`env::vars()`]: vars #[stable(feature = "env", since = "1.0.0")] pub struct Vars { inner: VarsOs, @@ -79,10 +78,9 @@ pub struct Vars { /// An iterator over a snapshot of the environment variables of this process. /// -/// This structure is created by the [`std::env::vars_os`] function. See -/// its documentation for more. +/// This structure is created by [`env::vars_os()`]. See its documentation for more. /// -/// [`std::env::vars_os`]: vars_os +/// [`env::vars_os()`]: vars_os #[stable(feature = "env", since = "1.0.0")] pub struct VarsOs { inner: os_imp::Env, @@ -98,10 +96,8 @@ pub struct VarsOs { /// # Panics /// /// While iterating, the returned iterator will panic if any key or value in the -/// environment is not valid unicode. If this is not desired, consider using the -/// [`env::vars_os`] function. -/// -/// [`env::vars_os`]: vars_os +/// environment is not valid unicode. If this is not desired, consider using +/// [`env::vars_os()`]. /// /// # Examples /// @@ -114,6 +110,8 @@ pub struct VarsOs { /// println!("{}: {}", key, value); /// } /// ``` +/// +/// [`env::vars_os()`]: vars_os #[stable(feature = "env", since = "1.0.0")] pub fn vars() -> Vars { Vars { inner: vars_os() } @@ -245,9 +243,9 @@ fn _var_os(key: &OsStr) -> Option { } /// The error type for operations interacting with environment variables. -/// Possibly returned from the [`env::var`] function. +/// Possibly returned from [`env::var()`]. /// -/// [`env::var`]: var +/// [`env::var()`]: var #[derive(Debug, PartialEq, Eq, Clone)] #[stable(feature = "env", since = "1.0.0")] pub enum VarError { @@ -372,10 +370,10 @@ fn _remove_var(k: &OsStr) { /// /// The iterator element type is [`PathBuf`]. /// -/// This structure is created by the [`std::env::split_paths`] function. See its +/// This structure is created by [`env::split_paths()`]. See its /// documentation for more. /// -/// [`std::env::split_paths`]: split_paths +/// [`env::split_paths()`]: split_paths #[stable(feature = "env", since = "1.0.0")] pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a>, @@ -426,9 +424,9 @@ impl fmt::Debug for SplitPaths<'_> { } /// The error type for operations on the `PATH` variable. Possibly returned from -/// the [`env::join_paths`] function. +/// [`env::join_paths()`]. /// -/// [`env::join_paths`]: join_paths +/// [`env::join_paths()`]: join_paths #[derive(Debug)] #[stable(feature = "env", since = "1.0.0")] pub struct JoinPathsError { @@ -463,7 +461,8 @@ pub struct JoinPathsError { /// } /// ``` /// -/// Joining a path containing a colon on a Unix-like platform results in an error: +/// Joining a path containing a colon on a Unix-like platform results in an +/// error: /// /// ``` /// # if cfg!(unix) { @@ -475,8 +474,8 @@ pub struct JoinPathsError { /// # } /// ``` /// -/// Using `env::join_paths` with [`env::split_paths`] to append an item to the `PATH` environment -/// variable: +/// Using `env::join_paths()` with [`env::split_paths()`] to append an item to +/// the `PATH` environment variable: /// /// ``` /// use std::env; @@ -494,7 +493,7 @@ pub struct JoinPathsError { /// } /// ``` /// -/// [`env::split_paths`]: split_paths +/// [`env::split_paths()`]: split_paths #[stable(feature = "env", since = "1.0.0")] pub fn join_paths(paths: I) -> Result where @@ -667,14 +666,14 @@ pub fn current_exe() -> io::Result { /// An iterator over the arguments of a process, yielding a [`String`] value for /// each argument. /// -/// This struct is created by the [`std::env::args`] function. See its -/// documentation for more. +/// This struct is created by [`env::args()`]. See its documentation +/// for more. /// /// The first element is traditionally the path of the executable, but it can be /// set to arbitrary text, and may not even exist. This means this property /// should not be relied upon for security purposes. /// -/// [`std::env::args`]: args +/// [`env::args()`]: args #[stable(feature = "env", since = "1.0.0")] pub struct Args { inner: ArgsOs, @@ -683,14 +682,14 @@ pub struct Args { /// An iterator over the arguments of a process, yielding an [`OsString`] value /// for each argument. /// -/// This struct is created by the [`std::env::args_os`] function. See its -/// documentation for more. +/// This struct is created by [`env::args_os()`]. See its documentation +/// for more. /// /// The first element is traditionally the path of the executable, but it can be /// set to arbitrary text, and may not even exist. This means this property /// should not be relied upon for security purposes. /// -/// [`std::env::args_os`]: args_os +/// [`env::args_os()`]: args_os #[stable(feature = "env", since = "1.0.0")] pub struct ArgsOs { inner: sys::args::Args, diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 616f208bb2fe1..ede5239446835 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -18,4 +18,4 @@ tempfile = "3" itertools = "0.8" [dev-dependencies] -expect-test = "0.1" +expect-test = "1.0" diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 3d2785541beea..484fbd0316dc4 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -75,8 +75,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { } }); debug!( - "get_blanket_impls: found applicable impl: {}\ - for trait_ref={:?}, ty={:?}", + "get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}", may_apply, trait_ref, ty ); if !may_apply { diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 96f0a1b7a7cb6..794a7bcaf1cb7 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -391,26 +391,25 @@ fn test_render_long_html() { (word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions")) .render_long_html(), "This is supported on Unix and Windows and debug-assertions enabled\ - only." + only." ); assert_eq!( (word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) .render_long_html(), "This is supported on Unix or Windows or debug-assertions enabled\ - only." + only." ); assert_eq!( (!(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions"))) .render_long_html(), "This is supported on neither Unix nor Windows nor debug-assertions \ - enabled." + enabled." ); assert_eq!( ((word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | (word_cfg("windows") & name_value_cfg("target_pointer_width", "64"))) .render_long_html(), - "This is supported on Unix and x86-64, or Windows and 64-bit \ - only." + "This is supported on Unix and x86-64, or Windows and 64-bit only." ); assert_eq!( (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(), @@ -420,7 +419,7 @@ fn test_render_long_html() { ((word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix")) .render_long_html(), "This is supported on (debug-assertions enabled or Windows) and Unix\ - only." + only." ); assert_eq!( name_value_cfg("target_feature", "sse2").render_long_html(), @@ -430,7 +429,7 @@ fn test_render_long_html() { (name_value_cfg("target_arch", "x86_64") & name_value_cfg("target_feature", "sse2")) .render_long_html(), "This is supported on x86-64 and target feature \ - sse2 only." + sse2 only." ); }) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 75fdcd5ec1c9c..8255bdab4f509 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -422,14 +422,13 @@ pub fn name_from_pat(p: &hir::Pat<'_>) -> String { PatKind::Ref(ref p, _) => name_from_pat(&**p), PatKind::Lit(..) => { warn!( - "tried to get argument name from PatKind::Lit, \ - which is silly in function arguments" + "tried to get argument name from PatKind::Lit, which is silly in function arguments" ); "()".to_string() } PatKind::Range(..) => panic!( "tried to get argument name from PatKind::Range, \ - which is not allowed in function arguments" + which is not allowed in function arguments" ), PatKind::Slice(ref begin, ref mid, ref end) => { let begin = begin.iter().map(|p| name_from_pat(&**p)); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 14df4e7aa8e59..a5fc07578169e 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -416,14 +416,12 @@ impl Options { return Err(1); } else if !ret.is_empty() { diag.struct_warn(&format!( - "theme file \"{}\" is missing CSS rules from the \ - default theme", + "theme file \"{}\" is missing CSS rules from the default theme", theme_s )) .warn("the theme may appear incorrect when loaded") .help(&format!( - "to see what rules are missing, call `rustdoc \ - --check-theme \"{}\"`", + "to see what rules are missing, call `rustdoc --check-theme \"{}\"`", theme_s )) .emit(); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 7c89b38a92c75..074a43f2a7099 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -561,8 +561,7 @@ fn run_global_ctxt( if let Some(ref m) = krate.module { if let None | Some("") = m.doc_value() { let help = "The following guide may be of use:\n\ - https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation\ - .html"; + https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html"; tcx.struct_lint_node( rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS, ctxt.as_local_hir_id(m.def_id).unwrap(), @@ -581,7 +580,7 @@ fn run_global_ctxt( .struct_warn(&format!("the `#![doc({})]` attribute is considered deprecated", name)); msg.warn( "see issue #44136 \ - for more information", + for more information", ); if name == "no_default_passes" { @@ -614,7 +613,7 @@ fn run_global_ctxt( report_deprecated_attr("plugins = \"...\"", diag); eprintln!( "WARNING: `#![doc(plugins = \"...\")]` \ - no longer functions; see CVE-2018-1000622" + no longer functions; see CVE-2018-1000622" ); continue; } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 699f8c36cba6a..2da9c68b1967c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -833,7 +833,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> write!( f, "{name}", + title=\"type {path}::{name}\">{name}", url = url, shortty = ItemType::AssocType, name = name, diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 26557fc1cb7ec..4769edc50ff07 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -27,7 +27,7 @@ pub fn render_with_highlighting( write!( out, "
{}
", + class='tooltiptext'>{}
", class, tooltip ) .unwrap(); diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs index 398cd4f670e56..c79471b1fae6b 100644 --- a/src/librustdoc/html/highlight/tests.rs +++ b/src/librustdoc/html/highlight/tests.rs @@ -9,7 +9,7 @@ fn test_html_highlighting() { write_code(&mut out, src); format!("{}
{}
\n", STYLE, out) }; - expect_file!["src/librustdoc/html/highlight/fixtures/sample.html"].assert_eq(&html); + expect_file!["fixtures/sample.html"].assert_eq(&html); } const STYLE: &str = r#" diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index fd67a66395d7c..287c85b8c2253 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -210,8 +210,8 @@ pub fn render( .collect::(), filter_crates = if layout.generate_search_filter { "" + \ + " } else { "" }, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 56499f736e163..d54b8ea747899 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -519,8 +519,7 @@ impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { Some(Event::FootnoteReference(ref reference)) => { let entry = self.get_entry(&reference); let reference = format!( - "{0}\ - ", + "{0}", (*entry).1 ); return Some(Event::Html(reference.into())); diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 783977d285dc4..01a897c93db8d 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -140,25 +140,26 @@ fn test_header() { t( "# Foo bar", - "

\ - Foo bar

", + "

Foo bar

", ); t( "## Foo-bar_baz qux", - "

Foo-bar_baz qux

", + "

\ + Foo-bar_baz qux

", ); t( "### **Foo** *bar* baz!?!& -_qux_-%", "

\ - Foo \ - bar baz!?!& -qux-%

", + Foo \ + bar baz!?!& -qux-%\ + ", ); t( "#### **Foo?** & \\*bar?!* _`baz`_ ❤ #qux", "

\ - Foo? & *bar?!* \ - baz ❤ #qux

", + Foo? & *bar?!* \ + baz ❤ #qux\ + ", ); } @@ -174,38 +175,32 @@ fn test_header_ids_multiple_blocks() { t( &mut map, "# Example", - "

\ - Example

", + "

Example

", ); t( &mut map, "# Panics", - "

\ - Panics

", + "

Panics

", ); t( &mut map, "# Example", - "

\ - Example

", + "

Example

", ); t( &mut map, "# Main", - "

\ - Main

", + "

Main

", ); t( &mut map, "# Example", - "

\ - Example

", + "

Example

", ); t( &mut map, "# Panics", - "

\ - Panics

", + "

Panics

", ); } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 15afe9257d187..470e9d5ae768d 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1061,8 +1061,8 @@ themePicker.onblur = handleThemeButtonsBlur; let content = format!( "

\ - List of all crates\ -

    {}
", + List of all crates\ +
    {}
", krates .iter() .map(|s| { @@ -1311,15 +1311,16 @@ impl AllTypes { write!( f, "

\ - \ - \ - \ - []\ - \ - - - List of all items\ -

" + \ + \ + \ + []\ + \ + + + List of all items\ + " ); print_entries(f, &self.structs, "Structs", "structs"); print_entries(f, &self.enums, "Enums", "enums"); @@ -1349,20 +1350,20 @@ impl Setting { match *self { Setting::Section { ref description, ref sub_settings } => format!( "
\ -
{}
\ -
{}
-
", +
{}
\ +
{}
+ ", description, sub_settings.iter().map(|s| s.display()).collect::() ), Setting::Entry { ref js_data_name, ref description, ref default_value } => format!( "
\ - \ -
{}
\ -
", + \ +
{}
\ + ", js_data_name, if *default_value { " checked" } else { "" }, description, @@ -1876,30 +1877,29 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) { write!( w, "Non-exhaustive structs could have additional fields added in future. \ - Therefore, non-exhaustive structs cannot be constructed in external crates \ - using the traditional Struct {{ .. }} syntax; cannot be \ - matched against without a wildcard ..; and \ - struct update syntax will not work." + Therefore, non-exhaustive structs cannot be constructed in external crates \ + using the traditional Struct {{ .. }} syntax; cannot be \ + matched against without a wildcard ..; and \ + struct update syntax will not work." ); } else if item.is_enum() { write!( w, "Non-exhaustive enums could have additional variants added in future. \ - Therefore, when matching against variants of non-exhaustive enums, an \ - extra wildcard arm must be added to account for any future variants." + Therefore, when matching against variants of non-exhaustive enums, an \ + extra wildcard arm must be added to account for any future variants." ); } else if item.is_variant() { write!( w, "Non-exhaustive enum variants could have additional fields added in future. \ - Therefore, non-exhaustive enum variants cannot be constructed in external \ - crates and cannot be matched against." + Therefore, non-exhaustive enum variants cannot be constructed in external \ + crates and cannot be matched against." ); } else { write!( w, - "This type will require a wildcard arm in any match statements or \ - constructors." + "This type will require a wildcard arm in any match statements or constructors." ); } @@ -2096,12 +2096,11 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: let doc_value = myitem.doc_value().unwrap_or(""); write!( w, - "\ - \ - {name}{unsafety_flag}\ - {stab_tags}{docs}\ - ", + "\ + {name}{unsafety_flag}\ + {stab_tags}{docs}\ + ", name = *myitem.name.as_ref().unwrap(), stab_tags = stability_tags(myitem), docs = MarkdownSummaryLine(doc_value, &myitem.links()).into_string(), @@ -2250,8 +2249,7 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons write!( w, - "{vis}const \ - {name}: {typ}", + "{vis}const {name}: {typ}", vis = it.visibility.print_with_space(), name = it.name.as_ref().unwrap(), typ = c.type_.print(), @@ -2285,8 +2283,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static render_attributes(w, it, false); write!( w, - "{vis}static {mutability}\ - {name}: {typ}", + "{vis}static {mutability} {name}: {typ}", vis = it.visibility.print_with_space(), mutability = s.mutability.print_with_space(), name = it.name.as_ref().unwrap(), @@ -2312,7 +2309,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func write!( w, "{vis}{constness}{asyncness}{unsafety}{abi}fn \ - {name}{generics}{decl}{spotlight}{where_clause}", + {name}{generics}{decl}{spotlight}{where_clause}", vis = it.visibility.print_with_space(), constness = f.header.constness.print_with_space(), asyncness = f.header.asyncness.print_with_space(), @@ -2503,10 +2500,9 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_content: &str) { write!( w, - " -

\ - {1}\ -

{2}", + "

\ + {1}\ +

{2}", id, title, extra_content ) } @@ -2835,7 +2831,7 @@ fn render_assoc_item( write!( w, "{}{}{}{}{}{}{}fn {name}\ - {generics}{decl}{spotlight}{where_clause}", + {generics}{decl}{spotlight}{where_clause}", if parent == ItemType::Trait { " " } else { "" }, meth.visibility.print_with_space(), header.constness.print_with_space(), @@ -2910,9 +2906,9 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct write!( w, "\ - \ - {name}: {ty}\ - ", + \ + {name}: {ty}\ +
", item_type = ItemType::StructField, id = id, name = field.name.as_ref().unwrap(), @@ -2954,9 +2950,9 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union, write!( w, "\ - \ - {name}: {ty}\ - ", + \ + {name}: {ty}\ + ", id = id, name = name, shortty = ItemType::StructField, @@ -3081,9 +3077,9 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca write!( w, "\ - \ - {f}: {t}\ - ", + \ + {f}: {t}\ + ", id = id, f = field.name.as_ref().unwrap(), t = ty.print() @@ -3296,23 +3292,19 @@ fn render_assoc_items( AssocItemRender::All => { write!( w, - "\ -

\ - Implementations\ -

\ - " + "

\ + Implementations\ +

" ); RenderMode::Normal } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { write!( w, - "\ -

\ - Methods from {}<Target = {}>\ - \ -

\ - ", + "

\ + Methods from {}<Target = {}>\ + \ +

", trait_.print(), type_.print() ); @@ -3359,11 +3351,10 @@ fn render_assoc_items( if !impls.is_empty() { write!( w, - "\ -

\ - Trait Implementations\ -

\ -
{}
", + "

\ + Trait Implementations\ +

\ +
{}
", impls ); } @@ -3371,13 +3362,11 @@ fn render_assoc_items( if !synthetic.is_empty() { write!( w, - "\ -

\ - Auto Trait Implementations\ - \ -

\ -
\ - " + "

\ + Auto Trait Implementations\ + \ +

\ +
" ); render_impls(cx, w, &synthetic, containing_item, cache); write!(w, "
"); @@ -3386,13 +3375,11 @@ fn render_assoc_items( if !blanket_impl.is_empty() { write!( w, - "\ -

\ - Blanket Implementations\ - \ -

\ -
\ - " + "

\ + Blanket Implementations\ + \ +

\ +
" ); render_impls(cx, w, &blanket_impl, containing_item, cache); write!(w, "
"); @@ -3473,7 +3460,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String { if out.is_empty() { out.push_str(&format!( "

Notable traits for {}

\ - ", + ", impl_.for_.print() )); trait_.push_str(&impl_.for_.print().to_string()); @@ -3909,8 +3896,8 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca write!( buffer, "
\ -

Version {}

\ -
", +

Version {}

\ +
", Escape(version) ); } @@ -4185,7 +4172,7 @@ fn sidebar_struct(buf: &mut Buffer, it: &clean::Item, s: &clean::Struct) { if let doctree::Plain = s.struct_type { sidebar.push_str(&format!( "Fields\ -
{}
", +
{}
", fields )); } @@ -4312,8 +4299,8 @@ fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) { res.sort(); sidebar.push_str(&format!( "\ - Implementations on Foreign Types
{}
", + Implementations on Foreign Types\ +
{}
", res.into_iter() .map(|(name, id)| format!("{}", id, Escape(&name))) .collect::>() diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index aaa73b100c243..02a7362bb3b2e 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -52,7 +52,7 @@ impl<'a> DocFolder for SourceCollector<'a> { Err(e) => { println!( "warning: source code was requested to be rendered, \ - but processing `{}` had an error: {}", + but processing `{}` had an error: {}", item.source.filename, e ); println!(" skipping rendering of source code"); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 8658b39b45578..73a783d54060c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -153,7 +153,7 @@ fn opts() -> Vec { "", "passes", "list of passes to also run, you might want to pass it multiple times; a value of \ - `list` will print available passes", + `list` will print available passes", "PASSES", ) }), @@ -183,7 +183,7 @@ fn opts() -> Vec { "", "html-in-header", "files to include inline in the section of a rendered Markdown file \ - or generated documentation", + or generated documentation", "FILES", ) }), @@ -192,7 +192,7 @@ fn opts() -> Vec { "", "html-before-content", "files to include inline between and the content of a rendered \ - Markdown file or generated documentation", + Markdown file or generated documentation", "FILES", ) }), @@ -201,7 +201,7 @@ fn opts() -> Vec { "", "html-after-content", "files to include inline between the content and of a rendered \ - Markdown file or generated documentation", + Markdown file or generated documentation", "FILES", ) }), @@ -210,7 +210,7 @@ fn opts() -> Vec { "", "markdown-before-content", "files to include inline between and the content of a rendered \ - Markdown file or generated documentation", + Markdown file or generated documentation", "FILES", ) }), @@ -219,7 +219,7 @@ fn opts() -> Vec { "", "markdown-after-content", "files to include inline between the content and of a rendered \ - Markdown file or generated documentation", + Markdown file or generated documentation", "FILES", ) }), @@ -234,8 +234,8 @@ fn opts() -> Vec { "e", "extend-css", "To add some CSS rules with a given file to generate doc with your \ - own theme. However, your theme might break if the rustdoc's generated HTML \ - changes, so be careful!", + own theme. However, your theme might break if the rustdoc's generated HTML \ + changes, so be careful!", "PATH", ) }), @@ -248,7 +248,7 @@ fn opts() -> Vec { "", "playground-url", "URL to send code snippets to, may be reset by --markdown-playground-url \ - or `#![doc(html_playground_url=...)]`", + or `#![doc(html_playground_url=...)]`", "URL", ) }), @@ -281,7 +281,7 @@ fn opts() -> Vec { "", "resource-suffix", "suffix to add to CSS and JavaScript files, e.g., \"light.css\" will become \ - \"light-suffix.css\"", + \"light-suffix.css\"", "PATH", ) }), @@ -343,7 +343,7 @@ fn opts() -> Vec { "", "static-root-path", "Path string to force loading static files from in output pages. \ - If not set, uses combinations of '../' to reach the documentation root.", + If not set, uses combinations of '../' to reach the documentation root.", "PATH", ) }), diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index d1f2c12ccd630..beb1f13ca6f75 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -1,7 +1,6 @@ -use rustc_ast::token; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::Emitter, Applicability, Diagnostic, Handler}; -use rustc_parse::lexer::StringReader as Lexer; +use rustc_parse::parse_stream_from_source_str; use rustc_session::parse::ParseSess; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileName, InnerSpan}; @@ -28,49 +27,34 @@ struct SyntaxChecker<'a, 'tcx> { impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) { - let buffered_messages = Lrc::new(Lock::new(vec![])); - - let emitter = BufferEmitter { messages: Lrc::clone(&buffered_messages) }; + let buffer = Lrc::new(Lock::new(Buffer::default())); + let emitter = BufferEmitter { buffer: Lrc::clone(&buffer) }; let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let handler = Handler::with_emitter(false, None, Box::new(emitter)); + let source = dox[code_block.code].to_owned(); let sess = ParseSess::with_span_handler(handler, sm); - let source_file = sess.source_map().new_source_file( - FileName::Custom(String::from("doctest")), - dox[code_block.code].to_owned(), - ); - - let validation_status = rustc_driver::catch_fatal_errors(|| { - let mut has_syntax_errors = false; - let mut only_whitespace = true; - // even if there is a syntax error, we need to run the lexer over the whole file - let mut lexer = Lexer::new(&sess, source_file, None); - loop { - match lexer.next_token().kind { - token::Eof => break, - token::Whitespace => (), - token::Unknown(..) => has_syntax_errors = true, - _ => only_whitespace = false, - } - } - if has_syntax_errors { - Some(CodeBlockInvalid::SyntaxError) - } else if only_whitespace { - Some(CodeBlockInvalid::Empty) - } else { - None - } + let is_empty = rustc_driver::catch_fatal_errors(|| { + parse_stream_from_source_str( + FileName::Custom(String::from("doctest")), + source, + &sess, + None, + ) + .is_empty() }) - .unwrap_or(Some(CodeBlockInvalid::SyntaxError)); + .unwrap_or(false); + let buffer = buffer.borrow(); - if let Some(code_block_invalid) = validation_status { + if buffer.has_errors || is_empty { let mut diag = if let Some(sp) = super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs) { - let warning_message = match code_block_invalid { - CodeBlockInvalid::SyntaxError => "could not parse code block as Rust code", - CodeBlockInvalid::Empty => "Rust code block is empty", + let warning_message = if buffer.has_errors { + "could not parse code block as Rust code" + } else { + "Rust code block is empty" }; let mut diag = self.cx.sess().struct_span_warn(sp, warning_message); @@ -102,7 +86,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { }; // FIXME(#67563): Provide more context for these errors by displaying the spans inline. - for message in buffered_messages.borrow().iter() { + for message in buffer.messages.iter() { diag.note(&message); } @@ -125,21 +109,26 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> { } } +#[derive(Default)] +struct Buffer { + messages: Vec, + has_errors: bool, +} + struct BufferEmitter { - messages: Lrc>>, + buffer: Lrc>, } impl Emitter for BufferEmitter { fn emit_diagnostic(&mut self, diag: &Diagnostic) { - self.messages.borrow_mut().push(format!("error from rustc: {}", diag.message[0].0)); + let mut buffer = self.buffer.borrow_mut(); + buffer.messages.push(format!("error from rustc: {}", diag.message[0].0)); + if diag.is_error() { + buffer.has_errors = true; + } } fn source_map(&self) -> Option<&Lrc> { None } } - -enum CodeBlockInvalid { - SyntaxError, - Empty, -} diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 8d4eb67204f53..f497f341e112d 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1157,7 +1157,7 @@ fn report_diagnostic( // Print the line containing the `link_range` and manually mark it with '^'s. diag.note(&format!( "the link appears in this line:\n\n{line}\n\ - {indicator: DocFolder for ImplStripper<'a> { if let Some(did) = typaram.def_id() { if did.is_local() && !self.retained.contains(&did) { debug!( - "ImplStripper: stripped item in trait's generics; \ - removing impl" + "ImplStripper: stripped item in trait's generics; removing impl" ); return None; } diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index f244956e50336..9173d8e96058e 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -9,7 +9,7 @@ pub const STRIP_PRIVATE: Pass = Pass { name: "strip-private", run: strip_private, description: "strips all private items from a crate which cannot be seen externally, \ - implies strip-priv-imports", + implies strip-priv-imports", }; /// Strip private items from the point of view of a crate or externally from a diff --git a/src/test/ui/consts/const-ordering.rs b/src/test/ui/consts/const-ordering.rs deleted file mode 100644 index 454f2da00df9e..0000000000000 --- a/src/test/ui/consts/const-ordering.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -use std::cmp::Ordering; - -// the following methods of core::cmp::Ordering are const: -// - reverse -// - then - -fn main() { - const REVERSE : Ordering = Ordering::Greater.reverse(); - assert_eq!(REVERSE, Ordering::Less); - - const THEN : Ordering = Ordering::Equal.then(REVERSE); - assert_eq!(THEN, Ordering::Less); -} diff --git a/src/test/ui/consts/cow-is-borrowed.rs b/src/test/ui/consts/cow-is-borrowed.rs new file mode 100644 index 0000000000000..adebe20f5a255 --- /dev/null +++ b/src/test/ui/consts/cow-is-borrowed.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(cow_is_borrowed)] + +use std::borrow::Cow; + +fn main() { + const COW: Cow = Cow::Borrowed("moo"); + + const IS_BORROWED: bool = COW.is_borrowed(); + assert!(IS_BORROWED); + + const IS_OWNED: bool = COW.is_owned(); + assert!(!IS_OWNED); +}