From 0dd0a5bc033a95ce980ccd13004afeac35521409 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 5 Apr 2018 13:27:41 -0400 Subject: [PATCH 01/24] initialize the rustc book --- src/doc/rustc/.gitignore | 1 + src/doc/rustc/book.toml | 5 +++++ src/doc/rustc/src/SUMMARY.md | 3 +++ src/doc/rustc/src/chapter_1.md | 1 + 4 files changed, 10 insertions(+) create mode 100644 src/doc/rustc/.gitignore create mode 100644 src/doc/rustc/book.toml create mode 100644 src/doc/rustc/src/SUMMARY.md create mode 100644 src/doc/rustc/src/chapter_1.md diff --git a/src/doc/rustc/.gitignore b/src/doc/rustc/.gitignore new file mode 100644 index 0000000000000..7585238efedfc --- /dev/null +++ b/src/doc/rustc/.gitignore @@ -0,0 +1 @@ +book diff --git a/src/doc/rustc/book.toml b/src/doc/rustc/book.toml new file mode 100644 index 0000000000000..821ad8fb09cde --- /dev/null +++ b/src/doc/rustc/book.toml @@ -0,0 +1,5 @@ +[book] +authors = ["steveklabnik"] +multilingual = false +src = "src" +title = "The rustc book" diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md new file mode 100644 index 0000000000000..7390c82896e56 --- /dev/null +++ b/src/doc/rustc/src/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +- [Chapter 1](./chapter_1.md) diff --git a/src/doc/rustc/src/chapter_1.md b/src/doc/rustc/src/chapter_1.md new file mode 100644 index 0000000000000..b743fda354692 --- /dev/null +++ b/src/doc/rustc/src/chapter_1.md @@ -0,0 +1 @@ +# Chapter 1 From b99418d4b031d8586b6767283a8628ba5cbca1b1 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 5 Apr 2018 14:41:48 -0400 Subject: [PATCH 02/24] Add rustc book to the build system --- src/bootstrap/builder.rs | 4 ++-- src/bootstrap/doc.rs | 1 + src/bootstrap/test.rs | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 3f5ec4933d02b..16e29427c607e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -323,7 +323,7 @@ impl<'a> Builder<'a> { test::Cargotest, test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck, test::RunMakeFullDeps, test::Nomicon, test::Reference, test::RustdocBook, test::RustByExample, - test::TheBook, test::UnstableBook, + test::TheBook, test::UnstableBook, test::RustcBook, test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme, // Run run-make last, since these won't pass without make on Windows test::RunMake), @@ -331,7 +331,7 @@ impl<'a> Builder<'a> { Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, doc::Standalone, doc::Std, doc::Test, doc::WhitelistedRustc, doc::Rustc, doc::ErrorIndex, doc::Nomicon, doc::Reference, doc::Rustdoc, doc::RustByExample, - doc::CargoBook), + doc::RustcBook, doc::CargoBook), Kind::Dist => describe!(dist::Docs, dist::RustcDocs, dist::Mingw, dist::Rustc, dist::DebuggerScripts, dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo, dist::Rls, dist::Rustfmt, dist::Extended, diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 4237ded2215c2..0618d1d89aa42 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -71,6 +71,7 @@ book!( Nomicon, "src/doc/nomicon", "nomicon"; Reference, "src/doc/reference", "reference"; Rustdoc, "src/doc/rustdoc", "rustdoc"; + RustcBook, "src/doc/rustc", "rustc"; RustByExample, "src/doc/rust-by-example", "rust-by-example"; ); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c175d2c69016f..569bd84172628 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1121,6 +1121,7 @@ test_book!( Nomicon, "src/doc/nomicon", "nomicon", default=false; Reference, "src/doc/reference", "reference", default=false; RustdocBook, "src/doc/rustdoc", "rustdoc", default=true; + RustcBook, "src/doc/rustc", "rustc", default=true; RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false; TheBook, "src/doc/book", "book", default=false; UnstableBook, "src/doc/unstable-book", "unstable-book", default=true; From 7de5b6034d035f8dc85cb073b2dde3b611a3d822 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Thu, 5 Apr 2018 14:53:58 -0400 Subject: [PATCH 03/24] update doc index to link to the rustc book --- src/doc/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/index.md b/src/doc/index.md index 2ea889da1fde2..3a4f51069fc3b 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -43,6 +43,10 @@ Rust's standard library has [extensive API documentation](std/index.html), with explanations of how to use various things, as well as example code for accomplishing various tasks. +## The Rustc Book + +[The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`. + ## The Cargo Book [The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and dependency manager. From c942bf42fcb7dfb39ad68aebd0365c14818bdcfb Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 09:11:09 -0400 Subject: [PATCH 04/24] Add a TOC --- src/doc/rustc/src/SUMMARY.md | 14 ++++++++++++-- src/doc/rustc/src/chapter_1.md | 1 - src/doc/rustc/src/codegen-options/index.md | 1 + src/doc/rustc/src/command-line-arguments/index.md | 1 + src/doc/rustc/src/contributing.md | 1 + src/doc/rustc/src/lints/groups.md | 1 + src/doc/rustc/src/lints/index.md | 1 + src/doc/rustc/src/lints/levels.md | 1 + .../rustc/src/lints/listing/allowed-by-default.md | 1 + src/doc/rustc/src/lints/listing/deny-by-default.md | 1 + src/doc/rustc/src/lints/listing/index.md | 1 + src/doc/rustc/src/lints/listing/warn-by-default.md | 1 + src/doc/rustc/src/what-is-rustc.md | 1 + 13 files changed, 23 insertions(+), 3 deletions(-) delete mode 100644 src/doc/rustc/src/chapter_1.md create mode 100644 src/doc/rustc/src/codegen-options/index.md create mode 100644 src/doc/rustc/src/command-line-arguments/index.md create mode 100644 src/doc/rustc/src/contributing.md create mode 100644 src/doc/rustc/src/lints/groups.md create mode 100644 src/doc/rustc/src/lints/index.md create mode 100644 src/doc/rustc/src/lints/levels.md create mode 100644 src/doc/rustc/src/lints/listing/allowed-by-default.md create mode 100644 src/doc/rustc/src/lints/listing/deny-by-default.md create mode 100644 src/doc/rustc/src/lints/listing/index.md create mode 100644 src/doc/rustc/src/lints/listing/warn-by-default.md create mode 100644 src/doc/rustc/src/what-is-rustc.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 7390c82896e56..197ff6ac410bb 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -1,3 +1,13 @@ -# Summary +# The Rustc Book -- [Chapter 1](./chapter_1.md) +- [What is rustc?](what-is-rustc.md) +- [Command-line arguments](command-line-arguments/index.md) +- [Lints](lints/index.md) + - [Lint levels](lints/levels.md) + - [Lint Groups](lints/groups.md) + - [Lint listing](lints/listing/index.md) + - [Allowed-by-default lints](lints/listing/allowed-by-default.md) + - [Warn-by-default lints](lints/listing/warn-by-default.md) + - [Deny-by-default lints](lints/listing/deny-by-default.md) +- [Codegen options](codegen-options/index.md) +- [Contributing to `rustc`](contributing.md) \ No newline at end of file diff --git a/src/doc/rustc/src/chapter_1.md b/src/doc/rustc/src/chapter_1.md deleted file mode 100644 index b743fda354692..0000000000000 --- a/src/doc/rustc/src/chapter_1.md +++ /dev/null @@ -1 +0,0 @@ -# Chapter 1 diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md new file mode 100644 index 0000000000000..4350db56ef683 --- /dev/null +++ b/src/doc/rustc/src/codegen-options/index.md @@ -0,0 +1 @@ +# Codegen options diff --git a/src/doc/rustc/src/command-line-arguments/index.md b/src/doc/rustc/src/command-line-arguments/index.md new file mode 100644 index 0000000000000..162c0e48d4e93 --- /dev/null +++ b/src/doc/rustc/src/command-line-arguments/index.md @@ -0,0 +1 @@ +# Command-line arguments diff --git a/src/doc/rustc/src/contributing.md b/src/doc/rustc/src/contributing.md new file mode 100644 index 0000000000000..e21b6fbd14aed --- /dev/null +++ b/src/doc/rustc/src/contributing.md @@ -0,0 +1 @@ +# Contributing to rustc diff --git a/src/doc/rustc/src/lints/groups.md b/src/doc/rustc/src/lints/groups.md new file mode 100644 index 0000000000000..f35b53b6b996e --- /dev/null +++ b/src/doc/rustc/src/lints/groups.md @@ -0,0 +1 @@ +# Lint Groups diff --git a/src/doc/rustc/src/lints/index.md b/src/doc/rustc/src/lints/index.md new file mode 100644 index 0000000000000..112c576a22c76 --- /dev/null +++ b/src/doc/rustc/src/lints/index.md @@ -0,0 +1 @@ +# Lints diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md new file mode 100644 index 0000000000000..6aed1e979f34d --- /dev/null +++ b/src/doc/rustc/src/lints/levels.md @@ -0,0 +1 @@ +# Lint levels diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md new file mode 100644 index 0000000000000..19c4d94edbb52 --- /dev/null +++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md @@ -0,0 +1 @@ +# Allowed-by-default lints diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md new file mode 100644 index 0000000000000..0f6fd4fe9312c --- /dev/null +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -0,0 +1 @@ +# Deny-by-default lints diff --git a/src/doc/rustc/src/lints/listing/index.md b/src/doc/rustc/src/lints/listing/index.md new file mode 100644 index 0000000000000..e279644e6449d --- /dev/null +++ b/src/doc/rustc/src/lints/listing/index.md @@ -0,0 +1 @@ +# Lint listing diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md new file mode 100644 index 0000000000000..5342b954a09e0 --- /dev/null +++ b/src/doc/rustc/src/lints/listing/warn-by-default.md @@ -0,0 +1 @@ +# Warn-by-default lints diff --git a/src/doc/rustc/src/what-is-rustc.md b/src/doc/rustc/src/what-is-rustc.md new file mode 100644 index 0000000000000..ac4c33e4b7119 --- /dev/null +++ b/src/doc/rustc/src/what-is-rustc.md @@ -0,0 +1 @@ +# What is rustc? From 4f6ed513d11baa71d39a1a048a6ccb67846775a1 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 09:12:02 -0400 Subject: [PATCH 05/24] fix authorship in book.toml --- src/doc/rustc/book.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/book.toml b/src/doc/rustc/book.toml index 821ad8fb09cde..8adc05c513720 100644 --- a/src/doc/rustc/book.toml +++ b/src/doc/rustc/book.toml @@ -1,5 +1,5 @@ [book] -authors = ["steveklabnik"] +authors = ["The Rust Project Developers"] multilingual = false src = "src" title = "The rustc book" From 5424dc46b719a86d94578ab260798c21bc42ea7e Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 09:32:57 -0400 Subject: [PATCH 06/24] write headings for command line arguments --- src/doc/rustc/src/SUMMARY.md | 2 +- src/doc/rustc/src/command-line-arguments.md | 57 +++++++++++++++++++ .../rustc/src/command-line-arguments/index.md | 1 - 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/doc/rustc/src/command-line-arguments.md delete mode 100644 src/doc/rustc/src/command-line-arguments/index.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 197ff6ac410bb..ba70c74532732 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -1,7 +1,7 @@ # The Rustc Book - [What is rustc?](what-is-rustc.md) -- [Command-line arguments](command-line-arguments/index.md) +- [Command-line arguments](command-line-arguments.md) - [Lints](lints/index.md) - [Lint levels](lints/levels.md) - [Lint Groups](lints/groups.md) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md new file mode 100644 index 0000000000000..7ea3e806e4a58 --- /dev/null +++ b/src/doc/rustc/src/command-line-arguments.md @@ -0,0 +1,57 @@ +# Command-line arguments + +Here's a list of command-line arguments to `rustc` and what they do. + +## `-h`/`--help`: get help + +## `--cfg`: configure the compilation environment + +## `-L`: add a directory to the library search path. + +## `-l`: link the generated crate to a native library + +## `--crate-type`: a list of types of crates for the compiler to emit + +## `--crate-name`: specify the name of the crate being built + +## `--emit`: emit output other than a crate + +## `--print`: print compiler information + +## `-g`: include debug information + +## `-O`: optimize your code + +## `-o`: filename of the output + +## `--out-dir`: directory to write the output in + +## `--explain`: provide a detailed explanation of an error message + +## `--test`: build a test harness + +## `--target`: select a target triple to build + +## `-W`: set lint warnings + +## `-A`: set lint allowed + +## `-D`: set lint denied + +## `-F`: set lint forbidden + +## `--cap-lints`: set the most restrictive lint level + +## `-C`/`--codegen`: code generation options + +## `-V`/`--verision`: print a version + +## `-v`/`--verbose`: use verbose output + +## `--extern`: specify where an external library is located + +## `--sysroot`: Override the system root + +## `--error-format`: control how errors are produced + +## `--color`: configur coloring of output \ No newline at end of file diff --git a/src/doc/rustc/src/command-line-arguments/index.md b/src/doc/rustc/src/command-line-arguments/index.md deleted file mode 100644 index 162c0e48d4e93..0000000000000 --- a/src/doc/rustc/src/command-line-arguments/index.md +++ /dev/null @@ -1 +0,0 @@ -# Command-line arguments From cd553642488f0f0ca070647a080e93fe85719930 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 09:33:10 -0400 Subject: [PATCH 07/24] write 'what is rustc' --- src/doc/rustc/src/what-is-rustc.md | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/doc/rustc/src/what-is-rustc.md b/src/doc/rustc/src/what-is-rustc.md index ac4c33e4b7119..bed1b71c24e00 100644 --- a/src/doc/rustc/src/what-is-rustc.md +++ b/src/doc/rustc/src/what-is-rustc.md @@ -1 +1,68 @@ # What is rustc? + +Welcome to "The rustc book"! `rustc` is the compiler for the Rust programming +language, provided by the project itself. Compilers take your source code and +produce binary code, either as a library or executable. + +Most Rust programmers don't invoke `rustc` directly, but instead do it through +[Cargo](../cargo/index.html). It's all in service of `rustc` though! If you +want to see how Cargo calls `rustc`, you can + +```bash +$ cargo build --verbose +``` + +And it will print out each `rustc` invocation. This book can help you +understand what each of these options does. Additionally, while most +Rustaceans use Cargo, not all do: sometimes they integrate `rustc` into other +build systems. This book should provide a guide to all of the options you'd +need to do so. + +## Basic usage + +Let's say you've got a little hello world program in a file `hello.rs`: + +```rust +fn main() { + println!("Hello, world!"); +} +``` + +To turn this source code into an executable, you can use `rustc`: + +```bash +$ rustc hello.rs +$ ./hello # on a *NIX +$ .\hello.exe # on Windows +``` + +Note that we only ever pass `rustc` the *crate root*, not every file we wish +to compile. For example, if we had a `main.rs` that looked like this: + +```rust,ignore +mod foo; + +fn main() { + foo::hello(); +} +``` + +And a `foo.rs` that had this: + +```rust,ignore +fn hello() { + println!("Hello, world!"); +} +``` + +To compile this, we'd run this command: + +```bash +$ rustc main.rs +``` + +No need to tell `rustc` about `foo.rs`; the `mod` statements give it +everything that it needs. This is different than how you would use a C +compiler, where you invoke the compiler on each file, and then link +everything together. In other words, the *crate* is a translation unit, not a +particular module. \ No newline at end of file From 78b076dadb0d8ac51be84ab3748e71a70abffa90 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 09:33:26 -0400 Subject: [PATCH 08/24] add targets to TOC --- src/doc/rustc/src/SUMMARY.md | 3 +++ src/doc/rustc/src/targets/built-in.md | 1 + src/doc/rustc/src/targets/custom.md | 1 + src/doc/rustc/src/targets/index.md | 1 + 4 files changed, 6 insertions(+) create mode 100644 src/doc/rustc/src/targets/built-in.md create mode 100644 src/doc/rustc/src/targets/custom.md create mode 100644 src/doc/rustc/src/targets/index.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index ba70c74532732..e4c0939fd4636 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -10,4 +10,7 @@ - [Warn-by-default lints](lints/listing/warn-by-default.md) - [Deny-by-default lints](lints/listing/deny-by-default.md) - [Codegen options](codegen-options/index.md) +- [Targets](targets/index.md) + - [Built-in Targets](targets/built-in.md) + - [Custom Targets](targets/custom.md) - [Contributing to `rustc`](contributing.md) \ No newline at end of file diff --git a/src/doc/rustc/src/targets/built-in.md b/src/doc/rustc/src/targets/built-in.md new file mode 100644 index 0000000000000..819d74457fe51 --- /dev/null +++ b/src/doc/rustc/src/targets/built-in.md @@ -0,0 +1 @@ +# Built-in Targets diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md new file mode 100644 index 0000000000000..59039ce67bad9 --- /dev/null +++ b/src/doc/rustc/src/targets/custom.md @@ -0,0 +1 @@ +# Custom Targets diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md new file mode 100644 index 0000000000000..01d0a4c8c0e3b --- /dev/null +++ b/src/doc/rustc/src/targets/index.md @@ -0,0 +1 @@ +# Targets From 50b3a3d1216fd68b483c88b603ec6c742e51c054 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 12:32:16 -0400 Subject: [PATCH 09/24] add a lot of text about lints --- src/doc/rustc/src/lints/groups.md | 28 ++ src/doc/rustc/src/lints/index.md | 27 ++ src/doc/rustc/src/lints/levels.md | 251 ++++++++++ .../src/lints/listing/allowed-by-default.md | 451 ++++++++++++++++++ .../src/lints/listing/deny-by-default.md | 15 + src/doc/rustc/src/lints/listing/index.md | 4 + .../src/lints/listing/warn-by-default.md | 48 ++ 7 files changed, 824 insertions(+) diff --git a/src/doc/rustc/src/lints/groups.md b/src/doc/rustc/src/lints/groups.md index f35b53b6b996e..46b717f3387d2 100644 --- a/src/doc/rustc/src/lints/groups.md +++ b/src/doc/rustc/src/lints/groups.md @@ -1 +1,29 @@ # Lint Groups + +`rustc` has the concept of a "lint group", where you can toggle several warnings +through one name. + +For example, the `nonstandard-style` lint sets `non-camel-case-types`, +`non-snake-case`, and `non-upper-case-globals` all at once. So these are +equivalent: + +```bash +$ rustc -D nonstandard-style +$ rustc -D non-camel-case-types -D non-snake-case -D non-upper-case-globals +``` + +Here's a list of each lint group, and the lints that they are made up of: + +| group | description | lints | +|---------------------|---------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| nonstandard-style | Violation of standard naming conventions | non-camel-case-types, non-snake-case, non-upper-case-globals | +| warnings | all lints that would be issuing warnings | all lints that would be issuing warnings | +| edition-2018 | Lints that will be turned into errors in Rust 2018 | tyvar-behind-raw-pointer | +| rust-2018-idioms | Lints to nudge you toward idiomatic features of Rust 2018 | bare-trait-object, unreachable-pub | +| unused | These lints detect things being declared but not used | unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-allocation, unused-doc-comment, unused-extern-crates, unused-features, unused-parens | +| future-incompatible | Lints that detect code that has future-compatibility problems | private-in-public, pub-use-of-private-extern-crate, patterns-in-fns-without-body, safe-extern-statics, invalid-type-param-default, legacy-directory-ownership, legacy-imports, legacy-constructor-visibility, missing-fragment-specifier, illegal-floating-point-literal-pattern, anonymous-parameters, parenthesized-params-in-types-and-modules, late-bound-lifetime-arguments, safe-packed-borrows, incoherent-fundamental-impls, tyvar-behind-raw-pointer, unstable-name-collision | + +Additionally, there's a `bad-style` lint group that's a deprecated alias for `nonstandard-style`. + +Finally, you can also see the table above by invoking `rustc -W help`. This will give you the exact values for the specific +compiler you have installed. \ No newline at end of file diff --git a/src/doc/rustc/src/lints/index.md b/src/doc/rustc/src/lints/index.md index 112c576a22c76..4706a10c908ee 100644 --- a/src/doc/rustc/src/lints/index.md +++ b/src/doc/rustc/src/lints/index.md @@ -1 +1,28 @@ # Lints + +In software, a "lint" is a tool used to help improve your source code. The +Rust compiler contains a number of lints, and when it compiles your code, it will +also run the lints. These lints may produce a warning, an error, or nothing at all, +depending on how you've configured things. + +Here's a small example: + +```rust +$ cat main.rs +fn main() { + let x = 5; +} +> rustc main.rs +warning: unused variable: `x` + --> main.rs:2:9 + | +2 | let x = 5; + | ^ + | + = note: #[warn(unused_variables)] on by default + = note: to avoid this warning, consider using `_x` instead +``` + +This is the `unused_variables` lint, and it tells you that you've introduced +a variable that you don't use in your code. That's not *wrong*, so it's not +an error, but it might be a bug, so you get a warning. \ No newline at end of file diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 6aed1e979f34d..f2d7241e648a4 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -1 +1,252 @@ # Lint levels + +In `rustc`, lints are divided into four *levels*: + +1. allow +2. warn +3. deny +4. forbid + +Each lint has a default level (explained in the lint listing later in this +chapter), and the compiler has a default warning level. First, let's explain +what these levels mean, and then we'll talk about configuration. + +## allow + +These lints exist, but by default, do nothing. For example, consider this +source: + +```rust +pub fn foo() {} +``` + +Compiling this file produces no warnings: + +```rust +$ rustc lib.rs --crate-type=lib +$ +``` + +But this code violates the `missing_docs` lint. + +These lints exist mostly to be manually turned on via configuration, as we'll +talk about later in this section. + +## warn + +The 'warn' lint level will produce a warning if you violate the lint. For example, +this code runs afoul of the `unused_variable` lint: + +```rust +pub fn foo() { + let x = 5; +} +``` + +This will produce this warning: + +```bash +> rustc lib.rs --crate-type=lib +warning: unused variable: `x` + --> lib.rs:2:9 + | +2 | let x = 5; + | ^ + | + = note: #[warn(unused_variables)] on by default + = note: to avoid this warning, consider using `_x` instead +``` + +## deny + +A 'deny' lint produces an error if you violate it. For example, this code +runs into the `exceeding_bitshifts` lint. + +```rust +fn main() { + 100u8 << 10; +} +``` + +```bash +> rustc main.rs +error: bitshift exceeds the type's number of bits + --> main.rs:2:13 + | +2 | 100u8 << 10; + | ^^^^^^^^^^^ + | + = note: #[deny(exceeding_bitshifts)] on by default +``` + +What's the difference between an error from a lint and a regular old error? +Lints are configurable via levels, so in a similar way to 'allow' lints, +warnings that are 'deny' by default let you allow them. Similarly, you may +wish to set up a lint that is `warn` by default to produce an error instead. +This lint level gives you that. + +## forbid + +'forbid' is a special lint level that's stronger than 'deny'. It's the same +as 'deny' in that a lint at this level will produce an error, but unlike the +'deny' level, the 'forbid' level can not be overridden to be anything lower +than an error. + +## Configuring warning levels + +Remember our `missing_docs` example from the 'allow' lint level? + +```bash +$ cat lib.rs +pub fn foo() {} +$ rustc lib.rs --crate-type=lib +$ +``` + +We can configure this lint to operate at a higher level, both with +compiler flags, as well as with an attribute in the source code. + +You can also "cap" lints so that the compiler can choose to ignore +certain lint levels. We'll talk about that last. + +### Via compiler flag + +The `-A`, `-W`, `-D`, and `-F` flags let you turn one or more lints +into allowed, warning, deny, or forbid levels, like this: + +```bash +$ rustc lib.rs --crate-type=lib -W missing-docs +warning: missing documentation for crate + --> lib.rs:1:1 + | +1 | pub fn foo() {} + | ^^^^^^^^^^^^ + | + = note: requested on the command line with `-W missing-docs` + +warning: missing documentation for a function + --> lib.rs:1:1 + | +1 | pub fn foo() {} + | ^^^^^^^^^^^^ +> rustc lib.rs --crate-type=lib -D missing-docs +error: missing documentation for crate + --> lib.rs:1:1 + | +1 | pub fn foo() {} + | ^^^^^^^^^^^^ + | + = note: requested on the command line with `-D missing-docs` + +error: missing documentation for a function + --> lib.rs:1:1 + | +1 | pub fn foo() {} + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors +``` + +You can also pass each flag more than once for changing multiple lints: + +```bash +rustc lib.rs --crate-type=lib -D missing-docs -D unused-variables +``` + +And of course, you can mix these four flags together: + +```bash +rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables +``` + +### Via an attribute + +You can also modify the lint level with a crate-wide attribute: + +```bash +> cat lib.rs +#![warn(missing_docs)] + +pub fn foo() {} +$ rustc lib.rs --crate-type=lib +warning: missing documentation for crate + --> lib.rs:1:1 + | +1 | / #![warn(missing_docs)] +2 | | +3 | | pub fn foo() {} + | |_______________^ + | +note: lint level defined here + --> lib.rs:1:9 + | +1 | #![warn(missing_docs)] + | ^^^^^^^^^^^^ + +warning: missing documentation for a function + --> lib.rs:3:1 + | +3 | pub fn foo() {} + | ^^^^^^^^^^^^ +``` + +All four, `warn`, `allow`, `deny`, and `forbid` all work this way. + +You can also pass in multiple lints per attribute: + +```rust +#![warn(missing_docs, unused_variables)] + +pub fn foo() {} +``` + +And use multiple attributes together: + +```rust +#![warn(missing_docs)] +#![deny(unused_variables)] + +pub fn foo() {} +``` + +### Capping lints + +`rustc` supports a flag, `--cap-lints LEVEL` that sets the "lint cap level." +This is the maximum level for all lints. So for example, if we take our +code sample from the "deny" lint level above: + +```rust +fn main() { + 100u8 << 10; +} +``` + +And we compile it, capping lints to warn: + +```bash +$ rustc lib.rs --cap-lints warn +warning: bitshift exceeds the type's number of bits + --> lib.rs:2:5 + | +2 | 100u8 << 10; + | ^^^^^^^^^^^ + | + = note: #[warn(exceeding_bitshifts)] on by default + +warning: this expression will panic at run-time + --> lib.rs:2:5 + | +2 | 100u8 << 10; + | ^^^^^^^^^^^ attempt to shift left with overflow +``` + +It now only warns, rather than errors. We can go further and allow all lints: + +```bash +$ rustc lib.rs --cap-lints allow +$ +``` + +This feature is used heavily by Cargo; it will pass `--cap-lints allow` when +compiling your dependencies, so that if they have any warnings, they do not +pollute the output of your build. \ No newline at end of file diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md index 19c4d94edbb52..61c7c5e88969e 100644 --- a/src/doc/rustc/src/lints/listing/allowed-by-default.md +++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md @@ -1 +1,452 @@ # Allowed-by-default lints + +These lints are all set to the 'allow' level by default. As such, they won't show up +unless you set them to a higher lint level with a flag or attribute. + +## anonymous-parameters + +This lint detects anonymous parameters. Some example code that triggers this lint: + +```rust +trait Foo { + fn foo(usize); +} +``` + +When set to 'deny', this will produce: + +```text +error: use of deprecated anonymous parameter + --> src/lib.rs:5:11 + | +5 | fn foo(usize); + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41686 +``` + +This syntax is mostly a historical accident, and can be worked around quite +easily: + +```rust +trait Foo { + fn foo(_: usize); +} +``` + +## bare-trait-object + +This lint suggests using `dyn Trait` for trait objects. Some example code +that triggers this lint: + +```rust +#![feature(dyn_trait)] + +trait Trait { } + +fn takes_trait_object(_: Box) { +} +``` + +When set to 'deny', this will produce: + +```text +error: trait objects without an explicit `dyn` are deprecated + --> src/lib.rs:7:30 + | +7 | fn takes_trait_object(_: Box) { + | ^^^^^ help: use `dyn`: `dyn Trait` + | +``` + +To fix it, do as the help message suggests: + +```rust +#![feature(dyn_trait)] +#![deny(bare_trait_object)] + +trait Trait { } + +fn takes_trait_object(_: Box) { +} +``` + +## box-pointers + +This lints use of the Box type. Some example code that triggers this lint: + +```rust +struct Foo { + x: Box, +} +``` + +When set to 'deny', this will produce: + +```text +error: type uses owned (Box type) pointers: std::boxed::Box + --> src/lib.rs:6:5 + | +6 | x: Box //~ ERROR type uses owned + | ^^^^^^^^^^^^^ + | +``` + +This lint is mostly historical, and not particularly useful. `Box` used to +be built into the language, and the only way to do heap allocation. Today's +Rust can call into other allocators, etc. + +## elided-lifetime-in-path + +This lint detects the use of hidden lifetime parameters. Some example code +that triggers this lint: + +```rust +struct Foo<'a> { + x: &'a u32 +} + +fn foo(x: &Foo) { +} +``` + +When set to 'deny', this will produce: + +```text +error: hidden lifetime parameters are deprecated, try `Foo<'_>` + --> src/lib.rs:5:12 + | +5 | fn foo(x: &Foo) { + | ^^^ + | +``` + +Lifetime elision elides this lifetime, but that is being deprecated. + +## missing-copy-implementations + +This lint detects potentially-forgotten implementations of `Copy`. Some +example code that triggers this lint: + +```rust +pub struct Foo { + pub field: i32 +} +``` + +When set to 'deny', this will produce: + +```text +error: type could implement `Copy`; consider adding `impl Copy` + --> src/main.rs:3:1 + | +3 | / pub struct Foo { //~ ERROR type could implement `Copy`; consider adding `impl Copy` +4 | | pub field: i32 +5 | | } + | |_^ + | +``` + +You can fix the lint by deriving `Copy`. + +This lint is set to 'allow' because this code isn't bad; it's common to write +newtypes like this specifically so that a `Copy` type is no longer `Copy`. + +## missing-debug-implementations + +This lint detects missing implementations of `fmt::Debug`. Some example code +that triggers this lint: + +```rust +pub struct Foo; +``` + +When set to 'deny', this will produce: + +```text +error: type does not implement `fmt::Debug`; consider adding #[derive(Debug)] or a manual implementation + --> src/main.rs:3:1 + | +3 | pub struct Foo; + | ^^^^^^^^^^^^^^^ + | +``` + +You can fix the lint by deriving `Debug`. + +## missing-docs + +This lint detects missing documentation for public items. Some example code +that triggers this lint: + +```rust +pub fn foo() {} +``` + +When set to 'deny', this will produce: + +```text +error: missing documentation for crate + --> src/main.rs:1:1 + | +1 | / #![deny(missing_docs)] +2 | | +3 | | pub fn foo() {} +4 | | +5 | | fn main() {} + | |____________^ + | + +error: missing documentation for a function + --> src/main.rs:3:1 + | +3 | pub fn foo() {} + | ^^^^^^^^^^^^ + +``` + +To fix the lint, add documentation to all items. + +## single-use-lifetime + +This lint detects lifetimes that are only used once. Some example code that +triggers this lint: + +```rust +struct Foo<'x> { + x: &'x u32 +} +``` + +When set to 'deny', this will produce: + +```text +error: lifetime name `'x` only used once + --> src/main.rs:3:12 + | +3 | struct Foo<'x> { + | ^^ + | +``` + +## trivial-casts + +This lint detects trivial casts which could be removed. Some example code +that triggers this lint: + +```rust +let x: &u32 = &42; +let _ = x as *const u32; +``` + +When set to 'deny', this will produce: + +```text +error: trivial cast: `&u32` as `*const u32`. Cast can be replaced by coercion, this might require type ascription or a temporary variable + --> src/main.rs:5:13 + | +5 | let _ = x as *const u32; + | ^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> src/main.rs:1:9 + | +1 | #![deny(trivial_casts)] + | ^^^^^^^^^^^^^ +``` + +## trivial-numeric-casts + +This lint detects trivial casts of numeric types which could be removed. Some +example code that triggers this lint: + +```rust +let x = 42i32 as i32; +``` + +When set to 'deny', this will produce: + +```text +error: trivial numeric cast: `i32` as `i32`. Cast can be replaced by coercion, this might require type ascription or a temporary variable + --> src/main.rs:4:13 + | +4 | let x = 42i32 as i32; + | ^^^^^^^^^^^^ + | +``` + +## unreachable-pub + +This lint triggers for `pub` items not reachable from the crate root. Some +example code that triggers this lint: + +```rust +mod foo { + pub mod bar { + + } +} +``` + +When set to 'deny', this will produce: + +```text +error: unreachable `pub` item + --> src/main.rs:4:5 + | +4 | pub mod bar { + | ---^^^^^^^^ + | | + | help: consider restricting its visibility: `pub(crate)` + | +``` + +## unsafe-code + +This lint catches usage of `unsafe` code. Some example code that triggers this lint: + +```rust +fn main() { + unsafe { + + } +} +``` + +When set to 'deny', this will produce: + +```text +error: usage of an `unsafe` block + --> src/main.rs:4:5 + | +4 | / unsafe { +5 | | +6 | | } + | |_____^ + | +``` + +## unstable-features + +This lint is deprecated and no longer used. + +## unused-extern-crates + +This lint guards against `extern crate` items that are never used. Some +example code that triggers this lint: + +```rust +extern crate semver; +``` + +When set to 'deny', this will produce: + +```text +error: unused extern crate + --> src/main.rs:3:1 + | +3 | extern crate semver; + | ^^^^^^^^^^^^^^^^^^^^ + | +``` + +## unused-import-braces + +This lint catches unnecessary braces around an imported item. Some example +code that triggers this lint: + +```rust +use test::{A}; + +mod test { + struct A; +} +``` + +When set to 'deny', this will produce: + +```text +error: braces around A is unnecessary + --> src/main.rs:3:1 + | +3 | use test::{A}; + | ^^^^^^^^^^^^^^ + | +``` + +To fix it, `use test::A;` + +## unused-qualifications + +This lint detects unnecessarily qualified names. Some example code that triggers this lint: + +```rust +mod foo { + pub fn bar() {} +} + +fn main() { + use foo::bar; + foo::bar(); +} +``` + +When set to 'deny', this will produce: + +```text +error: unnecessary qualification + --> src/main.rs:9:5 + | +9 | foo::bar(); + | ^^^^^^^^ + | +``` + +You can call `bar()` directly, without the `foo::`. + +## unused-results + +This lint checks for the unused result of an expression in a statement. Some +example code that triggers this lint: + +```rust +fn foo() -> T { panic!() } + +fn main() { + foo::(); +} +``` + +When set to 'deny', this will produce: + +```text +error: unused result + --> src/main.rs:6:5 + | +6 | foo::(); + | ^^^^^^^^^^^^^^^ + | +``` + +## variant-size-differences + +This lint detects enums with widely varying variant sizes. Some example code that triggers this lint: + +```rust +enum En { + V0(u8), + VBig([u8; 1024]), //~ ERROR variant is more than three times larger +} +``` + +When set to 'deny', this will produce: + +```text +error: enum variant is more than three times larger (1024 bytes) than the next largest + --> src/main.rs:5:5 + | +5 | VBig([u8; 1024]), //~ ERROR variant is more than three times larger + | ^^^^^^^^^^^^^^^^ + | +``` \ No newline at end of file diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index 0f6fd4fe9312c..54e857c885dbe 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -1 +1,16 @@ # Deny-by-default lints + +These lints are all set to the 'deny' level by default. + + exceeding-bitshifts deny shift exceeds the type's number of bits + invalid-type-param-default deny type parameter default erroneously allowed in invalid location + legacy-constructor-visibility deny detects use of struct constructors that would be invisible with new visibility rules + legacy-directory-ownership deny non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files not named `mod.rs` + legacy-imports deny detects names that resolve to ambiguous glob imports with RFC 1560 + missing-fragment-specifier deny detects missing fragment specifiers in unused `macro_rules!` patterns + mutable-transmutes deny mutating transmuted &mut T from &T may cause undefined behavior + no-mangle-const-items deny const items will not have their symbols exported + parenthesized-params-in-types-and-modules deny detects parenthesized generic parameters in type and module names + pub-use-of-private-extern-crate deny detect public re-exports of private extern crates + safe-extern-statics deny safe access to extern statics was erroneously allowed + unknown-crate-types deny unknown crate type found in #[crate_type] directive \ No newline at end of file diff --git a/src/doc/rustc/src/lints/listing/index.md b/src/doc/rustc/src/lints/listing/index.md index e279644e6449d..18cd2fe32a3cc 100644 --- a/src/doc/rustc/src/lints/listing/index.md +++ b/src/doc/rustc/src/lints/listing/index.md @@ -1 +1,5 @@ # Lint listing + +This section lists out all of the lints, grouped by their default lint levels. + +You can also see this list by running `rustc -W help`. \ No newline at end of file diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md index 5342b954a09e0..531cf7606b1ff 100644 --- a/src/doc/rustc/src/lints/listing/warn-by-default.md +++ b/src/doc/rustc/src/lints/listing/warn-by-default.md @@ -1 +1,49 @@ # Warn-by-default lints + +These lints are all set to the 'warn' level by default. + + const-err warn constant evaluation detected erroneous expression + dead-code warn detect unused, unexported items + deprecated warn detects use of deprecated items + illegal-floating-point-literal-pattern warn floating-point literals cannot be used in patterns + improper-ctypes warn proper use of libc types in foreign modules + incoherent-fundamental-impls warn potentially-conflicting impls were erroneously allowed + late-bound-lifetime-arguments warn detects generic lifetime arguments in path segments with late bound lifetime parameters + non-camel-case-types warn types, variants, traits and type parameters should have camel case names + non-shorthand-field-patterns warn using `Struct { x: x }` instead of `Struct { x }` in a pattern + non-snake-case warn variables, methods, functions, lifetime parameters and modules should have snake case names + non-upper-case-globals warn static constants should have uppercase identifiers + no-mangle-generic-items warn generic items must be mangled + overflowing-literals warn literal out of range for its type + path-statements warn path statements with no effect + patterns-in-fns-without-body warn patterns in functions without body were erroneously allowed + plugin-as-library warn compiler plugin used as ordinary library in non-plugin crate + private-in-public warn detect private items in public interfaces not caught by the old implementation + private-no-mangle-fns warn functions marked #[no_mangle] should be exported + private-no-mangle-statics warn statics marked #[no_mangle] should be exported + renamed-and-removed-lints warn lints that have been renamed or removed + safe-packed-borrows warn safe borrows of fields of packed structs were was erroneously allowed + stable-features warn stable features found in #[feature] directive + type-alias-bounds warn bounds in type aliases are not enforced + tyvar-behind-raw-pointer warn raw pointer to an inference variable + unconditional-recursion warn functions that cannot return without calling themselves + unions-with-drop-fields warn use of unions that contain fields with possibly non-trivial drop code + unknown-lints warn unrecognized lint attribute + unreachable-code warn detects unreachable code paths + unreachable-patterns warn detects unreachable patterns + unstable-name-collision warn detects name collision with an existing but unstable method + unused-allocation warn detects unnecessary allocations that can be eliminated + unused-assignments warn detect assignments that will never be read + unused-attributes warn detects attributes that were not used by the compiler + unused-comparisons warn comparisons made useless by limits of the types involved + unused-doc-comment warn detects doc comments that aren't used by rustdoc + unused-features warn unused or unknown features found in crate-level #[feature] directives + unused-imports warn imports that are never used + unused-macros warn detects macros that were not used + unused-must-use warn unused result of a type flagged as #[must_use] + unused-mut warn detect mut variables which don't need to be mutable + unused-parens warn `if`, `match`, `while` and `return` do not need parentheses + unused-unsafe warn unnecessary use of an `unsafe` block + unused-variables warn detect variables which are not used in any way + warnings warn mass-change the level for lints which produce warnings + while-true warn suggest using `loop { }` instead of `while true { }` \ No newline at end of file From df81ca37645835d41ae67d9f8e682244f40d53e7 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 13:08:33 -0400 Subject: [PATCH 10/24] document deny by default lints --- .../src/lints/listing/deny-by-default.md | 249 +++++++++++++++++- 1 file changed, 237 insertions(+), 12 deletions(-) diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index 54e857c885dbe..a361c117b10c9 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -2,15 +2,240 @@ These lints are all set to the 'deny' level by default. - exceeding-bitshifts deny shift exceeds the type's number of bits - invalid-type-param-default deny type parameter default erroneously allowed in invalid location - legacy-constructor-visibility deny detects use of struct constructors that would be invisible with new visibility rules - legacy-directory-ownership deny non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files not named `mod.rs` - legacy-imports deny detects names that resolve to ambiguous glob imports with RFC 1560 - missing-fragment-specifier deny detects missing fragment specifiers in unused `macro_rules!` patterns - mutable-transmutes deny mutating transmuted &mut T from &T may cause undefined behavior - no-mangle-const-items deny const items will not have their symbols exported - parenthesized-params-in-types-and-modules deny detects parenthesized generic parameters in type and module names - pub-use-of-private-extern-crate deny detect public re-exports of private extern crates - safe-extern-statics deny safe access to extern statics was erroneously allowed - unknown-crate-types deny unknown crate type found in #[crate_type] directive \ No newline at end of file +## exceeding-bitshifts + +This lint detects that a shift exceeds the type's number of bits. Some +example code that triggers this lint: + +```rust +1_i32 << 32; +``` + +This will produce: + +```text +error: bitshift exceeds the type's number of bits + --> src/main.rs:2:5 + | +2 | 1_i32 << 32; + | ^^^^^^^^^^^ + | +``` + +## invalid-type-param-default + +This lint detects type parameter default erroneously allowed in invalid location. Some +example code that triggers this lint: + +```rust +fn foo(t: T) {} +``` + +This will produce: + +```text +error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions. + --> src/main.rs:4:8 + | +4 | fn foo(t: T) {} + | ^ + | + = note: #[deny(invalid_type_param_default)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 +``` + +## legacy-constructor-visibility + +[RFC 1506](https://github.com/rust-lang/rfcs/blob/master/text/1506-adt-kinds.md) modified some +visibility rules, and changed the visibility of struct constructors. Some +example code that triggers this lint: + +```rust +mod m { + pub struct S(u8); + + fn f() { + // this is trying to use S from the 'use' line, but becuase the `u8` is + // not pub, it is private + ::S; + } +} + +use m::S; +``` + +This will produce: + +```text +error: private struct constructors are not usable through re-exports in outer modules + --> src/main.rs:5:9 + | +5 | ::S; + | ^^^ + | + = note: #[deny(legacy_constructor_visibility)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #39207 +``` + + +## legacy-directory-ownership + +The legacy_directory_ownership warning is issued when + +* There is a non-inline module with a #[path] attribute (e.g. #[path = "foo.rs"] mod bar;), +* The module's file ("foo.rs" in the above example) is not named "mod.rs", and +* The module's file contains a non-inline child module without a #[path] attribute. + +The warning can be fixed by renaming the parent module to "mod.rs" and moving +it into its own directory if appropriate. + +## legacy-imports + +This lint detects names that resolve to ambiguous glob imports. Some example +code that triggers this lint: + +```rust +pub struct Foo; + +mod bar { + struct Foo; + + mod baz { + use *; + use bar::*; + fn f(_: Foo) {} + } +} +``` + +This will produce: + +```text +error: `Foo` is ambiguous + --> src/main.rs:9:17 + | +7 | use *; + | - `Foo` could refer to the name imported here +8 | use bar::*; + | ------ `Foo` could also refer to the name imported here +9 | fn f(_: Foo) {} + | ^^^ + | + = note: #[deny(legacy_imports)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #38260 +``` + + +## missing-fragment-specifier + +The missing_fragment_specifier warning is issued when an unused pattern in a +`macro_rules!` macro definition has a meta-variable (e.g. `$e`) that is not +followed by a fragment specifier (e.g. `:expr`). + +This warning can always be fixed by removing the unused pattern in the +`macro_rules!` macro definition. + +## mutable-transmutes + +This lint catches transmuting from `&T` to `&mut T` becuase it is undefined +behavior. Some example code that triggers this lint: + +```rust +unsafe { + let y = std::mem::transmute::<&i32, &mut i32>(&5); +} +``` + +This will produce: + +```text +error: mutating transmuted &mut T from &T may cause undefined behavior, consider instead using an UnsafeCell + --> src/main.rs:3:17 + | +3 | let y = std::mem::transmute::<&i32, &mut i32>(&5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +``` + + +## no-mangle-const-items + +This lint detects any `const` items with the `#[no_mangle]` attribute. +Constants do not have their symbols exported, and therefore, this probably +means you meant to use a `static`, not a `const. Some example code that +triggers this lint: + +```rust +#[no_mangle] +const FOO: i32 = 5; +``` + +This will produce: + +```text +error: const items should never be #[no_mangle] + --> src/main.rs:3:1 + | +3 | const FOO: i32 = 5; + | -----^^^^^^^^^^^^^^ + | | + | help: try a static value: `pub static` + | +``` + +## parenthesized-params-in-types-and-modules + +This lint detects incorrect parentheses. Some example code that triggers this +lint: + +```rust +let x = 5 as usize(); +``` + +This will produce: + +```text +error: parenthesized parameters may only be used with a trait + --> src/main.rs:2:21 + | +2 | let x = 5 as usize(); + | ^^ + | + = note: #[deny(parenthesized_params_in_types_and_modules)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #42238 +``` + +To fix it, remove the `()`s. + +## pub-use-of-private-extern-crate + +This lint detects a specific situation of re-exporting a private `extern crate`; + +## safe-extern-statics + +In older versions of Rust, there was a soundness issue where `extern static`s were allowed +to be accessed in safe code. This lint now catches and denies this kind of code. + +## unknown-crate-types + +This lint detects an unknown crate type found in a `#[crate_type]` directive. Some +example code that triggers this lint: + +```rust +#![crate_type="lol"] +``` + +This will produce: + +```text +error: invalid `crate_type` value + --> src/lib.rs:1:1 + | +1 | #![crate_type="lol"] + | ^^^^^^^^^^^^^^^^^^^^ + | +``` \ No newline at end of file From 758a77d46c684fc646e8ec08065d23eb53c6444d Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 15:06:53 -0400 Subject: [PATCH 11/24] more lints --- .../src/lints/listing/allowed-by-default.md | 2 +- .../src/lints/listing/warn-by-default.md | 1079 ++++++++++++++++- 2 files changed, 1035 insertions(+), 46 deletions(-) diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md index 61c7c5e88969e..a432c00e0609a 100644 --- a/src/doc/rustc/src/lints/listing/allowed-by-default.md +++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md @@ -436,7 +436,7 @@ This lint detects enums with widely varying variant sizes. Some example code tha ```rust enum En { V0(u8), - VBig([u8; 1024]), //~ ERROR variant is more than three times larger + VBig([u8; 1024]), } ``` diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md index 531cf7606b1ff..a8f3400687c2a 100644 --- a/src/doc/rustc/src/lints/listing/warn-by-default.md +++ b/src/doc/rustc/src/lints/listing/warn-by-default.md @@ -2,48 +2,1037 @@ These lints are all set to the 'warn' level by default. - const-err warn constant evaluation detected erroneous expression - dead-code warn detect unused, unexported items - deprecated warn detects use of deprecated items - illegal-floating-point-literal-pattern warn floating-point literals cannot be used in patterns - improper-ctypes warn proper use of libc types in foreign modules - incoherent-fundamental-impls warn potentially-conflicting impls were erroneously allowed - late-bound-lifetime-arguments warn detects generic lifetime arguments in path segments with late bound lifetime parameters - non-camel-case-types warn types, variants, traits and type parameters should have camel case names - non-shorthand-field-patterns warn using `Struct { x: x }` instead of `Struct { x }` in a pattern - non-snake-case warn variables, methods, functions, lifetime parameters and modules should have snake case names - non-upper-case-globals warn static constants should have uppercase identifiers - no-mangle-generic-items warn generic items must be mangled - overflowing-literals warn literal out of range for its type - path-statements warn path statements with no effect - patterns-in-fns-without-body warn patterns in functions without body were erroneously allowed - plugin-as-library warn compiler plugin used as ordinary library in non-plugin crate - private-in-public warn detect private items in public interfaces not caught by the old implementation - private-no-mangle-fns warn functions marked #[no_mangle] should be exported - private-no-mangle-statics warn statics marked #[no_mangle] should be exported - renamed-and-removed-lints warn lints that have been renamed or removed - safe-packed-borrows warn safe borrows of fields of packed structs were was erroneously allowed - stable-features warn stable features found in #[feature] directive - type-alias-bounds warn bounds in type aliases are not enforced - tyvar-behind-raw-pointer warn raw pointer to an inference variable - unconditional-recursion warn functions that cannot return without calling themselves - unions-with-drop-fields warn use of unions that contain fields with possibly non-trivial drop code - unknown-lints warn unrecognized lint attribute - unreachable-code warn detects unreachable code paths - unreachable-patterns warn detects unreachable patterns - unstable-name-collision warn detects name collision with an existing but unstable method - unused-allocation warn detects unnecessary allocations that can be eliminated - unused-assignments warn detect assignments that will never be read - unused-attributes warn detects attributes that were not used by the compiler - unused-comparisons warn comparisons made useless by limits of the types involved - unused-doc-comment warn detects doc comments that aren't used by rustdoc - unused-features warn unused or unknown features found in crate-level #[feature] directives - unused-imports warn imports that are never used - unused-macros warn detects macros that were not used - unused-must-use warn unused result of a type flagged as #[must_use] - unused-mut warn detect mut variables which don't need to be mutable - unused-parens warn `if`, `match`, `while` and `return` do not need parentheses - unused-unsafe warn unnecessary use of an `unsafe` block - unused-variables warn detect variables which are not used in any way - warnings warn mass-change the level for lints which produce warnings - while-true warn suggest using `loop { }` instead of `while true { }` \ No newline at end of file +## const-err + +This lint detects an erroneous expression while doing constant evaluation. Some +example code that triggers this lint: + +```rust +let b = 200u8 + 200u8; +``` + +This will produce: + +```text +warning: attempt to add with overflow + --> src/main.rs:2:9 + | +2 | let b = 200u8 + 200u8; + | ^^^^^^^^^^^^^ + | +``` + +## dead-code + +This lint detects detect unused, unexported items. Some +example code that triggers this lint: + +```rust +fn foo() {} +``` + +This will produce: + +```text +warning: function is never used: `foo` + --> src/lib.rs:2:1 + | +2 | fn foo() {} + | ^^^^^^^^ + | +``` + +## deprecated + +This lint detects detects use of deprecated items. Some +example code that triggers this lint: + +```rust +#[deprecated] +fn foo() {} + +fn bar() { + foo(); +} +``` + +This will produce: + +```text +warning: use of deprecated item 'foo' + --> src/lib.rs:7:5 + | +7 | foo(); + | ^^^ + | +``` + +## illegal-floating-point-literal-pattern + +This lint detects floating-point literals used in patterns. Some example code +that triggers this lint: + +```rust +let x = 42.0; + +match x { + 5.0 => {}, + _ => {}, +} +``` + +This will produce: + +```text +warning: floating-point literals cannot be used in patterns + --> src/main.rs:4:9 + | +4 | 5.0 => {}, + | ^^^ + | + = note: #[warn(illegal_floating_point_literal_pattern)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 +``` + +## improper-ctypes + +This lint detects proper use of libc types in foreign modules. Some +example code that triggers this lint: + +```rust +extern "C" { + static STATIC: String; +} +``` + +This will produce: + +```text +warning: found struct without foreign-function-safe representation annotation in foreign module, consider adding a #[repr(C)] attribute to the type + --> src/main.rs:2:20 + | +2 | static STATIC: String; + | ^^^^^^ + | +``` + +## incoherent-fundamental-impls + +This lint detects potentially-conflicting impls that were erroneously allowed. Some +example code that triggers this lint: + +```rust +pub trait Trait1 { + type Output; +} + +pub trait Trait2 {} + +pub struct A; + +impl Trait1 for T where T: Trait2 { + type Output = (); +} + +impl Trait1> for A { + type Output = i32; +} +``` + +This will produce: + +```text +warning: conflicting implementations of trait `Trait1>` for type `A`: (E0119) + --> src/main.rs:13:1 + | +9 | impl Trait1 for T where T: Trait2 { + | --------------------------------------------- first implementation here +... +13 | impl Trait1> for A { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A` + | + = note: #[warn(incoherent_fundamental_impls)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #46205 + = note: downstream crates may implement trait `Trait2>` for type `A` +``` + +## late-bound-lifetime-arguments + +This lint detects detects generic lifetime arguments in path segments with +late bound lifetime parameters. Some example code that triggers this lint: + +```rust +struct S; + +impl S { + fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} +} + +fn main() { + S.late::<'static>(&0, &0); +} +``` + +This will produce: + +```text +warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> src/main.rs:8:14 + | +4 | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} + | -- the late bound lifetime parameter is introduced here +... +8 | S.late::<'static>(&0, &0); + | ^^^^^^^ + | + = note: #[warn(late_bound_lifetime_arguments)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #42868 +``` + +## non-camel-case-types + +This lint detects types, variants, traits and type parameters that don't have +camel case names. Some example code that triggers this lint: + +```rust +struct s; +``` + +This will produce: + +```text +warning: type `s` should have a camel case name such as `S` + --> src/main.rs:1:1 + | +1 | struct s; + | ^^^^^^^^^ + | +``` + +## non-shorthand-field-patterns + +This lint detects using `Struct { x: x }` instead of `Struct { x }` in a pattern. Some +example code that triggers this lint: + +```rust +struct Point { + x: i32, + y: i32, +} + + +fn main() { + let p = Point { + x: 5, + y: 5, + }; + + match p { + Point { x: x, y: y } => (), + } +} +``` + +This will produce: + +```text +warning: the `x:` in this pattern is redundant + --> src/main.rs:14:17 + | +14 | Point { x: x, y: y } => (), + | --^^ + | | + | help: remove this + | + +warning: the `y:` in this pattern is redundant + --> src/main.rs:14:23 + | +14 | Point { x: x, y: y } => (), + | --^^ + | | + | help: remove this + +``` + +## non-snake-case + +This lint detects variables, methods, functions, lifetime parameters and +modules that don't have snake case names. Some example code that triggers +this lint: + +```rust +let X = 5; +``` + +This will produce: + +```text +warning: variable `X` should have a snake case name such as `x` + --> src/main.rs:2:9 + | +2 | let X = 5; + | ^ + | +``` + +## non-upper-case-globals + +This lint detects static constants that don't have uppercase identifiers. +Some example code that triggers this lint: + +```rust +static x: i32 = 5; +``` + +This will produce: + +```text +warning: static variable `x` should have an upper case name such as `X` + --> src/main.rs:1:1 + | +1 | static x: i32 = 5; + | ^^^^^^^^^^^^^^^^^^ + | +``` + +## no-mangle-generic-items + +This lint detects generic items must be mangled. Some +example code that triggers this lint: + +```rust +#[no_mangle] +fn foo(t: T) { + +} +``` + +This will produce: + +```text +warning: functions generic over types must be mangled + --> src/main.rs:2:1 + | +1 | #[no_mangle] + | ------------ help: remove this attribute +2 | / fn foo(t: T) { +3 | | +4 | | } + | |_^ + | +``` + +## overflowing-literals + +This lint detects literal out of range for its type. Some +example code that triggers this lint: + +```rust +let x: u8 = 1000; +``` + +This will produce: + +```text +warning: literal out of range for u8 + --> src/main.rs:2:17 + | +2 | let x: u8 = 1000; + | ^^^^ + | +``` + +## path-statements + +This lint detects path statements with no effect. Some example code that +triggers this lint: + +```rust +let x = 42; + +x; +``` + +This will produce: + +```text +warning: path statement with no effect + --> src/main.rs:3:5 + | +3 | x; + | ^^ + | +``` + +## patterns-in-fns-without-body + +This lint detects patterns in functions without body were that were +previously erroneously allowed. Some example code that triggers this lint: + +```rust +trait Trait { + fn foo(mut arg: u8); +} +``` + +This will produce: + +```text +warning: patterns aren't allowed in methods without bodies + --> src/main.rs:2:12 + | +2 | fn foo(mut arg: u8); + | ^^^^^^^ + | + = note: #[warn(patterns_in_fns_without_body)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #35203 +``` + +To fix this, remove the pattern; it can be used in the implementation without +being used in the definition. That is: + +```rust +trait Trait { + fn foo(arg: u8); +} + +impl Trait for i32 { + fn foo(mut arg: u8) { + + } +} +``` + +## plugin-as-library + +This lint detects when compiler plugins are used as ordinary library in +non-plugin crate. Some example code that triggers this lint: + +```rust +#![feature(plugin)] +#![plugin(macro_crate_test)] + +extern crate macro_crate_test; +``` + +## private-in-public + +This lint detects detect private items in public interfaces not caught by the old implementation. Some +example code that triggers this lint: + +```rust +pub trait Trait { + type A; +} + +pub struct S; + +mod foo { + struct Z; + + impl ::Trait for ::S { + type A = Z; + } +} +``` + +This will produce: + +```text +error[E0446]: private type `foo::Z` in public interface + --> src/main.rs:11:9 + | +11 | type A = Z; + | ^^^^^^^^^^^ can't leak private type +``` + +## private-no-mangle-fns + +This lint detects functions marked `#[no_mangle]` that are also private. +Given that private functions aren't exposed publicly, and `#[no_mangle]` +controls the public symbol, this combination is erroneous. Some example code +that triggers this lint: + +```rust +#[no_mangle] +fn foo() {} +``` + +This will produce: + +```text +warning: function is marked #[no_mangle], but not exported + --> src/main.rs:2:1 + | +2 | fn foo() {} + | -^^^^^^^^^^ + | | + | help: try making it public: `pub` + | +``` + +To fix this, either make it public or remove the `#[no_mangle]`. + +## private-no-mangle-statics + +This lint detects any statics marked `#[no_mangle]` that are private. +Given that private statics aren't exposed publicly, and `#[no_mangle]` +controls the public symbol, this combination is erroneous. Some example code +that triggers this lint: + +```rust +#[no_mangle] +static X: i32 = 4; +``` + +This will produce: + +```text +warning: static is marked #[no_mangle], but not exported + --> src/main.rs:2:1 + | +2 | static X: i32 = 4; + | -^^^^^^^^^^^^^^^^^ + | | + | help: try making it public: `pub` + | +``` + +To fix this, either make it public or remove the `#[no_mangle]`. + +## renamed-and-removed-lints + +This lint detects lints that have been renamed or removed. Some +example code that triggers this lint: + +```rust +#![deny(raw_pointer_derive)] +``` + +This will produce: + +```text +warning: lint raw_pointer_derive has been removed: using derive with raw pointers is ok + --> src/main.rs:1:9 + | +1 | #![deny(raw_pointer_derive)] + | ^^^^^^^^^^^^^^^^^^ + | +``` + +To fix this, either remove the lint or use the new name. + +## safe-packed-borrows + +This lint detects borrowing a field in the interior of a packed structure +with alignment other than 1. Some example code that triggers this lint: + +```rust +#[repr(packed)] +pub struct Unaligned(pub T); + +pub struct Foo { + start: u8, + data: Unaligned, +} + +fn main() { + let x = Foo { start: 0, data: Unaligned(1) }; + let y = &x.data.0; +} +``` + +This will produce: + +```text +warning: borrow of packed field requires unsafe function or block (error E0133) + --> src/main.rs:11:13 + | +11 | let y = &x.data.0; + | ^^^^^^^^^ + | + = note: #[warn(safe_packed_borrows)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #46043 +``` + +## stable-features + +This lint detects a `#[feature]` attribute that's since been made stable. Some +example code that triggers this lint: + +```rust +#![feature(test_accepted_feature)] +``` + +This will produce: + +```text +warning: this feature has been stable since 1.0.0. Attribute no longer needed + --> src/main.rs:1:12 + | +1 | #![feature(test_accepted_feature)] + | ^^^^^^^^^^^^^^^^^^^^^ + | +``` + +To fix, simply remove the `#![feature]` attribute, as it's no longer needed. + +## type-alias-bounds + +This lint detects bounds in type aliases. These are not currently enforced. +Some example code that triggers this lint: + +```rust +type SendVec = Vec; +``` + +This will produce: + +```text +warning: type alias is never used: `SendVec` + --> src/main.rs:1:1 + | +1 | type SendVec = Vec; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +``` + +## tyvar-behind-raw-pointer + +This lint detects raw pointer to an inference variable. Some +example code that triggers this lint: + +```rust +let data = std::ptr::null(); +let _ = &data as *const *const (); + +if data.is_null() {} +``` + +This will produce: + +```text +warning: type annotations needed + --> src/main.rs:4:13 + | +4 | if data.is_null() {} + | ^^^^^^^ + | + = note: #[warn(tyvar_behind_raw_pointer)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #46906 +``` + +## unconditional-recursion + +This lint detects functions that cannot return without calling themselves. +Some example code that triggers this lint: + +```rust +fn foo() { + foo(); +} +``` + +This will produce: + +```text +warning: function cannot return without recurring + --> src/main.rs:1:1 + | +1 | fn foo() { + | ^^^^^^^^ cannot return without recurring +2 | foo(); + | ----- recursive call site + | +``` + +## unions-with-drop-fields + +This lint detects use of unions that contain fields with possibly non-trivial drop code. Some +example code that triggers this lint: + +```rust +#![feature(untagged_unions)] + +union U { + s: String, +} +``` + +This will produce: + +```text +warning: union contains a field with possibly non-trivial drop code, drop code of union fields is ignored when dropping the union + --> src/main.rs:4:5 + | +4 | s: String, + | ^^^^^^^^^ + | +``` + +## unknown-lints + +This lint detects unrecognized lint attribute. Some +example code that triggers this lint: + +```rust +#[allow(not_a_real_lint)] +``` + +This will produce: + +```text +warning: unknown lint: `not_a_real_lint` + --> src/main.rs:1:10 + | +1 | #![allow(not_a_real_lint)] + | ^^^^^^^^^^^^^^^ + | +``` + +## unreachable-code + +This lint detects detects unreachable code paths. Some example code that +triggers this lint: + +```rust +panic!("we never go past here!"); + +let x = 5; +``` + +This will produce: + +```text +warning: unreachable statement + --> src/main.rs:4:5 + | +4 | let x = 5; + | ^^^^^^^^^^ + | +``` + +## unreachable-patterns + +This lint detects detects unreachable patterns. Some +example code that triggers this lint: + +```rust +let x = 5; +match x { + y => (), + 5 => (), +} +``` + +This will produce: + +```text +warning: unreachable pattern + --> src/main.rs:5:5 + | +5 | 5 => (), + | ^ + | +``` + +The `y` pattern will always match, so the five is impossible to reach. +Remember, match arms match in order, you probably wanted to put the `5` case +above the `y` case. + +## unstable-name-collision + +This lint detects that you've used a name that the standard library plans to +add in the future, which means that your code may fail to compile without +additional type annotations in the future. Either rename, or add those +annotations now. + +## unused-allocation + +This lint detects detects unnecessary allocations that can be eliminated. + +## unused-assignments + +This lint detects detect assignments that will never be read. Some +example code that triggers this lint: + +```rust +let mut x = 5; +x = 6; +``` + +This will produce: + +```text +warning: value assigned to `x` is never read + --> src/main.rs:4:5 + | +4 | x = 6; + | ^ + | +``` + +## unused-attributes + +This lint detects detects attributes that were not used by the compiler. Some +example code that triggers this lint: + +```rust +#![feature(custom_attribute)] + +#![mutable_doc] +``` + +This will produce: + +```text +warning: unused attribute + --> src/main.rs:4:1 + | +4 | #![mutable_doc] + | ^^^^^^^^^^^^^^^ + | +``` + +## unused-comparisons + +This lint detects comparisons made useless by limits of the types involved. Some +example code that triggers this lint: + +```rust +fn foo(x: u8) { + x >= 0; +} +``` + +This will produce: + +```text +warning: comparison is useless due to type limits + --> src/main.rs:6:5 + | +6 | x >= 0; + | ^^^^^^ + | +``` + +## unused-doc-comment + +This lint detects detects doc comments that aren't used by rustdoc. Some +example code that triggers this lint: + +```rust +/// docs for x +let x = 12; +``` + +This will produce: + +```text +warning: doc comment not used by rustdoc + --> src/main.rs:2:5 + | +2 | /// docs for x + | ^^^^^^^^^^^^^^ + | +``` + +## unused-features + +This lint detects unused or unknown features found in crate-level #[feature] directives. +To fix this, simply remove the feature flag. + +## unused-imports + +This lint detects imports that are never used. Some +example code that triggers this lint: + +```rust +use std::collections::HashMap; +``` + +This will produce: + +```text +warning: unused import: `std::collections::HashMap` + --> src/main.rs:1:5 + | +1 | use std::collections::HashMap; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +``` + +## unused-macros + +This lint detects detects macros that were not used. Some example code that +triggers this lint: + +```rust +macro_rules! unused { + () => {}; +} + +fn main() { +} +``` + +This will produce: + +```text +warning: unused macro definition + --> src/main.rs:1:1 + | +1 | / macro_rules! unused { +2 | | () => {}; +3 | | } + | |_^ + | +``` + +## unused-must-use + +This lint detects unused result of a type flagged as #[must_use]. Some +example code that triggers this lint: + +```rust +fn returns_result() -> Result<(), ()> { + Ok(()) +} + +fn main() { + returns_result(); +} +``` + +This will produce: + +```text +warning: unused `std::result::Result` which must be used + --> src/main.rs:6:5 + | +6 | returns_result(); + | ^^^^^^^^^^^^^^^^^ + | +``` + +## unused-mut + +This lint detects detect mut variables which don't need to be mutable. Some +example code that triggers this lint: + +```rust +let mut x = 5; +``` + +This will produce: + +```text +warning: variable does not need to be mutable + --> src/main.rs:2:9 + | +2 | let mut x = 5; + | ----^ + | | + | help: remove this `mut` + | +``` + +## unused-parens + +This lint detects `if`, `match`, `while` and `return` with parentheses; they +do not need them. Some example code that triggers this lint: + +```rust +if(true) {} +``` + +This will produce: + +```text +warning: unnecessary parentheses around `if` condition + --> src/main.rs:2:7 + | +2 | if(true) {} + | ^^^^^^ help: remove these parentheses + | +``` + +## unused-unsafe + +This lint detects unnecessary use of an `unsafe` block. Some +example code that triggers this lint: + +```rust +unsafe {} +``` + +This will produce: + +```text +warning: unnecessary `unsafe` block + --> src/main.rs:2:5 + | +2 | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + | +``` + +## unused-variables + +This lint detects detect variables which are not used in any way. Some +example code that triggers this lint: + +```rust +let x = 5; +``` + +This will produce: + +```text +warning: unused variable: `x` + --> src/main.rs:2:9 + | +2 | let x = 5; + | ^ help: consider using `_x` instead + | +``` + +## warnings + +This lint is a bit special; by changing its level, you change every other warning +that would produce a warning to whatever value you'd like: + +```rust +#![deny(warnings)] +``` + +As such, you won't ever trigger this lint in your code directly. + +## while-true + +This lint detects `while true { }`. Some example code that triggers this +lint: + +```rust +while true { + +} +``` + +This will produce: + +```text +warning: denote infinite loops with `loop { ... }` + --> src/main.rs:2:5 + | +2 | while true { + | ^^^^^^^^^^ help: use `loop` + | +``` \ No newline at end of file From 142c52f4a3f7db42613239953d4615ab5a0ac3c6 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 6 Apr 2018 15:18:16 -0400 Subject: [PATCH 12/24] fix tests --- src/doc/rustc/src/lints/index.md | 4 ++-- src/doc/rustc/src/lints/levels.md | 8 ++++---- .../src/lints/listing/allowed-by-default.md | 11 ++++++----- .../rustc/src/lints/listing/deny-by-default.md | 18 +++++++++--------- .../rustc/src/lints/listing/warn-by-default.md | 15 ++++++++------- 5 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/doc/rustc/src/lints/index.md b/src/doc/rustc/src/lints/index.md index 4706a10c908ee..bf345a24389d2 100644 --- a/src/doc/rustc/src/lints/index.md +++ b/src/doc/rustc/src/lints/index.md @@ -7,7 +7,7 @@ depending on how you've configured things. Here's a small example: -```rust +```bash $ cat main.rs fn main() { let x = 5; @@ -25,4 +25,4 @@ warning: unused variable: `x` This is the `unused_variables` lint, and it tells you that you've introduced a variable that you don't use in your code. That's not *wrong*, so it's not -an error, but it might be a bug, so you get a warning. \ No newline at end of file +an error, but it might be a bug, so you get a warning. diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index f2d7241e648a4..83b65cd648e0f 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -22,7 +22,7 @@ pub fn foo() {} Compiling this file produces no warnings: -```rust +```bash $ rustc lib.rs --crate-type=lib $ ``` @@ -62,7 +62,7 @@ warning: unused variable: `x` A 'deny' lint produces an error if you violate it. For example, this code runs into the `exceeding_bitshifts` lint. -```rust +```rust,ignore fn main() { 100u8 << 10; } @@ -215,7 +215,7 @@ pub fn foo() {} This is the maximum level for all lints. So for example, if we take our code sample from the "deny" lint level above: -```rust +```rust,ignore fn main() { 100u8 << 10; } @@ -249,4 +249,4 @@ $ This feature is used heavily by Cargo; it will pass `--cap-lints allow` when compiling your dependencies, so that if they have any warnings, they do not -pollute the output of your build. \ No newline at end of file +pollute the output of your build. diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md index a432c00e0609a..e1a3f96a6fe6e 100644 --- a/src/doc/rustc/src/lints/listing/allowed-by-default.md +++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md @@ -336,7 +336,7 @@ This lint is deprecated and no longer used. This lint guards against `extern crate` items that are never used. Some example code that triggers this lint: -```rust +```rust,ignore extern crate semver; ``` @@ -359,9 +359,10 @@ code that triggers this lint: ```rust use test::{A}; -mod test { - struct A; +pub mod test { + pub struct A; } +# fn main() {} ``` When set to 'deny', this will produce: @@ -410,7 +411,7 @@ You can call `bar()` directly, without the `foo::`. This lint checks for the unused result of an expression in a statement. Some example code that triggers this lint: -```rust +```rust,no_run fn foo() -> T { panic!() } fn main() { @@ -449,4 +450,4 @@ error: enum variant is more than three times larger (1024 bytes) than the next l 5 | VBig([u8; 1024]), //~ ERROR variant is more than three times larger | ^^^^^^^^^^^^^^^^ | -``` \ No newline at end of file +``` diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index a361c117b10c9..0c49f2f7b36eb 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -7,7 +7,7 @@ These lints are all set to the 'deny' level by default. This lint detects that a shift exceeds the type's number of bits. Some example code that triggers this lint: -```rust +```rust,ignore 1_i32 << 32; ``` @@ -27,7 +27,7 @@ error: bitshift exceeds the type's number of bits This lint detects type parameter default erroneously allowed in invalid location. Some example code that triggers this lint: -```rust +```rust,ignore fn foo(t: T) {} ``` @@ -51,7 +51,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type` visibility rules, and changed the visibility of struct constructors. Some example code that triggers this lint: -```rust +```rust,ignore mod m { pub struct S(u8); @@ -96,7 +96,7 @@ it into its own directory if appropriate. This lint detects names that resolve to ambiguous glob imports. Some example code that triggers this lint: -```rust +```rust,ignore pub struct Foo; mod bar { @@ -143,7 +143,7 @@ This warning can always be fixed by removing the unused pattern in the This lint catches transmuting from `&T` to `&mut T` becuase it is undefined behavior. Some example code that triggers this lint: -```rust +```rust,ignore unsafe { let y = std::mem::transmute::<&i32, &mut i32>(&5); } @@ -168,7 +168,7 @@ Constants do not have their symbols exported, and therefore, this probably means you meant to use a `static`, not a `const. Some example code that triggers this lint: -```rust +```rust,ignore #[no_mangle] const FOO: i32 = 5; ``` @@ -191,7 +191,7 @@ error: const items should never be #[no_mangle] This lint detects incorrect parentheses. Some example code that triggers this lint: -```rust +```rust,ignore let x = 5 as usize(); ``` @@ -225,7 +225,7 @@ to be accessed in safe code. This lint now catches and denies this kind of code. This lint detects an unknown crate type found in a `#[crate_type]` directive. Some example code that triggers this lint: -```rust +```rust,ignore #![crate_type="lol"] ``` @@ -238,4 +238,4 @@ error: invalid `crate_type` value 1 | #![crate_type="lol"] | ^^^^^^^^^^^^^^^^^^^^ | -``` \ No newline at end of file +``` diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md index a8f3400687c2a..1171f75caa1fd 100644 --- a/src/doc/rustc/src/lints/listing/warn-by-default.md +++ b/src/doc/rustc/src/lints/listing/warn-by-default.md @@ -7,7 +7,7 @@ These lints are all set to the 'warn' level by default. This lint detects an erroneous expression while doing constant evaluation. Some example code that triggers this lint: -```rust +```rust,ignore let b = 200u8 + 200u8; ``` @@ -413,7 +413,7 @@ impl Trait for i32 { This lint detects when compiler plugins are used as ordinary library in non-plugin crate. Some example code that triggers this lint: -```rust +```rust,ignore #![feature(plugin)] #![plugin(macro_crate_test)] @@ -425,7 +425,7 @@ extern crate macro_crate_test; This lint detects detect private items in public interfaces not caught by the old implementation. Some example code that triggers this lint: -```rust +```rust,ignore pub trait Trait { type A; } @@ -439,6 +439,7 @@ mod foo { type A = Z; } } +# fn main() {} ``` This will produce: @@ -682,7 +683,7 @@ warning: union contains a field with possibly non-trivial drop code, drop code o This lint detects unrecognized lint attribute. Some example code that triggers this lint: -```rust +```rust,ignore #[allow(not_a_real_lint)] ``` @@ -702,7 +703,7 @@ warning: unknown lint: `not_a_real_lint` This lint detects detects unreachable code paths. Some example code that triggers this lint: -```rust +```rust,no_run panic!("we never go past here!"); let x = 5; @@ -1020,7 +1021,7 @@ As such, you won't ever trigger this lint in your code directly. This lint detects `while true { }`. Some example code that triggers this lint: -```rust +```rust,no_run while true { } @@ -1035,4 +1036,4 @@ warning: denote infinite loops with `loop { ... }` 2 | while true { | ^^^^^^^^^^ help: use `loop` | -``` \ No newline at end of file +``` From cb6a19925a542dcf07c4318adb751d5aa4773465 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 10 Apr 2018 16:35:28 -0400 Subject: [PATCH 13/24] add codegen options section --- src/doc/rustc/src/codegen-options/index.md | 208 +++++++++++++++++++++ 1 file changed, 208 insertions(+) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 4350db56ef683..70dae9314c1f7 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -1 +1,209 @@ # Codegen options + +All of these options are passed to `rustc` via the `-C` flag, short for "codegen." You can see +a version of this list for your exact compiler by running `rustc -C help`. + +## ar + +This option is deprecated and does nothing. + +## linker + +This flag lets you control which linker `rustc` invokes to link your code. + +## link-arg=val + +This flag lets you append a single extra argument to the linker invocation. + +"Append" is significant; you can pass this flag multiple times to add multiple arguments. + +## link-args + +This flag lets you append multiple extra arguments to the linker invocation. The +options should be separated by spaces. + +## link-dead-code + +Normally, the linker will remove dead code. This flag disables this behavior. + +An example of when this flag might be useful is when trying to construct code coverage +metrics. + +## lto + +This flag instructs LLVM to use [link time +optimizations](https://llvm.org/docs/LinkTimeOptimization.html). + +It takes one of two values, `thin` and `fat`. 'thin' LTO [is a new feature of +LLVM](http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html), +'fat' referring to the classic version of LTO. + +## target-cpu + +This instructs `rustc` to generate code specifically for a particular processor. + +You can run `rustc --print target-cpus` to see the valid options to pass +here. Additionally, `native` can be passed to use the processor of the host +machine. + +## target-feature + +Individual targets will support different features; this flag lets you control +enabling or disabling a feature. + +To see the valid options and an example of use, run `rustc --print +target-features`. + +## passes + +This flag can be used to add extra LLVM passes to the compilation. + +The list must be separated by spaces. + +## llvm-args + +This flag can be used to pass a list of arguments directly to LLVM. + +The list must be separated by spaces. + +## save-temps + +`rustc` will generate temporary files during compilation; normally it will +delete them after it's done with its work. This option will cause them to be +preserved instead of removed. + +## rpath + +This option allows you to set the value of +[`rpath`](https://en.wikipedia.org/wiki/Rpath). + +## overflow-checks + +This flag allows you to control the behavior of integer overflow. This flag +can be passed many options: + +* To turn overflow checks on: `y`, `yes`, or `on`. +* To turn overflow checks off: `n`, `no`, or `off`. + +## no-prepopulate-passes + +The pass manager comes pre-populated with a list of passes; this flag +ensures that list is empty. + +## no-vectorize-loops + +By default, `rustc` will attempt to [vectorize +loops](https://llvm.org/docs/Vectorizers.html#the-loop-vectorizer). This +flag will turn that behavior off. + +## no-vectorize-slp + +By default, `rustc` will attempt to vectorize loops using [superword-level +parallism](https://llvm.org/docs/Vectorizers.html#the-slp-vectorizer). This +flag will turn that behavior off. + +## soft-float + +This option will make `rustc` generate code using "soft floats." By default, +a lot of hardware supports floating point instructions, and so the code generated +will take advantage of this. "soft floats" emulate floating point instructions +in software. + +## prefer-dynamic + +By default, `rustc` prefers to statically link dependencies. This option will +make it use dynamic linking instead. + +## no-integrated-as + +LLVM comes with an internal assembler; this option will let you use an +external assembler instead. + +## no-redzone + +This flag allows you to disable [the +red zone](https://en.wikipedia.org/wiki/Red_zone_\(computing\)). This flag can +be passed many options: + +* To enable the red zone: `y`, `yes`, or `on`. +* To disable it: `n`, `no`, or `off`. + +## relocation-model + +This option lets you choose which relocation model to use. + +To find the valid options for this flag, run `rustc --print relocation-models`. + +## code-model=val + +This option lets you choose which code model to use. + +To find the valid options for this flag, run `rustc --print code-models`. + +## metadata + +This option allows you to control the metadata used for symbol mangling. + +## extra-filename + +This option allows you to put extra data in each output filename. + +## codegen-units + +This flag lets you control how many threads are used when doing +code generation. + +Increasing paralellism may speed up compile times, but may also +produce slower code. + +## remark + +This flag lets you print remarks for these optimization passes. + +The list of passes should be separated by spaces. + +`all` will remark on every pass. + +## no-stack-check + +This option is deprecated and does nothing. + +## debuginfo + +This flag lets you control debug information: + +* `0`: no debug info at all +* `1`: line tables only +* `2`: full debug info + +## opt-level + +This flag lets you control the optimization level. + +* `0`: no optimizations +* `1`: basic optimizations +* `2`: some optimizations +* `3`: all optimizations +* `s`: optimize for binary size +* `z`: optimize for binary size, but also turn off loop vectorization. + +## debug-assertions + +This flag lets you turn `cfg(debug_assertions)` on or off. + +## inline-threshold + +This option lets you set the threshold for inlining a function. + +The default is 225. + +## panic + +This option lets you control what happens when the code panics. + +* `abort`: terminate the process upon panic +* `unwind`: unwind the stack upon panic + +## incremental + +This flag allows you to enable incremental compilation. \ No newline at end of file From cd3f6cf3fef900c7461cc02d4bb4cd226d7c5b6e Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 16 Apr 2018 12:57:01 -0400 Subject: [PATCH 14/24] fill out command line arguments --- src/doc/rustc/src/command-line-arguments.md | 63 ++++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 7ea3e806e4a58..488102f926a95 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -4,54 +4,113 @@ Here's a list of command-line arguments to `rustc` and what they do. ## `-h`/`--help`: get help +This flag will print out help information for `rustc`. + ## `--cfg`: configure the compilation environment -## `-L`: add a directory to the library search path. +This flag can turn on or off various `#[cfg]` settings. + +## `-L`: add a directory to the library search path + +When looking for external crates, a directory passed to this flag will be searched. ## `-l`: link the generated crate to a native library +This flag allows you to specify linking to a specific native library when building +a crate. + ## `--crate-type`: a list of types of crates for the compiler to emit +This instructs `rustc` on which crate type to build. + ## `--crate-name`: specify the name of the crate being built +This informs `rustc` of the name of your crate. + ## `--emit`: emit output other than a crate +Instead of producing a crate, this flag can print out things like the assembly or LLVM-IR. + ## `--print`: print compiler information +This flag prints out various information about the compiler. + ## `-g`: include debug information +A synonym for `-C debug-level=2`. + ## `-O`: optimize your code +A synonym for `-C opt-level=2`. + ## `-o`: filename of the output +This flag controls the output filename. + ## `--out-dir`: directory to write the output in +The outputted crate will be written to this directory. + ## `--explain`: provide a detailed explanation of an error message +Each error of `rustc`'s comes with an error code; this will print +out a longer explanation of a given error. + ## `--test`: build a test harness +When compiling this crate, `rustc` will ignore your `main` function +and instead produce a test harness. + ## `--target`: select a target triple to build +This controls which [target](targets/index.html) to produce. + ## `-W`: set lint warnings +This flag will set which lints should be set to the [warn level](lints/levels.html#warn). + ## `-A`: set lint allowed +This flag will set which lints should be set to the [allow level](lints/levels.html#allow). + ## `-D`: set lint denied +This flag will set which lints should be set to the [deny level](lints/levels.html#deny). + ## `-F`: set lint forbidden +This flag will set which lints should be set to the [forbid level](lints/levels.html#forbid). + ## `--cap-lints`: set the most restrictive lint level +This flag lets you 'cap' lints, for more, [see here](lints/levels.html#capping-lints). + ## `-C`/`--codegen`: code generation options +This flag will allow you to set [codegen options](codegen-options/index.html). + ## `-V`/`--verision`: print a version +This flag will print out `rustc`'s version. + ## `-v`/`--verbose`: use verbose output +This flag, when combined with other flags, makes them produce extra output. + ## `--extern`: specify where an external library is located +This flag allows you to pass the name and location of an external crate that will +be linked into the crate you're buildling. + ## `--sysroot`: Override the system root +The "sysroot" is where `rustc` looks for the crates that come with the Rust +distribution; this flag allows that to be overridden. + ## `--error-format`: control how errors are produced -## `--color`: configur coloring of output \ No newline at end of file +This flag lets you control the format of errors. + +## `--color`: configur coloring of output + +This flag lets you control color settings of the output. \ No newline at end of file From b204968239188719b34929195e28b2cce25eb836 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 16 Apr 2018 12:57:09 -0400 Subject: [PATCH 15/24] fill out contributing --- src/doc/rustc/src/contributing.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/rustc/src/contributing.md b/src/doc/rustc/src/contributing.md index e21b6fbd14aed..fcb8e6b27dbf0 100644 --- a/src/doc/rustc/src/contributing.md +++ b/src/doc/rustc/src/contributing.md @@ -1 +1,6 @@ # Contributing to rustc + +We'd love to have your help improving `rustc`! To that end, we've written [a +whole book](https://rust-lang-nursery.github.io/rustc-guide/) on its +internals, how it works, and how to get started working on it. To learn +more, you'll want to check that out. \ No newline at end of file From 00c860e8a908ae09eee0a3508a377fc6b7003d8c Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 16 Apr 2018 12:57:16 -0400 Subject: [PATCH 16/24] write docs for targets --- src/doc/rustc/src/targets/built-in.md | 9 +++++++++ src/doc/rustc/src/targets/custom.md | 16 ++++++++++++++++ src/doc/rustc/src/targets/index.md | 13 +++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/doc/rustc/src/targets/built-in.md b/src/doc/rustc/src/targets/built-in.md index 819d74457fe51..8620346e5b748 100644 --- a/src/doc/rustc/src/targets/built-in.md +++ b/src/doc/rustc/src/targets/built-in.md @@ -1 +1,10 @@ # Built-in Targets + +`rustc` ships with the ability to compile to many targets automatically, we +call these "built-in" targets, and they generally correspond to targets that +the team is supporting directly. + +To see the list of built-in targets, you can run `rustc --print target-list`, +or look at [the API +docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/#modules). +Each module there defines a builder for a particular target. \ No newline at end of file diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md index 59039ce67bad9..0691afc60eae1 100644 --- a/src/doc/rustc/src/targets/custom.md +++ b/src/doc/rustc/src/targets/custom.md @@ -1 +1,17 @@ # Custom Targets + +If you'd like to build for a target that is not yet supported by `rustc`, you can use a +"custom target specification" to define a target. These target specification files +are JSON. To see the JSON for the host target, you can run: + +```bash +$ rustc +nightly -Z unstable-options --print target-spec-json +``` + +To see it for a different target, add the `--target` flag: + +```bash +$ rustc +nightly -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json +``` + +To use a custom target, see [`xargo`](https://github.com/japaric/xargo). \ No newline at end of file diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md index 01d0a4c8c0e3b..cea7ce4dea56a 100644 --- a/src/doc/rustc/src/targets/index.md +++ b/src/doc/rustc/src/targets/index.md @@ -1 +1,14 @@ # Targets + +`rustc` is a cross-compiler by default. This means that you can use any compiler to build for any +architecture. The list of *targets* are the possible architectures that you can build for. + +You can see the API docs for a given target +[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/struct.Target.html), all +of these options can be set on a per-target basis. + +To compile to a particular target, use the `--target` flag: + +```bash +$ rustc src/main.rs --target=wasm32-unknown-unknown +``` \ No newline at end of file From ac79c41edc2ed9d7125009dd5f21bdcc9fecb3c8 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 23 Apr 2018 11:58:11 -0400 Subject: [PATCH 17/24] review nits --- src/doc/rustc/src/codegen-options/index.md | 4 ++-- src/doc/rustc/src/lints/levels.md | 4 ++-- src/doc/rustc/src/lints/listing/deny-by-default.md | 2 +- src/doc/rustc/src/targets/index.md | 7 +++---- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 70dae9314c1f7..eff09428902e8 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -99,7 +99,7 @@ flag will turn that behavior off. ## no-vectorize-slp By default, `rustc` will attempt to vectorize loops using [superword-level -parallism](https://llvm.org/docs/Vectorizers.html#the-slp-vectorizer). This +parallelism](https://llvm.org/docs/Vectorizers.html#the-slp-vectorizer). This flag will turn that behavior off. ## soft-float @@ -206,4 +206,4 @@ This option lets you control what happens when the code panics. ## incremental -This flag allows you to enable incremental compilation. \ No newline at end of file +This flag allows you to enable incremental compilation. diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 83b65cd648e0f..19bb6707d2285 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -45,8 +45,8 @@ pub fn foo() { This will produce this warning: -```bash -> rustc lib.rs --crate-type=lib +```console +$ rustc lib.rs --crate-type=lib warning: unused variable: `x` --> lib.rs:2:9 | diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index 0c49f2f7b36eb..e7ec6af8be1e3 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -165,7 +165,7 @@ error: mutating transmuted &mut T from &T may cause undefined behavior, consider This lint detects any `const` items with the `#[no_mangle]` attribute. Constants do not have their symbols exported, and therefore, this probably -means you meant to use a `static`, not a `const. Some example code that +means you meant to use a `static`, not a `const`. Some example code that triggers this lint: ```rust,ignore diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md index cea7ce4dea56a..07e3a79471f5b 100644 --- a/src/doc/rustc/src/targets/index.md +++ b/src/doc/rustc/src/targets/index.md @@ -3,12 +3,11 @@ `rustc` is a cross-compiler by default. This means that you can use any compiler to build for any architecture. The list of *targets* are the possible architectures that you can build for. -You can see the API docs for a given target -[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/struct.Target.html), all -of these options can be set on a per-target basis. +To see all the options that you can set with a target, see the docs +[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/struct.Target.html). To compile to a particular target, use the `--target` flag: ```bash $ rustc src/main.rs --target=wasm32-unknown-unknown -``` \ No newline at end of file +``` From 36475d947b4c39ec9dcaad137d51019c8b861918 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 24 Apr 2018 12:21:08 -0400 Subject: [PATCH 18/24] more nits --- src/doc/rustc/src/command-line-arguments.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 488102f926a95..e2b001832fe31 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -89,7 +89,7 @@ This flag lets you 'cap' lints, for more, [see here](lints/levels.html#capping-l This flag will allow you to set [codegen options](codegen-options/index.html). -## `-V`/`--verision`: print a version +## `-V`/`--version`: print a version This flag will print out `rustc`'s version. @@ -111,6 +111,6 @@ distribution; this flag allows that to be overridden. This flag lets you control the format of errors. -## `--color`: configur coloring of output +## `--color`: configure coloring of output -This flag lets you control color settings of the output. \ No newline at end of file +This flag lets you control color settings of the output. From a95bff3ed40e46e89ca778b7674304bad92bc16e Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 25 Apr 2018 15:57:33 +0200 Subject: [PATCH 19/24] Bump bootstrap compiler to 2018-04-24 --- src/stage0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stage0.txt b/src/stage0.txt index e8db3358cf076..a5ad2b315a1dd 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2018-04-04 +date: 2018-04-24 rustc: beta cargo: beta From 2e4f66a86f7baa5644d18bb2adc07a8cd1c7409d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 26 Apr 2018 15:35:24 +1000 Subject: [PATCH 20/24] Make dump_{alloc,allocs,local}() no-ops when tracing is disabled. Because they traverse data structures and build up strings, which is wasted effort if those strings aren't printed. The patch also removes some now-unnecessary log_enabled! tests at call sites. --- src/librustc_mir/interpret/eval_context.rs | 7 ++++--- src/librustc_mir/interpret/memory.rs | 6 ++++++ src/librustc_mir/interpret/place.rs | 4 +--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b98ab218de5cb..90f1b5dda0162 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -749,9 +749,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M } } - if log_enabled!(::log::Level::Trace) { - self.dump_local(dest); - } + self.dump_local(dest); Ok(()) } @@ -1538,6 +1536,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M pub fn dump_local(&self, place: Place) { // Debug output + if !log_enabled!(::log::Level::Trace) { + return; + } match place { Place::Local { frame, local } => { let mut allocs = Vec::new(); diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 5e156e9271f57..7f8205b8327fa 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -334,11 +334,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { /// For debugging, print an allocation and all allocations it points to, recursively. pub fn dump_alloc(&self, id: AllocId) { + if !log_enabled!(::log::Level::Trace) { + return; + } self.dump_allocs(vec![id]); } /// For debugging, print a list of allocations and all allocations they point to, recursively. pub fn dump_allocs(&self, mut allocs: Vec) { + if !log_enabled!(::log::Level::Trace) { + return; + } use std::fmt::Write; allocs.sort(); allocs.dedup(); diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 456f5fd75db09..2d57ff44b4725 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -218,9 +218,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { } }; - if log_enabled!(::log::Level::Trace) { - self.dump_local(place); - } + self.dump_local(place); Ok(place) } From 30e3f1a620b06b6edd697c55858ea9f251a4332a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 25 Apr 2018 20:10:58 +0200 Subject: [PATCH 21/24] Add more doc aliases --- src/libcore/cmp.rs | 12 ++++++++++++ src/libcore/fmt/mod.rs | 2 ++ src/libcore/ops/bit.rs | 10 ++++++++++ src/libcore/ops/deref.rs | 3 +++ src/libcore/ops/range.rs | 6 ++++++ 5 files changed, 33 insertions(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index c91aa06609dd7..13e838773a587 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -106,6 +106,8 @@ use self::Ordering::*; /// ``` #[lang = "eq"] #[stable(feature = "rust1", since = "1.0.0")] +#[doc(alias = "==")] +#[doc(alias = "!=")] #[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"] pub trait PartialEq { /// This method tests for `self` and `other` values to be equal, and is used @@ -160,6 +162,8 @@ pub trait PartialEq { /// } /// impl Eq for Book {} /// ``` +#[doc(alias = "==")] +#[doc(alias = "!=")] #[stable(feature = "rust1", since = "1.0.0")] pub trait Eq: PartialEq { // this method is used solely by #[deriving] to assert @@ -428,6 +432,10 @@ impl Ord for Reverse { /// } /// ``` #[lang = "ord"] +#[doc(alias = "<")] +#[doc(alias = ">")] +#[doc(alias = "<=")] +#[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] pub trait Ord: Eq + PartialOrd { /// This method returns an `Ordering` between `self` and `other`. @@ -599,6 +607,10 @@ impl PartialOrd for Ordering { /// ``` #[lang = "partial_ord"] #[stable(feature = "rust1", since = "1.0.0")] +#[doc(alias = ">")] +#[doc(alias = "<")] +#[doc(alias = "<=")] +#[doc(alias = ">=")] #[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"] pub trait PartialOrd: PartialEq { /// This method returns an ordering between `self` and `other` values if one exists. diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index a8430f14410e6..99e3012c9bf8c 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -547,6 +547,7 @@ impl<'a> Display for Arguments<'a> { message="`{Self}` doesn't implement `{Debug}`", label="`{Self}` cannot be formatted using `:?` because it doesn't implement `{Debug}`", )] +#[doc(alias = "{:?}")] #[lang = "debug_trait"] pub trait Debug { /// Formats the value using the given formatter. @@ -612,6 +613,7 @@ pub trait Debug { label="`{Self}` cannot be formatted with the default formatter; \ try using `:?` instead if you are using a format string", )] +#[doc(alias = "{}")] #[stable(feature = "rust1", since = "1.0.0")] pub trait Display { /// Formats the value using the given formatter. diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs index 81c4455cef4d9..02b6f62db6eb1 100644 --- a/src/libcore/ops/bit.rs +++ b/src/libcore/ops/bit.rs @@ -119,6 +119,7 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(bv1 & bv2, expected); /// ``` #[lang = "bitand"] +#[doc(alias = "&")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} & {RHS}`", label="no implementation for `{Self} & {RHS}`")] @@ -201,6 +202,7 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(bv1 | bv2, expected); /// ``` #[lang = "bitor"] +#[doc(alias = "|")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} | {RHS}`", label="no implementation for `{Self} | {RHS}`")] @@ -286,6 +288,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(bv1 ^ bv2, expected); /// ``` #[lang = "bitxor"] +#[doc(alias = "^")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} ^ {RHS}`", label="no implementation for `{Self} ^ {RHS}`")] @@ -372,6 +375,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// SpinVector { vec: vec![2, 3, 4, 0, 1] }); /// ``` #[lang = "shl"] +#[doc(alias = "<<")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} << {RHS}`", label="no implementation for `{Self} << {RHS}`")] @@ -479,6 +483,7 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 } /// SpinVector { vec: vec![3, 4, 0, 1, 2] }); /// ``` #[lang = "shr"] +#[doc(alias = ">>")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} >> {RHS}`", label="no implementation for `{Self} >> {RHS}`")] @@ -593,6 +598,7 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// assert_eq!(bv, expected); /// ``` #[lang = "bitand_assign"] +#[doc(alias = "&=")] #[stable(feature = "op_assign_traits", since = "1.8.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} &= {Rhs}`", label="no implementation for `{Self} &= {Rhs}`")] @@ -641,6 +647,7 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(prefs, PersonalPreferences { likes_cats: true, likes_dogs: true }); /// ``` #[lang = "bitor_assign"] +#[doc(alias = "|=")] #[stable(feature = "op_assign_traits", since = "1.8.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} |= {Rhs}`", label="no implementation for `{Self} |= {Rhs}`")] @@ -689,6 +696,7 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(personality, Personality { has_soul: true, likes_knitting: false}); /// ``` #[lang = "bitxor_assign"] +#[doc(alias = "^=")] #[stable(feature = "op_assign_traits", since = "1.8.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} ^= {Rhs}`", label="no implementation for `{Self} ^= {Rhs}`")] @@ -735,6 +743,7 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(scalar, Scalar(16)); /// ``` #[lang = "shl_assign"] +#[doc(alias = "<<=")] #[stable(feature = "op_assign_traits", since = "1.8.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} <<= {Rhs}`", label="no implementation for `{Self} <<= {Rhs}`")] @@ -802,6 +811,7 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// assert_eq!(scalar, Scalar(4)); /// ``` #[lang = "shr_assign"] +#[doc(alias = ">>=")] #[stable(feature = "op_assign_traits", since = "1.8.0")] #[rustc_on_unimplemented(message="no implementation for `{Self} >>= {Rhs}`", label="no implementation for `{Self} >>= {Rhs}`")] diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs index 4ce0740130b98..332d154170f4d 100644 --- a/src/libcore/ops/deref.rs +++ b/src/libcore/ops/deref.rs @@ -68,6 +68,8 @@ /// assert_eq!('a', *x); /// ``` #[lang = "deref"] +#[doc(alias = "*")] +#[doc(alias = "&*")] #[stable(feature = "rust1", since = "1.0.0")] pub trait Deref { /// The resulting type after dereferencing. @@ -162,6 +164,7 @@ impl<'a, T: ?Sized> Deref for &'a mut T { /// assert_eq!('b', *x); /// ``` #[lang = "deref_mut"] +#[doc(alias = "*")] #[stable(feature = "rust1", since = "1.0.0")] pub trait DerefMut: Deref { /// Mutably dereferences the value. diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 6f3e3b508853b..d70f7ae66f903 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -45,6 +45,7 @@ use fmt; /// [`IntoIterator`]: ../iter/trait.Iterator.html /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html +#[doc(alias = "..")] #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFull; @@ -74,6 +75,7 @@ impl fmt::Debug for RangeFull { /// assert_eq!(arr[1.. ], [ 'b', 'c', 'd']); /// assert_eq!(arr[1..3], [ 'b', 'c' ]); // Range /// ``` +#[doc(alias = "..")] #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { @@ -175,6 +177,7 @@ impl> Range { /// ``` /// /// [`Iterator`]: ../iter/trait.IntoIterator.html +#[doc(alias = "..")] #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { @@ -256,6 +259,7 @@ impl> RangeFrom { /// [`IntoIterator`]: ../iter/trait.Iterator.html /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html +#[doc(alias = "..")] #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeTo { @@ -323,6 +327,7 @@ impl> RangeTo { /// assert_eq!(arr[ ..=2], [0,1,2 ]); /// assert_eq!(arr[1..=2], [ 1,2 ]); // RangeInclusive /// ``` +#[doc(alias = "..=")] #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { @@ -449,6 +454,7 @@ impl> RangeInclusive { /// [`IntoIterator`]: ../iter/trait.Iterator.html /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html +#[doc(alias = "..=")] #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeToInclusive { From 98c2e0976d6c4d0d3bd22e477b504f1a6f9b4ffa Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Mon, 23 Apr 2018 13:54:09 +0900 Subject: [PATCH 22/24] Do not ICE on generics mismatch with non-local traits Fixes #49841 --- src/librustc_typeck/check/compare_method.rs | 3 +-- .../compile-fail/impl-trait/impl-generic-mismatch.rs | 11 +++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index e1e3dea9a2a11..2003e0cc3d28f 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -730,8 +730,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if impl_ty.synthetic != trait_ty.synthetic { let impl_node_id = tcx.hir.as_local_node_id(impl_ty.def_id).unwrap(); let impl_span = tcx.hir.span(impl_node_id); - let trait_node_id = tcx.hir.as_local_node_id(trait_ty.def_id).unwrap(); - let trait_span = tcx.hir.span(trait_node_id); + let trait_span = tcx.def_span(trait_ty.def_id); let mut err = struct_span_err!(tcx.sess, impl_span, E0643, diff --git a/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs b/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs index eea7ca2095780..d6707f590113c 100644 --- a/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs +++ b/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs @@ -28,4 +28,15 @@ impl Bar for () { //~^ Error method `bar` has incompatible signature for trait } +// With non-local trait (#49841): + +use std::hash::{Hash, Hasher}; + +struct X; + +impl Hash for X { + fn hash(&self, hasher: &mut impl Hasher) {} + //~^ Error method `hash` has incompatible signature for trait +} + fn main() {} From acf0adf7984d7bfc9bf5f81465471976c0f6b626 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 25 Apr 2018 19:50:32 +0200 Subject: [PATCH 23/24] Add setting to go to item if there is only one result --- src/librustdoc/html/render.rs | 2 + src/librustdoc/html/static/main.js | 88 +++++++++++++++++++----------- 2 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 0ae946c418286..0784c7b10e8c6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1594,6 +1594,8 @@ impl<'a> Settings<'a> { settings: vec![ ("item-declarations", "Auto-hide item declarations.", true), ("item-attributes", "Auto-hide item attributes.", true), + ("go-to-only-result", "Directly go to item in search if there is only one result", + false), ], root_path, suffix, diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 58a57f43d3745..bcad2eb19f574 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1013,7 +1013,8 @@ 'returned': sortResults(results_returned, true), 'others': sortResults(results), }; - if (ALIASES[window.currentCrate][query.raw]) { + if (ALIASES && ALIASES[window.currentCrate] && + ALIASES[window.currentCrate][query.raw]) { var aliases = ALIASES[window.currentCrate][query.raw]; for (var i = 0; i < aliases.length; ++i) { ret['others'].unshift(aliases[i]); @@ -1188,6 +1189,44 @@ return '' + path.replace(/::/g, '::'); } + function buildHrefAndPath(item) { + var displayPath; + var href; + var type = itemTypes[item.ty]; + var name = item.name; + + if (type === 'mod') { + displayPath = item.path + '::'; + href = rootPath + item.path.replace(/::/g, '/') + '/' + + name + '/index.html'; + } else if (type === "primitive") { + displayPath = ""; + href = rootPath + item.path.replace(/::/g, '/') + + '/' + type + '.' + name + '.html'; + } else if (type === "externcrate") { + displayPath = ""; + href = rootPath + name + '/index.html'; + } else if (item.parent !== undefined) { + var myparent = item.parent; + var anchor = '#' + type + '.' + name; + var parentType = itemTypes[myparent.ty]; + if (parentType === "primitive") { + displayPath = myparent.name + '::'; + } else { + displayPath = item.path + '::' + myparent.name + '::'; + } + href = rootPath + item.path.replace(/::/g, '/') + + '/' + parentType + + '.' + myparent.name + + '.html' + anchor; + } else { + displayPath = item.path + '::'; + href = rootPath + item.path.replace(/::/g, '/') + + '/' + type + '.' + name + '.html'; + } + return [displayPath, href]; + } + function addTab(array, query, display) { var extraStyle = ''; if (display === false) { @@ -1211,35 +1250,9 @@ name = item.name; type = itemTypes[item.ty]; - if (type === 'mod') { - displayPath = item.path + '::'; - href = rootPath + item.path.replace(/::/g, '/') + '/' + - name + '/index.html'; - } else if (type === "primitive") { - displayPath = ""; - href = rootPath + item.path.replace(/::/g, '/') + - '/' + type + '.' + name + '.html'; - } else if (type === "externcrate") { - displayPath = ""; - href = rootPath + name + '/index.html'; - } else if (item.parent !== undefined) { - var myparent = item.parent; - var anchor = '#' + type + '.' + name; - var parentType = itemTypes[myparent.ty]; - if (parentType === "primitive") { - displayPath = myparent.name + '::'; - } else { - displayPath = item.path + '::' + myparent.name + '::'; - } - href = rootPath + item.path.replace(/::/g, '/') + - '/' + parentType + - '.' + myparent.name + - '.html' + anchor; - } else { - displayPath = item.path + '::'; - href = rootPath + item.path.replace(/::/g, '/') + - '/' + type + '.' + name + '.html'; - } + var res = buildHrefAndPath(item); + var href = res[1]; + var displayPath = res[0]; output += '' + '' + @@ -1268,6 +1281,16 @@ } function showResults(results) { + if (results['others'].length === 1 && + getCurrentValue('rustdoc-go-to-only-result') === "true") { + var elem = document.createElement('a'); + var res = buildHrefAndPath(results['others'][0]); + elem.href = res[1]; + elem.style.display = 'none'; + // For firefox, we need the element to be in the DOM so it can be clicked. + document.body.appendChild(elem); + elem.click(); + } var output, query = getQuery(search_input.value); currentResults = query.id; @@ -1721,6 +1744,9 @@ function toggleAllDocs(pageId) { var toggle = document.getElementById("toggle-all-docs"); + if (!toggle) { + return; + } if (hasClass(toggle, "will-expand")) { updateLocalStorage("rustdoc-collapse", "false"); removeClass(toggle, "will-expand"); @@ -1977,7 +2003,7 @@ collapseDocs(e.previousSibling.childNodes[0], "toggle"); } } - }) + }); autoCollapseAllImpls(getPageId()); From 4d52751d12429f4508f9a3c537521ba1113fabf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 11 Apr 2018 23:02:41 +0200 Subject: [PATCH 24/24] Rename InternedString to LocalInternedString and introduce a new thread-safe InternedString --- src/librustc/hir/lowering.rs | 4 +- src/librustc/hir/map/def_collector.rs | 33 +-- src/librustc/hir/map/definitions.rs | 6 +- src/librustc/ich/impls_syntax.rs | 28 ++- src/librustc/lib.rs | 1 + src/librustc/traits/on_unimplemented.rs | 6 +- src/librustc/ty/context.rs | 2 +- src/librustc/ty/item_path.rs | 11 +- src/librustc/ty/maps/values.rs | 2 +- src/librustc/ty/mod.rs | 14 +- src/librustc/ty/sty.rs | 2 +- src/librustc/util/ppaux.rs | 2 +- src/librustc_driver/test.rs | 4 +- .../assert_module_sources.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_metadata/decoder.rs | 16 +- src/librustc_mir/build/expr/into.rs | 2 +- src/librustc_mir/interpret/const_eval.rs | 2 +- src/librustc_mir/monomorphize/item.rs | 2 +- src/librustc_mir/monomorphize/partitioning.rs | 14 +- src/librustc_mir/transform/check_unsafety.rs | 12 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_resolve/build_reduced_graph.rs | 5 +- src/librustc_trans/back/symbol_export.rs | 2 +- src/librustc_trans/base.rs | 2 +- src/librustc_trans/callee.rs | 2 +- src/librustc_trans/common.rs | 6 +- src/librustc_trans/consts.rs | 2 +- src/librustc_trans/context.rs | 6 +- src/librustc_trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/debuginfo/mod.rs | 2 +- src/librustc_trans/debuginfo/namespace.rs | 2 +- src/librustc_trans/debuginfo/type_names.rs | 4 +- src/librustc_trans/intrinsic.rs | 2 +- src/librustc_trans/mir/block.rs | 2 +- src/librustc_trans/trans_item.rs | 2 +- src/librustc_trans_utils/symbol_names.rs | 6 +- src/librustc_typeck/astconv.rs | 4 +- src/librustc_typeck/check/intrinsic.rs | 4 +- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/check/wfcheck.rs | 2 +- src/librustc_typeck/collect.rs | 18 +- src/librustdoc/clean/auto_trait.rs | 4 +- src/librustdoc/clean/mod.rs | 12 +- src/libsyntax_pos/symbol.rs | 192 +++++++++++++++--- 45 files changed, 307 insertions(+), 149 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4023521147e78..f5d590f25c80f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -655,7 +655,7 @@ impl<'a> LoweringContext<'a> { self.resolver.definitions().create_def_with_parent( parent_id.index, def_node_id, - DefPathData::LifetimeDef(str_name), + DefPathData::LifetimeDef(str_name.as_interned_str()), DefIndexAddressSpace::High, Mark::root(), span, @@ -1302,7 +1302,7 @@ impl<'a> LoweringContext<'a> { self.context.resolver.definitions().create_def_with_parent( self.parent, def_node_id, - DefPathData::LifetimeDef(name.name().as_str()), + DefPathData::LifetimeDef(name.name().as_interned_str()), DefIndexAddressSpace::High, Mark::root(), lifetime.span, diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index bfe21549e453d..ebd8e6235825c 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -107,18 +107,18 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { // information we encapsulate into let def_data = match i.node { ItemKind::Impl(..) => DefPathData::Impl, - ItemKind::Trait(..) => DefPathData::Trait(i.ident.name.as_str()), + ItemKind::Trait(..) => DefPathData::Trait(i.ident.name.as_interned_str()), ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::TraitAlias(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) => - DefPathData::TypeNs(i.ident.name.as_str()), + DefPathData::TypeNs(i.ident.name.as_interned_str()), ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => { return visit::walk_item(self, i); } - ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_str()), + ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_interned_str()), ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => - DefPathData::ValueNs(i.ident.name.as_str()), - ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name.as_str()), + DefPathData::ValueNs(i.ident.name.as_interned_str()), + ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name.as_interned_str()), ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false), ItemKind::GlobalAsm(..) => DefPathData::Misc, ItemKind::Use(..) => { @@ -133,7 +133,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { for v in &enum_definition.variants { let variant_def_index = this.create_def(v.node.data.id(), - DefPathData::EnumVariant(v.node.ident.name.as_str()), + DefPathData::EnumVariant(v.node.ident + .name.as_interned_str()), REGULAR_SPACE, v.span); this.with_parent(variant_def_index, |this| { @@ -141,7 +142,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { let name = field.ident.map(|ident| ident.name) .unwrap_or_else(|| Symbol::intern(&index.to_string())); this.create_def(field.id, - DefPathData::Field(name.as_str()), + DefPathData::Field(name.as_interned_str()), REGULAR_SPACE, field.span); } @@ -165,7 +166,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { let name = field.ident.map(|ident| ident.name) .unwrap_or_else(|| Symbol::intern(&index.to_string())); this.create_def(field.id, - DefPathData::Field(name.as_str()), + DefPathData::Field(name.as_interned_str()), REGULAR_SPACE, field.span); } @@ -187,7 +188,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } let def = self.create_def(foreign_item.id, - DefPathData::ValueNs(foreign_item.ident.name.as_str()), + DefPathData::ValueNs(foreign_item.ident.name.as_interned_str()), REGULAR_SPACE, foreign_item.span); @@ -201,7 +202,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { GenericParam::Lifetime(ref lifetime_def) => { self.create_def( lifetime_def.lifetime.id, - DefPathData::LifetimeDef(lifetime_def.lifetime.ident.name.as_str()), + DefPathData::LifetimeDef(lifetime_def.lifetime.ident.name.as_interned_str()), REGULAR_SPACE, lifetime_def.lifetime.ident.span ); @@ -209,7 +210,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { GenericParam::Type(ref ty_param) => { self.create_def( ty_param.id, - DefPathData::TypeParam(ty_param.ident.name.as_str()), + DefPathData::TypeParam(ty_param.ident.name.as_interned_str()), REGULAR_SPACE, ty_param.ident.span ); @@ -222,8 +223,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_trait_item(&mut self, ti: &'a TraitItem) { let def_data = match ti.node { TraitItemKind::Method(..) | TraitItemKind::Const(..) => - DefPathData::ValueNs(ti.ident.name.as_str()), - TraitItemKind::Type(..) => DefPathData::AssocTypeInTrait(ti.ident.name.as_str()), + DefPathData::ValueNs(ti.ident.name.as_interned_str()), + TraitItemKind::Type(..) => { + DefPathData::AssocTypeInTrait(ti.ident.name.as_interned_str()) + }, TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false), }; @@ -240,8 +243,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_impl_item(&mut self, ii: &'a ImplItem) { let def_data = match ii.node { ImplItemKind::Method(..) | ImplItemKind::Const(..) => - DefPathData::ValueNs(ii.ident.name.as_str()), - ImplItemKind::Type(..) => DefPathData::AssocTypeInImpl(ii.ident.name.as_str()), + DefPathData::ValueNs(ii.ident.name.as_interned_str()), + ImplItemKind::Type(..) => DefPathData::AssocTypeInImpl(ii.ident.name.as_interned_str()), ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false), }; diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 12f146ef49115..616dc22486d92 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -701,7 +701,7 @@ impl DefPathData { Typeof => "{{typeof}}", }; - Symbol::intern(s).as_str() + Symbol::intern(s).as_interned_str() } pub fn to_string(&self) -> String { @@ -731,7 +731,7 @@ macro_rules! define_global_metadata_kind { definitions.create_def_with_parent( CRATE_DEF_INDEX, ast::DUMMY_NODE_ID, - DefPathData::GlobalMetaData(instance.name().as_str()), + DefPathData::GlobalMetaData(instance.name().as_interned_str()), GLOBAL_MD_ADDRESS_SPACE, Mark::root(), DUMMY_SP @@ -746,7 +746,7 @@ macro_rules! define_global_metadata_kind { let def_key = DefKey { parent: Some(CRATE_DEF_INDEX), disambiguated_data: DisambiguatedDefPathData { - data: DefPathData::GlobalMetaData(self.name().as_str()), + data: DefPathData::GlobalMetaData(self.name().as_interned_str()), disambiguator: 0, } }; diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index d7e16ab36205e..c1e86473996d0 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -19,7 +19,7 @@ use std::mem; use syntax::ast; use syntax::feature_gate; use syntax::parse::token; -use syntax::symbol::InternedString; +use syntax::symbol::{InternedString, LocalInternedString}; use syntax::tokenstream; use syntax_pos::FileMap; @@ -34,8 +34,7 @@ impl<'a> HashStable> for InternedString { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let s: &str = &**self; - s.hash_stable(hcx, hasher); + self.with(|s| s.hash_stable(hcx, hasher)) } } @@ -50,6 +49,27 @@ impl<'a> ToStableHashKey> for InternedString { } } +impl<'a> HashStable> for LocalInternedString { + #[inline] + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + let s: &str = &**self; + s.hash_stable(hcx, hasher); + } +} + +impl<'a> ToStableHashKey> for LocalInternedString { + type KeyType = LocalInternedString; + + #[inline] + fn to_stable_hash_key(&self, + _: &StableHashingContext<'a>) + -> LocalInternedString { + self.clone() + } +} + impl<'a> HashStable> for ast::Name { #[inline] fn hash_stable(&self, @@ -66,7 +86,7 @@ impl<'a> ToStableHashKey> for ast::Name { fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> InternedString { - self.as_str() + self.as_interned_str() } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index f85d0a9bf0c2e..c2b1d7f09149e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -58,6 +58,7 @@ #![feature(nonzero)] #![feature(proc_macro_internals)] #![feature(quote)] +#![feature(optin_builtin_traits)] #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 405dafdff2b34..d1fd70ae02d69 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -18,10 +18,10 @@ use util::nodemap::FxHashMap; use syntax::ast::{MetaItem, NestedMetaItem}; use syntax::attr; use syntax_pos::Span; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::LocalInternedString; #[derive(Clone, Debug)] -pub struct OnUnimplementedFormatString(InternedString); +pub struct OnUnimplementedFormatString(LocalInternedString); #[derive(Debug)] pub struct OnUnimplementedDirective { @@ -225,7 +225,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { pub fn try_parse(tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_def_id: DefId, - from: InternedString, + from: LocalInternedString, err_sp: Span) -> Result { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 4f49b159ad387..d38c003ef8aeb 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2471,7 +2471,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn mk_self_type(self) -> Ty<'tcx> { - self.mk_param(0, keywords::SelfType.name().as_str()) + self.mk_param(0, keywords::SelfType.name().as_interned_str()) } pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> { diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 2819141c81be2..752b7f69a6a7f 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -14,7 +14,7 @@ use ty::{self, Ty, TyCtxt}; use middle::cstore::{ExternCrate, ExternCrateSource}; use syntax::ast; use syntax::symbol::Symbol; -use syntax::symbol::InternedString; +use syntax::symbol::LocalInternedString; use std::cell::Cell; @@ -131,7 +131,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { { let visible_parent_map = self.visible_parent_map(LOCAL_CRATE); - let (mut cur_def, mut cur_path) = (external_def_id, Vec::::new()); + let (mut cur_def, mut cur_path) = (external_def_id, Vec::::new()); loop { // If `cur_def` is a direct or injected extern crate, push the path to the crate // followed by the path to the item within the crate and return. @@ -168,8 +168,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } let data = cur_def_key.disambiguated_data.data; - let symbol = - data.get_opt_name().unwrap_or_else(|| Symbol::intern("").as_str()); + let symbol = data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { + Symbol::intern("").as_str() + }); cur_path.push(symbol); match visible_parent_map.get(&cur_def) { @@ -221,7 +222,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { data @ DefPathData::GlobalMetaData(..) => { let parent_def_id = self.parent_def_id(def_id).unwrap(); self.push_item_path(buffer, parent_def_id); - buffer.push(&data.as_interned_str()); + buffer.push(&data.as_interned_str().as_symbol().as_str()); } DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` let parent_def_id = self.parent_def_id(def_id).unwrap(); diff --git a/src/librustc/ty/maps/values.rs b/src/librustc/ty/maps/values.rs index 8d38d7dbbbbff..d3d0624879240 100644 --- a/src/librustc/ty/maps/values.rs +++ b/src/librustc/ty/maps/values.rs @@ -37,7 +37,7 @@ impl<'tcx> Value<'tcx> for Ty<'tcx> { impl<'tcx> Value<'tcx> for ty::SymbolName { fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self { - ty::SymbolName { name: Symbol::intern("").as_str() } + ty::SymbolName { name: Symbol::intern("").as_interned_str() } } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index de04366841076..19532bc80aa0d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -51,7 +51,7 @@ use std::mem; use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId}; use syntax::attr; use syntax::ext::hygiene::Mark; -use syntax::symbol::{Symbol, InternedString}; +use syntax::symbol::{Symbol, LocalInternedString, InternedString}; use syntax_pos::{DUMMY_SP, Span}; use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter; @@ -2463,7 +2463,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn item_name(self, id: DefId) -> InternedString { if id.index == CRATE_DEF_INDEX { - self.original_crate_name(id.krate).as_str() + self.original_crate_name(id.krate).as_interned_str() } else { let def_key = self.def_key(id); // The name of a StructCtor is that of its struct parent. @@ -2820,15 +2820,13 @@ impl_stable_hash_for!(struct self::SymbolName { impl SymbolName { pub fn new(name: &str) -> SymbolName { SymbolName { - name: Symbol::intern(name).as_str() + name: Symbol::intern(name).as_interned_str() } } -} - -impl Deref for SymbolName { - type Target = str; - fn deref(&self) -> &str { &self.name } + pub fn as_str(&self) -> LocalInternedString { + self.name.as_str() + } } impl fmt::Display for SymbolName { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 0dfae13cc753a..2220f2b0aaf3a 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -864,7 +864,7 @@ impl<'a, 'gcx, 'tcx> ParamTy { } pub fn for_self() -> ParamTy { - ParamTy::new(0, keywords::SelfType.name().as_str()) + ParamTy::new(0, keywords::SelfType.name().as_interned_str()) } pub fn for_def(def: &ty::TypeParameterDef) -> ParamTy { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 905776373bd37..b777f513e6df0 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -462,7 +462,7 @@ impl PrintContext { 0 => Symbol::intern("'r"), 1 => Symbol::intern("'s"), i => Symbol::intern(&format!("'t{}", i-2)), - }.as_str() + }.as_interned_str() } // Replace any anonymous late-bound regions with named diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 47c49fbe9ef47..d2ee3d8743c2c 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -303,11 +303,11 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { pub fn t_param(&self, index: u32) -> Ty<'tcx> { let name = format!("T{}", index); - self.infcx.tcx.mk_param(index, Symbol::intern(&name).as_str()) + self.infcx.tcx.mk_param(index, Symbol::intern(&name).as_interned_str()) } pub fn re_early_bound(&self, index: u32, name: &'static str) -> ty::Region<'tcx> { - let name = Symbol::intern(name).as_str(); + let name = Symbol::intern(name).as_interned_str(); self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: self.infcx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), index, diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index 46ba94f206151..6906dacfc5ef6 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -74,7 +74,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> { let mname = self.field(attr, MODULE); let mangled_cgu_name = CodegenUnit::mangle_name(&mname.as_str()); - let mangled_cgu_name = Symbol::intern(&mangled_cgu_name).as_str(); + let mangled_cgu_name = Symbol::intern(&mangled_cgu_name).as_interned_str(); let dep_node = DepNode::new(self.tcx, DepConstructor::CompileCodegenUnit(mangled_cgu_name)); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index a11b95cb5b6c1..91f8beeaafb00 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -535,7 +535,7 @@ impl CrateStore for cstore::CStore { .insert(local_span, (name.to_string(), data.get_span(id.index, sess))); LoadedMacro::MacroDef(ast::Item { - ident: ast::Ident::from_str(&name), + ident: ast::Ident::from_str(&name.as_str()), id: ast::DUMMY_NODE_ID, span: local_span, attrs: attrs.iter().cloned().collect(), diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0147e8dc60759..388bf1fb99a34 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -40,7 +40,7 @@ use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque}; use syntax::attr; use syntax::ast::{self, Ident}; use syntax::codemap; -use syntax::symbol::{InternedString, Symbol}; +use syntax::symbol::InternedString; use syntax::ext::base::MacroKind; use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION}; @@ -537,12 +537,12 @@ impl<'a, 'tcx> CrateMetadata { ty::VariantDef { did: self.local_def_id(data.struct_ctor.unwrap_or(index)), - name: Symbol::intern(&self.item_name(index)), + name: self.item_name(index).as_symbol(), fields: item.children.decode(self).map(|index| { let f = self.entry(index); ty::FieldDef { did: self.local_def_id(index), - name: Symbol::intern(&self.item_name(index)), + name: self.item_name(index).as_symbol(), vis: f.visibility.decode(self) } }).collect(), @@ -730,7 +730,7 @@ impl<'a, 'tcx> CrateMetadata { if let Some(def) = self.get_def(child_index) { callback(def::Export { def, - ident: Ident::from_str(&self.item_name(child_index)), + ident: Ident::from_interned_str(self.item_name(child_index)), vis: self.get_visibility(child_index), span: self.entry(child_index).span.decode((self, sess)), is_import: false, @@ -748,7 +748,7 @@ impl<'a, 'tcx> CrateMetadata { let span = child.span.decode((self, sess)); if let (Some(def), Some(name)) = (self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) { - let ident = Ident::from_str(&name); + let ident = Ident::from_interned_str(name); let vis = self.get_visibility(child_index); let is_import = false; callback(def::Export { def, ident, vis, span, is_import }); @@ -847,7 +847,7 @@ impl<'a, 'tcx> CrateMetadata { }; ty::AssociatedItem { - name: Symbol::intern(&name), + name: name.as_symbol(), kind, vis: item.visibility.decode(self), defaultness: container.defaultness(), @@ -914,7 +914,7 @@ impl<'a, 'tcx> CrateMetadata { self.entry(id) .children .decode(self) - .map(|index| Symbol::intern(&self.item_name(index))) + .map(|index| self.item_name(index).as_symbol()) .collect() } @@ -1106,7 +1106,7 @@ impl<'a, 'tcx> CrateMetadata { DefKey { parent: Some(CRATE_DEF_INDEX), disambiguated_data: DisambiguatedDefPathData { - data: DefPathData::MacroDef(name.as_str()), + data: DefPathData::MacroDef(name.as_interned_str()), disambiguator: 0, } } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index c130b4f550fd4..562f890b4c0fb 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -220,7 +220,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let f = ty.fn_sig(this.hir.tcx()); if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic { - Some(this.hir.tcx().item_name(def_id)) + Some(this.hir.tcx().item_name(def_id).as_str()) } else { None } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index a25331f7279fb..dff9fa271aba5 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -263,7 +263,7 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator { ) -> EvalResult<'tcx> { let substs = instance.substs; - let intrinsic_name = &ecx.tcx.item_name(instance.def_id())[..]; + let intrinsic_name = &ecx.tcx.item_name(instance.def_id()).as_str()[..]; match intrinsic_name { "min_align_of" => { let elem_ty = substs.type_at(0); diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 9e0c977a3f062..9e43bed1b63af 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -76,7 +76,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { MonoItem::GlobalAsm(node_id) => { let def_id = tcx.hir.local_def_id(node_id); ty::SymbolName { - name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_str() + name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_interned_str() } } } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index f29f86af4aba7..3a65cd4ea770b 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -146,7 +146,7 @@ pub trait CodegenUnitExt<'tcx> { } fn work_product_id(&self) -> WorkProductId { - WorkProductId::from_cgu_name(self.name()) + WorkProductId::from_cgu_name(&self.name().as_str()) } fn items_in_deterministic_order<'a>(&self, @@ -206,9 +206,9 @@ fn fallback_cgu_name(tcx: TyCtxt) -> InternedString { const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit"; if tcx.sess.opts.debugging_opts.human_readable_cgu_names { - Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str() + Symbol::intern(FALLBACK_CODEGEN_UNIT).as_interned_str() } else { - Symbol::intern(&CodegenUnit::mangle_name(FALLBACK_CODEGEN_UNIT)).as_str() + Symbol::intern(&CodegenUnit::mangle_name(FALLBACK_CODEGEN_UNIT)).as_interned_str() } } @@ -740,7 +740,7 @@ fn compute_codegen_unit_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } }) { cgu_name.push_str("-"); - cgu_name.push_str(&part.data.as_interned_str()); + cgu_name.push_str(&part.data.as_interned_str().as_str()); } if volatile { @@ -753,11 +753,11 @@ fn compute_codegen_unit_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, CodegenUnit::mangle_name(&cgu_name) }; - Symbol::intern(&cgu_name[..]).as_str() + Symbol::intern(&cgu_name[..]).as_interned_str() } fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString { - Symbol::intern(&format!("{}{}", crate_name, index)).as_str() + Symbol::intern(&format!("{}{}", crate_name, index)).as_interned_str() } fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -772,7 +772,7 @@ fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("CodegenUnit {}:", cgu.name()); for (trans_item, linkage) in cgu.items() { - let symbol_name = trans_item.symbol_name(tcx); + let symbol_name = trans_item.symbol_name(tcx).name.as_str(); let symbol_hash_start = symbol_name.rfind('h'); let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..]) .unwrap_or(""); diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 31af7c2185794..2bf5a49c97e8f 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -149,7 +149,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.visibility_scope_info[source_info.scope].lint_root; self.register_violations(&[UnsafetyViolation { source_info, - description: Symbol::intern("borrow of packed field").as_str(), + description: Symbol::intern("borrow of packed field").as_interned_str(), kind: UnsafetyViolationKind::BorrowPacked(lint_root) }], &[]); } @@ -214,7 +214,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.visibility_scope_info[source_info.scope].lint_root; self.register_violations(&[UnsafetyViolation { source_info, - description: Symbol::intern("use of extern static").as_str(), + description: Symbol::intern("use of extern static").as_interned_str(), kind: UnsafetyViolationKind::ExternStatic(lint_root) }], &[]); } @@ -231,7 +231,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { let source_info = self.source_info; self.register_violations(&[UnsafetyViolation { source_info, - description: Symbol::intern(description).as_str(), + description: Symbol::intern(description).as_interned_str(), kind: UnsafetyViolationKind::General, }], &[]); } @@ -444,7 +444,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { struct_span_err!( tcx.sess, source_info.span, E0133, "{} requires unsafe function or block", description) - .span_label(source_info.span, &description[..]) + .span_label(source_info.span, &description.as_str()[..]) .emit(); } UnsafetyViolationKind::ExternStatic(lint_node_id) => { @@ -452,7 +452,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { lint_node_id, source_info.span, &format!("{} requires unsafe function or \ - block (error E0133)", &description[..])); + block (error E0133)", &description.as_str()[..])); } UnsafetyViolationKind::BorrowPacked(lint_node_id) => { if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) { @@ -462,7 +462,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { lint_node_id, source_info.span, &format!("{} requires unsafe function or \ - block (error E0133)", &description[..])); + block (error E0133)", &description.as_str()[..])); } } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index ff7551ed6f4f8..4762c6aaa27cc 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -868,7 +868,7 @@ This does not pose a problem by itself because they can't be accessed directly." Abi::RustIntrinsic | Abi::PlatformIntrinsic => { assert!(!self.tcx.is_const_fn(def_id)); - match &self.tcx.item_name(def_id)[..] { + match &self.tcx.item_name(def_id).as_str()[..] { "size_of" | "min_align_of" | "type_id" => is_const_fn = Some(def_id), name if name.starts_with("simd_shuffle") => { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index f4e2136a5a115..14ceb5f59a3ec 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -41,7 +41,6 @@ use syntax::ext::tt::macro_rules; use syntax::parse::token::{self, Token}; use syntax::std_inject::injected_crate_name; use syntax::symbol::keywords; -use syntax::symbol::Symbol; use syntax::visit::{self, Visitor}; use syntax_pos::{Span, DUMMY_SP}; @@ -544,14 +543,14 @@ impl<'a> Resolver<'a> { } let (name, parent) = if def_id.index == CRATE_DEF_INDEX { - (self.cstore.crate_name_untracked(def_id.krate).as_str(), None) + (self.cstore.crate_name_untracked(def_id.krate).as_interned_str(), None) } else { let def_key = self.cstore.def_key(def_id); (def_key.disambiguated_data.data.get_opt_name().unwrap(), Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }))) }; - let kind = ModuleKind::Def(Def::Mod(def_id), Symbol::intern(&name)); + let kind = ModuleKind::Def(Def::Mod(def_id), name.as_symbol()); let module = self.arenas.alloc_module(ModuleData::new(parent, kind, def_id, Mark::root(), DUMMY_SP)); self.extern_module_map.insert((def_id, macros_only), module); diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 965a34eccb862..d8520b61d9157 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -132,7 +132,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) .map(|def_id| { let export_level = if special_runtime_crate { - let name = tcx.symbol_name(Instance::mono(tcx, def_id)); + let name = tcx.symbol_name(Instance::mono(tcx, def_id)).as_str(); // We can probably do better here by just ensuring that // it has hidden visibility rather than public // visibility, as this is primarily here to ensure it's diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 2323ec3ef1108..b756a6695f941 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1037,7 +1037,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>( cgus.dedup(); for &(ref cgu_name, (linkage, _)) in cgus.iter() { output.push_str(" "); - output.push_str(&cgu_name); + output.push_str(&cgu_name.as_str()); let linkage_abbrev = match linkage { Linkage::External => "External", diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 5849437758af6..9263d9a5f5dc2 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -52,7 +52,7 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return llfn; } - let sym = tcx.symbol_name(instance); + let sym = tcx.symbol_name(instance).as_str(); debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym); // Create a fn pointer with the substituted signature. diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 25ca2152b2768..4a0619b23360d 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -33,7 +33,7 @@ use libc::{c_uint, c_char}; use std::iter; use rustc_target::spec::abi::Abi; -use syntax::symbol::InternedString; +use syntax::symbol::LocalInternedString; use syntax_pos::{Span, DUMMY_SP}; pub use context::CodegenCx; @@ -183,7 +183,7 @@ pub fn C_u8(cx: &CodegenCx, i: u8) -> ValueRef { // This is a 'c-like' raw string, which differs from // our boxed-and-length-annotated strings. -pub fn C_cstr(cx: &CodegenCx, s: InternedString, null_terminated: bool) -> ValueRef { +pub fn C_cstr(cx: &CodegenCx, s: LocalInternedString, null_terminated: bool) -> ValueRef { unsafe { if let Some(&llval) = cx.const_cstr_cache.borrow().get(&s) { return llval; @@ -208,7 +208,7 @@ pub fn C_cstr(cx: &CodegenCx, s: InternedString, null_terminated: bool) -> Value // NB: Do not use `do_spill_noroot` to make this into a constant string, or // you will be kicked off fast isel. See issue #4352 for an example of this. -pub fn C_str_slice(cx: &CodegenCx, s: InternedString) -> ValueRef { +pub fn C_str_slice(cx: &CodegenCx, s: LocalInternedString) -> ValueRef { let len = s.len(); let cs = consts::ptrcast(C_cstr(cx, s, false), cx.layout_of(cx.tcx.mk_str()).llvm_type(cx).ptr_to()); diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 122b51dbbb778..405cb83ad4d75 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -118,7 +118,7 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { def_id); let ty = instance.ty(cx.tcx); - let sym = cx.tcx.symbol_name(instance); + let sym = cx.tcx.symbol_name(instance).as_str(); let g = if let Some(id) = cx.tcx.hir.as_local_node_id(def_id) { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 76f8be9ee98a6..90b2fb4b59a70 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -39,7 +39,7 @@ use std::ptr; use std::iter; use std::str; use std::sync::Arc; -use syntax::symbol::InternedString; +use syntax::symbol::LocalInternedString; use abi::Abi; /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM @@ -62,7 +62,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> { pub vtables: RefCell, Option>), ValueRef>>, /// Cache of constant strings, - pub const_cstr_cache: RefCell>, + pub const_cstr_cache: RefCell>, /// Reverse-direction for const ptrs cast from globals. /// Key is a ValueRef holding a *T, @@ -273,7 +273,7 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> { let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo { let dctx = debuginfo::CrateDebugContext::new(llmod); debuginfo::metadata::compile_unit_metadata(tcx, - codegen_unit.name(), + &codegen_unit.name().as_str(), &dctx); Some(dctx) } else { diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 5359e0e0405a1..123b9cf7931a5 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -1399,7 +1399,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, (discr.size(cx), discr.align(cx)); let discriminant_base_type_metadata = type_metadata(cx, discr.to_ty(cx.tcx), syntax_pos::DUMMY_SP); - let discriminant_name = get_enum_discriminant_name(cx, enum_def_id); + let discriminant_name = get_enum_discriminant_name(cx, enum_def_id).as_str(); let name = CString::new(discriminant_name.as_bytes()).unwrap(); let discriminant_type_metadata = unsafe { diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 706dc3dca8a61..193db15303f97 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -394,7 +394,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, substs.types().zip(names).map(|(ty, name)| { let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); - let name = CString::new(name.as_bytes()).unwrap(); + let name = CString::new(name.as_str().as_bytes()).unwrap(); unsafe { llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs index 891bf649c388a..51c45de9dc22a 100644 --- a/src/librustc_trans/debuginfo/namespace.rs +++ b/src/librustc_trans/debuginfo/namespace.rs @@ -47,7 +47,7 @@ pub fn item_namespace(cx: &CodegenCx, def_id: DefId) -> DIScope { let namespace_name = match def_key.disambiguated_data.data { DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate).as_str(), - data => data.as_interned_str() + data => data.as_interned_str().as_str() }; let namespace_name = CString::new(namespace_name.as_bytes()).unwrap(); diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 96ed4e8847115..825fac36c93d7 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -190,10 +190,10 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, output.push_str(&cx.tcx.crate_name(def_id.krate).as_str()); for path_element in cx.tcx.def_path(def_id).data { output.push_str("::"); - output.push_str(&path_element.data.as_interned_str()); + output.push_str(&path_element.data.as_interned_str().as_str()); } } else { - output.push_str(&cx.tcx.item_name(def_id)); + output.push_str(&cx.tcx.item_name(def_id).as_str()); } } diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 103b04e6f135b..49a207a2d8ab5 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -103,7 +103,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); let arg_tys = sig.inputs(); let ret_ty = sig.output(); - let name = &*tcx.item_name(def_id); + let name = &*tcx.item_name(def_id).as_str(); let llret_ty = cx.layout_of(ret_ty).llvm_type(cx); let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align); diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 36f03605feabd..fb6a17a1c75b4 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -442,7 +442,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { // Handle intrinsics old trans wants Expr's for, ourselves. let intrinsic = match def { Some(ty::InstanceDef::Intrinsic(def_id)) - => Some(bx.tcx().item_name(def_id)), + => Some(bx.tcx().item_name(def_id).as_str()), _ => None }; let intrinsic = intrinsic.as_ref().map(|s| &s[..]); diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 06d94e8d15569..d19b5af25273d 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -88,7 +88,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { self.to_raw_string(), cx.codegen_unit.name()); - let symbol_name = self.symbol_name(cx.tcx); + let symbol_name = self.symbol_name(cx.tcx).as_str(); debug!("symbol {}", &symbol_name); diff --git a/src/librustc_trans_utils/symbol_names.rs b/src/librustc_trans_utils/symbol_names.rs index f3b7326b21071..be5bff60805c3 100644 --- a/src/librustc_trans_utils/symbol_names.rs +++ b/src/librustc_trans_utils/symbol_names.rs @@ -229,7 +229,7 @@ fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { - ty::SymbolName { name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_str() } + ty::SymbolName { name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str() } } fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) @@ -355,12 +355,12 @@ impl SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16) }; - result.result.push_str(&symbol.name); + result.result.push_str(&symbol.name.as_str()); result } fn into_interned(self) -> ty::SymbolName { - ty::SymbolName { name: Symbol::intern(&self.result).as_str() } + ty::SymbolName { name: Symbol::intern(&self.result).as_interned_str() } } fn finish(mut self, hash: u64) -> String { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 6cdce127308f6..93dbba6e873a9 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -101,7 +101,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { { let tcx = self.tcx(); let lifetime_name = |def_id| { - tcx.hir.name(tcx.hir.as_local_node_id(def_id).unwrap()).as_str() + tcx.hir.name(tcx.hir.as_local_node_id(def_id).unwrap()).as_interned_str() }; let hir_id = tcx.hir.node_to_hir_id(lifetime.id); @@ -981,7 +981,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let item_def_id = tcx.hir.local_def_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id)]; - tcx.mk_param(index, tcx.hir.name(node_id).as_str()) + tcx.mk_param(index, tcx.hir.name(node_id).as_interned_str()) } Def::SelfTy(_, Some(def_id)) => { // Self in impl (we know the concrete type). diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 283fbf8fecc42..fcf7541a159b0 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -76,7 +76,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// and in libcore/intrinsics.rs pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::ForeignItem) { - let param = |n| tcx.mk_param(n, Symbol::intern(&format!("P{}", n)).as_str()); + let param = |n| tcx.mk_param(n, Symbol::intern(&format!("P{}", n)).as_interned_str()); let name = it.name.as_str(); let (n_tps, inputs, output) = if name.starts_with("atomic_") { let split : Vec<&str> = name.split('_').collect(); @@ -341,7 +341,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::ForeignItem) { let param = |n| { - let name = Symbol::intern(&format!("P{}", n)).as_str(); + let name = Symbol::intern(&format!("P{}", n)).as_interned_str(); tcx.mk_param(n, name) }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 787df7c647969..db859e42057e9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -124,7 +124,7 @@ use syntax::attr; use syntax::codemap::{original_sp, Spanned}; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::ptr::P; -use syntax::symbol::{Symbol, InternedString, keywords}; +use syntax::symbol::{Symbol, LocalInternedString, keywords}; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{self, BytePos, Span, MultiSpan}; @@ -3172,7 +3172,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Return an hint about the closest match in field names fn suggest_field_name(variant: &'tcx ty::VariantDef, field: &Spanned, - skip: Vec) + skip: Vec) -> Option { let name = field.node.as_str(); let names = variant.fields.iter().filter_map(|field| { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 9c4807bec2f08..d0ff44c8e7e10 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -655,7 +655,7 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) { // local so it should be okay to just unwrap everything. let trait_def_id = impl_params[&method_param.name]; let trait_decl_span = tcx.def_span(trait_def_id); - error_194(tcx, type_span, trait_decl_span, &method_param.name[..]); + error_194(tcx, type_span, trait_decl_span, &method_param.name.as_str()[..]); } } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 2ebbd64cab90e..1b8f2e661c30d 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -244,7 +244,7 @@ fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let param_owner_def_id = tcx.hir.local_def_id(param_owner); let generics = tcx.generics_of(param_owner_def_id); let index = generics.type_param_to_index[&def_id]; - let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id).as_str()); + let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id).as_interned_str()); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner_def_id { @@ -842,7 +842,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, opt_self = Some(ty::TypeParameterDef { index: 0, - name: keywords::SelfType.name().as_str(), + name: keywords::SelfType.name().as_interned_str(), def_id: tcx.hir.local_def_id(param_id), has_default: false, object_lifetime_default: rl::Set1::Empty, @@ -888,7 +888,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics); let regions = early_lifetimes.enumerate().map(|(i, l)| { ty::RegionParameterDef { - name: l.lifetime.name.name().as_str(), + name: l.lifetime.name.name().as_interned_str(), index: own_start + i as u32, def_id: tcx.hir.local_def_id(l.lifetime.id), pure_wrt_drop: l.pure_wrt_drop, @@ -918,7 +918,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TypeParameterDef { index: type_start + i as u32, - name: p.name.as_str(), + name: p.name.as_interned_str(), def_id: tcx.hir.local_def_id(p.id), has_default: p.default.is_some(), object_lifetime_default: @@ -937,7 +937,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // add a dummy parameter for the closure kind types.push(ty::TypeParameterDef { index: type_start, - name: Symbol::intern("").as_str(), + name: Symbol::intern("").as_interned_str(), def_id, has_default: false, object_lifetime_default: rl::Set1::Empty, @@ -948,7 +948,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // add a dummy parameter for the closure signature types.push(ty::TypeParameterDef { index: type_start + 1, - name: Symbol::intern("").as_str(), + name: Symbol::intern("").as_interned_str(), def_id, has_default: false, object_lifetime_default: rl::Set1::Empty, @@ -959,7 +959,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.with_freevars(node_id, |fv| { types.extend(fv.iter().zip(2..).map(|(_, i)| ty::TypeParameterDef { index: type_start + i, - name: Symbol::intern("").as_str(), + name: Symbol::intern("").as_interned_str(), def_id, has_default: false, object_lifetime_default: rl::Set1::Empty, @@ -1429,7 +1429,7 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: tcx.hir.local_def_id(param.lifetime.id), index, - name: param.lifetime.name.name().as_str(), + name: param.lifetime.name.name().as_interned_str(), })); index += 1; @@ -1443,7 +1443,7 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Collect the predicates that were written inline by the user on each // type parameter (e.g., ``). for param in ast_generics.ty_params() { - let param_ty = ty::ParamTy::new(index, param.name.as_str()).to_ty(tcx); + let param_ty = ty::ParamTy::new(index, param.name.as_interned_str()).to_ty(tcx); index += 1; let bounds = compute_bounds(&icx, diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 477b576ad217e..221fc4dab7232 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -224,7 +224,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let name = if p.name == "" { hir::LifetimeName::Static } else { - hir::LifetimeName::Name(Symbol::intern(&p.name)) + hir::LifetimeName::Name(p.name.as_symbol()) }; hir::Lifetime { @@ -261,7 +261,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { span: DUMMY_SP, def: Def::TyParam(param.def_id), segments: HirVec::from_vec(vec![ - hir::PathSegment::from_name(Symbol::intern(¶m.name)) + hir::PathSegment::from_name(param.name.as_symbol()) ]), }), )), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fb05cbfe32c70..6623d5ab3c2c2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1367,7 +1367,7 @@ impl TyParamBound { fn maybe_sized(cx: &DocContext) -> TyParamBound { let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem); let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, &cx.tcx.item_name(did), + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), false, vec![], empty); inline::record_extern_fqn(cx, did, TypeKind::Trait); TraitBound(PolyTrait { @@ -1474,7 +1474,7 @@ impl<'a, 'tcx> Clean for (&'a ty::TraitRef<'tcx>, Vec fn clean(&self, cx: &DocContext) -> TyParamBound { let (trait_ref, ref bounds) = *self; inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait); - let path = external_path(cx, &cx.tcx.item_name(trait_ref.def_id), + let path = external_path(cx, &cx.tcx.item_name(trait_ref.def_id).as_str(), Some(trait_ref.def_id), true, bounds.clone(), trait_ref.substs); debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); @@ -2801,7 +2801,7 @@ impl<'tcx> Clean for Ty<'tcx> { AdtKind::Enum => TypeKind::Enum, }; inline::record_extern_fqn(cx, did, kind); - let path = external_path(cx, &cx.tcx.item_name(did), + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), None, false, vec![], substs); ResolvedPath { path, @@ -2812,7 +2812,7 @@ impl<'tcx> Clean for Ty<'tcx> { } ty::TyForeign(did) => { inline::record_extern_fqn(cx, did, TypeKind::Foreign); - let path = external_path(cx, &cx.tcx.item_name(did), + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), None, false, vec![], Substs::empty()); ResolvedPath { path: path, @@ -2830,7 +2830,7 @@ impl<'tcx> Clean for Ty<'tcx> { reg.clean(cx).map(|b| typarams.push(RegionBound(b))); for did in obj.auto_traits() { let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, &cx.tcx.item_name(did), + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), false, vec![], empty); inline::record_extern_fqn(cx, did, TypeKind::Trait); let bound = TraitBound(PolyTrait { @@ -2853,7 +2853,7 @@ impl<'tcx> Clean for Ty<'tcx> { }); } - let path = external_path(cx, &cx.tcx.item_name(did), Some(did), + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), false, bindings, principal.skip_binder().substs); ResolvedPath { path, diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 556ee162c6ef2..4a8b1e8b1c1e4 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -18,6 +18,7 @@ use {Span, DUMMY_SP, GLOBALS}; use rustc_data_structures::fx::FxHashMap; use serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; +use std::cmp::{PartialEq, Ordering, PartialOrd, Ord}; use std::hash::{Hash, Hasher}; #[derive(Copy, Clone, Eq)] @@ -36,6 +37,11 @@ impl Ident { Ident::new(name, DUMMY_SP) } + /// Maps an interned string to an identifier with an empty syntax context. + pub fn from_interned_str(string: InternedString) -> Ident { + Ident::with_empty_ctxt(string.as_symbol()) + } + /// Maps a string to an identifier with an empty syntax context. pub fn from_str(string: &str) -> Ident { Ident::with_empty_ctxt(Symbol::intern(string)) @@ -138,14 +144,20 @@ impl Symbol { with_interner(|interner| interner.gensymed(self)) } - pub fn as_str(self) -> InternedString { + pub fn as_str(self) -> LocalInternedString { with_interner(|interner| unsafe { - InternedString { + LocalInternedString { string: ::std::mem::transmute::<&str, &str>(interner.get(self)) } }) } + pub fn as_interned_str(self) -> InternedString { + with_interner(|interner| InternedString { + symbol: interner.interned(self) + }) + } + pub fn as_u32(self) -> u32 { self.0 } @@ -365,84 +377,208 @@ fn with_interner T>(f: F) -> T { GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock())) } -/// Represents a string stored in the thread-local interner. Because the -/// interner lives for the life of the thread, this can be safely treated as an -/// immortal string, as long as it never crosses between threads. -/// -/// FIXME(pcwalton): You must be careful about what you do in the destructors -/// of objects stored in TLS, because they may run after the interner is -/// destroyed. In particular, they must not access string contents. This can -/// be fixed in the future by just leaking all strings until thread death -/// somehow. +/// Represents a string stored in the interner. Because the interner outlives any thread +/// which uses this type, we can safely treat `string` which points to interner data, +/// as an immortal string, as long as this type never crosses between threads. +// FIXME: Ensure that the interner outlives any thread which uses LocalInternedString, +// by creating a new thread right after constructing the interner #[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)] -pub struct InternedString { +pub struct LocalInternedString { string: &'static str, } -impl ::std::convert::AsRef for InternedString where str: ::std::convert::AsRef { +impl LocalInternedString { + pub fn as_interned_str(self) -> InternedString { + InternedString { + symbol: Symbol::intern(self.string) + } + } +} + +impl ::std::convert::AsRef for LocalInternedString +where + str: ::std::convert::AsRef +{ fn as_ref(&self) -> &U { self.string.as_ref() } } -impl> ::std::cmp::PartialEq for InternedString { +impl> ::std::cmp::PartialEq for LocalInternedString { fn eq(&self, other: &T) -> bool { self.string == other.deref() } } -impl ::std::cmp::PartialEq for str { - fn eq(&self, other: &InternedString) -> bool { +impl ::std::cmp::PartialEq for str { + fn eq(&self, other: &LocalInternedString) -> bool { self == other.string } } -impl<'a> ::std::cmp::PartialEq for &'a str { - fn eq(&self, other: &InternedString) -> bool { +impl<'a> ::std::cmp::PartialEq for &'a str { + fn eq(&self, other: &LocalInternedString) -> bool { *self == other.string } } -impl ::std::cmp::PartialEq for String { - fn eq(&self, other: &InternedString) -> bool { +impl ::std::cmp::PartialEq for String { + fn eq(&self, other: &LocalInternedString) -> bool { self == other.string } } -impl<'a> ::std::cmp::PartialEq for &'a String { - fn eq(&self, other: &InternedString) -> bool { +impl<'a> ::std::cmp::PartialEq for &'a String { + fn eq(&self, other: &LocalInternedString) -> bool { *self == other.string } } -impl !Send for InternedString { } +impl !Send for LocalInternedString {} +impl !Sync for LocalInternedString {} -impl ::std::ops::Deref for InternedString { +impl ::std::ops::Deref for LocalInternedString { type Target = str; fn deref(&self) -> &str { self.string } } -impl fmt::Debug for InternedString { +impl fmt::Debug for LocalInternedString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(self.string, f) } } -impl fmt::Display for InternedString { +impl fmt::Display for LocalInternedString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self.string, f) } } +impl Decodable for LocalInternedString { + fn decode(d: &mut D) -> Result { + Ok(Symbol::intern(&d.read_str()?).as_str()) + } +} + +impl Encodable for LocalInternedString { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_str(self.string) + } +} + +/// Represents a string stored in the string interner +#[derive(Clone, Copy, Eq)] +pub struct InternedString { + symbol: Symbol, +} + +impl InternedString { + pub fn with R, R>(self, f: F) -> R { + let str = with_interner(|interner| { + interner.get(self.symbol) as *const str + }); + // This is safe because the interner keeps string alive until it is dropped. + // We can access it because we know the interner is still alive since we use a + // scoped thread local to access it, and it was alive at the begining of this scope + unsafe { f(&*str) } + } + + pub fn as_symbol(self) -> Symbol { + self.symbol + } + + pub fn as_str(self) -> LocalInternedString { + self.symbol.as_str() + } +} + +impl Hash for InternedString { + fn hash(&self, state: &mut H) { + self.with(|str| str.hash(state)) + } +} + +impl PartialOrd for InternedString { + fn partial_cmp(&self, other: &InternedString) -> Option { + if self.symbol == other.symbol { + return Some(Ordering::Equal); + } + self.with(|self_str| other.with(|other_str| self_str.partial_cmp(&other_str))) + } +} + +impl Ord for InternedString { + fn cmp(&self, other: &InternedString) -> Ordering { + if self.symbol == other.symbol { + return Ordering::Equal; + } + self.with(|self_str| other.with(|other_str| self_str.cmp(&other_str))) + } +} + +impl> PartialEq for InternedString { + fn eq(&self, other: &T) -> bool { + self.with(|string| string == other.deref()) + } +} + +impl PartialEq for InternedString { + fn eq(&self, other: &InternedString) -> bool { + self.symbol == other.symbol + } +} + +impl PartialEq for str { + fn eq(&self, other: &InternedString) -> bool { + other.with(|string| self == string) + } +} + +impl<'a> PartialEq for &'a str { + fn eq(&self, other: &InternedString) -> bool { + other.with(|string| *self == string) + } +} + +impl PartialEq for String { + fn eq(&self, other: &InternedString) -> bool { + other.with(|string| self == string) + } +} + +impl<'a> PartialEq for &'a String { + fn eq(&self, other: &InternedString) -> bool { + other.with(|string| *self == string) + } +} + +impl ::std::convert::From for String { + fn from(val: InternedString) -> String { + val.as_symbol().to_string() + } +} + +impl fmt::Debug for InternedString { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.with(|str| fmt::Debug::fmt(&str, f)) + } +} + +impl fmt::Display for InternedString { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.with(|str| fmt::Display::fmt(&str, f)) + } +} + impl Decodable for InternedString { fn decode(d: &mut D) -> Result { - Ok(Symbol::intern(&d.read_str()?).as_str()) + Ok(Symbol::intern(&d.read_str()?).as_interned_str()) } } impl Encodable for InternedString { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_str(self.string) + self.with(|string| s.emit_str(string)) } }