Auto merge of #50275 - kennytm:rollup, r=kennytm

Rollup of 7 pull requests

Successful merges:

 - #49707 (Add "the Rustc book")
 - #50222 (Bump bootstrap compiler to 2018-04-24)
 - #50227 (Fix ICE with erroneous `impl Trait` in a trait impl)
 - #50229 (Add setting to go to item if there is only one result)
 - #50231 (Add more doc aliases)
 - #50246 (Make dump_{alloc,allocs,local}() no-ops when tracing is disabled.)
 - #49894 (Rename InternedString to LocalInternedString and introduce a new thread-safe InternedString)

Failed merges:
This commit is contained in:
bors 2018-04-27 09:59:12 +00:00
commit ada45fd49a
79 changed files with 2939 additions and 191 deletions

View File

@ -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, test::RustdocUi),
@ -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,

View File

@ -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";
);

View File

@ -1212,6 +1212,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;

View File

@ -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.

1
src/doc/rustc/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
book

5
src/doc/rustc/book.toml Normal file
View File

@ -0,0 +1,5 @@
[book]
authors = ["The Rust Project Developers"]
multilingual = false
src = "src"
title = "The rustc book"

View File

@ -0,0 +1,16 @@
# The Rustc Book
- [What is rustc?](what-is-rustc.md)
- [Command-line arguments](command-line-arguments.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)
- [Targets](targets/index.md)
- [Built-in Targets](targets/built-in.md)
- [Custom Targets](targets/custom.md)
- [Contributing to `rustc`](contributing.md)

View File

@ -0,0 +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
parallelism](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.

View File

@ -0,0 +1,116 @@
# Command-line arguments
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
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`/`--version`: 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
This flag lets you control the format of errors.
## `--color`: configure coloring of output
This flag lets you control color settings of the output.

View File

@ -0,0 +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.

View File

@ -0,0 +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.

View File

@ -0,0 +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:
```bash
$ 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.

View File

@ -0,0 +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:
```bash
$ 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:
```console
$ 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,ignore
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,ignore
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.

View File

@ -0,0 +1,453 @@
# 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 <https://github.com/rust-lang/rust/issues/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<Trait>) {
}
```
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<Trait>) {
| ^^^^^ 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<dyn Trait>) {
}
```
## box-pointers
This lints use of the Box type. Some example code that triggers this lint:
```rust
struct Foo {
x: Box<isize>,
}
```
When set to 'deny', this will produce:
```text
error: type uses owned (Box type) pointers: std::boxed::Box<isize>
--> src/lib.rs:6:5
|
6 | x: Box<isize> //~ ERROR type uses owned
| ^^^^^^^^^^^^^
|
```
This lint is mostly historical, and not particularly useful. `Box<T>` 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,ignore
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};
pub mod test {
pub struct A;
}
# fn main() {}
```
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,no_run
fn foo<T>() -> T { panic!() }
fn main() {
foo::<usize>();
}
```
When set to 'deny', this will produce:
```text
error: unused result
--> src/main.rs:6:5
|
6 | foo::<usize>();
| ^^^^^^^^^^^^^^^
|
```
## 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]),
}
```
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
| ^^^^^^^^^^^^^^^^
|
```

View File

@ -0,0 +1,241 @@
# Deny-by-default lints
These lints are all set to the 'deny' level by default.
## exceeding-bitshifts
This lint detects that a shift exceeds the type's number of bits. Some
example code that triggers this lint:
```rust,ignore
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,ignore
fn foo<T=i32>(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=i32>(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 <https://github.com/rust-lang/rust/issues/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,ignore
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 <https://github.com/rust-lang/rust/issues/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,ignore
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 <https://github.com/rust-lang/rust/issues/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,ignore
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,ignore
#[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,ignore
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 <https://github.com/rust-lang/rust/issues/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,ignore
#![crate_type="lol"]
```
This will produce:
```text
error: invalid `crate_type` value
--> src/lib.rs:1:1
|
1 | #![crate_type="lol"]
| ^^^^^^^^^^^^^^^^^^^^
|
```

View File

@ -0,0 +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`.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +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.

View File

@ -0,0 +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).

View File

@ -0,0 +1,13 @@
# 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.
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
```

View File

@ -0,0 +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.

View File

