From 7aca34b8963fd9ac8681485a44417e537e617245 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Feb 2018 16:47:00 -0600 Subject: [PATCH 01/17] add readme for librustdoc --- src/librustdoc/README.md | 170 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/librustdoc/README.md diff --git a/src/librustdoc/README.md b/src/librustdoc/README.md new file mode 100644 index 0000000000000..844c54c7aa88c --- /dev/null +++ b/src/librustdoc/README.md @@ -0,0 +1,170 @@ +# The walking tour of rustdoc + +Rustdoc is implemented entirely within the crate `librustdoc`. After partially compiling a crate to +get its AST (technically the HIR map) from rustc, librustdoc performs two major steps past that to +render a set of documentation: + +* "Clean" the AST into a form that's more suited to creating documentation (and slightly more + resistant to churn in the compiler). +* Use this cleaned AST to render a crate's documentation, one page at a time. + +Naturally, there's more than just this, and those descriptions simplify out lots of details, but +that's the high-level overview. + +(Side note: this is a library crate! The `rustdoc` binary is crated using the project in +`src/tools/rustdoc`. Note that literally all that does is call the `main()` that's in this crate's +`lib.rs`, though.) + +## Cheat sheet + +* Use `x.py build --stage 1 src/libstd src/tools/rustdoc` to make a useable rustdoc you can run on + other projects. + * Add `src/libtest` to be able to use `rustdoc --test`. + * If you've used `rustup toolchain link local /path/to/build/$TARGET/stage1` previously, then + after the previous build command, `cargo +local doc` will Just Work. +* Use `x.py doc --stage 1 src/libstd` to use this rustdoc to generate the standard library docs. + * The completed docs will be available in `build/$TARGET/doc/std`, though the bundle is meant to + be used as though you would copy out the `doc` folder to a web server, since that's where the + CSS/JS and landing page are. +* Most of the HTML printing code is in `html/format.rs` and `html/render.rs`. It's in a bunch of + `fmt::Display` implementations and supplementary functions. +* The types that operates on are defined in `clean/mod.rs`, right next to the custom `Clean` trait + used to process them out of the rustc HIR. +* The bits specific to using rustdoc as a test harness are in `test.rs`. +* The Markdown renderer is loaded up in `html/markdown.rs`, including functions for extracting + doctests from a given block of Markdown. +* The tests on rustdoc *output* are located in `src/test/rustdoc`, where they're handled by the test + runner of rustbuild and the supplementary script `src/etc/htmldocck.py`. +* Tests on search index generation are located in `src/test/rustdoc-js`, as a series of JavaScript + files that encode queries on the standard library search index and expected results. + +## From crate to clean + +In `core.rs` are two central items: the `DocContext` struct, and the `run_core` function. The latter +is where rustdoc calls out to rustc to compile a crate to the point where rustdoc can take over. The +former is a state container used when crawling through a crate to gather its documentation. + +The main process of crate crawling is done in `clean/mod.rs` through several implementations of the +`Clean` trait defined within. This is a conversion trait, which defines one method: + +```rust +pub trait Clean { + fn clean(&self, cx: &DocContext) -> T; +} +``` + +`clean/mod.rs` also defines the types for the "cleaned" AST used later on to render documentation +pages. Each usually accompanies an implementation of `Clean` that takes some AST or HIR type from +rustc and converts it into the appropriate "cleaned" type. "Big" items like modules or associated +items may have some extra processing in its `Clean` implementation, but for the most part these +impls are straightforward conversions. The "entry point" to this module is the `impl Clean +for visit_ast::RustdocVisitor`, which is called by `run_core` above. + +You see, I actually lied a little earlier: There's another AST transformation that happens before +the events in `clean/mod.rs`. In `visit_ast.rs` is the type `RustdocVisitor`, which *actually* +crawls a `hir::Crate` to get the first intermediate representation, defined in `doctree.rs`. This +pass is mainly to get a few intermediate wrappers around the HIR types and to process visibility +and inlining. This is where `#[doc(inline)]`, `#[doc(no_inline)]`, and `#[doc(hidden)]` are +processed, as well as the logic for whether a `pub use` should get the full page or a "Reexport" +line in the module page. + +Back in `clean/mod.rs`, the other major thing that happens here is the special collection of doc +comments (and basic `#[doc=""]` attributes) into a separate field in the `Attributes` struct from +the other attributes. The primary output of this process is a `clean::Crate` with a tree of `Item`s +which describe the publicly-documentable items in the target crate. + +### Hot potato + +Before moving on to the next major step, a few important "passes" occur over the documentation. +These do things like combine the separate "attributes" into a single string and strip leading +whitespace to make the document easier on the markdown parser, or drop items that are not public or +deliberately hidden with `#[doc(hidden)]`. These are all implemented in the `passes/` directory, one +file per pass. By default, all of these passes are run on a crate, but the ones regarding dropping +private/hidden items can be bypassed by passing `--document-private-items` to rustdoc. + +(Strictly speaking, you can fine-tune the passes run and even add your own, but [we're trying to +deprecate that][44136]. If you need finer-grain control over these passes, please let us know!) + +[44136]: https://github.com/rust-lang/rust/issues/44136 + +## From clean to crate + +This is where the "second phase" in rustdoc begins. This phase primarily lives in the `html/` +folder, and it all starts with `run()` in `html/render.rs`. This code is responsible for setting up +the `Context`, `SharedContext`, and `Cache` which are used during rendering, copying out the static +files which live in every rendered set of documentation (things like the fonts, CSS, and JavaScript +that live in `html/static/`), creating the search index, and printing out the source code rendering, +before beginning the process of rendering all the documentation for the crate. + +Several functions implemented directly on `Context` take the `clean::Crate` and set up some state +between rendering items or recursing on a module's child items. From here the "page rendering" +begins, via an enormous `write!()` call in `html/layout.rs`. The parts that actually generate HTML +from the items and documentation occurs within a series of `std::fmt::Display` implementations and +functions that pass around a `&mut std::fmt::Formatter`. The top-level implementation that writes +out the page body is the `impl<'a> fmt::Display for Item<'a>` in `html/render.rs`, which switches +out to one of several `item_*` functions based on the kind of `Item` being rendered. + +Depending on what kind of rendering code you're looking for, you'll probably find it either in +`html/render.rs` for major items like "what sections should I print for a struct page" or +`html/format.rs` for smaller component pieces like "how should I print a where clause as part of +some other item". + +Whenever rustdoc comes across an item that should print hand-written documentation alongside, it +calls out to `html/markdown.rs` which interfaces with the Markdown parser. This is exposed as a +series of types that wrap a string of Markdown, and implement `fmt::Display` to emit HTML text. It +takes special care to enable certain features like footnotes and tables and add syntax highlighting +to Rust code blocks (via `html/highlight.rs`) before running the Markdown parser. There's also a +function in here (`find_testable_code`) that specifically scans for Rust code blocks so the +test-runner code can find all the doctests in the crate. + +### From soup to nuts + +(alternate title: ["An unbroken thread that stretches from those first `Cell`s to us"][video]) + +[video]: https://www.youtube.com/watch?v=hOLAGYmUQV0 + +It's important to note that the AST cleaning can ask the compiler for information (crucially, +`DocContext` contains a `TyCtxt`), but page rendering cannot. The `clean::Crate` created within +`run_core` is passed outside the compiler context before being handed to `html::render::run`. This +means that a lot of the "supplementary data" that isn't immediately available inside an item's +definition, like which trait is the `Deref` trait used by the language, needs to be collected during +cleaning, stored in the `DocContext`, and passed along to the `SharedContext` during HTML rendering. +This manifests as a bunch of shared state, context variables, and `RefCell`s. + +Also of note is that some items that come from "asking the compiler" don't go directly into the +`DocContext` - for example, when loading items from a foreign crate, rustdoc will ask about trait +implementations and generate new `Item`s for the impls based on that information. This goes directly +into the returned `Crate` rather than roundabout through the `DocContext`. This way, these +implementations can be collected alongside the others, right before rendering the HTML. + +## Other tricks up its sleeve + +All this describes the process for generating HTML documentation from a Rust crate, but there are +couple other major modes that rustdoc runs in. It can also be run on a standalone Markdown file, or +it can run doctests on Rust code or standalone Markdown files. For the former, it shortcuts straight +to `html/markdown.rs`, optionally including a mode which inserts a Table of Contents to the output +HTML. + +For the latter, rustdoc runs a similar partial-compilation to get relevant documentation in +`test.rs`, but instead of going through the full clean and render process, it runs a much simpler +crate walk to grab *just* the hand-written documentation. Combined with the aforementioned +"`find_testable_code`" in `html/markdown.rs`, it builds up a collection of tests to run before +handing them off to the libtest test runner. One notable location in `test.rs` is the function +`make_test`, which is where hand-written doctests get transformed into something that can be +executed. + +## Dotting i's and crossing t's + +So that's rustdoc's code in a nutshell, but there's more things in the repo that deal with it. Since +we have the full `compiletest` suite at hand, there's a set of tests in `src/test/rustdoc` that make +sure the final HTML is what we expect in various situations. These tests also use a supplementary +script, `src/etc/htmldocck.py`, that allows it to look through the final HTML using XPath notation +to get a precise look at the output. The full description of all the commands available to rustdoc +tests is in `htmldocck.py`. + +In addition, there are separate tests for the search index and rustdoc's ability to query it. The +files in `src/test/rustdoc-js` each contain a different search query and the expected results, +broken out by search tab. These files are processed by a script in `src/tools/rustdoc-js` and the +Node.js runtime. These tests don't have as thorough of a writeup, but a broad example that features +results in all tabs can be found in `basic.js`. The basic idea is that you match a given `QUERY` +with a set of `EXPECTED` results, complete with the full item path of each item. From 8d893c1e9e136302a1640035b29e23023f87866e Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 20 Feb 2018 09:26:44 -0600 Subject: [PATCH 02/17] review nits --- src/librustdoc/README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/README.md b/src/librustdoc/README.md index 844c54c7aa88c..b0a5ae3718df3 100644 --- a/src/librustdoc/README.md +++ b/src/librustdoc/README.md @@ -28,8 +28,8 @@ that's the high-level overview. CSS/JS and landing page are. * Most of the HTML printing code is in `html/format.rs` and `html/render.rs`. It's in a bunch of `fmt::Display` implementations and supplementary functions. -* The types that operates on are defined in `clean/mod.rs`, right next to the custom `Clean` trait - used to process them out of the rustc HIR. +* The types that got `Display` impls above are defined in `clean/mod.rs`, right next to the custom + `Clean` trait used to process them out of the rustc HIR. * The bits specific to using rustdoc as a test harness are in `test.rs`. * The Markdown renderer is loaded up in `html/markdown.rs`, including functions for extracting doctests from a given block of Markdown. @@ -68,10 +68,12 @@ and inlining. This is where `#[doc(inline)]`, `#[doc(no_inline)]`, and `#[doc(hi processed, as well as the logic for whether a `pub use` should get the full page or a "Reexport" line in the module page. -Back in `clean/mod.rs`, the other major thing that happens here is the special collection of doc -comments (and basic `#[doc=""]` attributes) into a separate field in the `Attributes` struct from -the other attributes. The primary output of this process is a `clean::Crate` with a tree of `Item`s -which describe the publicly-documentable items in the target crate. +The other major thing that happens in `clean/mod.rs` is the collection of doc comments and +`#[doc=""]` attributes into a separate field of the Attributes struct, present on anything that gets +hand-written documentation. This makes it easier to collect this documentation later in the process. + +The primary output of this process is a clean::Crate with a tree of Items which describe the +publicly-documentable items in the target crate. ### Hot potato From 8e4ad29cb9cc74bf44486f4507f36df70d495187 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Fri, 23 Feb 2018 21:48:41 +0900 Subject: [PATCH 03/17] Disable NEON on musl ARMv7 --- .../target/armv7_unknown_linux_musleabihf.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs index a36e26c0b7d5f..88f2b59675186 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -12,13 +12,7 @@ use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::linux_musl_base::opts(); - - // Most of these settings are copied from the armv7_unknown_linux_gnueabihf - // target. - base.features = "+v7,+vfp3,+neon".to_string(); - base.cpu = "cortex-a8".to_string(); - base.max_atomic_width = Some(64); + let base = super::linux_musl_base::opts(); Ok(Target { // It's important we use "gnueabihf" and not "musleabihf" here. LLVM // uses it to determine the calling convention and float ABI, and LLVM @@ -33,9 +27,15 @@ pub fn target() -> TargetResult { target_env: "musl".to_string(), target_vendor: "unknown".to_string(), linker_flavor: LinkerFlavor::Gcc, + + // Most of these settings are copied from the armv7_unknown_linux_gnueabihf + // target. options: TargetOptions { + features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(), + cpu: "generic".to_string(), + max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), .. base - }, + } }) } From ffb6291cd032e3b0577bf67a2b6d932d6ba0787c Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Mon, 26 Feb 2018 20:45:52 -0500 Subject: [PATCH 04/17] Improve --help performance for x.py Since compiling the bootstrap command doesn't require any submodules, we can skip updating submodules when a --help command is passed in. On my machine, this saves 1 minute if the submodules are already downloaded, and 10 minutes if run on a clean repo. This commit also adds a message before compiling/downloading anything when a --help command is passed in, to tell the user WHY --help takes so long to complete. It also points the user to the bootstrap README.md for faster help. Finally, this fixes one warning message that still referenced using make instead of x.py, even though x.py is now the standard way of building rust. --- src/bootstrap/bootstrap.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 603a97ddfd412..f5fcf4ba0f560 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -670,7 +670,7 @@ def set_dev_environment(self): self._download_url = 'https://dev-static.rust-lang.org' -def bootstrap(): +def bootstrap(help_triggered): """Configure, fetch, build and run the initial bootstrap""" parser = argparse.ArgumentParser(description='Build rust') parser.add_argument('--config') @@ -708,7 +708,7 @@ def bootstrap(): print(' and so in order to preserve your $HOME this will now') print(' use vendored sources by default. Note that if this') print(' does not work you should run a normal build first') - print(' before running a command like `sudo make install`') + print(' before running a command like `sudo ./x.py install`') if build.use_vendored_sources: if not os.path.exists('.cargo'): @@ -734,7 +734,10 @@ def bootstrap(): if 'dev' in data: build.set_dev_environment() - build.update_submodules() + # No help text depends on submodules. This check saves ~1 minute of git commands, even if + # all the submodules are present and downloaded! + if not help_triggered: + build.update_submodules() # Fetch/build the bootstrap build.build = args.build or build.build_triple() @@ -760,7 +763,13 @@ def main(): help_triggered = ( '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) try: - bootstrap() + # If the user is asking for help, let them know that the whole download-and-build + # process has to happen before anything is printed out. + if help_triggered: + print("NOTE: Downloading and compiling bootstrap requirements before processing") + print(" --help command. See src/bootstrap/README.md for help with common") + print(" commands.") + bootstrap(help_triggered) if not help_triggered: print("Build completed successfully in {}".format( format_build_time(time() - start_time))) From 89e55d108c5c6d5f29c4eb0cb829e47bccb8598b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 3 Dec 2017 14:24:14 +0100 Subject: [PATCH 05/17] Make TransitiveRelation thread safe. Avoid locking by using get_mut in some cases. --- .../transitive_relation.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index ba7ab0c07c66a..6d63bc4436fe8 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -10,16 +10,16 @@ use bitvec::BitMatrix; use fx::FxHashMap; +use sync::Lock; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use stable_hasher::{HashStable, StableHasher, StableHasherResult}; -use std::cell::RefCell; use std::fmt::Debug; use std::hash::Hash; use std::mem; #[derive(Clone, Debug)] -pub struct TransitiveRelation { +pub struct TransitiveRelation { // List of elements. This is used to map from a T to a usize. elements: Vec, @@ -32,14 +32,14 @@ pub struct TransitiveRelation { // This is a cached transitive closure derived from the edges. // Currently, we build it lazilly and just throw out any existing - // copy whenever a new edge is added. (The RefCell is to permit + // copy whenever a new edge is added. (The Lock is to permit // the lazy computation.) This is kind of silly, except for the // fact its size is tied to `self.elements.len()`, so I wanted to // wait before building it up to avoid reallocating as new edges // are added with new elements. Perhaps better would be to ask the // user for a batch of edges to minimize this effect, but I // already wrote the code this way. :P -nmatsakis - closure: RefCell>, + closure: Lock>, } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] @@ -51,13 +51,13 @@ struct Edge { target: Index, } -impl TransitiveRelation { +impl TransitiveRelation { pub fn new() -> TransitiveRelation { TransitiveRelation { elements: vec![], map: FxHashMap(), edges: vec![], - closure: RefCell::new(None), + closure: Lock::new(None), } } @@ -72,7 +72,7 @@ impl TransitiveRelation { fn add_index(&mut self, a: T) -> Index { let &mut TransitiveRelation { ref mut elements, - ref closure, + ref mut closure, ref mut map, .. } = self; @@ -82,7 +82,7 @@ impl TransitiveRelation { elements.push(a); // if we changed the dimensions, clear the cache - *closure.borrow_mut() = None; + *closure.get_mut() = None; Index(elements.len() - 1) }) @@ -122,7 +122,7 @@ impl TransitiveRelation { self.edges.push(edge); // added an edge, clear the cache - *self.closure.borrow_mut() = None; + *self.closure.get_mut() = None; } } @@ -443,7 +443,7 @@ impl Decodable for TransitiveRelation .enumerate() .map(|(index, elem)| (elem.clone(), Index(index))) .collect(); - Ok(TransitiveRelation { elements, edges, map, closure: RefCell::new(None) }) + Ok(TransitiveRelation { elements, edges, map, closure: Lock::new(None) }) }) } } From 993e594d30e560d9242f97614c981b1d55727ef3 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 23 Feb 2018 09:53:00 -0800 Subject: [PATCH 06/17] Run Rustfix on librustc --- src/librustc/dep_graph/debug.rs | 2 +- src/librustc/hir/lowering.rs | 8 +++---- src/librustc/hir/map/collector.rs | 2 +- src/librustc/hir/map/def_collector.rs | 2 +- src/librustc/hir/map/mod.rs | 2 +- src/librustc/hir/print.rs | 22 +++++++++---------- src/librustc/ich/hcx.rs | 4 ++-- src/librustc/infer/region_constraints/mod.rs | 2 +- src/librustc/lint/mod.rs | 4 ++-- src/librustc/middle/cstore.rs | 8 +++---- src/librustc/middle/dependency_format.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 6 ++--- src/librustc/middle/liveness.rs | 4 ++-- src/librustc/mir/interpret/error.rs | 4 ++-- src/librustc/session/config.rs | 6 ++--- src/librustc/session/mod.rs | 8 +++---- src/librustc/traits/error_reporting.rs | 2 +- .../traits/specialize/specialization_graph.rs | 4 ++-- src/librustc/ty/context.rs | 10 ++++----- src/librustc/ty/fold.rs | 4 ++-- src/librustc/ty/util.rs | 2 +- src/librustc/util/common.rs | 2 +- 22 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/librustc/dep_graph/debug.rs b/src/librustc/dep_graph/debug.rs index e22552008d5a8..e56333aba9be5 100644 --- a/src/librustc/dep_graph/debug.rs +++ b/src/librustc/dep_graph/debug.rs @@ -54,7 +54,7 @@ pub struct EdgeFilter { } impl EdgeFilter { - pub fn new(test: &str) -> Result> { + pub fn new(test: &str) -> Result> { let parts: Vec<_> = test.split("->").collect(); if parts.len() != 2 { Err(format!("expected a filter like `a&b -> c&d`, not `{}`", test).into()) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index b15ee53e22571..50fd9638f08ba 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -80,13 +80,13 @@ pub struct LoweringContext<'a> { // Use to assign ids to hir nodes that do not directly correspond to an ast node sess: &'a Session, - cstore: &'a CrateStore, + cstore: &'a dyn CrateStore, // As we walk the AST we must keep track of the current 'parent' def id (in // the form of a DefIndex) so that if we create a new node which introduces // a definition, then we can properly create the def id. parent_def: Option, - resolver: &'a mut Resolver, + resolver: &'a mut dyn Resolver, name_map: FxHashMap, /// The items being lowered are collected here. @@ -177,10 +177,10 @@ enum ImplTraitContext { } pub fn lower_crate(sess: &Session, - cstore: &CrateStore, + cstore: &dyn CrateStore, dep_graph: &DepGraph, krate: &Crate, - resolver: &mut Resolver) + resolver: &mut dyn Resolver) -> hir::Crate { // We're constructing the HIR here; we don't care what we will // read, since we haven't even constructed the *input* to diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 99b1e5783e01e..9bbda9d74479b 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -123,7 +123,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { pub(super) fn finalize_and_compute_crate_hash(self, crate_disambiguator: CrateDisambiguator, - cstore: &CrateStore, + cstore: &dyn CrateStore, codemap: &CodeMap, commandline_args_hash: u64) -> (Vec>, Svh) { diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index d68b18dd2f17d..cdd6395747865 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -26,7 +26,7 @@ pub struct DefCollector<'a> { definitions: &'a mut Definitions, parent_def: Option, expansion: Mark, - pub visit_macro_invoc: Option<&'a mut FnMut(MacroInvocationData)>, + pub visit_macro_invoc: Option<&'a mut dyn FnMut(MacroInvocationData)>, } pub struct MacroInvocationData { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 3799bdada888e..b5a757564242c 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1137,7 +1137,7 @@ impl Named for TraitItem { fn name(&self) -> Name { self.name } } impl Named for ImplItem { fn name(&self) -> Name { self.name } } pub fn map_crate<'hir>(sess: &::session::Session, - cstore: &::middle::cstore::CrateStore, + cstore: &dyn ::middle::cstore::CrateStore, forest: &'hir mut Forest, definitions: &'hir Definitions) -> Map<'hir> { diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 30c1ad01d1401..ed8cea3eb6563 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -62,7 +62,7 @@ pub trait PpAnn { pub struct NoAnn; impl PpAnn for NoAnn {} -pub const NO_ANN: &'static PpAnn = &NoAnn; +pub const NO_ANN: &'static dyn PpAnn = &NoAnn; impl PpAnn for hir::Crate { fn nested(&self, state: &mut State, nested: Nested) -> io::Result<()> { @@ -83,7 +83,7 @@ pub struct State<'a> { literals: Peekable>, cur_cmnt: usize, boxes: Vec, - ann: &'a (PpAnn + 'a), + ann: &'a (dyn PpAnn + 'a), } impl<'a> PrintState<'a> for State<'a> { @@ -126,9 +126,9 @@ pub fn print_crate<'a>(cm: &'a CodeMap, sess: &ParseSess, krate: &hir::Crate, filename: FileName, - input: &mut Read, - out: Box, - ann: &'a PpAnn, + input: &mut dyn Read, + out: Box, + ann: &'a dyn PpAnn, is_expanded: bool) -> io::Result<()> { let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded); @@ -145,9 +145,9 @@ impl<'a> State<'a> { pub fn new_from_input(cm: &'a CodeMap, sess: &ParseSess, filename: FileName, - input: &mut Read, - out: Box, - ann: &'a PpAnn, + input: &mut dyn Read, + out: Box, + ann: &'a dyn PpAnn, is_expanded: bool) -> State<'a> { let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input); @@ -167,8 +167,8 @@ impl<'a> State<'a> { } pub fn new(cm: &'a CodeMap, - out: Box, - ann: &'a PpAnn, + out: Box, + ann: &'a dyn PpAnn, comments: Option>, literals: Option>) -> State<'a> { @@ -184,7 +184,7 @@ impl<'a> State<'a> { } } -pub fn to_string(ann: &PpAnn, f: F) -> String +pub fn to_string(ann: &dyn PpAnn, f: F) -> String where F: FnOnce(&mut State) -> io::Result<()> { let mut wr = Vec::new(); diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 67f6c0c2e49e8..4dcab6a04ee20 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -49,7 +49,7 @@ pub fn compute_ignored_attr_names() -> FxHashSet { pub struct StableHashingContext<'gcx> { sess: &'gcx Session, definitions: &'gcx Definitions, - cstore: &'gcx CrateStore, + cstore: &'gcx dyn CrateStore, body_resolver: BodyResolver<'gcx>, hash_spans: bool, hash_bodies: bool, @@ -88,7 +88,7 @@ impl<'gcx> StableHashingContext<'gcx> { pub fn new(sess: &'gcx Session, krate: &'gcx hir::Crate, definitions: &'gcx Definitions, - cstore: &'gcx CrateStore) + cstore: &'gcx dyn CrateStore) -> Self { let hash_spans_initial = !sess.opts.debugging_opts.incremental_ignore_spans; diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index be196192371fd..1136895128848 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -896,7 +896,7 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> { } impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { - fn for_each_region(&self, f: &mut FnMut(ty::Region<'tcx>)) { + fn for_each_region(&self, f: &mut dyn FnMut(ty::Region<'tcx>)) { match self { &VerifyBound::AnyRegion(ref rs) | &VerifyBound::AllRegions(ref rs) => for &r in rs { f(r); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index a51d06c06edd3..5cc7cd5440f8c 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -280,8 +280,8 @@ pub trait EarlyLintPass: LintPass { } /// A lint pass boxed up as a trait object. -pub type EarlyLintPassObject = Box; -pub type LateLintPassObject = Box LateLintPass<'a, 'tcx> + 'static>; +pub type EarlyLintPassObject = Box; +pub type LateLintPassObject = Box LateLintPass<'a, 'tcx> + 'static>; /// Identifies a lint known to the compiler. #[derive(Clone, Copy, Debug)] diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 9708afd204593..b0aaa76c75ed7 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -225,10 +225,10 @@ pub struct ExternBodyNestedBodies { /// (it'd break incremental compilation) and should only be called pre-HIR (e.g. /// during resolve) pub trait CrateStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc; + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc; // access to the metadata loader - fn metadata_loader(&self) -> &MetadataLoader; + fn metadata_loader(&self) -> &dyn MetadataLoader; // resolve fn def_key(&self, def: DefId) -> DefKey; @@ -297,7 +297,7 @@ pub struct DummyCrateStore; #[allow(unused_variables)] impl CrateStore for DummyCrateStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc { bug!("crate_data_as_rc_any") } // item info fn visibility_untracked(&self, def: DefId) -> ty::Visibility { bug!("visibility") } @@ -351,7 +351,7 @@ impl CrateStore for DummyCrateStore { fn postorder_cnums_untracked(&self) -> Vec { bug!("postorder_cnums_untracked") } // access to the metadata loader - fn metadata_loader(&self) -> &MetadataLoader { bug!("metadata_loader") } + fn metadata_loader(&self) -> &dyn MetadataLoader { bug!("metadata_loader") } } pub trait CrateLoader { diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index db0ecb6aa5eb1..e7055827c491f 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -319,7 +319,7 @@ fn attempt_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option, list: &mut DependencyList, - replaces_injected: &Fn(CrateNum) -> bool) { + replaces_injected: &dyn Fn(CrateNum) -> bool) { for (i, slot) in list.iter().enumerate() { let cnum = CrateNum::new(i + 1); if !replaces_injected(cnum) { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 7db75a5166898..0ee25ae8116fd 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -239,7 +239,7 @@ impl OverloadedCallType { // This is the code that actually walks the tree. pub struct ExprUseVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { mc: mc::MemCategorizationContext<'a, 'gcx, 'tcx>, - delegate: &'a mut Delegate<'tcx>, + delegate: &'a mut dyn Delegate<'tcx>, param_env: ty::ParamEnv<'tcx>, } @@ -274,7 +274,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> { /// `None` means that rvalues will be given more conservative lifetimes. /// /// See also `with_infer`, which is used *during* typeck. - pub fn new(delegate: &'a mut (Delegate<'tcx>+'a), + pub fn new(delegate: &'a mut (dyn Delegate<'tcx>+'a), tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, region_scope_tree: &'a region::ScopeTree, @@ -294,7 +294,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> { } impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { - pub fn with_infer(delegate: &'a mut (Delegate<'tcx>+'a), + pub fn with_infer(delegate: &'a mut (dyn Delegate<'tcx>+'a), infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, region_scope_tree: &'a region::ScopeTree, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 10497c95e27d0..d13b16dce8986 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -673,7 +673,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn write_vars(&self, - wr: &mut Write, + wr: &mut dyn Write, ln: LiveNode, mut test: F) -> io::Result<()> where @@ -694,7 +694,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn ln_str(&self, ln: LiveNode) -> String { let mut wr = Vec::new(); { - let wr = &mut wr as &mut Write; + let wr = &mut wr as &mut dyn Write; write!(wr, "[ln({:?}) of kind {:?} reads", ln.get(), self.ir.lnk(ln)); self.write_vars(wr, ln, |idx| self.users[idx].reader); write!(wr, " writes"); diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 9ebfe25c107a9..f9ea544156ce3 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -35,7 +35,7 @@ impl<'tcx> From> for EvalError<'tcx> { pub enum EvalErrorKind<'tcx> { /// This variant is used by machines to signal their own errors that do not /// match an existing variant - MachineError(Box), + MachineError(Box), FunctionPointerTyMismatch(FnSig<'tcx>, FnSig<'tcx>), NoMirFor(String), UnterminatedCString(MemoryPointer), @@ -248,7 +248,7 @@ impl<'tcx> Error for EvalError<'tcx> { } } - fn cause(&self) -> Option<&Error> { + fn cause(&self) -> Option<&dyn Error> { use self::EvalErrorKind::*; match self.kind { MachineError(ref inner) => Some(&**inner), diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index b69f5d6c8bdd7..f48006839441d 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -341,7 +341,7 @@ macro_rules! hash_option { ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [UNTRACKED]) => ({}); ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [TRACKED]) => ({ if $sub_hashes.insert(stringify!($opt_name), - $opt_expr as &dep_tracking::DepTrackingHash).is_some() { + $opt_expr as &dyn dep_tracking::DepTrackingHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHash).is_some() { bug!("Duplicate key in CLI DepTrackingHash: {}", stringify!($opt_name)) } }); @@ -1456,7 +1456,7 @@ pub enum OptionStability { } pub struct RustcOptGroup { - pub apply: Box &mut getopts::Options>, + pub apply: Box &mut getopts::Options>, pub name: &'static str, pub stability: OptionStability, } @@ -2256,7 +2256,7 @@ mod dep_tracking { } // This is a stable hash because BTreeMap is a sorted container - pub fn stable_hash(sub_hashes: BTreeMap<&'static str, &DepTrackingHash>, + pub fn stable_hash(sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { for (key, sub_hash) in sub_hashes { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 2437eaadc6d48..c0085a803dc40 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -904,7 +904,7 @@ pub fn build_session_with_codemap(sopts: config::Options, local_crate_source_file: Option, registry: errors::registry::Registry, codemap: Rc, - emitter_dest: Option>) + emitter_dest: Option>) -> Session { // FIXME: This is not general enough to make the warning lint completely override // normal diagnostic warnings, since the warning lint can also be denied and changed @@ -923,7 +923,7 @@ pub fn build_session_with_codemap(sopts: config::Options, let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace; - let emitter: Box = match (sopts.error_format, emitter_dest) { + let emitter: Box = match (sopts.error_format, emitter_dest) { (config::ErrorOutputType::HumanReadable(color_config), None) => { Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), false, sopts.debugging_opts.teach) @@ -1122,7 +1122,7 @@ pub enum IncrCompSession { } pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { - let emitter: Box = match output { + let emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { Box::new(EmitterWriter::stderr(color_config, None, false, false)) } @@ -1137,7 +1137,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { } pub fn early_warn(output: config::ErrorOutputType, msg: &str) { - let emitter: Box = match output { + let emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { Box::new(EmitterWriter::stderr(color_config, None, false, false)) } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 118d4ddd4457b..242ba0b0e5904 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -497,7 +497,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { item_name: ast::Name, _impl_item_def_id: DefId, trait_item_def_id: DefId, - requirement: &fmt::Display) + requirement: &dyn fmt::Display) -> DiagnosticBuilder<'tcx> { let msg = "impl has stricter requirements than trait"; diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index a10169e13e60a..efc4089367486 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -190,13 +190,13 @@ impl<'a, 'gcx, 'tcx> Children { Ok(Inserted::BecameNewSibling(last_lint)) } - fn iter_mut(&'a mut self) -> Box + 'a> { + fn iter_mut(&'a mut self) -> Box + 'a> { let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter_mut()); Box::new(self.blanket_impls.iter_mut().chain(nonblanket)) } fn filtered_mut(&'a mut self, sty: SimplifiedType) - -> Box + 'a> { + -> Box + 'a> { let nonblanket = self.nonblanket_impls.entry(sty).or_insert(vec![]).iter_mut(); Box::new(self.blanket_impls.iter_mut().chain(nonblanket)) } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index a39d63d05eeaf..a02115c4afb85 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -799,7 +799,7 @@ pub struct GlobalCtxt<'tcx> { global_arenas: &'tcx GlobalArenas<'tcx>, global_interners: CtxtInterners<'tcx>, - cstore: &'tcx CrateStore, + cstore: &'tcx dyn CrateStore, pub sess: &'tcx Session, @@ -883,7 +883,7 @@ pub struct GlobalCtxt<'tcx> { /// This is intended to only get used during the trans phase of the compiler /// when satisfying the query for a particular codegen unit. Internally in /// the query it'll send data along this channel to get processed later. - pub tx_to_llvm_workers: mpsc::Sender>, + pub tx_to_llvm_workers: mpsc::Sender>, output_filenames: Arc, } @@ -1131,7 +1131,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// value (types, substs, etc.) can only be used while `ty::tls` has a valid /// reference to the context, to allow formatting values that need it. pub fn create_and_enter(s: &'tcx Session, - cstore: &'tcx CrateStore, + cstore: &'tcx dyn CrateStore, local_providers: ty::maps::Providers<'tcx>, extern_providers: ty::maps::Providers<'tcx>, arenas: &'tcx AllArenas<'tcx>, @@ -1139,7 +1139,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { hir: hir_map::Map<'tcx>, on_disk_query_result_cache: maps::OnDiskCache<'tcx>, crate_name: &str, - tx: mpsc::Sender>, + tx: mpsc::Sender>, output_filenames: &OutputFilenames, f: F) -> R where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R @@ -1312,7 +1312,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Note that this is *untracked* and should only be used within the query // system if the result is otherwise tracked through queries - pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Rc { + pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Rc { self.cstore.crate_data_as_rc_any(cnum) } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index c5b82730e488c..4cc7406af721e 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -277,7 +277,7 @@ pub struct RegionFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, skipped_regions: &'a mut bool, current_depth: u32, - fld_r: &'a mut (FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx> + 'a), + fld_r: &'a mut (dyn FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx> + 'a), } impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> { @@ -330,7 +330,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> { struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, current_depth: u32, - fld_r: &'a mut (FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a), + fld_r: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a), map: BTreeMap> } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 110808919e905..9a4203b897f05 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -418,7 +418,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn calculate_dtor( self, adt_did: DefId, - validate: &mut FnMut(Self, DefId) -> Result<(), ErrorReported> + validate: &mut dyn FnMut(Self, DefId) -> Result<(), ErrorReported> ) -> Option { let drop_trait = if let Some(def_id) = self.lang_items().drop_trait() { def_id diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 55e9a98e7ef13..bdb120ea59c8a 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -38,7 +38,7 @@ pub struct ErrorReported; thread_local!(static TIME_DEPTH: Cell = Cell::new(0)); lazy_static! { - static ref DEFAULT_HOOK: Box = { + static ref DEFAULT_HOOK: Box = { let hook = panic::take_hook(); panic::set_hook(Box::new(panic_hook)); hook From 753f61ec595ef5f9c8338c4bce5a4c119bd689c3 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 23 Feb 2018 10:02:10 -0800 Subject: [PATCH 07/17] Perform manual fixups --- src/librustc/hir/map/mod.rs | 5 ++++- src/librustc/session/config.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b5a757564242c..61fae4609d54f 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -19,6 +19,8 @@ use dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex}; use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace}; +use middle::cstore::CrateStore; + use syntax::abi::Abi; use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID}; use syntax::codemap::Spanned; @@ -1136,8 +1138,9 @@ impl Named for StructField { fn name(&self) -> Name { self.name } } impl Named for TraitItem { fn name(&self) -> Name { self.name } } impl Named for ImplItem { fn name(&self) -> Name { self.name } } + pub fn map_crate<'hir>(sess: &::session::Session, - cstore: &dyn ::middle::cstore::CrateStore, + cstore: &dyn CrateStore, forest: &'hir mut Forest, definitions: &'hir Definitions) -> Map<'hir> { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index f48006839441d..ca17e18beccba 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -341,7 +341,7 @@ macro_rules! hash_option { ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [UNTRACKED]) => ({}); ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [TRACKED]) => ({ if $sub_hashes.insert(stringify!($opt_name), - $opt_expr as &dyn dep_tracking::DepTrackingHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHash).is_some() { + $opt_expr as &dyn dep_tracking::DepTrackingHash).is_some() { bug!("Duplicate key in CLI DepTrackingHash: {}", stringify!($opt_name)) } }); From bde583a1c2800d131704dc2416520b04d530e19a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 23 Feb 2018 09:52:03 -0800 Subject: [PATCH 08/17] Remove allow(bare_trait_object) from librustc --- src/librustc/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index f05ed0a460d87..d08a41010ab16 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -41,8 +41,6 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![deny(warnings)] -#![cfg_attr(not(stage0), allow(bare_trait_object))] - #![feature(box_patterns)] #![feature(box_syntax)] #![feature(conservative_impl_trait)] From 28381bd0be9b1ab6ffe281d31a8d0dc30699d4e4 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 23 Feb 2018 10:15:26 -0800 Subject: [PATCH 09/17] Run Rustfix on librustc_mir --- .../borrow_check/nll/explain_borrow/mod.rs | 2 +- src/librustc_mir/borrow_check/nll/mod.rs | 4 +- .../borrow_check/nll/region_infer/dump_mir.rs | 4 +- .../borrow_check/nll/region_infer/graphviz.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 8 ++-- src/librustc_mir/dataflow/mod.rs | 2 +- src/librustc_mir/interpret/const_eval.rs | 2 +- src/librustc_mir/transform/dump_mir.rs | 2 +- src/librustc_mir/transform/mod.rs | 2 +- src/librustc_mir/util/liveness.rs | 4 +- src/librustc_mir/util/pretty.rs | 40 +++++++++---------- 11 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 948c1ac0b1362..b6d8e14b74757 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -176,7 +176,7 @@ impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> { None } - fn def_use(&self, location: Location, thing: &MirVisitable<'tcx>) -> (bool, bool) { + fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) { let mut visitor = DefUseVisitor { defined: false, used: false, diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 07e5091da9c1e..dbfb8a6d06e63 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -260,10 +260,10 @@ fn dump_annotation<'a, 'gcx, 'tcx>( fn for_each_region_constraint( closure_region_requirements: &ClosureRegionRequirements, - with_msg: &mut FnMut(&str) -> io::Result<()>, + with_msg: &mut dyn FnMut(&str) -> io::Result<()>, ) -> io::Result<()> { for req in &closure_region_requirements.outlives_requirements { - let subject: &Debug = match &req.subject { + let subject: &dyn Debug = match &req.subject { ClosureOutlivesSubject::Region(subject) => subject, ClosureOutlivesSubject::Ty(ty) => ty, }; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs index 69ecafa66aee7..631b1d0f8941d 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs @@ -23,7 +23,7 @@ const REGION_WIDTH: usize = 8; impl<'tcx> RegionInferenceContext<'tcx> { /// Write out our state into the `.mir` files. - pub(crate) fn dump_mir(&self, out: &mut Write) -> io::Result<()> { + pub(crate) fn dump_mir(&self, out: &mut dyn Write) -> io::Result<()> { writeln!(out, "| Free Region Mapping")?; for region in self.regions() { @@ -67,7 +67,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// inference resulted in the values that it did when debugging. fn for_each_constraint( &self, - with_msg: &mut FnMut(&str) -> io::Result<()>, + with_msg: &mut dyn FnMut(&str) -> io::Result<()>, ) -> io::Result<()> { for region in self.definitions.indices() { let value = self.liveness_constraints.region_value_str(region); diff --git a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs index 7923b159d80dc..db773240809c5 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs @@ -20,7 +20,7 @@ use super::*; impl<'tcx> RegionInferenceContext<'tcx> { /// Write out the region constraint graph. - pub(crate) fn dump_graphviz(&self, mut w: &mut Write) -> io::Result<()> { + pub(crate) fn dump_graphviz(&self, mut w: &mut dyn Write) -> io::Result<()> { dot::render(self, &mut w) } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index d57b8e78f18a9..a06d39d225c45 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -127,7 +127,7 @@ fn type_check_internal<'gcx, 'tcx>( mir: &Mir<'tcx>, region_bound_pairs: &[(ty::Region<'tcx>, GenericKind<'tcx>)], implicit_region_bound: Option>, - extra: &mut FnMut(&mut TypeChecker<'_, 'gcx, 'tcx>), + extra: &mut dyn FnMut(&mut TypeChecker<'_, 'gcx, 'tcx>), ) -> MirTypeckRegionConstraints<'tcx> { let mut checker = TypeChecker::new( infcx, @@ -231,7 +231,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { self.cx.infcx.tcx } - fn sanitize_type(&mut self, parent: &fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> { + fn sanitize_type(&mut self, parent: &dyn fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> { if ty.has_escaping_regions() || ty.references_error() { span_mirbug_and_err!(self, parent, "bad type {:?}", ty) } else { @@ -516,7 +516,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { fn field_ty( &mut self, - parent: &fmt::Debug, + parent: &dyn fmt::Debug, base_ty: PlaceTy<'tcx>, field: Field, location: Location, @@ -1171,7 +1171,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { fn assert_iscleanup( &mut self, mir: &Mir<'tcx>, - ctxt: &fmt::Debug, + ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool, ) { diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 9c7d9b398cc56..aa7bb6f97786c 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -61,7 +61,7 @@ pub(crate) struct DataflowBuilder<'a, 'tcx: 'a, BD> where BD: BitDenotation pub(crate) struct DebugFormatted(String); impl DebugFormatted { - pub fn new(input: &fmt::Debug) -> DebugFormatted { + pub fn new(input: &dyn fmt::Debug) -> DebugFormatted { DebugFormatted(format!("{:?}", input)) } } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index d3b084fde6ab8..bc555368f0f5f 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -168,7 +168,7 @@ impl Error for ConstEvalError { } } - fn cause(&self) -> Option<&Error> { + fn cause(&self) -> Option<&dyn Error> { None } } diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 98753eaa5a354..a16ef2adea9be 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -49,7 +49,7 @@ impl fmt::Display for Disambiguator { pub fn on_mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - pass_num: &fmt::Display, + pass_num: &dyn fmt::Display, pass_name: &str, source: MirSource, mir: &Mir<'tcx>, diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 54a7a0eafe0af..3be42c336d540 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -161,7 +161,7 @@ pub macro run_passes($tcx:ident, $mir:ident, $def_id:ident, $suite_index:expr; $ promoted }; let mut index = 0; - let mut run_pass = |pass: &MirPass| { + let mut run_pass = |pass: &dyn MirPassPassPass| { let run_hooks = |mir: &_, index, is_after| { dump_mir::on_mir_pass($tcx, &format_args!("{:03}-{:03}", suite_index, index), &pass.name(), source, mir, is_after); diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 6251b64bb279d..42ddabddd2dcd 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -425,12 +425,12 @@ pub fn write_mir_fn<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &Mir<'tcx>, - w: &mut Write, + w: &mut dyn Write, result: &LivenessResult, ) -> io::Result<()> { write_mir_intro(tcx, src, mir, w)?; for block in mir.basic_blocks().indices() { - let print = |w: &mut Write, prefix, result: &IndexVec| { + let print = |w: &mut dyn Write, prefix, result: &IndexVec| { let live: Vec = mir.local_decls .indices() .filter(|i| result[block].contains(i)) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index f326b6e9274fc..4509cace794d4 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -72,14 +72,14 @@ pub enum PassWhere { /// or `typeck` and `bar` both appear in the name. pub fn dump_mir<'a, 'gcx, 'tcx, F>( tcx: TyCtxt<'a, 'gcx, 'tcx>, - pass_num: Option<&Display>, + pass_num: Option<&dyn Display>, pass_name: &str, - disambiguator: &Display, + disambiguator: &dyn Display, source: MirSource, mir: &Mir<'tcx>, extra_data: F, ) where - F: FnMut(PassWhere, &mut Write) -> io::Result<()>, + F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { if !dump_enabled(tcx, pass_name, source) { return; @@ -127,15 +127,15 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>( fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( tcx: TyCtxt<'a, 'gcx, 'tcx>, - pass_num: Option<&Display>, + pass_num: Option<&dyn Display>, pass_name: &str, node_path: &str, - disambiguator: &Display, + disambiguator: &dyn Display, source: MirSource, mir: &Mir<'tcx>, mut extra_data: F, ) where - F: FnMut(PassWhere, &mut Write) -> io::Result<()>, + F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { let _: io::Result<()> = do catch { let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?; @@ -169,9 +169,9 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( fn dump_path( tcx: TyCtxt<'_, '_, '_>, extension: &str, - pass_num: Option<&Display>, + pass_num: Option<&dyn Display>, pass_name: &str, - disambiguator: &Display, + disambiguator: &dyn Display, source: MirSource, ) -> PathBuf { let promotion_id = match source.promoted { @@ -217,9 +217,9 @@ fn dump_path( pub(crate) fn create_dump_file( tcx: TyCtxt<'_, '_, '_>, extension: &str, - pass_num: Option<&Display>, + pass_num: Option<&dyn Display>, pass_name: &str, - disambiguator: &Display, + disambiguator: &dyn Display, source: MirSource, ) -> io::Result { let file_path = dump_path(tcx, extension, pass_num, pass_name, disambiguator, source); @@ -233,7 +233,7 @@ pub(crate) fn create_dump_file( pub fn write_mir_pretty<'a, 'gcx, 'tcx>( tcx: TyCtxt<'a, 'gcx, 'tcx>, single: Option, - w: &mut Write, + w: &mut dyn Write, ) -> io::Result<()> { writeln!( w, @@ -274,10 +274,10 @@ pub fn write_mir_fn<'a, 'gcx, 'tcx, F>( src: MirSource, mir: &Mir<'tcx>, extra_data: &mut F, - w: &mut Write, + w: &mut dyn Write, ) -> io::Result<()> where - F: FnMut(PassWhere, &mut Write) -> io::Result<()>, + F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { write_mir_intro(tcx, src, mir, w)?; for block in mir.basic_blocks().indices() { @@ -298,10 +298,10 @@ pub fn write_basic_block<'cx, 'gcx, 'tcx, F>( block: BasicBlock, mir: &Mir<'tcx>, extra_data: &mut F, - w: &mut Write, + w: &mut dyn Write, ) -> io::Result<()> where - F: FnMut(PassWhere, &mut Write) -> io::Result<()>, + F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { let data = &mir[block]; @@ -362,7 +362,7 @@ where /// a statement. fn write_extra<'cx, 'gcx, 'tcx, F>( tcx: TyCtxt<'cx, 'gcx, 'tcx>, - write: &mut Write, + write: &mut dyn Write, mut visit_op: F, ) -> io::Result<()> where @@ -450,7 +450,7 @@ fn write_scope_tree( tcx: TyCtxt, mir: &Mir, scope_tree: &FxHashMap>, - w: &mut Write, + w: &mut dyn Write, parent: VisibilityScope, depth: usize, ) -> io::Result<()> { @@ -515,7 +515,7 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>( tcx: TyCtxt<'a, 'gcx, 'tcx>, src: MirSource, mir: &Mir, - w: &mut Write, + w: &mut dyn Write, ) -> io::Result<()> { write_mir_sig(tcx, src, mir, w)?; writeln!(w, "{{")?; @@ -553,7 +553,7 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>( Ok(()) } -fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write) -> io::Result<()> { +fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> io::Result<()> { let id = tcx.hir.as_local_node_id(src.def_id).unwrap(); let body_owner_kind = tcx.hir.body_owner_kind(id); match (body_owner_kind, src.promoted) { @@ -597,7 +597,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write) -> io::R Ok(()) } -fn write_temp_decls(mir: &Mir, w: &mut Write) -> io::Result<()> { +fn write_temp_decls(mir: &Mir, w: &mut dyn Write) -> io::Result<()> { // Compiler-introduced temporary types. for temp in mir.temps_iter() { writeln!( From 12e03eed7a6de98f064cdec96e34b57782d6e54c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 23 Feb 2018 10:17:07 -0800 Subject: [PATCH 10/17] Perform manual fixups --- src/librustc_mir/transform/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 3be42c336d540..24a2790b1e79a 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -161,7 +161,7 @@ pub macro run_passes($tcx:ident, $mir:ident, $def_id:ident, $suite_index:expr; $ promoted }; let mut index = 0; - let mut run_pass = |pass: &dyn MirPassPassPass| { + let mut run_pass = |pass: &dyn MirPass| { let run_hooks = |mir: &_, index, is_after| { dump_mir::on_mir_pass($tcx, &format_args!("{:03}-{:03}", suite_index, index), &pass.name(), source, mir, is_after); From 38676c68f04b955009fbdb5e2eea1dd75577019d Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 23 Feb 2018 10:04:46 -0800 Subject: [PATCH 11/17] Remove allow(bare_trait_object) from librustc_mir --- src/librustc_mir/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 9887ac82a2ea6..8c15d1cf8b03a 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -15,7 +15,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! */ #![deny(warnings)] -#![cfg_attr(not(stage0), allow(bare_trait_object))] #![feature(box_patterns)] #![feature(box_syntax)] From 5ac4f62f3832f2a4ed26ab95567c96a38a9f4f15 Mon Sep 17 00:00:00 2001 From: M Farkas-Dyck Date: Wed, 28 Feb 2018 20:57:56 -0800 Subject: [PATCH 12/17] impl Clone for ::std_unicode::char::{ToLowercase, ToUppercase} --- src/libstd_unicode/char.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index 844ff7a3c1252..5dd9c62775097 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -59,7 +59,7 @@ pub use version::UnicodeVersion; /// [`to_lowercase`]: ../../std/primitive.char.html#method.to_lowercase /// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ToLowercase(CaseMappingIter); #[stable(feature = "rust1", since = "1.0.0")] @@ -81,7 +81,7 @@ impl FusedIterator for ToLowercase {} /// [`to_uppercase`]: ../../std/primitive.char.html#method.to_uppercase /// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ToUppercase(CaseMappingIter); #[stable(feature = "rust1", since = "1.0.0")] @@ -95,7 +95,7 @@ impl Iterator for ToUppercase { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for ToUppercase {} -#[derive(Debug)] +#[derive(Debug, Clone)] enum CaseMappingIter { Three(char, char, char), Two(char, char), From 70d5a4600b21451aa98b447cd59384d86e2eadce Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 1 Mar 2018 01:57:25 -0800 Subject: [PATCH 13/17] Specialize Zip::nth for TrustedRandomAccess Makes the bench asked about on URLO 58x faster :) --- src/libcore/benches/iter.rs | 29 ++++++++++++++++++++++++++++ src/libcore/iter/mod.rs | 38 +++++++++++++++++++++++++++++++++++++ src/libcore/tests/iter.rs | 17 +++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index b284d855c4515..6c597301ac204 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -281,3 +281,32 @@ bench_sums! { bench_take_while_chain_ref_sum, (0i64..1000000).chain(1000000..).take_while(|&x| x < 1111111) } + +// Checks whether Skip> is as fast as Zip, Skip>, from +// https://users.rust-lang.org/t/performance-difference-between-iterator-zip-and-skip-order/15743 +#[bench] +fn bench_zip_then_skip(b: &mut Bencher) { + let v: Vec<_> = (0..100_000).collect(); + let t: Vec<_> = (0..100_000).collect(); + + b.iter(|| { + let s = v.iter().zip(t.iter()).skip(10000) + .take_while(|t| *t.0 < 10100) + .map(|(a, b)| *a + *b) + .sum::(); + assert_eq!(s, 2009900); + }); +} +#[bench] +fn bench_skip_then_zip(b: &mut Bencher) { + let v: Vec<_> = (0..100_000).collect(); + let t: Vec<_> = (0..100_000).collect(); + + b.iter(|| { + let s = v.iter().skip(10000).zip(t.iter().skip(10000)) + .take_while(|t| *t.0 < 10100) + .map(|(a, b)| *a + *b) + .sum::(); + assert_eq!(s, 2009900); + }); +} diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 623cad754dd72..533ff388b7604 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -1045,6 +1045,11 @@ impl Iterator for Zip where A: Iterator, B: Iterator fn size_hint(&self) -> (usize, Option) { ZipImpl::size_hint(self) } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + ZipImpl::nth(self, n) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1065,6 +1070,14 @@ trait ZipImpl { fn new(a: A, b: B) -> Self; fn next(&mut self) -> Option; fn size_hint(&self) -> (usize, Option); + fn nth(&mut self, n: usize) -> Option; + fn super_nth(&mut self, mut n: usize) -> Option { + while let Some(x) = self.next() { + if n == 0 { return Some(x) } + n -= 1; + } + None + } fn next_back(&mut self) -> Option where A: DoubleEndedIterator + ExactSizeIterator, B: DoubleEndedIterator + ExactSizeIterator; @@ -1094,6 +1107,12 @@ impl ZipImpl for Zip }) } + #[inline] + default fn nth(&mut self, n: usize) -> Option + { + self.super_nth(n) + } + #[inline] default fn next_back(&mut self) -> Option<(A::Item, B::Item)> where A: DoubleEndedIterator + ExactSizeIterator, @@ -1174,6 +1193,25 @@ impl ZipImpl for Zip (len, Some(len)) } + #[inline] + fn nth(&mut self, n: usize) -> Option + { + let delta = cmp::min(n, self.len - self.index); + let end = self.index + delta; + while self.index < end { + let i = self.index; + self.index += 1; + if A::may_have_side_effect() { + unsafe { self.a.get_unchecked(i); } + } + if B::may_have_side_effect() { + unsafe { self.b.get_unchecked(i); } + } + } + + self.super_nth(n - delta) + } + #[inline] fn next_back(&mut self) -> Option<(A::Item, B::Item)> where A: DoubleEndedIterator + ExactSizeIterator, diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index edd75f7795ed7..5e2fef95d2606 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -144,6 +144,23 @@ fn test_iterator_chain_find() { assert_eq!(iter.next(), None); } +#[test] +fn test_zip_nth() { + let xs = [0, 1, 2, 4, 5]; + let ys = [10, 11, 12]; + + let mut it = xs.iter().zip(&ys); + assert_eq!(it.nth(0), Some((&0, &10))); + assert_eq!(it.nth(1), Some((&2, &12))); + assert_eq!(it.nth(0), None); + + let mut it = xs.iter().zip(&ys); + assert_eq!(it.nth(3), None); + + let mut it = ys.iter().zip(&xs); + assert_eq!(it.nth(3), None); +} + #[test] fn test_iterator_step_by() { // Identity From 11fefeb61c959c6a964120036992aed34f9d4282 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 1 Mar 2018 02:17:50 -0800 Subject: [PATCH 14/17] Add a Zip::nth test for side effects --- src/libcore/tests/iter.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 5e2fef95d2606..a962efadd64e9 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -161,6 +161,26 @@ fn test_zip_nth() { assert_eq!(it.nth(3), None); } +#[test] +fn test_zip_nth_side_effects() { + let mut a = Vec::new(); + let mut b = Vec::new(); + let value = [1, 2, 3, 4, 5, 6].iter().cloned() + .map(|n| { + a.push(n); + n * 10 + }) + .zip([2, 3, 4, 5, 6, 7, 8].iter().cloned().map(|n| { + b.push(n * 100); + n * 1000 + })) + .skip(1) + .nth(3); + assert_eq!(value, Some((50, 6000))); + assert_eq!(a, vec![1, 2, 3, 4, 5]); + assert_eq!(b, vec![200, 300, 400, 500, 600]); +} + #[test] fn test_iterator_step_by() { // Identity From 5105fc1681bb5be631850a6ae699dd97f929dd76 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 1 Mar 2018 02:29:46 -0800 Subject: [PATCH 15/17] Fix braces --- src/libcore/iter/mod.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 533ff388b7604..257d7d6caaaf8 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -1108,8 +1108,7 @@ impl ZipImpl for Zip } #[inline] - default fn nth(&mut self, n: usize) -> Option - { + default fn nth(&mut self, n: usize) -> Option { self.super_nth(n) } @@ -1194,8 +1193,7 @@ impl ZipImpl for Zip } #[inline] - fn nth(&mut self, n: usize) -> Option - { + fn nth(&mut self, n: usize) -> Option { let delta = cmp::min(n, self.len - self.index); let end = self.index + delta; while self.index < end { From 2269ff521fe2a945e462d5156799011c5fce2966 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Fri, 2 Mar 2018 03:29:35 -0500 Subject: [PATCH 16/17] Remove print_what_bootstrap_means It was an existing solution to tell the user why a --help command takes a long time to process. However, it would only print if the stage0 rust compiler needed to be downloaded, it came after update_submodules (which took a long time), and it was immediately followed by download messages and loading bars, meaning users could easily gloss over the message. This commit also moves the help message out of main(), and instead puts it at the top of bootstrap(). main() is intended to be minimal, only handling error messages. --- src/bootstrap/bootstrap.py | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index f5fcf4ba0f560..327ae0cb65c88 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -314,7 +314,6 @@ def __init__(self): self.build_dir = os.path.join(os.getcwd(), "build") self.clean = False self.config_toml = '' - self.printed = False self.rust_root = os.path.abspath(os.path.join(__file__, '../../..')) self.use_locked_deps = '' self.use_vendored_sources = '' @@ -336,7 +335,6 @@ def download_stage0(self): if self.rustc().startswith(self.bin_root()) and \ (not os.path.exists(self.rustc()) or self.program_out_of_date(self.rustc_stamp())): - self.print_what_bootstrap_means() if os.path.exists(self.bin_root()): shutil.rmtree(self.bin_root()) filename = "rust-std-{}-{}.tar.gz".format( @@ -354,7 +352,6 @@ def download_stage0(self): if self.cargo().startswith(self.bin_root()) and \ (not os.path.exists(self.cargo()) or self.program_out_of_date(self.cargo_stamp())): - self.print_what_bootstrap_means() filename = "cargo-{}-{}.tar.gz".format(cargo_channel, self.build) self._download_stage0_helper(filename, "cargo") self.fix_executable("{}/bin/cargo".format(self.bin_root())) @@ -555,23 +552,6 @@ def exe_suffix(): return '.exe' return '' - def print_what_bootstrap_means(self): - """Prints more information about the build system""" - if hasattr(self, 'printed'): - return - self.printed = True - if os.path.exists(self.bootstrap_binary()): - return - if '--help' not in sys.argv or len(sys.argv) == 1: - return - - print('info: the build system for Rust is written in Rust, so this') - print(' script is now going to download a stage0 rust compiler') - print(' and then compile the build system itself') - print('') - print('info: in the meantime you can read more about rustbuild at') - print(' src/bootstrap/README.md before the download finishes') - def bootstrap_binary(self): """Return the path of the boostrap binary @@ -585,7 +565,6 @@ def bootstrap_binary(self): def build_bootstrap(self): """Build bootstrap""" - self.print_what_bootstrap_means() build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) @@ -672,6 +651,14 @@ def set_dev_environment(self): def bootstrap(help_triggered): """Configure, fetch, build and run the initial bootstrap""" + + # If the user is asking for help, let them know that the whole download-and-build + # process has to happen before anything is printed out. + if help_triggered: + print("info: Downloading and building bootstrap before processing --help") + print(" command. See src/bootstrap/README.md for help with common") + print(" commands.") + parser = argparse.ArgumentParser(description='Build rust') parser.add_argument('--config') parser.add_argument('--build') @@ -763,12 +750,6 @@ def main(): help_triggered = ( '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) try: - # If the user is asking for help, let them know that the whole download-and-build - # process has to happen before anything is printed out. - if help_triggered: - print("NOTE: Downloading and compiling bootstrap requirements before processing") - print(" --help command. See src/bootstrap/README.md for help with common") - print(" commands.") bootstrap(help_triggered) if not help_triggered: print("Build completed successfully in {}".format( From 900d511fdca20998e42634d5351f7033bbde1aed Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 2 Mar 2018 13:52:13 -0500 Subject: [PATCH 17/17] Don't produce TOCs for doc markdown files Currently, we are producing headers for markdown files, which is generally not what we want. As such, passing this flag causes them to render normally. --- src/bootstrap/doc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 55d9723527e6d..a791dd13f0f4b 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -312,6 +312,7 @@ fn invoke_rustdoc(builder: &Builder, compiler: Compiler, target: Interned