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:
commit
ada45fd49a
@ -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,
|
||||
|
@ -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";
|
||||
);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
1
src/doc/rustc/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
book
|
5
src/doc/rustc/book.toml
Normal file
5
src/doc/rustc/book.toml
Normal file
@ -0,0 +1,5 @@
|
||||
[book]
|
||||
authors = ["The Rust Project Developers"]
|
||||
multilingual = false
|
||||
src = "src"
|
||||
title = "The rustc book"
|
16
src/doc/rustc/src/SUMMARY.md
Normal file
16
src/doc/rustc/src/SUMMARY.md
Normal 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)
|
209
src/doc/rustc/src/codegen-options/index.md
Normal file
209
src/doc/rustc/src/codegen-options/index.md
Normal 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.
|
116
src/doc/rustc/src/command-line-arguments.md
Normal file
116
src/doc/rustc/src/command-line-arguments.md
Normal 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.
|
6
src/doc/rustc/src/contributing.md
Normal file
6
src/doc/rustc/src/contributing.md
Normal 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.
|
29
src/doc/rustc/src/lints/groups.md
Normal file
29
src/doc/rustc/src/lints/groups.md
Normal 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.
|
28
src/doc/rustc/src/lints/index.md
Normal file
28
src/doc/rustc/src/lints/index.md
Normal 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.
|
252
src/doc/rustc/src/lints/levels.md
Normal file
252
src/doc/rustc/src/lints/levels.md
Normal 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.
|
453
src/doc/rustc/src/lints/listing/allowed-by-default.md
Normal file
453
src/doc/rustc/src/lints/listing/allowed-by-default.md
Normal 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
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
```
|
241
src/doc/rustc/src/lints/listing/deny-by-default.md
Normal file
241
src/doc/rustc/src/lints/listing/deny-by-default.md
Normal 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"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
```
|
5
src/doc/rustc/src/lints/listing/index.md
Normal file
5
src/doc/rustc/src/lints/listing/index.md
Normal 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`.
|
1039
src/doc/rustc/src/lints/listing/warn-by-default.md
Normal file
1039
src/doc/rustc/src/lints/listing/warn-by-default.md
Normal file
File diff suppressed because it is too large
Load Diff
10
src/doc/rustc/src/targets/built-in.md
Normal file
10
src/doc/rustc/src/targets/built-in.md
Normal 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.
|
17
src/doc/rustc/src/targets/custom.md
Normal file
17
src/doc/rustc/src/targets/custom.md
Normal 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).
|
13
src/doc/rustc/src/targets/index.md
Normal file
13
src/doc/rustc/src/targets/index.md
Normal 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
|
||||
```
|
68
src/doc/rustc/src/what-is-rustc.md
Normal file
68
src/doc/rustc/src/what-is-rustc.md
Normal 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.
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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}`")]
|
||||
|
@ -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.
|
||||
|
@ -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> {
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)]
|
||||
|
@ -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>
|
||||
{
|
||||
|
@ -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> {
|
||||
|
@ -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();
|
||||
|
@ -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() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>");
|
||||
|
@ -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()[..]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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") => {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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[..]);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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).
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
};
|
||||
|
||||
|
@ -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| {
|
||||
|
@ -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()[..]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -224,7 +224,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
|
||||
let name = if p.name == "" {
|
||||
hir::LifetimeName::Static
|
||||
} else {
|
||||
hir::LifetimeName::Name(Symbol::intern(&p.name))
|
||||
hir::LifetimeName::Name(p.name.as_symbol())
|
||||
};
|
||||
|
||||
hir::Lifetime {
|
||||
@ -261,7 +261,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
|
||||
span: DUMMY_SP,
|
||||
def: Def::TyParam(param.def_id),
|
||||
segments: HirVec::from_vec(vec![
|
||||
hir::PathSegment::from_name(Symbol::intern(¶m.name))
|
||||
hir::PathSegment::from_name(param.name.as_symbol())
|
||||
]),
|
||||
}),
|
||||
)),
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user