@ -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<Rhs: ?Sized = Self> {
/// This method tests for `self` and `other` values to be equal, and is used
@ -160,6 +162,8 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
/// }
/// impl Eq for Book {}
/// ```
#[doc(alias = "==")]
#[doc(alias = "!=")]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Eq: PartialEq<Self> {
// this method is used solely by #[deriving] to assert
@ -428,6 +432,10 @@ impl<T: Ord> Ord for Reverse<T> {
/// }
/// ```
#[lang = "ord"]
#[doc(alias = "<")]
#[doc(alias = ">")]
#[doc(alias = "<=")]
#[doc(alias = ">=")]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Ord: Eq + PartialOrd<Self> {
/// 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<Rhs: ?Sized = Self>: PartialEq<Rhs> {
/// This method returns an ordering between `self` and `other` values if one exists.

View File

@ -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.

View File

@ -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}`")]

View File

@ -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.

View File

@ -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<Idx> {
@ -175,6 +177,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// ```
///
/// [`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<Idx> {
@ -256,6 +259,7 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
/// [`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<Idx> {
@ -323,6 +327,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
/// 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<Idx> {
@ -449,6 +454,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// [`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<Idx> {

View File

@ -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,

View File

@ -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),
};

View File

@ -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,
}
};

View File

@ -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<StableHashingContext<'a>> for InternedString {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let s: &str = &**self;
s.hash_stable(hcx, hasher);
self.with(|s| s.hash_stable(hcx, hasher))
}
}
@ -50,6 +49,27 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
}
}
impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let s: &str = &**self;
s.hash_stable(hcx, hasher);
}
}
impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
type KeyType = LocalInternedString;
#[inline]
fn to_stable_hash_key(&self,
_: &StableHashingContext<'a>)
-> LocalInternedString {
self.clone()
}
}
impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
@ -66,7 +86,7 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
fn to_stable_hash_key(&self,
_: &StableHashingContext<'a>)
-> InternedString {
self.as_str()
self.as_interned_str()
}
}

View File

@ -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)]

View File

@ -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<Self, ErrorReported>
{

View File

@ -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> {

View File

@ -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::<InternedString>::new());
let (mut cur_def, mut cur_path) = (external_def_id, Vec::<LocalInternedString>::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("<unnamed>").as_str());
let symbol = data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| {
Symbol::intern("<unnamed>").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();

View File

@ -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("<error>").as_str() }
ty::SymbolName { name: Symbol::intern("<error>").as_interned_str() }
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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,

View File

@ -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));

View File

@ -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(),

View File

@ -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,
}
}

View File

@ -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
}

View File

@ -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);

View File

@ -768,9 +768,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(())
}
@ -1572,6 +1570,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();

View File

@ -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<AllocId>) {
if !log_enabled!(::log::Level::Trace) {
return;
}
use std::fmt::Write;
allocs.sort();
allocs.dedup();

View File

@ -219,9 +219,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)
}

View File

@ -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()
}
}
}

View File

@ -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("<no hash>");

View File

@ -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()[..]));
}
}
}

View File

@ -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") => {

View File

@ -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);

View File

@ -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

View File

@ -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",

View File

@ -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.

View File

@ -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());

View File

@ -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) {

View File

@ -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<FxHashMap<(Ty<'tcx>,
Option<ty::PolyExistentialTraitRef<'tcx>>), ValueRef>>,
/// Cache of constant strings,
pub const_cstr_cache: RefCell<FxHashMap<InternedString, ValueRef>>,
pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, ValueRef>>,
/// 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 {

View File

@ -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 {

View File

@ -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),

View File

@ -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();

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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[..]);

View File

@ -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);

View File

@ -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 {

View File

@ -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).

View File

@ -732,8 +732,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,

View File

@ -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)
};

View File

@ -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<ast::Name>,
skip: Vec<InternedString>)
skip: Vec<LocalInternedString>)
-> Option<Symbol> {
let name = field.node.as_str();
let names = variant.fields.iter().filter_map(|field| {

View File

@ -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()[..]);
}
}
}

View File

@ -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("<closure_kind>").as_str(),
name: Symbol::intern("<closure_kind>").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("<closure_signature>").as_str(),
name: Symbol::intern("<closure_signature>").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("<upvar>").as_str(),
name: Symbol::intern("<upvar>").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., `<T:Foo>`).
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,

