From 85079f8b1fa8291593735b9b577e8e0dc22ad3b6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 26 Jan 2020 17:24:40 +0100 Subject: [PATCH 1/8] Fix run button positionning in case of scrolling --- src/librustdoc/html/highlight.rs | 11 ++++------- src/librustdoc/html/static/rustdoc.css | 4 +++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 5bea1b5614159..2a603d9900fb9 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -22,7 +22,7 @@ use syntax::token::{self, Token}; pub fn render_with_highlighting( src: &str, class: Option<&str>, - extension: Option<&str>, + playground_button: Option<&str>, tooltip: Option<(&str, &str)>, ) -> String { debug!("highlighting: ================\n{}\n==============", src); @@ -58,10 +58,7 @@ pub fn render_with_highlighting( Ok(highlighted_source) => { write_header(class, &mut out).unwrap(); write!(out, "{}", highlighted_source).unwrap(); - if let Some(extension) = extension { - write!(out, "{}", extension).unwrap(); - } - write_footer(&mut out).unwrap(); + write_footer(&mut out, playground_button).unwrap(); } Err(()) => { // If errors are encountered while trying to highlight, just emit @@ -433,6 +430,6 @@ fn write_header(class: Option<&str>, out: &mut dyn Write) -> io::Result<()> { write!(out, "
\n", class.unwrap_or(""))
 }
 
-fn write_footer(out: &mut dyn Write) -> io::Result<()> {
-    write!(out, "
\n") +fn write_footer(out: &mut dyn Write, playground_button: Option<&str>) -> io::Result<()> { + write!(out, "{}\n", if let Some(button) = playground_button { button } else { "" }) } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index a91fdb7a10e0d..0dfe82c501469 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -136,7 +136,7 @@ summary { outline: none; } -code, pre { +code, pre, a.test-arrow { font-family: "Source Code Pro", monospace; } .docblock code, .docblock-short code { @@ -305,6 +305,7 @@ nav.sub { .rustdoc:not(.source) .example-wrap { display: inline-flex; margin-bottom: 10px; + position: relative; } .example-wrap { @@ -878,6 +879,7 @@ a.test-arrow { font-size: 130%; top: 5px; right: 5px; + z-index: 1; } a.test-arrow:hover{ text-decoration: none; From bbc2ae7590ad53fca02fda187e7f9c2470c9e949 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sun, 26 Jan 2020 21:28:09 +0000 Subject: [PATCH 2/8] rustdoc: Fix re-exporting primitive types * Generate links to the primitive type docs for re-exports. * Don't ICE on cross crate primitive type re-exports. * Make primitive type re-exports show up cross crate. --- src/librustdoc/clean/inline.rs | 37 +++++++++++++++++-- src/librustdoc/clean/types.rs | 13 +++++++ src/librustdoc/clean/utils.rs | 9 +---- src/librustdoc/html/format.rs | 13 ++++--- .../rustdoc/auxiliary/primitive-reexport.rs | 8 ++++ src/test/rustdoc/primitive-reexport.rs | 28 ++++++++++++++ 6 files changed, 91 insertions(+), 17 deletions(-) create mode 100644 src/test/rustdoc/auxiliary/primitive-reexport.rs create mode 100644 src/test/rustdoc/primitive-reexport.rs diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 8a6abe036dc14..df72bf0b56e61 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -445,12 +445,41 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet) // two namespaces, so the target may be listed twice. Make sure we only // visit each node at most once. for &item in cx.tcx.item_children(did).iter() { - let def_id = item.res.def_id(); if item.vis == ty::Visibility::Public { - if did == def_id || !visited.insert(def_id) { - continue; + if let Some(def_id) = item.res.mod_def_id() { + if did == def_id || !visited.insert(def_id) { + continue; + } } - if let Some(i) = try_inline(cx, item.res, item.ident.name, None, visited) { + if let Res::PrimTy(p) = item.res { + // Primitive types can't be inlined so generate an import instead. + items.push(clean::Item { + name: None, + attrs: clean::Attributes::default(), + source: clean::Span::empty(), + def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID), + visibility: clean::Public, + stability: None, + deprecation: None, + inner: clean::ImportItem(clean::Import::Simple( + item.ident.to_string(), + clean::ImportSource { + path: clean::Path { + global: false, + res: item.res, + segments: vec![clean::PathSegment { + name: clean::PrimitiveType::from(p).as_str().to_string(), + args: clean::GenericArgs::AngleBracketed { + args: Vec::new(), + bindings: Vec::new(), + }, + }], + }, + did: None, + }, + )), + }); + } else if let Some(i) = try_inline(cx, item.res, item.ident.name, None, visited) { items.extend(i) } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 79a078ca7a991..8501fee56cfae 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1290,6 +1290,19 @@ impl From for PrimitiveType { } } +impl From for PrimitiveType { + fn from(prim_ty: hir::PrimTy) -> PrimitiveType { + match prim_ty { + hir::PrimTy::Int(int_ty) => int_ty.into(), + hir::PrimTy::Uint(uint_ty) => uint_ty.into(), + hir::PrimTy::Float(float_ty) => float_ty.into(), + hir::PrimTy::Str => PrimitiveType::Str, + hir::PrimTy::Bool => PrimitiveType::Bool, + hir::PrimTy::Char => PrimitiveType::Char, + } + } +} + #[derive(Clone, PartialEq, Eq, Debug)] pub enum Visibility { Public, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8058536d60b31..b6a39c7422fdc 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -570,14 +570,7 @@ pub fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type { } let is_generic = match path.res { - Res::PrimTy(p) => match p { - hir::PrimTy::Str => return Primitive(PrimitiveType::Str), - hir::PrimTy::Bool => return Primitive(PrimitiveType::Bool), - hir::PrimTy::Char => return Primitive(PrimitiveType::Char), - hir::PrimTy::Int(int_ty) => return Primitive(int_ty.into()), - hir::PrimTy::Uint(uint_ty) => return Primitive(uint_ty.into()), - hir::PrimTy::Float(float_ty) => return Primitive(float_ty.into()), - }, + Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)), Res::SelfTy(..) if path.segments.len() == 1 => { return Generic(kw::SelfUpper.to_string()); } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 79923fc3d3689..c3313ba63ef13 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1171,11 +1171,14 @@ impl clean::ImportSource { display_fn(move |f| match self.did { Some(did) => resolved_path(f, did, &self.path, true, false), _ => { - for (i, seg) in self.path.segments.iter().enumerate() { - if i > 0 { - write!(f, "::")? - } - write!(f, "{}", seg.name)?; + for seg in &self.path.segments[..self.path.segments.len() - 1] { + write!(f, "{}::", seg.name)?; + } + let name = self.path.last_name(); + if let hir::def::Res::PrimTy(p) = self.path.res { + primitive_link(f, PrimitiveType::from(p), name)?; + } else { + write!(f, "{}", name)?; } Ok(()) } diff --git a/src/test/rustdoc/auxiliary/primitive-reexport.rs b/src/test/rustdoc/auxiliary/primitive-reexport.rs new file mode 100644 index 0000000000000..b2e9fa43b395a --- /dev/null +++ b/src/test/rustdoc/auxiliary/primitive-reexport.rs @@ -0,0 +1,8 @@ +// compile-flags: --emit metadata --crate-type lib --edition 2018 + +#![crate_name = "foo"] + +pub mod bar { + pub use bool; + pub use char as my_char; +} diff --git a/src/test/rustdoc/primitive-reexport.rs b/src/test/rustdoc/primitive-reexport.rs new file mode 100644 index 0000000000000..de18360d4077c --- /dev/null +++ b/src/test/rustdoc/primitive-reexport.rs @@ -0,0 +1,28 @@ +// aux-build: primitive-reexport.rs +// compile-flags:--extern foo --edition 2018 + +#![crate_name = "bar"] + +// @has bar/p/index.html +// @has - '//code' 'pub use bool;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'bool' +// @has - '//code' 'pub use char as my_char;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char' +pub mod p { + pub use foo::bar::*; +} + +// @has bar/baz/index.html +// @has - '//code' 'pub use bool;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'bool' +// @has - '//code' 'pub use char as my_char;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char' +pub use foo::bar as baz; + +// @has bar/index.html +// @has - '//code' 'pub use str;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html"]' 'str' +// @has - '//code' 'pub use i32 as my_i32;' +// @has - '//code/a[@href="https://doc.rust-lang.org/nightly/std/primitive.i32.html"]' 'i32' +pub use str; +pub use i32 as my_i32; From 6f4b904aa999aded3b1ee317146387a8686715e3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 16 Jan 2020 20:33:18 +0100 Subject: [PATCH 3/8] Collisions in the dep-graph due to path-reuse are rare but can occur. So, instead of ICE'ing, just fail to mark green in such cases (for `DepKind::{Hir, HirBody, CrateMetadata}`). Fix #62649. --- src/librustc/dep_graph/graph.rs | 39 ++++++++++++++----- .../issue-62649-path-collisions-happen.rs | 13 +++++++ 2 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 src/test/incremental/issue-62649-path-collisions-happen.rs diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 8d1efc7bc048d..258723bb39d83 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -6,6 +6,7 @@ use rustc_data_structures::sharded::{self, Sharded}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; use rustc_errors::Diagnostic; +use rustc_hir::def_id::DefId; use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::collections::hash_map::Entry; @@ -677,18 +678,33 @@ impl DepGraph { } else { match dep_dep_node.kind { DepKind::Hir | DepKind::HirBody | DepKind::CrateMetadata => { - if dep_dep_node.extract_def_id(tcx).is_none() { + if let Some(def_id) = dep_dep_node.extract_def_id(tcx) { + if def_id_corresponds_to_hir_dep_node(tcx, def_id) { + // The `DefPath` has corresponding node, + // and that node should have been marked + // either red or green in `data.colors`. + bug!( + "DepNode {:?} should have been \ + pre-marked as red or green but wasn't.", + dep_dep_node + ); + } else { + // This `DefPath` does not have a + // corresponding `DepNode` (e.g. a + // struct field), and the ` DefPath` + // collided with the `DefPath` of a + // proper item that existed in the + // previous compilation session. + // + // Since the given `DefPath` does not + // denote the item that previously + // existed, we just fail to mark green. + return None; + } + } else { // If the node does not exist anymore, we // just fail to mark green. return None; - } else { - // If the node does exist, it should have - // been pre-allocated. - bug!( - "DepNode {:?} should have been \ - pre-allocated but wasn't.", - dep_dep_node - ) } } _ => { @@ -899,6 +915,11 @@ impl DepGraph { } } +fn def_id_corresponds_to_hir_dep_node(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + def_id.index == hir_id.owner +} + /// A "work product" is an intermediate result that we save into the /// incremental directory for later re-use. The primary example are /// the object files that we save for each partition at code diff --git a/src/test/incremental/issue-62649-path-collisions-happen.rs b/src/test/incremental/issue-62649-path-collisions-happen.rs new file mode 100644 index 0000000000000..ee81be76bafe3 --- /dev/null +++ b/src/test/incremental/issue-62649-path-collisions-happen.rs @@ -0,0 +1,13 @@ +// revisions: rpass1 rpass2 + +#[cfg(rpass1)] +pub trait Something { + fn foo(); +} + +#[cfg(rpass2)] +pub struct Something { + pub foo: u8, +} + +fn main() {} From 5654305a7ba419e4a7c0334fc77d0ef41a1ca2ac Mon Sep 17 00:00:00 2001 From: Billy Rieger Date: Sun, 19 Jan 2020 21:44:46 -0500 Subject: [PATCH 4/8] Add BTreeMap::remove_entry Mainly for API parity with HashMap. - Add BTreeMap::remove_entry - Rewrite BTreeMap::remove to use remove_entry - Use btreemap_remove_entry feature in doc comment --- src/liballoc/collections/btree/map.rs | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 302c2bcd5e4a3..551a406f8d237 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -806,13 +806,42 @@ impl BTreeMap { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, key: &Q) -> Option + where + K: Borrow, + Q: Ord, + { + self.remove_entry(key).map(|(_, v)| v) + } + + /// Removes a key from the map, returning the stored key and value if the key + /// was previously in the map. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(btreemap_remove_entry)] + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.remove_entry(&1), Some((1, "a"))); + /// assert_eq!(map.remove_entry(&1), None); + /// ``` + #[unstable(feature = "btreemap_remove_entry", issue = "66714")] + pub fn remove_entry(&mut self, key: &Q) -> Option<(K, V)> where K: Borrow, Q: Ord, { match search::search_tree(self.root.as_mut(), key) { Found(handle) => Some( - OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData }.remove(), + OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData } + .remove_entry(), ), GoDown(_) => None, } From 074cfcbf2d5fcddfc44f4a30ec096d01868176bd Mon Sep 17 00:00:00 2001 From: Pedro de Brito Date: Tue, 28 Jan 2020 07:59:07 +0100 Subject: [PATCH 5/8] fix: typo in vec.rs --- src/liballoc/vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index e9cbf627846b5..26a7812f58e01 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -176,7 +176,7 @@ use crate::raw_vec::RawVec; /// ``` /// /// In Rust, it's more common to pass slices as arguments rather than vectors -/// when you just want to provide a read access. The same goes for [`String`] and +/// when you just want to provide read access. The same goes for [`String`] and /// [`&str`]. /// /// # Capacity and reallocation From 976a146203a61d2feb9d3304aaaf35b0995d2bc3 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Mon, 27 Jan 2020 21:22:05 +0100 Subject: [PATCH 6/8] Add E0727 long explanation --- src/librustc_error_codes/error_codes.rs | 2 +- src/librustc_error_codes/error_codes/E0727.md | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 src/librustc_error_codes/error_codes/E0727.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 180ccb15977dd..c3d9ed088981d 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -397,6 +397,7 @@ E0718: include_str!("./error_codes/E0718.md"), E0720: include_str!("./error_codes/E0720.md"), E0723: include_str!("./error_codes/E0723.md"), E0725: include_str!("./error_codes/E0725.md"), +E0727: include_str!("./error_codes/E0727.md"), E0728: include_str!("./error_codes/E0728.md"), E0729: include_str!("./error_codes/E0729.md"), E0730: include_str!("./error_codes/E0730.md"), @@ -607,6 +608,5 @@ E0746: include_str!("./error_codes/E0746.md"), E0722, // Malformed `#[optimize]` attribute E0724, // `#[ffi_returns_twice]` is only allowed in foreign functions E0726, // non-explicit (not `'_`) elided lifetime in unsupported position - E0727, // `async` generators are not yet supported E0739, // invalid track_caller application/syntax } diff --git a/src/librustc_error_codes/error_codes/E0727.md b/src/librustc_error_codes/error_codes/E0727.md new file mode 100644 index 0000000000000..528807ee9afe2 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0727.md @@ -0,0 +1,26 @@ +A `yield` clause was used in an `async` context. + +Example of erroneous code: + +```compile_fail +#![feature(generators)] + +let generator = || { + async { + yield; + } +}; +``` + +Here, the `yield` keyword is used in an `async` block, +which is not yet supported. + +To fix this error, you have to move `yield` out of the `async` block: + +``` +#![feature(generators)] + +let generator = || { + yield; +}; +``` From f0a7e8f58ccdd8a87c0a2e187437b7891bded722 Mon Sep 17 00:00:00 2001 From: gorilskij <43991400+gorilskij@users.noreply.github.com> Date: Tue, 28 Jan 2020 23:06:58 +0100 Subject: [PATCH 7/8] Fix a few spelling mistakes --- src/librustc/mir/traversal.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index a89811ed43bb8..ed8129b1e09a5 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -4,7 +4,7 @@ use super::*; /// Preorder traversal of a graph. /// -/// Preorder traversal is when each node is visited before an of it's +/// Preorder traversal is when each node is visited before any of its /// successors /// /// ```text @@ -82,7 +82,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { /// Postorder traversal of a graph. /// -/// Postorder traversal is when each node is visited after all of it's +/// Postorder traversal is when each node is visited after all of its /// successors, except when the successor is only reachable by a back-edge /// /// From 6fbb0008932642de1935b8e46c218dab9b8ad45c Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Jan 2020 23:34:00 +0100 Subject: [PATCH 8/8] Update links to WASI docs in time.rs module Since the docs for the WASI API are now evolving in [WebAssembly/WASI] repo, I thought it might be useful to update the links in the docs to point to that location instead of using the outdated `CraneStation/wasmtime` destination. [WebAssembly/WASI]: https://github.com/WebAssembly/WASI --- src/libstd/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 5bc8fe5ae6d79..68a549158730d 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -76,7 +76,7 @@ pub use core::time::Duration; /// [QueryPerformanceCounter]: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter /// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode -/// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get +/// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md#clock_time_get /// [clock_gettime (Monotonic Clock)]: https://linux.die.net/man/3/clock_gettime /// [mach_absolute_time]: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html /// [clock_time_get (Monotonic Clock)]: https://nuxi.nl/cloudabi/#clock_time_get @@ -157,7 +157,7 @@ pub struct Instant(time::Instant); /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode /// [gettimeofday]: http://man7.org/linux/man-pages/man2/gettimeofday.2.html /// [clock_gettime (Realtime Clock)]: https://linux.die.net/man/3/clock_gettime -/// [__wasi_clock_time_get (Realtime Clock)]: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get +/// [__wasi_clock_time_get (Realtime Clock)]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md#clock_time_get /// [GetSystemTimeAsFileTime]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime /// /// **Disclaimer:** These system calls might change over time.