From b60f08bd6d3fbe784eb47a57e0c41954454af3dd Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Mon, 23 Sep 2019 18:39:55 -0700 Subject: [PATCH 1/9] rustdoc: NodeId is now DefId --- src/librustdoc/html/render/cache.rs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index f1f83acdda59e..3acfb82fe7840 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -43,7 +43,7 @@ crate struct Cache { /// found on that implementation. pub impls: FxHashMap>, - /// Maintains a mapping of local crate `NodeId`s to the fully qualified name + /// Maintains a mapping of local crate `DefId`s to the fully qualified name /// and "short type description" of that node. This is used when generating /// URLs when a type is being linked to. External paths are not located in /// this map because the `External` type itself has all the information @@ -358,6 +358,7 @@ impl DocFolder for Cache { | clean::ForeignTypeItem | clean::MacroItem(..) | clean::ProcMacroItem(..) + | clean::VariantItem(..) if !self.stripped_mod => { // Re-exported items mean that the same id can show up twice @@ -373,13 +374,6 @@ impl DocFolder for Cache { } self.add_aliases(&item); } - // Link variants to their parent enum because pages aren't emitted - // for each variant. - clean::VariantItem(..) if !self.stripped_mod => { - let mut stack = self.stack.clone(); - stack.pop(); - self.paths.insert(item.def_id, (stack, ItemType::Enum)); - } clean::PrimitiveItem(..) => { self.add_aliases(&item); @@ -396,7 +390,8 @@ impl DocFolder for Cache { | clean::EnumItem(..) | clean::ForeignTypeItem | clean::StructItem(..) - | clean::UnionItem(..) => { + | clean::UnionItem(..) + | clean::VariantItem(..) => { self.parent_stack.push(item.def_id); self.parent_is_trait_impl = false; true @@ -564,7 +559,7 @@ fn extern_location( /// Builds the search index from the collected metadata fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { - let mut nodeid_to_pathid = FxHashMap::default(); + let mut defid_to_pathid = FxHashMap::default(); let mut crate_items = Vec::with_capacity(cache.search_index.len()); let mut crate_paths = vec![]; @@ -586,21 +581,21 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { } } - // Reduce `NodeId` in paths into smaller sequential numbers, + // Reduce `DefId` in paths into smaller sequential numbers, // and prune the paths that do not appear in the index. let mut lastpath = String::new(); let mut lastpathid = 0usize; for item in search_index { - item.parent_idx = item.parent.map(|nodeid| { - if nodeid_to_pathid.contains_key(&nodeid) { - *nodeid_to_pathid.get(&nodeid).expect("no pathid") + item.parent_idx = item.parent.map(|defid| { + if defid_to_pathid.contains_key(&defid) { + *defid_to_pathid.get(&defid).expect("no pathid") } else { let pathid = lastpathid; - nodeid_to_pathid.insert(nodeid, pathid); + defid_to_pathid.insert(defid, pathid); lastpathid += 1; - let &(ref fqp, short) = paths.get(&nodeid).unwrap(); + let &(ref fqp, short) = paths.get(&defid).unwrap(); crate_paths.push((short, fqp.last().unwrap().clone())); pathid } From 05c6f329e785c9b53a50217de0f21df906ae7ba0 Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Mon, 23 Sep 2019 18:37:20 -0700 Subject: [PATCH 2/9] rustdoc: emit JS paths for struct-like variants On the backend, rustdoc now emits `paths` entries to a crate's search index for struct-like enum variants, and index items of type structfield which belong to such variants point to their variant parents in the `paths` table, rather than their enum grandparents. The path entry for a variant is the fully qualified module path plus the enum name. On the frontend, the search code recognizes structfields belonging to structlike variants in the `paths` table and re-constructs the URL to the field's anchor on the enum documentation page. closes #16017 --- src/librustdoc/html/static/main.js | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ec881d25dd2bf..069139ec69108 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1364,14 +1364,15 @@ function getSearchElement() { var href; var type = itemTypes[item.ty]; var name = item.name; + var path = item.path; if (type === "mod") { - displayPath = item.path + "::"; - href = rootPath + item.path.replace(/::/g, "/") + "/" + + displayPath = path + "::"; + href = rootPath + path.replace(/::/g, "/") + "/" + name + "/index.html"; } else if (type === "primitive" || type === "keyword") { displayPath = ""; - href = rootPath + item.path.replace(/::/g, "/") + + href = rootPath + path.replace(/::/g, "/") + "/" + type + "." + name + ".html"; } else if (type === "externcrate") { displayPath = ""; @@ -1380,14 +1381,27 @@ function getSearchElement() { var myparent = item.parent; var anchor = "#" + type + "." + name; var parentType = itemTypes[myparent.ty]; + var pageType = parentType; + var pageName = myparent.name; + if (parentType === "primitive") { displayPath = myparent.name + "::"; + } else if (type === "structfield" && parentType === "variant") { + // Structfields belonging to variants are special: the + // final path element is the enum name. + var splitPath = item.path.split("::"); + var enumName = splitPath.pop(); + path = splitPath.join("::"); + displayPath = path + "::" + enumName + "::" + myparent.name + "::"; + anchor = "#variant." + myparent.name + ".field." + name; + pageType = "enum"; + pageName = enumName; } else { - displayPath = item.path + "::" + myparent.name + "::"; + displayPath = path + "::" + myparent.name + "::"; } - href = rootPath + item.path.replace(/::/g, "/") + - "/" + parentType + - "." + myparent.name + + href = rootPath + path.replace(/::/g, "/") + + "/" + pageType + + "." + pageName + ".html" + anchor; } else { displayPath = item.path + "::"; @@ -1668,7 +1682,7 @@ function getSearchElement() { // (String) name] var paths = rawSearchIndex[crate].p; - // convert `paths` into an object form + // convert `rawPaths` entries into object form var len = paths.length; for (i = 0; i < len; ++i) { paths[i] = {ty: paths[i][0], name: paths[i][1]}; From 862af629512eaca9741ca4c9cb4190cca4b1c955 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 30 Jan 2020 13:43:54 +0100 Subject: [PATCH 3/9] Add tests for struct variant field in search --- src/test/rustdoc-js/struct-like-variant.js | 7 +++++++ src/test/rustdoc-js/struct-like-variant.rs | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 src/test/rustdoc-js/struct-like-variant.js create mode 100644 src/test/rustdoc-js/struct-like-variant.rs diff --git a/src/test/rustdoc-js/struct-like-variant.js b/src/test/rustdoc-js/struct-like-variant.js new file mode 100644 index 0000000000000..a698b1d4013fe --- /dev/null +++ b/src/test/rustdoc-js/struct-like-variant.js @@ -0,0 +1,7 @@ +const QUERY = 'name'; + +const EXPECTED = { + 'others': [ + { 'path': 'struct_like_variant::Enum::Bar::name', 'name': 'l' }, + ], +}; diff --git a/src/test/rustdoc-js/struct-like-variant.rs b/src/test/rustdoc-js/struct-like-variant.rs new file mode 100644 index 0000000000000..9c000a44ab10d --- /dev/null +++ b/src/test/rustdoc-js/struct-like-variant.rs @@ -0,0 +1,5 @@ +#![crate_name = "struct_like_variant"] + +pub enum Enum { + Bar { name: String } +} From 2a79ed0b4999bf9e805e0e38cd1faf5f85068368 Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Thu, 30 Jan 2020 17:25:58 -0800 Subject: [PATCH 4/9] [docs] remind bug reporters to update nightly --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fc8ca5d07b212..d6840b20c89ac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,6 +50,9 @@ is a bug or not, feel free to file a bug anyway. **If you believe reporting your bug publicly represents a security risk to Rust users, please follow our [instructions for reporting security vulnerabilities](https://www.rust-lang.org/policies/security)**. +If you're using the nightly channel, please check if the bug exists in the +latest toolchain before filing your bug. It might be fixed already. + If you have the chance, before reporting a bug, please [search existing issues](https://github.com/rust-lang/rust/search?q=&type=Issues&utf8=%E2%9C%93), as it's possible that someone else has already reported your error. This doesn't From 08e85aa5865dcb8198942a082d892d863367d4d2 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 31 Jan 2020 17:09:34 +0100 Subject: [PATCH 5/9] Ignore `build` dir formatting --- rustfmt.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rustfmt.toml b/rustfmt.toml index 73f8cc1ff68c6..2a034845c6e0b 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -6,6 +6,8 @@ merge_derives = false # by default we ignore everything in the repository # tidy only checks files which are not ignored, each entry follows gitignore style ignore = [ + "build", + # tests for now are not formatted, as they are sometimes pretty-printing constrained # (and generally rustfmt can move around comments in UI-testing incompatible ways) "src/test", From 346920c3c844e650aff6428c6b5c6e70cbce9954 Mon Sep 17 00:00:00 2001 From: hman523 Date: Fri, 31 Jan 2020 13:41:07 -0600 Subject: [PATCH 6/9] Fixed issue 68593 --- src/liballoc/boxed.rs | 3 ++- src/liballoc/vec.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8735c2c8f3625..7e5efbe307861 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -2,7 +2,8 @@ //! //! [`Box`], casually referred to as a 'box', provides the simplest form of //! heap allocation in Rust. Boxes provide ownership for this allocation, and -//! drop their contents when they go out of scope. +//! drop their contents when they go out of scope. Boxes also ensure that they +//! never allocate more than `isize::MAX` bytes. //! //! # Examples //! diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 26a7812f58e01..4f6b7870e2e8c 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -4,6 +4,8 @@ //! Vectors have `O(1)` indexing, amortized `O(1)` push (to the end) and //! `O(1)` pop (from the end). //! +//! Vectors ensure they never allocate more than `isize::MAX` bytes. +//! //! # Examples //! //! You can explicitly create a [`Vec`] with [`new`]: From 482c761704b9f7d08d00b6cf4c567db427da7ec7 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Thu, 23 Jan 2020 00:22:46 +0900 Subject: [PATCH 7/9] Use BufWriter --- .../obligation_forest/graphviz.rs | 3 +- src/librustc_incremental/assert_dep_graph.rs | 4 +-- src/librustc_interface/passes.rs | 4 +-- src/librustc_mir/borrow_check/facts.rs | 34 +++++++++++++++---- src/librustc_mir/transform/dump_mir.rs | 2 +- src/librustc_mir/util/liveness.rs | 5 +-- 6 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/librustc_data_structures/obligation_forest/graphviz.rs b/src/librustc_data_structures/obligation_forest/graphviz.rs index ddf89d99621ca..0fd83dad56b1a 100644 --- a/src/librustc_data_structures/obligation_forest/graphviz.rs +++ b/src/librustc_data_structures/obligation_forest/graphviz.rs @@ -2,6 +2,7 @@ use crate::obligation_forest::{ForestObligation, ObligationForest}; use graphviz as dot; use std::env::var_os; use std::fs::File; +use std::io::BufWriter; use std::path::Path; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; @@ -31,7 +32,7 @@ impl ObligationForest { let file_path = dir.as_ref().join(format!("{:010}_{}.gv", counter, description)); - let mut gv_file = File::create(file_path).unwrap(); + let mut gv_file = BufWriter::new(File::create(file_path).unwrap()); dot::render(&self, &mut gv_file).unwrap(); } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 9490128e32d6a..51cc091b6c0af 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -49,7 +49,7 @@ use syntax::ast; use std::env; use std::fs::{self, File}; -use std::io::Write; +use std::io::{BufWriter, Write}; pub fn assert_dep_graph(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { @@ -235,7 +235,7 @@ fn dump_graph(tcx: TyCtxt<'_>) { { // dump a .txt file with just the edges: let txt_path = format!("{}.txt", path); - let mut file = File::create(&txt_path).unwrap(); + let mut file = BufWriter::new(File::create(&txt_path).unwrap()); for &(ref source, ref target) in &edges { write!(file, "{:?} -> {:?}\n", source, target).unwrap(); } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index d62c7539d5f21..6af83a4c5abc1 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -49,7 +49,7 @@ use tempfile::Builder as TempFileBuilder; use std::any::Any; use std::cell::RefCell; use std::ffi::OsString; -use std::io::{self, Write}; +use std::io::{self, BufWriter, Write}; use std::path::PathBuf; use std::rc::Rc; use std::{env, fs, iter, mem}; @@ -575,7 +575,7 @@ fn write_out_deps( }); } - let mut file = fs::File::create(&deps_filename)?; + let mut file = BufWriter::new(fs::File::create(&deps_filename)?); for path in out_filenames { writeln!(file, "{}: {}\n", path.display(), files.join(" "))?; } diff --git a/src/librustc_mir/borrow_check/facts.rs b/src/librustc_mir/borrow_check/facts.rs index a16c36d749f0d..827ccb1c85733 100644 --- a/src/librustc_mir/borrow_check/facts.rs +++ b/src/librustc_mir/borrow_check/facts.rs @@ -8,7 +8,7 @@ use rustc_index::vec::Idx; use std::error::Error; use std::fmt::Debug; use std::fs::{self, File}; -use std::io::Write; +use std::io::{BufWriter, Write}; use std::path::Path; #[derive(Copy, Clone, Debug)] @@ -117,7 +117,7 @@ impl<'w> FactWriter<'w> { T: FactRow, { let file = &self.dir.join(file_name); - let mut file = File::create(file)?; + let mut file = BufWriter::new(File::create(file)?); for row in rows { row.write(&mut file, self.location_table)?; } @@ -126,11 +126,19 @@ impl<'w> FactWriter<'w> { } trait FactRow { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box>; + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box>; } impl FactRow for RegionVid { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box> { write_row(out, location_table, &[self]) } } @@ -140,7 +148,11 @@ where A: FactCell, B: FactCell, { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1]) } } @@ -151,7 +163,11 @@ where B: FactCell, C: FactCell, { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1, &self.2]) } } @@ -163,7 +179,11 @@ where C: FactCell, D: FactCell, { - fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { + fn write( + &self, + out: &mut dyn Write, + location_table: &LocationTable, + ) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1, &self.2, &self.3]) } } diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 2cbda33ad2db1..5dec2c6df99dc 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -61,7 +61,7 @@ pub fn on_mir_pass<'tcx>( pub fn emit_mir(tcx: TyCtxt<'_>, outputs: &OutputFilenames) -> io::Result<()> { let path = outputs.path(OutputType::Mir); - let mut f = File::create(&path)?; + let mut f = io::BufWriter::new(File::create(&path)?); mir_util::write_mir_pretty(tcx, None, &mut f)?; Ok(()) } diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 1488bfe4d627a..b12ad1e4c15cc 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -36,7 +36,7 @@ use rustc_data_structures::work_queue::WorkQueue; use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; use std::fs; -use std::io::{self, Write}; +use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; pub type LiveVarSet = BitSet; @@ -288,7 +288,8 @@ fn dump_matched_mir_node<'tcx>( let item_id = tcx.hir().as_local_hir_id(source.def_id()).unwrap(); let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name); file_path.push(&file_name); - let _ = fs::File::create(&file_path).and_then(|mut file| { + let _ = fs::File::create(&file_path).and_then(|file| { + let mut file = BufWriter::new(file); writeln!(file, "// MIR local liveness analysis for `{}`", node_path)?; writeln!(file, "// source = {:?}", source)?; writeln!(file, "// pass_name = {}", pass_name)?; From cad0cfd9fdbc64dece3f38c03b15ed9aad032d5c Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sat, 1 Feb 2020 13:29:00 +0100 Subject: [PATCH 8/9] Remove a comment about pretty printer in formatting tests rustc is now using rustfmt, not the old formatter. --- src/test/ui/ifmt.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/ui/ifmt.rs b/src/test/ui/ifmt.rs index 1a070843cc446..27ab3d6b7abff 100644 --- a/src/test/ui/ifmt.rs +++ b/src/test/ui/ifmt.rs @@ -99,7 +99,6 @@ pub fn main() { let a: &dyn fmt::Debug = &1; t!(format!("{:?}", a), "1"); - // Formatting strings and their arguments t!(format!("{}", "a"), "a"); t!(format!("{:4}", "a"), "a "); @@ -187,10 +186,6 @@ pub fn main() { // Ergonomic format_args! t!(format!("{0:x} {0:X}", 15), "f F"); t!(format!("{0:x} {0:X} {}", 15), "f F 15"); - // NOTE: For now the longer test cases must not be followed immediately by - // >1 empty lines, or the pretty printer will break. Since no one wants to - // touch the current pretty printer (#751), we have no choice but to work - // around it. Some of the following test cases are also affected. t!(format!("{:x}{0:X}{a:x}{:X}{1:x}{a:X}", 13, 14, a=15), "dDfEeF"); t!(format!("{a:x} {a:X}", a=15), "f F"); @@ -201,7 +196,6 @@ pub fn main() { t!(format!("{a:.*} {0} {:.*}", 4, 3, "efgh", a="abcdef"), "abcd 4 efg"); t!(format!("{:.a$} {a} {a:#x}", "aaaaaa", a=2), "aa 2 0x2"); - // Test that pointers don't get truncated. { let val = usize::MAX; From 103e87c0b4c83ad147d6a660a6df6c328fe40557 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 1 Feb 2020 18:45:03 +0100 Subject: [PATCH 9/9] pretty: print attrs in struct expr --- src/libsyntax/print/pprust.rs | 4 ++++ .../issue-68710-field-attr-proc-mac-lost.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d6f18fda8b25c..d9e75a4aae32c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1751,12 +1751,15 @@ impl<'a> State<'a> { attrs: &[Attribute], ) { self.print_path(path, true, 0); + self.nbsp(); self.s.word("{"); self.print_inner_attributes_inline(attrs); self.commasep_cmnt( Consistent, &fields[..], |s, field| { + s.print_outer_attributes(&field.attrs); + s.space_if_not_bol(); s.ibox(INDENT_UNIT); if !field.is_shorthand { s.print_ident(field.ident); @@ -1769,6 +1772,7 @@ impl<'a> State<'a> { ); match *wth { Some(ref expr) => { + self.space_if_not_bol(); self.ibox(INDENT_UNIT); if !fields.is_empty() { self.s.word(","); diff --git a/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs b/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs new file mode 100644 index 0000000000000..c2aa0c48d05a7 --- /dev/null +++ b/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs @@ -0,0 +1,16 @@ +// pp-exact + +fn main() { } + +struct C { + field: u8, +} + +#[allow()] +const C: C = + C { + #[cfg(debug_assertions)] + field: 0, + + #[cfg(not (debug_assertions))] + field: 1,};