View File

@ -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(&param.name))
hir::PathSegment::from_name(param.name.as_symbol())
]),
}),
)),

View File

@ -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<TyParamBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>
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<Type> 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<Type> 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<Type> 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<Type> 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,

View File

@ -1595,6 +1595,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,

View File

@ -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 '<span>' + path.replace(/::/g, '::</span><span>');
}
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 += '<tr class="' + type + ' result"><td>' +
'<a href="' + href + '">' +
@ -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());

View File

@ -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: FnOnce(&mut 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<U: ?Sized> ::std::convert::AsRef<U> for InternedString where str: ::std::convert::AsRef<U> {
impl LocalInternedString {
pub fn as_interned_str(self) -> InternedString {
InternedString {
symbol: Symbol::intern(self.string)
}
}
}
impl<U: ?Sized> ::std::convert::AsRef<U> for LocalInternedString
where
str: ::std::convert::AsRef<U>
{
fn as_ref(&self) -> &U {
self.string.as_ref()
}
}
impl<T: ::std::ops::Deref<Target = str>> ::std::cmp::PartialEq<T> for InternedString {
impl<T: ::std::ops::Deref<Target = str>> ::std::cmp::PartialEq<T> for LocalInternedString {
fn eq(&self, other: &T) -> bool {
self.string == other.deref()
}
}
impl ::std::cmp::PartialEq<InternedString> for str {
fn eq(&self, other: &InternedString) -> bool {
impl ::std::cmp::PartialEq<LocalInternedString> for str {
fn eq(&self, other: &LocalInternedString) -> bool {
self == other.string
}
}
impl<'a> ::std::cmp::PartialEq<InternedString> for &'a str {
fn eq(&self, other: &InternedString) -> bool {
impl<'a> ::std::cmp::PartialEq<LocalInternedString> for &'a str {
fn eq(&self, other: &LocalInternedString) -> bool {
*self == other.string
}
}
impl ::std::cmp::PartialEq<InternedString> for String {
fn eq(&self, other: &InternedString) -> bool {
impl ::std::cmp::PartialEq<LocalInternedString> for String {
fn eq(&self, other: &LocalInternedString) -> bool {
self == other.string
}
}
impl<'a> ::std::cmp::PartialEq<InternedString> for &'a String {
fn eq(&self, other: &InternedString) -> bool {
impl<'a> ::std::cmp::PartialEq<LocalInternedString> 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: Decoder>(d: &mut D) -> Result<LocalInternedString, D::Error> {
Ok(Symbol::intern(&d.read_str()?).as_str())
}
}
impl Encodable for LocalInternedString {
fn encode<S: Encoder>(&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<F: FnOnce(&str) -> 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<H: Hasher>(&self, state: &mut H) {
self.with(|str| str.hash(state))
}
}
impl PartialOrd<InternedString> for InternedString {
fn partial_cmp(&self, other: &InternedString) -> Option<Ordering> {
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<T: ::std::ops::Deref<Target = str>> PartialEq<T> for InternedString {
fn eq(&self, other: &T) -> bool {
self.with(|string| string == other.deref())
}
}
impl PartialEq<InternedString> for InternedString {
fn eq(&self, other: &InternedString) -> bool {
self.symbol == other.symbol
}
}
impl PartialEq<InternedString> for str {
fn eq(&self, other: &InternedString) -> bool {
other.with(|string| self == string)
}
}
impl<'a> PartialEq<InternedString> for &'a str {
fn eq(&self, other: &InternedString) -> bool {
other.with(|string| *self == string)
}
}
impl PartialEq<InternedString> for String {
fn eq(&self, other: &InternedString) -> bool {
other.with(|string| self == string)
}
}
impl<'a> PartialEq<InternedString> for &'a String {
fn eq(&self, other: &InternedString) -> bool {
other.with(|string| *self == string)
}
}
impl ::std::convert::From<InternedString> 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: Decoder>(d: &mut D) -> Result<InternedString, D::Error> {
Ok(Symbol::intern(&d.read_str()?).as_str())
Ok(Symbol::intern(&d.read_str()?).as_interned_str())
}
}
impl Encodable for InternedString {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_str(self.string)
self.with(|string| s.emit_str(string))
}
}

View File

@ -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

View File

@ -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() {}