Merge remote-tracking branch 'origin/master' into gen
This commit is contained in:
commit
b8aa595e6d
168 changed files with 2634 additions and 1443 deletions
186
RELEASES.md
186
RELEASES.md
|
|
@ -1,3 +1,187 @@
|
|||
Version 1.20.0 (2017-08-31)
|
||||
===========================
|
||||
|
||||
Language
|
||||
--------
|
||||
- [Associated constants in traits is now stabilised.][42809]
|
||||
- [A lot of macro bugs are now fixed.][42913]
|
||||
|
||||
Compiler
|
||||
--------
|
||||
|
||||
- [Struct fields are now properly coerced to the expected field type.][42807]
|
||||
- [Enabled wasm LLVM backend][42571] WASM can now be built with the
|
||||
`wasm32-experimental-emscripten` target.
|
||||
- [Changed some of the error messages to be more helpful.][42033]
|
||||
- [Add support for RELRO(RELocation Read-Only) for platforms that support
|
||||
it.][43170]
|
||||
- [rustc now reports the total number of errors on compilation failure][43015]
|
||||
previously this was only the number of errors in the pass that failed.
|
||||
- [Expansion in rustc has been sped up 29x.][42533]
|
||||
- [added `msp430-none-elf` target.][43099]
|
||||
- [rustc will now suggest one-argument enum variant to fix type mismatch when
|
||||
applicable][43178]
|
||||
- [Fixes backtraces on Redox][43228]
|
||||
- [rustc now identifies different versions of same crate when absolute paths of
|
||||
different types match in an error message.][42826]
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
|
||||
- [Relaxed Debug constraints on `{HashMap,BTreeMap}::{Keys,Values}`.][42854]
|
||||
- [Impl `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `Debug`, `Hash` for unsized
|
||||
tuples.][43011]
|
||||
- [Impl `fmt::{Display, Debug}` for `Ref`, `RefMut`, `MutexGuard`,
|
||||
`RwLockReadGuard`, `RwLockWriteGuard`][42822]
|
||||
- [Impl `Clone` for `DefaultHasher`.][42799]
|
||||
- [Impl `Sync` for `SyncSender`.][42397]
|
||||
- [Impl `FromStr` for `char`][42271]
|
||||
- [Fixed how `{f32, f64}::{is_sign_negative, is_sign_positive}` handles
|
||||
NaN.][42431]
|
||||
- [allow messages in the `unimplemented!()` macro.][42155]
|
||||
ie. `unimplemented!("Waiting for 1.21 to be stable")`
|
||||
- [`pub(restricted)` is now supported in the `thread_local!` macro.][43185]
|
||||
- [Upgrade to Unicode 10.0.0][42999]
|
||||
- [Reimplemented `{f32, f64}::{min, max}` in Rust instead of using CMath.][42430]
|
||||
- [Skip the main thread's manual stack guard on Linux][43072]
|
||||
- [Iterator::nth for `ops::{Range, RangeFrom}` is now done in O(1) time][43077]
|
||||
- [`#[repr(align(N))]` attribute max number is now 2^31 - 1.][43097] This was
|
||||
previously 2^15.
|
||||
- [`{OsStr, Path}::Display` now avoids allocations where possible][42613]
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`CStr::into_c_string`]
|
||||
- [`CString::as_c_str`]
|
||||
- [`CString::into_boxed_c_str`]
|
||||
- [`Chain::get_mut`]
|
||||
- [`Chain::get_ref`]
|
||||
- [`Chain::into_inner`]
|
||||
- [`Option::get_or_insert_with`]
|
||||
- [`Option::get_or_insert`]
|
||||
- [`OsStr::into_os_string`]
|
||||
- [`OsString::into_boxed_os_str`]
|
||||
- [`Take::get_mut`]
|
||||
- [`Take::get_ref`]
|
||||
- [`Utf8Error::error_len`]
|
||||
- [`char::EscapeDebug`]
|
||||
- [`char::escape_debug`]
|
||||
- [`compile_error!`]
|
||||
- [`f32::from_bits`]
|
||||
- [`f32::to_bits`]
|
||||
- [`f64::from_bits`]
|
||||
- [`f64::to_bits`]
|
||||
- [`mem::ManuallyDrop`]
|
||||
- [`slice::sort_unstable_by_key`]
|
||||
- [`slice::sort_unstable_by`]
|
||||
- [`slice::sort_unstable`]
|
||||
- [`ste::from_boxed_utf8_unchecked`]
|
||||
- [`str::as_bytes_mut`]
|
||||
- [`str::as_bytes_mut`]
|
||||
- [`str::from_utf8_mut`]
|
||||
- [`str::from_utf8_unchecked_mut`]
|
||||
- [`str::get_mut`]
|
||||
- [`str::get_unchecked_mut`]
|
||||
- [`str::get_unchecked`]
|
||||
- [`str::get`]
|
||||
- [`str::into_boxed_bytes`]
|
||||
|
||||
|
||||
Cargo
|
||||
-----
|
||||
- [Cargo API token location moved from `~/.cargo/config` to
|
||||
`~/cargo/credentials`.][cargo/3978]
|
||||
- [Cargo will now build `main.rs` binaries that are in sub-directories of
|
||||
`src/bin`.][cargo/4214] ie. Having `src/bin/server/main.rs` and
|
||||
`src/bin/client/main.rs` generates `target/debug/server` and `target/debug/client`
|
||||
- [You can now specify version of a binary when installed through
|
||||
`cargo install` using `--vers`.][cargo/4229]
|
||||
- [Added `--no-fail-fast` flag to cargo to run all benchmarks regardless of
|
||||
failure.][cargo/4248]
|
||||
- [Changed the convention around which file is the crate root.][cargo/4259]
|
||||
- [The `include`/`exclude` property in `Cargo.toml` now accepts gitignore paths
|
||||
instead of glob patterns][cargo/4270]. Glob patterns are now deprecated.
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- [Functions with `'static` in their return types will now not be as usable as
|
||||
if they were using lifetime parameters instead.][42417]
|
||||
- [The reimplementation of `{f32, f64}::is_sign_{negative, positive}` now
|
||||
takes the sign of NaN into account where previously didn't.][42430]
|
||||
|
||||
[42033]: https://github.com/rust-lang/rust/pull/42033
|
||||
[42155]: https://github.com/rust-lang/rust/pull/42155
|
||||
[42271]: https://github.com/rust-lang/rust/pull/42271
|
||||
[42397]: https://github.com/rust-lang/rust/pull/42397
|
||||
[42417]: https://github.com/rust-lang/rust/pull/42417
|
||||
[42430]: https://github.com/rust-lang/rust/pull/42430
|
||||
[42431]: https://github.com/rust-lang/rust/pull/42431
|
||||
[42533]: https://github.com/rust-lang/rust/pull/42533
|
||||
[42571]: https://github.com/rust-lang/rust/pull/42571
|
||||
[42613]: https://github.com/rust-lang/rust/pull/42613
|
||||
[42799]: https://github.com/rust-lang/rust/pull/42799
|
||||
[42807]: https://github.com/rust-lang/rust/pull/42807
|
||||
[42809]: https://github.com/rust-lang/rust/pull/42809
|
||||
[42822]: https://github.com/rust-lang/rust/pull/42822
|
||||
[42826]: https://github.com/rust-lang/rust/pull/42826
|
||||
[42854]: https://github.com/rust-lang/rust/pull/42854
|
||||
[42913]: https://github.com/rust-lang/rust/pull/42913
|
||||
[42999]: https://github.com/rust-lang/rust/pull/42999
|
||||
[43011]: https://github.com/rust-lang/rust/pull/43011
|
||||
[43015]: https://github.com/rust-lang/rust/pull/43015
|
||||
[43072]: https://github.com/rust-lang/rust/pull/43072
|
||||
[43077]: https://github.com/rust-lang/rust/pull/43077
|
||||
[43097]: https://github.com/rust-lang/rust/pull/43097
|
||||
[43099]: https://github.com/rust-lang/rust/pull/43099
|
||||
[43170]: https://github.com/rust-lang/rust/pull/43170
|
||||
[43178]: https://github.com/rust-lang/rust/pull/43178
|
||||
[43185]: https://github.com/rust-lang/rust/pull/43185
|
||||
[43228]: https://github.com/rust-lang/rust/pull/43228
|
||||
[cargo/3978]: https://github.com/rust-lang/cargo/pull/3978
|
||||
[cargo/4214]: https://github.com/rust-lang/cargo/pull/4214
|
||||
[cargo/4229]: https://github.com/rust-lang/cargo/pull/4229
|
||||
[cargo/4248]: https://github.com/rust-lang/cargo/pull/4248
|
||||
[cargo/4259]: https://github.com/rust-lang/cargo/pull/4259
|
||||
[cargo/4270]: https://github.com/rust-lang/cargo/pull/4270
|
||||
[`CStr::into_c_string`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html#method.into_c_string
|
||||
[`CString::as_c_str`]: https://doc.rust-lang.org/std/ffi/struct.CString.html#method.as_c_str
|
||||
[`CString::into_boxed_c_str`]: https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
|
||||
[`Chain::get_mut`]: https://doc.rust-lang.org/std/io/struct.Chain.html#method.get_mut
|
||||
[`Chain::get_ref`]: https://doc.rust-lang.org/std/io/struct.Chain.html#method.get_ref
|
||||
[`Chain::into_inner`]: https://doc.rust-lang.org/std/io/struct.Chain.html#method.into_inner
|
||||
[`Option::get_or_insert_with`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.get_or_insert_with
|
||||
[`Option::get_or_insert`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.get_or_insert
|
||||
[`OsStr::into_os_string`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.into_os_string
|
||||
[`OsString::into_boxed_os_str`]: https://doc.rust-lang.org/std/ffi/struct.OsString.html#method.into_boxed_os_str
|
||||
[`Take::get_mut`]: https://doc.rust-lang.org/std/io/struct.Take.html#method.get_mut
|
||||
[`Take::get_ref`]: https://doc.rust-lang.org/std/io/struct.Take.html#method.get_ref
|
||||
[`Utf8Error::error_len`]: https://doc.rust-lang.org/std/str/struct.Utf8Error.html#method.error_len
|
||||
[`char::EscapeDebug`]: https://doc.rust-lang.org/std/char/struct.EscapeDebug.html
|
||||
[`char::escape_debug`]: https://doc.rust-lang.org/std/primitive.char.html#method.escape_debug
|
||||
[`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
|
||||
[`f32::from_bits`]: https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits
|
||||
[`f32::to_bits`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_bits
|
||||
[`f64::from_bits`]: https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits
|
||||
[`f64::to_bits`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_bits
|
||||
[`mem::ManuallyDrop`]: https://doc.rust-lang.org/std/mem/union.ManuallyDrop.html
|
||||
[`slice::sort_unstable_by_key`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable_by_key
|
||||
[`slice::sort_unstable_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable_by
|
||||
[`slice::sort_unstable`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable
|
||||
[`ste::from_boxed_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_boxed_utf8_unchecked.html
|
||||
[`str::as_bytes_mut`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_bytes_mut
|
||||
[`str::as_bytes_mut`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_bytes_mut
|
||||
[`str::from_utf8_mut`]: https://doc.rust-lang.org/std/str/fn.from_utf8_mut.html
|
||||
[`str::from_utf8_unchecked_mut`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked_mut.html
|
||||
[`str::get_mut`]: https://doc.rust-lang.org/std/primitive.str.html#method.get_mut
|
||||
[`str::get_unchecked_mut`]: https://doc.rust-lang.org/std/primitive.str.html#method.get_unchecked_mut
|
||||
[`str::get_unchecked`]: https://doc.rust-lang.org/std/primitive.str.html#method.get_unchecked
|
||||
[`str::get`]: https://doc.rust-lang.org/std/primitive.str.html#method.get
|
||||
[`str::into_boxed_bytes`]: https://doc.rust-lang.org/std/primitive.str.html#method.into_boxed_bytes
|
||||
|
||||
|
||||
Version 1.19.0 (2017-07-20)
|
||||
===========================
|
||||
|
||||
|
|
@ -1679,7 +1863,7 @@ Tooling
|
|||
|
||||
* [Test binaries now support a `--test-threads` argument to specify the number
|
||||
of threads used to run tests, and which acts the same as the
|
||||
`RUST_TEST_THREADS` environment variable](https://github.com/rust-lang/rust/pull/35414)
|
||||
`RUST_TEST_THREADS` environment variable](https://github.com/rust-lang/rust/pull/35414)
|
||||
* [The test runner now emits a warning when tests run over 60 seconds](https://github.com/rust-lang/rust/pull/35405)
|
||||
* [rustdoc: Fix methods in search results](https://github.com/rust-lang/rust/pull/34752)
|
||||
* [`rust-lldb` warns about unsupported versions of LLDB](https://github.com/rust-lang/rust/pull/34646)
|
||||
|
|
|
|||
72
src/Cargo.lock
generated
72
src/Cargo.lock
generated
|
|
@ -75,7 +75,7 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ dependencies = [
|
|||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -99,7 +99,7 @@ version = "0.1.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -135,7 +135,7 @@ dependencies = [
|
|||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -200,7 +200,7 @@ dependencies = [
|
|||
"ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jobserver 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -234,7 +234,7 @@ dependencies = [
|
|||
"hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -302,7 +302,7 @@ dependencies = [
|
|||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -341,7 +341,7 @@ version = "0.4.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"curl-sys 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"socket2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -354,7 +354,7 @@ version = "0.3.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -456,7 +456,7 @@ name = "filetime"
|
|||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -472,7 +472,7 @@ name = "flate2"
|
|||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -496,7 +496,7 @@ version = "0.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -521,7 +521,7 @@ version = "0.6.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -662,7 +662,7 @@ name = "jobserver"
|
|||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -714,7 +714,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.27"
|
||||
version = "0.2.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
|
@ -725,7 +725,7 @@ dependencies = [
|
|||
"cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"curl-sys 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -738,7 +738,7 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -750,7 +750,7 @@ version = "1.0.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -771,7 +771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -801,7 +801,7 @@ name = "memchr"
|
|||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -809,7 +809,7 @@ name = "memchr"
|
|||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -818,7 +818,7 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -843,7 +843,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -919,7 +919,7 @@ name = "num_cpus"
|
|||
version = "1.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -935,7 +935,7 @@ dependencies = [
|
|||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -950,7 +950,7 @@ version = "0.9.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -1072,7 +1072,7 @@ name = "rand"
|
|||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1604,7 +1604,7 @@ dependencies = [
|
|||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -1709,7 +1709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -1828,7 +1828,7 @@ name = "syntex_errors"
|
|||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -1850,7 +1850,7 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -1865,7 +1865,7 @@ version = "0.4.13"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -1896,7 +1896,7 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -1931,7 +1931,7 @@ version = "2.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2120,7 +2120,7 @@ name = "xattr"
|
|||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2189,7 +2189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum languageserver-types 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d52e477b23bf52cd3ca0f9fc6c5d14be954eec97e3b9cdfbd962d911bd533caf"
|
||||
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
|
||||
"checksum libc 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)" = "719aa0af4c241fa71d396ffdfe584aa758f08f35b4680ec3f03ecc2c3fe69b76"
|
||||
"checksum libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8a014d9226c2cc402676fbe9ea2e15dd5222cd1dd57f576b5b283178c944a264"
|
||||
"checksum libgit2-sys 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "df18a822100352d9863b302faf6f8f25c0e77f0e60feb40e5dbe1238b7f13b1d"
|
||||
"checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75"
|
||||
"checksum libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "3fdd64ef8ee652185674455c1d450b83cbc8ad895625d543b5324d923f82e4d8"
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ impl<'a> Builder<'a> {
|
|||
} else {
|
||||
self.sysroot(compiler)
|
||||
})
|
||||
.env("RUSTC_LIBDIR", self.sysroot_libdir(compiler, self.build.build))
|
||||
.env("RUSTC_LIBDIR", self.rustc_libdir(compiler))
|
||||
.env("CFG_RELEASE_CHANNEL", &self.build.config.channel)
|
||||
.env("RUSTDOC_REAL", self.rustdoc(compiler));
|
||||
cmd
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import itertools
|
|||
SPEC = re.compile(
|
||||
r'^(?:(?P<void>V)|(?P<id>[iusfIUSF])(?:\((?P<start>\d+)-(?P<end>\d+)\)|'
|
||||
r'(?P<width>\d+)(:?/(?P<llvm_width>\d+))?)'
|
||||
r'|(?P<reference>\d+))(?P<index>\.\d+)?(?P<modifiers>[vShdnwusfDMC]*)(?P<force_width>x\d+)?'
|
||||
r'|(?P<reference>\d+))(?P<index>\.\d+)?(?P<modifiers>[vShdnwusfDMCNW]*)(?P<force_width>x\d+)?'
|
||||
r'(?:(?P<pointer>Pm|Pc)(?P<llvm_pointer>/.*)?|(?P<bitcast>->.*))?$'
|
||||
)
|
||||
|
||||
|
|
@ -246,6 +246,12 @@ class Vector(Type):
|
|||
return Vector(self._elem, self._length // 2)
|
||||
elif spec == 'd':
|
||||
return Vector(self._elem, self._length * 2)
|
||||
elif spec == 'N':
|
||||
elem = self._elem.__class__(self._elem.bitwidth() // 2)
|
||||
return Vector(elem, self._length * 2)
|
||||
elif spec == 'W':
|
||||
elem = self._elem.__class__(self._elem.bitwidth() * 2)
|
||||
return Vector(elem, self._length // 2)
|
||||
elif spec.startswith('x'):
|
||||
new_bitwidth = int(spec[1:])
|
||||
return Vector(self._elem, new_bitwidth // self._elem.bitwidth())
|
||||
|
|
@ -714,6 +720,8 @@ def parse_args():
|
|||
- 'd': double the length of the vector (u32x2 -> u32x4)
|
||||
- 'n': narrow the element of the vector (u32x4 -> u16x4)
|
||||
- 'w': widen the element of the vector (u16x4 -> u32x4)
|
||||
- 'N': half the length of the vector element (u32x4 -> u16x8)
|
||||
- 'W': double the length of the vector element (u16x8 -> u32x4)
|
||||
- 'u': force a number (vector or scalar) to be unsigned int (f32x4 -> u32x4)
|
||||
- 's': force a number (vector or scalar) to be signed int (u32x4 -> i32x4)
|
||||
- 'f': force a number (vector or scalar) to be float (u32x4 -> f32x4)
|
||||
|
|
|
|||
|
|
@ -72,6 +72,55 @@
|
|||
"llvm": "vmin{0.kind}{0.data_type_short}",
|
||||
"ret": "i(8-32)",
|
||||
"args": ["0", "0"]
|
||||
},
|
||||
{
|
||||
"intrinsic": "sub{0.kind}{0.data_type_short}s",
|
||||
"width": [128],
|
||||
"llvm": "vsub{0.kind}{0.data_type_short}s",
|
||||
"ret": "i(8-32)",
|
||||
"args": ["0", "0"]
|
||||
},
|
||||
{
|
||||
"intrinsic": "subc",
|
||||
"width": [128],
|
||||
"llvm": "vsubcuw",
|
||||
"ret": "u32",
|
||||
"args": ["0", "0"]
|
||||
},
|
||||
{
|
||||
"intrinsic": "add{0.kind}{0.data_type_short}s",
|
||||
"width": [128],
|
||||
"llvm": "vadd{0.kind}{0.data_type_short}s",
|
||||
"ret": "i(8-32)",
|
||||
"args": ["0", "0"]
|
||||
},
|
||||
{
|
||||
"intrinsic": "addc",
|
||||
"width": [128],
|
||||
"llvm": "vaddcuw",
|
||||
"ret": "u32",
|
||||
"args": ["0", "0"]
|
||||
},
|
||||
{
|
||||
"intrinsic": "mule{1.kind}{1.data_type_short}",
|
||||
"width": [128],
|
||||
"llvm": "vmule{0.kind}{1.data_type_short}",
|
||||
"ret": "i(16-32)",
|
||||
"args": ["0N", "1"]
|
||||
},
|
||||
{
|
||||
"intrinsic": "mulo{1.kind}{1.data_type_short}",
|
||||
"width": [128],
|
||||
"llvm": "vmulo{0.kind}{1.data_type_short}",
|
||||
"ret": "i(16-32)",
|
||||
"args": ["0N", "1"]
|
||||
},
|
||||
{
|
||||
"intrinsic": "avg{0.kind}{0.data_type_short}",
|
||||
"width": [128],
|
||||
"llvm": "vavg{0.kind}{0.data_type_short}",
|
||||
"ret": "i(8-32)",
|
||||
"args": ["0", "0"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1037,7 +1037,7 @@ impl<'a, K: 'a, V: 'a, NodeType>
|
|||
Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
|
||||
|
||||
pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
|
||||
let (mut keys, mut vals) = self.node.into_slices_mut();
|
||||
let (keys, vals) = self.node.into_slices_mut();
|
||||
unsafe {
|
||||
(keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx))
|
||||
}
|
||||
|
|
@ -1047,7 +1047,7 @@ impl<'a, K: 'a, V: 'a, NodeType>
|
|||
impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
|
||||
pub fn kv_mut(&mut self) -> (&mut K, &mut V) {
|
||||
unsafe {
|
||||
let (mut keys, mut vals) = self.node.reborrow_mut().into_slices_mut();
|
||||
let (keys, vals) = self.node.reborrow_mut().into_slices_mut();
|
||||
(keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1751,7 +1751,7 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
|
|||
type Item = &'a mut T;
|
||||
type IntoIter = slice::IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> slice::IterMut<'a, T> {
|
||||
fn into_iter(self) -> slice::IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2394,7 +2394,7 @@ impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
|
|||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
fn into_iter(self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
|
@ -2558,7 +2558,7 @@ impl<'a, T> Place<T> for PlaceBack<'a, T> {
|
|||
impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
|
||||
type Owner = &'a mut T;
|
||||
|
||||
unsafe fn finalize(mut self) -> &'a mut T {
|
||||
unsafe fn finalize(self) -> &'a mut T {
|
||||
let head = self.vec_deque.head;
|
||||
self.vec_deque.head = self.vec_deque.wrap_add(head, 1);
|
||||
&mut *(self.vec_deque.ptr().offset(head as isize))
|
||||
|
|
@ -2605,7 +2605,7 @@ impl<'a, T> Place<T> for PlaceFront<'a, T> {
|
|||
impl<'a, T> InPlace<T> for PlaceFront<'a, T> {
|
||||
type Owner = &'a mut T;
|
||||
|
||||
unsafe fn finalize(mut self) -> &'a mut T {
|
||||
unsafe fn finalize(self) -> &'a mut T {
|
||||
self.vec_deque.tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
|
||||
&mut *(self.vec_deque.ptr().offset(self.vec_deque.tail as isize))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,11 +110,13 @@ use self::Ordering::*;
|
|||
pub trait PartialEq<Rhs: ?Sized = Self> {
|
||||
/// This method tests for `self` and `other` values to be equal, and is used
|
||||
/// by `==`.
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn eq(&self, other: &Rhs) -> bool;
|
||||
|
||||
/// This method tests for `!=`.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
|
@ -625,6 +627,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
|
|||
/// let result = std::f64::NAN.partial_cmp(&1.0);
|
||||
/// assert_eq!(result, None);
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
|
||||
|
||||
|
|
@ -640,6 +643,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
|
|||
/// assert_eq!(result, false);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn lt(&self, other: &Rhs) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
|
|
@ -661,6 +665,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
|
|||
/// assert_eq!(result, true);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn le(&self, other: &Rhs) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
|
|
@ -681,6 +686,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
|
|||
/// assert_eq!(result, false);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn gt(&self, other: &Rhs) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
|
|
@ -702,6 +708,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
|
|||
/// assert_eq!(result, true);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn ge(&self, other: &Rhs) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
|
|
|
|||
|
|
@ -214,9 +214,16 @@ impl<A: Step> Iterator for ops::Range<A> {
|
|||
#[inline]
|
||||
fn next(&mut self) -> Option<A> {
|
||||
if self.start < self.end {
|
||||
let mut n = self.start.add_one();
|
||||
mem::swap(&mut n, &mut self.start);
|
||||
Some(n)
|
||||
// We check for overflow here, even though it can't actually
|
||||
// happen. Adding this check does however help llvm vectorize loops
|
||||
// for some ranges that don't get vectorized otherwise,
|
||||
// and this won't actually result in an extra check in an optimized build.
|
||||
if let Some(mut n) = self.start.add_usize(1) {
|
||||
mem::swap(&mut n, &mut self.start);
|
||||
Some(n)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,16 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[macro_export]
|
||||
// This stability attribute is totally useless.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(stage0)]
|
||||
macro_rules! __rust_unstable_column {
|
||||
() => {
|
||||
column!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Entry point of thread panic, for details, see std::macros
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable]
|
||||
|
|
@ -18,7 +28,7 @@ macro_rules! panic {
|
|||
);
|
||||
($msg:expr) => ({
|
||||
static _MSG_FILE_LINE_COL: (&'static str, &'static str, u32, u32) =
|
||||
($msg, file!(), line!(), column!());
|
||||
($msg, file!(), line!(), __rust_unstable_column!());
|
||||
$crate::panicking::panic(&_MSG_FILE_LINE_COL)
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => ({
|
||||
|
|
@ -27,7 +37,7 @@ macro_rules! panic {
|
|||
// insufficient, since the user may have
|
||||
// `#[forbid(dead_code)]` and which cannot be overridden.
|
||||
static _MSG_FILE_LINE_COL: (&'static str, u32, u32) =
|
||||
(file!(), line!(), column!());
|
||||
(file!(), line!(), __rust_unstable_column!());
|
||||
$crate::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_MSG_FILE_LINE_COL)
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ mod impls {
|
|||
where F : FnMut<A>
|
||||
{
|
||||
type Output = F::Output;
|
||||
extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
|
||||
extern "rust-call" fn call_once(self, args: A) -> F::Output {
|
||||
(*self).call_mut(args)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -872,7 +872,7 @@ impl<'a, T> IntoIterator for &'a mut Option<T> {
|
|||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
fn into_iter(self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -909,7 +909,7 @@ impl<'a, T, E> IntoIterator for &'a mut Result<T, E> {
|
|||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
fn into_iter(self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,27 +105,27 @@ fn test_chunks_last() {
|
|||
|
||||
#[test]
|
||||
fn test_chunks_mut_count() {
|
||||
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let c = v.chunks_mut(3);
|
||||
assert_eq!(c.count(), 2);
|
||||
|
||||
let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let c2 = v2.chunks_mut(2);
|
||||
assert_eq!(c2.count(), 3);
|
||||
|
||||
let mut v3: &mut [i32] = &mut [];
|
||||
let v3: &mut [i32] = &mut [];
|
||||
let c3 = v3.chunks_mut(2);
|
||||
assert_eq!(c3.count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chunks_mut_nth() {
|
||||
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let mut c = v.chunks_mut(2);
|
||||
assert_eq!(c.nth(1).unwrap()[1], 3);
|
||||
assert_eq!(c.next().unwrap()[0], 4);
|
||||
|
||||
let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let mut c2 = v2.chunks_mut(3);
|
||||
assert_eq!(c2.nth(1).unwrap()[1], 4);
|
||||
assert_eq!(c2.next(), None);
|
||||
|
|
@ -194,7 +194,7 @@ fn get_range() {
|
|||
|
||||
#[test]
|
||||
fn get_mut_range() {
|
||||
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..]));
|
||||
assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..]));
|
||||
assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..]));
|
||||
|
|
|
|||
|
|
@ -521,6 +521,7 @@ define_dep_nodes!( <'tcx>
|
|||
[] IsAllocator(DefId),
|
||||
[] IsPanicRuntime(DefId),
|
||||
[] ExternCrate(DefId),
|
||||
[] LintLevels,
|
||||
);
|
||||
|
||||
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
|
||||
|
|
|
|||
|
|
@ -640,8 +640,6 @@ for ty::TypeckTables<'tcx> {
|
|||
|
||||
ref cast_kinds,
|
||||
|
||||
// FIXME(#41184): This is still ignored at the moment.
|
||||
lints: _,
|
||||
ref used_trait_imports,
|
||||
tainted_by_errors,
|
||||
ref free_region_map,
|
||||
|
|
|
|||
|
|
@ -415,8 +415,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
/// -------- this type is the same as a type argument in the other type, not highlighted
|
||||
/// ```
|
||||
fn highlight_outer(&self,
|
||||
mut value: &mut DiagnosticStyledString,
|
||||
mut other_value: &mut DiagnosticStyledString,
|
||||
value: &mut DiagnosticStyledString,
|
||||
other_value: &mut DiagnosticStyledString,
|
||||
name: String,
|
||||
sub: &ty::subst::Substs<'tcx>,
|
||||
pos: usize,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
343
src/librustc/lint/levels.rs
Normal file
343
src/librustc/lint/levels.rs
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::cmp;
|
||||
|
||||
use errors::DiagnosticBuilder;
|
||||
use hir::HirId;
|
||||
use lint::builtin;
|
||||
use lint::context::CheckLintNameResult;
|
||||
use lint::{self, Lint, LintId, Level, LintSource};
|
||||
use session::Session;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::MultiSpan;
|
||||
use syntax::symbol::Symbol;
|
||||
use util::nodemap::FxHashMap;
|
||||
|
||||
pub struct LintLevelSets {
|
||||
list: Vec<LintSet>,
|
||||
lint_cap: Level,
|
||||
}
|
||||
|
||||
enum LintSet {
|
||||
CommandLine {
|
||||
// -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which
|
||||
// flag.
|
||||
specs: FxHashMap<LintId, (Level, LintSource)>,
|
||||
},
|
||||
|
||||
Node {
|
||||
specs: FxHashMap<LintId, (Level, LintSource)>,
|
||||
parent: u32,
|
||||
},
|
||||
}
|
||||
|
||||
impl LintLevelSets {
|
||||
pub fn new(sess: &Session) -> LintLevelSets {
|
||||
let mut me = LintLevelSets {
|
||||
list: Vec::new(),
|
||||
lint_cap: Level::Forbid,
|
||||
};
|
||||
me.process_command_line(sess);
|
||||
return me
|
||||
}
|
||||
|
||||
pub fn builder(sess: &Session) -> LintLevelsBuilder {
|
||||
LintLevelsBuilder::new(sess, LintLevelSets::new(sess))
|
||||
}
|
||||
|
||||
fn process_command_line(&mut self, sess: &Session) {
|
||||
let store = sess.lint_store.borrow();
|
||||
let mut specs = FxHashMap();
|
||||
self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid);
|
||||
|
||||
for &(ref lint_name, level) in &sess.opts.lint_opts {
|
||||
store.check_lint_name_cmdline(sess, &lint_name, level);
|
||||
|
||||
// If the cap is less than this specified level, e.g. if we've got
|
||||
// `--cap-lints allow` but we've also got `-D foo` then we ignore
|
||||
// this specification as the lint cap will set it to allow anyway.
|
||||
let level = cmp::min(level, self.lint_cap);
|
||||
|
||||
let lint_flag_val = Symbol::intern(lint_name);
|
||||
let ids = match store.find_lints(&lint_name) {
|
||||
Ok(ids) => ids,
|
||||
Err(_) => continue, // errors handled in check_lint_name_cmdline above
|
||||
};
|
||||
for id in ids {
|
||||
let src = LintSource::CommandLine(lint_flag_val);
|
||||
specs.insert(id, (level, src));
|
||||
}
|
||||
}
|
||||
|
||||
self.list.push(LintSet::CommandLine {
|
||||
specs: specs,
|
||||
});
|
||||
}
|
||||
|
||||
fn get_lint_level(&self, lint: &'static Lint, idx: u32)
|
||||
-> (Level, LintSource)
|
||||
{
|
||||
let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx);
|
||||
|
||||
// If `level` is none then we actually assume the default level for this
|
||||
// lint.
|
||||
let mut level = level.unwrap_or(lint.default_level);
|
||||
|
||||
// If we're about to issue a warning, check at the last minute for any
|
||||
// directives against the warnings "lint". If, for example, there's an
|
||||
// `allow(warnings)` in scope then we want to respect that instead.
|
||||
if level == Level::Warn {
|
||||
let (warnings_level, warnings_src) =
|
||||
self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS), idx);
|
||||
if let Some(configured_warning_level) = warnings_level {
|
||||
if configured_warning_level != Level::Warn {
|
||||
level = configured_warning_level;
|
||||
src = warnings_src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that we never exceed the `--cap-lints` argument.
|
||||
level = cmp::min(level, self.lint_cap);
|
||||
|
||||
return (level, src)
|
||||
}
|
||||
|
||||
fn get_lint_id_level(&self, id: LintId, mut idx: u32)
|
||||
-> (Option<Level>, LintSource)
|
||||
{
|
||||
loop {
|
||||
match self.list[idx as usize] {
|
||||
LintSet::CommandLine { ref specs } => {
|
||||
if let Some(&(level, src)) = specs.get(&id) {
|
||||
return (Some(level), src)
|
||||
}
|
||||
return (None, LintSource::Default)
|
||||
}
|
||||
LintSet::Node { ref specs, parent } => {
|
||||
if let Some(&(level, src)) = specs.get(&id) {
|
||||
return (Some(level), src)
|
||||
}
|
||||
idx = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LintLevelsBuilder<'a> {
|
||||
sess: &'a Session,
|
||||
sets: LintLevelSets,
|
||||
id_to_set: FxHashMap<HirId, u32>,
|
||||
cur: u32,
|
||||
warn_about_weird_lints: bool,
|
||||
}
|
||||
|
||||
pub struct BuilderPush {
|
||||
prev: u32,
|
||||
}
|
||||
|
||||
impl<'a> LintLevelsBuilder<'a> {
|
||||
pub fn new(sess: &'a Session, sets: LintLevelSets) -> LintLevelsBuilder<'a> {
|
||||
assert_eq!(sets.list.len(), 1);
|
||||
LintLevelsBuilder {
|
||||
sess,
|
||||
sets,
|
||||
cur: 0,
|
||||
id_to_set: FxHashMap(),
|
||||
warn_about_weird_lints: sess.buffered_lints.borrow().is_some(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes a list of AST lint attributes onto this context.
|
||||
///
|
||||
/// This function will return a `BuilderPush` object which should be be
|
||||
/// passed to `pop` when this scope for the attributes provided is exited.
|
||||
///
|
||||
/// This function will perform a number of tasks:
|
||||
///
|
||||
/// * It'll validate all lint-related attributes in `attrs`
|
||||
/// * It'll mark all lint-related attriutes as used
|
||||
/// * Lint levels will be updated based on the attributes provided
|
||||
/// * Lint attributes are validated, e.g. a #[forbid] can't be switched to
|
||||
/// #[allow]
|
||||
///
|
||||
/// Don't forget to call `pop`!
|
||||
pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
|
||||
let mut specs = FxHashMap();
|
||||
let store = self.sess.lint_store.borrow();
|
||||
let sess = self.sess;
|
||||
let bad_attr = |span| {
|
||||
span_err!(sess, span, E0452,
|
||||
"malformed lint attribute");
|
||||
};
|
||||
for attr in attrs {
|
||||
let level = match attr.name().and_then(|name| Level::from_str(&name.as_str())) {
|
||||
None => continue,
|
||||
Some(lvl) => lvl,
|
||||
};
|
||||
|
||||
let meta = unwrap_or!(attr.meta(), continue);
|
||||
attr::mark_used(attr);
|
||||
|
||||
let metas = if let Some(metas) = meta.meta_item_list() {
|
||||
metas
|
||||
} else {
|
||||
bad_attr(meta.span);
|
||||
continue
|
||||
};
|
||||
|
||||
for li in metas {
|
||||
let word = match li.word() {
|
||||
Some(word) => word,
|
||||
None => {
|
||||
bad_attr(li.span);
|
||||
continue
|
||||
}
|
||||
};
|
||||
let name = word.name();
|
||||
match store.check_lint_name(&name.as_str()) {
|
||||
CheckLintNameResult::Ok(ids) => {
|
||||
let src = LintSource::Node(name, li.span);
|
||||
for id in ids {
|
||||
specs.insert(*id, (level, src));
|
||||
}
|
||||
}
|
||||
CheckLintNameResult::Warning(ref msg) => {
|
||||
if self.warn_about_weird_lints {
|
||||
self.struct_lint(builtin::RENAMED_AND_REMOVED_LINTS,
|
||||
Some(li.span.into()),
|
||||
msg)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
CheckLintNameResult::NoLint => {
|
||||
if self.warn_about_weird_lints {
|
||||
self.struct_lint(builtin::UNKNOWN_LINTS,
|
||||
Some(li.span.into()),
|
||||
&format!("unknown lint: `{}`", name))
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (id, &(level, ref src)) in specs.iter() {
|
||||
if level == Level::Forbid {
|
||||
continue
|
||||
}
|
||||
let forbid_src = match self.sets.get_lint_id_level(*id, self.cur) {
|
||||
(Some(Level::Forbid), src) => src,
|
||||
_ => continue,
|
||||
};
|
||||
let forbidden_lint_name = match forbid_src {
|
||||
LintSource::Default => id.to_string(),
|
||||
LintSource::Node(name, _) => name.to_string(),
|
||||
LintSource::CommandLine(name) => name.to_string(),
|
||||
};
|
||||
let (lint_attr_name, lint_attr_span) = match *src {
|
||||
LintSource::Node(name, span) => (name, span),
|
||||
_ => continue,
|
||||
};
|
||||
let mut diag_builder = struct_span_err!(self.sess,
|
||||
lint_attr_span,
|
||||
E0453,
|
||||
"{}({}) overruled by outer forbid({})",
|
||||
level.as_str(),
|
||||
lint_attr_name,
|
||||
forbidden_lint_name);
|
||||
diag_builder.span_label(lint_attr_span, "overruled by previous forbid");
|
||||
match forbid_src {
|
||||
LintSource::Default => &mut diag_builder,
|
||||
LintSource::Node(_, forbid_source_span) => {
|
||||
diag_builder.span_label(forbid_source_span,
|
||||
"`forbid` level set here")
|
||||
},
|
||||
LintSource::CommandLine(_) => {
|
||||
diag_builder.note("`forbid` lint level was set on command line")
|
||||
}
|
||||
}.emit();
|
||||
// don't set a separate error for every lint in the group
|
||||
break
|
||||
}
|
||||
|
||||
let prev = self.cur;
|
||||
if specs.len() > 0 {
|
||||
self.cur = self.sets.list.len() as u32;
|
||||
self.sets.list.push(LintSet::Node {
|
||||
specs: specs,
|
||||
parent: prev,
|
||||
});
|
||||
}
|
||||
|
||||
BuilderPush {
|
||||
prev: prev,
|
||||
}
|
||||
}
|
||||
|
||||
/// Called after `push` when the scope of a set of attributes are exited.
|
||||
pub fn pop(&mut self, push: BuilderPush) {
|
||||
self.cur = push.prev;
|
||||
}
|
||||
|
||||
/// Used to emit a lint-related diagnostic based on the current state of
|
||||
/// this lint context.
|
||||
pub fn struct_lint(&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<MultiSpan>,
|
||||
msg: &str)
|
||||
-> DiagnosticBuilder<'a>
|
||||
{
|
||||
let (level, src) = self.sets.get_lint_level(lint, self.cur);
|
||||
lint::struct_lint_level(self.sess, lint, level, src, span, msg)
|
||||
}
|
||||
|
||||
/// Registers the ID provided with the current set of lints stored in
|
||||
/// this context.
|
||||
pub fn register_id(&mut self, id: HirId) {
|
||||
self.id_to_set.insert(id, self.cur);
|
||||
}
|
||||
|
||||
pub fn build(self) -> LintLevelSets {
|
||||
self.sets
|
||||
}
|
||||
|
||||
pub fn build_map(self) -> LintLevelMap {
|
||||
LintLevelMap {
|
||||
sets: self.sets,
|
||||
id_to_set: self.id_to_set,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LintLevelMap {
|
||||
sets: LintLevelSets,
|
||||
id_to_set: FxHashMap<HirId, u32>,
|
||||
}
|
||||
|
||||
impl LintLevelMap {
|
||||
/// If the `id` was previously registered with `register_id` when building
|
||||
/// this `LintLevelMap` this returns the corresponding lint level and source
|
||||
/// of the lint level for the lint provided.
|
||||
///
|
||||
/// If the `id` was not previously registered, returns `None`. If `None` is
|
||||
/// returned then the parent of `id` should be acquired and this function
|
||||
/// should be called again.
|
||||
pub fn level_and_source(&self, lint: &'static Lint, id: HirId)
|
||||
-> Option<(Level, LintSource)>
|
||||
{
|
||||
self.id_to_set.get(&id).map(|idx| {
|
||||
self.sets.get_lint_level(lint, *idx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -31,20 +31,27 @@
|
|||
pub use self::Level::*;
|
||||
pub use self::LintSource::*;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use errors::DiagnosticBuilder;
|
||||
use hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use hir::intravisit::{self, FnKind};
|
||||
use hir;
|
||||
use hir::intravisit::FnKind;
|
||||
use std::hash;
|
||||
use session::Session;
|
||||
use std::ascii::AsciiExt;
|
||||
use syntax_pos::Span;
|
||||
use syntax::visit as ast_visit;
|
||||
use std::hash;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::MultiSpan;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::visit as ast_visit;
|
||||
use syntax_pos::Span;
|
||||
use ty::TyCtxt;
|
||||
use ty::maps::Providers;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
|
||||
raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
|
||||
raw_struct_lint, FutureIncompatibleInfo, EarlyLint, IntoEarlyLint};
|
||||
|
||||
pub use lint::table::LintTable;
|
||||
check_crate, check_ast_crate,
|
||||
FutureIncompatibleInfo, BufferedEarlyLint};
|
||||
|
||||
/// Specification of a single lint.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
|
@ -351,4 +358,215 @@ pub type LevelSource = (Level, LintSource);
|
|||
|
||||
pub mod builtin;
|
||||
mod context;
|
||||
mod table;
|
||||
mod levels;
|
||||
|
||||
pub use self::levels::{LintLevelSets, LintLevelMap};
|
||||
|
||||
pub struct LintBuffer {
|
||||
map: NodeMap<Vec<BufferedEarlyLint>>,
|
||||
}
|
||||
|
||||
impl LintBuffer {
|
||||
pub fn new() -> LintBuffer {
|
||||
LintBuffer { map: NodeMap() }
|
||||
}
|
||||
|
||||
pub fn add_lint(&mut self,
|
||||
lint: &'static Lint,
|
||||
id: ast::NodeId,
|
||||
sp: MultiSpan,
|
||||
msg: &str) {
|
||||
let early_lint = BufferedEarlyLint {
|
||||
lint_id: LintId::of(lint),
|
||||
ast_id: id,
|
||||
span: sp,
|
||||
msg: msg.to_string(),
|
||||
};
|
||||
let arr = self.map.entry(id).or_insert(Vec::new());
|
||||
if !arr.contains(&early_lint) {
|
||||
arr.push(early_lint);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take(&mut self, id: ast::NodeId) -> Vec<BufferedEarlyLint> {
|
||||
self.map.remove(&id).unwrap_or(Vec::new())
|
||||
}
|
||||
|
||||
pub fn get_any(&self) -> Option<&[BufferedEarlyLint]> {
|
||||
let key = self.map.keys().next().map(|k| *k);
|
||||
key.map(|k| &self.map[&k][..])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_lint_level<'a>(sess: &'a Session,
|
||||
lint: &'static Lint,
|
||||
level: Level,
|
||||
src: LintSource,
|
||||
span: Option<MultiSpan>,
|
||||
msg: &str)
|
||||
-> DiagnosticBuilder<'a>
|
||||
{
|
||||
let mut err = match (level, span) {
|
||||
(Level::Allow, _) => return sess.diagnostic().struct_dummy(),
|
||||
(Level::Warn, Some(span)) => sess.struct_span_warn(span, msg),
|
||||
(Level::Warn, None) => sess.struct_warn(msg),
|
||||
(Level::Deny, Some(span)) |
|
||||
(Level::Forbid, Some(span)) => sess.struct_span_err(span, msg),
|
||||
(Level::Deny, None) |
|
||||
(Level::Forbid, None) => sess.struct_err(msg),
|
||||
};
|
||||
|
||||
let name = lint.name_lower();
|
||||
match src {
|
||||
LintSource::Default => {
|
||||
sess.diag_note_once(
|
||||
&mut err,
|
||||
lint,
|
||||
&format!("#[{}({})] on by default", level.as_str(), name));
|
||||
}
|
||||
LintSource::CommandLine(lint_flag_val) => {
|
||||
let flag = match level {
|
||||
Level::Warn => "-W",
|
||||
Level::Deny => "-D",
|
||||
Level::Forbid => "-F",
|
||||
Level::Allow => panic!(),
|
||||
};
|
||||
let hyphen_case_lint_name = name.replace("_", "-");
|
||||
if lint_flag_val.as_str() == name {
|
||||
sess.diag_note_once(
|
||||
&mut err,
|
||||
lint,
|
||||
&format!("requested on the command line with `{} {}`",
|
||||
flag, hyphen_case_lint_name));
|
||||
} else {
|
||||
let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
|
||||
sess.diag_note_once(
|
||||
&mut err,
|
||||
lint,
|
||||
&format!("`{} {}` implied by `{} {}`",
|
||||
flag, hyphen_case_lint_name, flag,
|
||||
hyphen_case_flag_val));
|
||||
}
|
||||
}
|
||||
LintSource::Node(lint_attr_name, src) => {
|
||||
sess.diag_span_note_once(&mut err, lint, src, "lint level defined here");
|
||||
if lint_attr_name.as_str() != name {
|
||||
let level_str = level.as_str();
|
||||
sess.diag_note_once(&mut err, lint,
|
||||
&format!("#[{}({})] implied by #[{}({})]",
|
||||
level_str, name, level_str, lint_attr_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for future incompatibility lints and issue a stronger warning.
|
||||
let lints = sess.lint_store.borrow();
|
||||
if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) {
|
||||
let explanation = format!("this was previously accepted by the compiler \
|
||||
but is being phased out; \
|
||||
it will become a hard error in a future release!");
|
||||
let citation = format!("for more information, see {}",
|
||||
future_incompatible.reference);
|
||||
err.warn(&explanation);
|
||||
err.note(&citation);
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
|
||||
-> Rc<LintLevelMap>
|
||||
{
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
let mut builder = LintLevelMapBuilder {
|
||||
levels: LintLevelSets::builder(tcx.sess),
|
||||
tcx: tcx,
|
||||
};
|
||||
let krate = tcx.hir.krate();
|
||||
|
||||
builder.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |builder| {
|
||||
intravisit::walk_crate(builder, krate);
|
||||
});
|
||||
|
||||
Rc::new(builder.levels.build_map())
|
||||
}
|
||||
|
||||
struct LintLevelMapBuilder<'a, 'tcx: 'a> {
|
||||
levels: levels::LintLevelsBuilder<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LintLevelMapBuilder<'a, 'tcx> {
|
||||
fn with_lint_attrs<F>(&mut self,
|
||||
id: ast::NodeId,
|
||||
attrs: &[ast::Attribute],
|
||||
f: F)
|
||||
where F: FnOnce(&mut Self)
|
||||
{
|
||||
let push = self.levels.push(attrs);
|
||||
self.levels.register_id(self.tcx.hir.definitions().node_to_hir_id(id));
|
||||
f(self);
|
||||
self.levels.pop(push);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
|
||||
intravisit::NestedVisitorMap::All(&self.tcx.hir)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, it: &'tcx hir::Item) {
|
||||
self.with_lint_attrs(it.id, &it.attrs, |builder| {
|
||||
intravisit::walk_item(builder, it);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem) {
|
||||
self.with_lint_attrs(it.id, &it.attrs, |builder| {
|
||||
intravisit::walk_foreign_item(builder, it);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &'tcx hir::Expr) {
|
||||
self.with_lint_attrs(e.id, &e.attrs, |builder| {
|
||||
intravisit::walk_expr(builder, e);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
|
||||
self.with_lint_attrs(s.id, &s.attrs, |builder| {
|
||||
intravisit::walk_struct_field(builder, s);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self,
|
||||
v: &'tcx hir::Variant,
|
||||
g: &'tcx hir::Generics,
|
||||
item_id: ast::NodeId) {
|
||||
self.with_lint_attrs(v.node.data.id(), &v.node.attrs, |builder| {
|
||||
intravisit::walk_variant(builder, v, g, item_id);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local) {
|
||||
self.with_lint_attrs(l.id, &l.attrs, |builder| {
|
||||
intravisit::walk_local(builder, l);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
|
||||
self.with_lint_attrs(trait_item.id, &trait_item.attrs, |builder| {
|
||||
intravisit::walk_trait_item(builder, trait_item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
|
||||
self.with_lint_attrs(impl_item.id, &impl_item.attrs, |builder| {
|
||||
intravisit::walk_impl_item(builder, impl_item);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
providers.lint_levels = lint_levels;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use syntax::ast;
|
||||
use syntax_pos::MultiSpan;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
use super::{Lint, LintId, EarlyLint, IntoEarlyLint};
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
pub struct LintTable {
|
||||
map: NodeMap<Vec<EarlyLint>>
|
||||
}
|
||||
|
||||
impl LintTable {
|
||||
pub fn new() -> Self {
|
||||
LintTable { map: NodeMap() }
|
||||
}
|
||||
|
||||
pub fn add_lint<S: Into<MultiSpan>>(&mut self,
|
||||
lint: &'static Lint,
|
||||
id: ast::NodeId,
|
||||
sp: S,
|
||||
msg: String)
|
||||
{
|
||||
self.add_lint_diagnostic(lint, id, (sp, &msg[..]))
|
||||
}
|
||||
|
||||
pub fn add_lint_diagnostic<M>(&mut self,
|
||||
lint: &'static Lint,
|
||||
id: ast::NodeId,
|
||||
msg: M)
|
||||
where M: IntoEarlyLint,
|
||||
{
|
||||
let lint_id = LintId::of(lint);
|
||||
let early_lint = msg.into_early_lint(lint_id);
|
||||
let arr = self.map.entry(id).or_insert(vec![]);
|
||||
if !arr.contains(&early_lint) {
|
||||
arr.push(early_lint);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, id: ast::NodeId) -> &[EarlyLint] {
|
||||
self.map.get(&id).map(|v| &v[..]).unwrap_or(&[])
|
||||
}
|
||||
|
||||
pub fn take(&mut self, id: ast::NodeId) -> Vec<EarlyLint> {
|
||||
self.map.remove(&id).unwrap_or(vec![])
|
||||
}
|
||||
|
||||
pub fn transfer(&mut self, into: &mut LintTable) {
|
||||
into.map.extend(self.map.drain());
|
||||
}
|
||||
|
||||
/// Returns the first (id, lint) pair that is non-empty. Used to
|
||||
/// implement a sanity check in lints that all node-ids are
|
||||
/// visited.
|
||||
pub fn get_any(&self) -> Option<(&ast::NodeId, &Vec<EarlyLint>)> {
|
||||
self.map.iter()
|
||||
.filter(|&(_, v)| !v.is_empty())
|
||||
.next()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -17,11 +17,11 @@ use hir::{self, Item_, PatKind};
|
|||
use hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
use hir::itemlikevisit::ItemLikeVisitor;
|
||||
|
||||
use middle::privacy;
|
||||
use ty::{self, TyCtxt};
|
||||
use hir::def::Def;
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use lint;
|
||||
use middle::privacy;
|
||||
use ty::{self, TyCtxt};
|
||||
use util::nodemap::FxHashSet;
|
||||
|
||||
use syntax::{ast, codemap};
|
||||
|
|
@ -299,7 +299,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
|
||||
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
|
||||
id: ast::NodeId,
|
||||
attrs: &[ast::Attribute]) -> bool {
|
||||
if attr::contains_name(attrs, "lang") {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -315,14 +317,7 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
let dead_code = lint::builtin::DEAD_CODE.name_lower();
|
||||
for attr in lint::gather_attrs(attrs) {
|
||||
match attr {
|
||||
Ok((name, lint::Allow, _)) if name == &*dead_code => return true,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
false
|
||||
tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
|
||||
}
|
||||
|
||||
// This visitor seeds items that
|
||||
|
|
@ -338,14 +333,17 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
|
|||
// or
|
||||
// 2) We are not sure to be live or not
|
||||
// * Implementation of a trait method
|
||||
struct LifeSeeder<'k> {
|
||||
struct LifeSeeder<'k, 'tcx: 'k> {
|
||||
worklist: Vec<ast::NodeId>,
|
||||
krate: &'k hir::Crate,
|
||||
tcx: TyCtxt<'k, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
|
||||
impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
let allow_dead_code = has_allow_dead_code_or_lang_attr(&item.attrs);
|
||||
let allow_dead_code = has_allow_dead_code_or_lang_attr(self.tcx,
|
||||
item.id,
|
||||
&item.attrs);
|
||||
if allow_dead_code {
|
||||
self.worklist.push(item.id);
|
||||
}
|
||||
|
|
@ -360,7 +358,9 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
|
|||
match trait_item.node {
|
||||
hir::TraitItemKind::Const(_, Some(_)) |
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => {
|
||||
if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
|
||||
if has_allow_dead_code_or_lang_attr(self.tcx,
|
||||
trait_item.id,
|
||||
&trait_item.attrs) {
|
||||
self.worklist.push(trait_item.id);
|
||||
}
|
||||
}
|
||||
|
|
@ -372,7 +372,9 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
|
|||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.krate.impl_item(impl_item_ref.id);
|
||||
if opt_trait.is_some() ||
|
||||
has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
|
||||
has_allow_dead_code_or_lang_attr(self.tcx,
|
||||
impl_item.id,
|
||||
&impl_item.attrs) {
|
||||
self.worklist.push(impl_item_ref.id.node_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -408,6 +410,7 @@ fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let mut life_seeder = LifeSeeder {
|
||||
worklist,
|
||||
krate,
|
||||
tcx,
|
||||
};
|
||||
krate.visit_all_item_likes(&mut life_seeder);
|
||||
|
||||
|
|
@ -472,17 +475,19 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|
|||
!field.is_positional()
|
||||
&& !self.symbol_is_live(field.id, None)
|
||||
&& !is_marker_field
|
||||
&& !has_allow_dead_code_or_lang_attr(&field.attrs)
|
||||
&& !has_allow_dead_code_or_lang_attr(self.tcx, field.id, &field.attrs)
|
||||
}
|
||||
|
||||
fn should_warn_about_variant(&mut self, variant: &hir::Variant_) -> bool {
|
||||
!self.symbol_is_live(variant.data.id(), None)
|
||||
&& !has_allow_dead_code_or_lang_attr(&variant.attrs)
|
||||
&& !has_allow_dead_code_or_lang_attr(self.tcx,
|
||||
variant.data.id(),
|
||||
&variant.attrs)
|
||||
}
|
||||
|
||||
fn should_warn_about_foreign_item(&mut self, fi: &hir::ForeignItem) -> bool {
|
||||
!self.symbol_is_live(fi.id, None)
|
||||
&& !has_allow_dead_code_or_lang_attr(&fi.attrs)
|
||||
&& !has_allow_dead_code_or_lang_attr(self.tcx, fi.id, &fi.attrs)
|
||||
}
|
||||
|
||||
// id := node id of an item's definition.
|
||||
|
|
@ -528,11 +533,10 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|
|||
node_type: &str) {
|
||||
if !name.as_str().starts_with("_") {
|
||||
self.tcx
|
||||
.sess
|
||||
.add_lint(lint::builtin::DEAD_CODE,
|
||||
id,
|
||||
span,
|
||||
format!("{} is never used: `{}`", node_type, name));
|
||||
.lint_node(lint::builtin::DEAD_CODE,
|
||||
id,
|
||||
span,
|
||||
&format!("{} is never used: `{}`", node_type, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
|
|||
match self.unsafe_context.root {
|
||||
SafeContext => {
|
||||
if is_lint {
|
||||
self.tcx.sess.add_lint(lint::builtin::SAFE_EXTERN_STATICS,
|
||||
node_id,
|
||||
span,
|
||||
format!("{} requires unsafe function or \
|
||||
block (error E0133)", description));
|
||||
self.tcx.lint_node(lint::builtin::SAFE_EXTERN_STATICS,
|
||||
node_id,
|
||||
span,
|
||||
&format!("{} requires unsafe function or \
|
||||
block (error E0133)", description));
|
||||
} else {
|
||||
// Report an error.
|
||||
struct_span_err!(
|
||||
|
|
|
|||
|
|
@ -1487,12 +1487,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
};
|
||||
|
||||
if is_assigned {
|
||||
self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLES, id, sp,
|
||||
format!("variable `{}` is assigned to, but never used",
|
||||
name));
|
||||
self.ir.tcx.lint_node(lint::builtin::UNUSED_VARIABLES, id, sp,
|
||||
&format!("variable `{}` is assigned to, but never used",
|
||||
name));
|
||||
} else if name != "self" {
|
||||
self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLES, id, sp,
|
||||
format!("unused variable: `{}`", name));
|
||||
self.ir.tcx.lint_node(lint::builtin::UNUSED_VARIABLES, id, sp,
|
||||
&format!("unused variable: `{}`", name));
|
||||
}
|
||||
}
|
||||
true
|
||||
|
|
@ -1514,11 +1514,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
fn report_dead_assign(&self, id: NodeId, sp: Span, var: Variable, is_argument: bool) {
|
||||
if let Some(name) = self.should_warn(var) {
|
||||
if is_argument {
|
||||
self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
|
||||
format!("value passed to `{}` is never read", name));
|
||||
self.ir.tcx.lint_node(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
|
||||
&format!("value passed to `{}` is never read", name));
|
||||
} else {
|
||||
self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
|
||||
format!("value assigned to `{}` is never read", name));
|
||||
self.ir.tcx.lint_node(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
|
||||
&format!("value assigned to `{}` is never read", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -493,7 +493,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
format!("use of deprecated item")
|
||||
};
|
||||
|
||||
self.sess.add_lint(lint::builtin::DEPRECATED, id, span, msg);
|
||||
self.lint_node(lint::builtin::DEPRECATED, id, span, &msg);
|
||||
};
|
||||
|
||||
// Deprecated attributes apply in-crate and cross-crate.
|
||||
|
|
@ -737,10 +737,10 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
for &(ref stable_lang_feature, span) in &sess.features.borrow().declared_stable_lang_features {
|
||||
let version = find_lang_feature_accepted_version(&stable_lang_feature.as_str())
|
||||
.expect("unexpectedly couldn't find version feature was stabilized");
|
||||
sess.add_lint(lint::builtin::STABLE_FEATURES,
|
||||
tcx.lint_node(lint::builtin::STABLE_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
format_stable_since_msg(version));
|
||||
&format_stable_since_msg(version));
|
||||
}
|
||||
|
||||
let index = tcx.stability.borrow();
|
||||
|
|
@ -748,10 +748,10 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
match remaining_lib_features.remove(used_lib_feature) {
|
||||
Some(span) => {
|
||||
if let &attr::StabilityLevel::Stable { since: ref version } = level {
|
||||
sess.add_lint(lint::builtin::STABLE_FEATURES,
|
||||
tcx.lint_node(lint::builtin::STABLE_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
format_stable_since_msg(&version.as_str()));
|
||||
&format_stable_since_msg(&version.as_str()));
|
||||
}
|
||||
}
|
||||
None => ( /* used but undeclared, handled during the previous ast visit */ )
|
||||
|
|
@ -759,9 +759,9 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
}
|
||||
|
||||
for &span in remaining_lib_features.values() {
|
||||
sess.add_lint(lint::builtin::UNUSED_FEATURES,
|
||||
tcx.lint_node(lint::builtin::UNUSED_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
"unused or unknown feature".to_string());
|
||||
"unused or unknown feature");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ pub struct Session {
|
|||
// if the value stored here has been affected by path remapping.
|
||||
pub working_dir: (String, bool),
|
||||
pub lint_store: RefCell<lint::LintStore>,
|
||||
pub lints: RefCell<lint::LintTable>,
|
||||
pub buffered_lints: RefCell<Option<lint::LintBuffer>>,
|
||||
/// Set of (LintId, Option<Span>, message) tuples tracking lint
|
||||
/// (sub)diagnostics that have been set once, but should not be set again,
|
||||
/// in order to avoid redundantly verbose output (Issue #24690).
|
||||
|
|
@ -307,22 +307,15 @@ impl Session {
|
|||
self.diagnostic().unimpl(msg)
|
||||
}
|
||||
|
||||
pub fn add_lint<S: Into<MultiSpan>>(&self,
|
||||
lint: &'static lint::Lint,
|
||||
id: ast::NodeId,
|
||||
sp: S,
|
||||
msg: String)
|
||||
{
|
||||
self.lints.borrow_mut().add_lint(lint, id, sp, msg);
|
||||
}
|
||||
|
||||
pub fn add_lint_diagnostic<M>(&self,
|
||||
lint: &'static lint::Lint,
|
||||
id: ast::NodeId,
|
||||
msg: M)
|
||||
where M: lint::IntoEarlyLint,
|
||||
{
|
||||
self.lints.borrow_mut().add_lint_diagnostic(lint, id, msg);
|
||||
pub fn buffer_lint<S: Into<MultiSpan>>(&self,
|
||||
lint: &'static lint::Lint,
|
||||
id: ast::NodeId,
|
||||
sp: S,
|
||||
msg: &str) {
|
||||
match *self.buffered_lints.borrow_mut() {
|
||||
Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(), msg),
|
||||
None => bug!("can't buffer lints after HIR lowering"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reserve_node_ids(&self, count: usize) -> ast::NodeId {
|
||||
|
|
@ -708,7 +701,7 @@ pub fn build_session_(sopts: config::Options,
|
|||
local_crate_source_file,
|
||||
working_dir,
|
||||
lint_store: RefCell::new(lint::LintStore::new()),
|
||||
lints: RefCell::new(lint::LintTable::new()),
|
||||
buffered_lints: RefCell::new(Some(lint::LintBuffer::new())),
|
||||
one_time_diagnostics: RefCell::new(FxHashSet()),
|
||||
plugin_llvm_passes: RefCell::new(Vec::new()),
|
||||
plugin_attributes: RefCell::new(Vec::new()),
|
||||
|
|
|
|||
|
|
@ -279,8 +279,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
let mut self_match_impls = vec![];
|
||||
let mut fuzzy_match_impls = vec![];
|
||||
|
||||
self.tcx.trait_def(trait_ref.def_id)
|
||||
.for_each_relevant_impl(self.tcx, trait_self_ty, |def_id| {
|
||||
self.tcx.for_each_relevant_impl(
|
||||
trait_ref.def_id, trait_self_ty, |def_id| {
|
||||
let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
|
||||
let impl_trait_ref = tcx
|
||||
.impl_trait_ref(def_id)
|
||||
|
|
@ -397,10 +397,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
trait_ref.skip_binder().self_ty(),
|
||||
true);
|
||||
let mut impl_candidates = Vec::new();
|
||||
let trait_def = self.tcx.trait_def(trait_ref.def_id());
|
||||
|
||||
match simp {
|
||||
Some(simp) => trait_def.for_each_impl(self.tcx, |def_id| {
|
||||
Some(simp) => self.tcx.for_each_impl(trait_ref.def_id(), |def_id| {
|
||||
let imp = self.tcx.impl_trait_ref(def_id).unwrap();
|
||||
let imp_simp = fast_reject::simplify_type(self.tcx,
|
||||
imp.self_ty(),
|
||||
|
|
@ -412,7 +411,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
impl_candidates.push(imp);
|
||||
}),
|
||||
None => trait_def.for_each_impl(self.tcx, |def_id| {
|
||||
None => self.tcx.for_each_impl(trait_ref.def_id(), |def_id| {
|
||||
impl_candidates.push(
|
||||
self.tcx.impl_trait_ref(def_id).unwrap());
|
||||
})
|
||||
|
|
@ -501,11 +500,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
// weird effect -- the diagnostic is reported as a lint, and
|
||||
// the builder which is returned is marked as canceled.
|
||||
|
||||
let mut err =
|
||||
struct_span_err!(self.tcx.sess,
|
||||
error_span,
|
||||
E0276,
|
||||
"impl has stricter requirements than trait");
|
||||
let msg = "impl has stricter requirements than trait";
|
||||
let mut err = match lint_id {
|
||||
Some(node_id) => {
|
||||
self.tcx.struct_span_lint_node(EXTRA_REQUIREMENT_IN_IMPL,
|
||||
node_id,
|
||||
error_span,
|
||||
msg)
|
||||
}
|
||||
None => {
|
||||
struct_span_err!(self.tcx.sess,
|
||||
error_span,
|
||||
E0276,
|
||||
"{}", msg)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
|
||||
let span = self.tcx.sess.codemap().def_span(trait_item_span);
|
||||
|
|
@ -516,13 +525,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
error_span,
|
||||
format!("impl has extra requirement {}", requirement));
|
||||
|
||||
if let Some(node_id) = lint_id {
|
||||
self.tcx.sess.add_lint_diagnostic(EXTRA_REQUIREMENT_IN_IMPL,
|
||||
node_id,
|
||||
(*err).clone());
|
||||
err.cancel();
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -572,7 +572,7 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
|||
{
|
||||
debug!("fully_normalize(value={:?})", value);
|
||||
|
||||
let mut selcx = &mut SelectionContext::new(infcx);
|
||||
let selcx = &mut SelectionContext::new(infcx);
|
||||
// FIXME (@jroesch) ISSUE 26721
|
||||
// I'm not sure if this is a bug or not, needs further investigation.
|
||||
// It appears that by reusing the fulfillment_cx here we incur more
|
||||
|
|
|
|||
|
|
@ -504,7 +504,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| {
|
||||
// Swap out () with ! so we can check if the trait is impld for !
|
||||
{
|
||||
let mut trait_ref = &mut trait_pred.trait_ref;
|
||||
let trait_ref = &mut trait_pred.trait_ref;
|
||||
let unit_substs = trait_ref.substs;
|
||||
let mut never_substs = Vec::with_capacity(unit_substs.len());
|
||||
never_substs.push(From::from(tcx.types.never));
|
||||
|
|
@ -522,11 +522,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
if raise_warning {
|
||||
tcx.sess.add_lint(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
|
||||
obligation.cause.body_id,
|
||||
obligation.cause.span,
|
||||
format!("code relies on type inference rules which are likely \
|
||||
to change"));
|
||||
tcx.lint_node(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
|
||||
obligation.cause.body_id,
|
||||
obligation.cause.span,
|
||||
&format!("code relies on type inference rules which are likely \
|
||||
to change"));
|
||||
}
|
||||
}
|
||||
Ok(ret)
|
||||
|
|
@ -1619,10 +1619,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
{
|
||||
debug!("assemble_candidates_from_impls(obligation={:?})", obligation);
|
||||
|
||||
let def = self.tcx().trait_def(obligation.predicate.def_id());
|
||||
|
||||
def.for_each_relevant_impl(
|
||||
self.tcx(),
|
||||
self.tcx().for_each_relevant_impl(
|
||||
obligation.predicate.def_id(),
|
||||
obligation.predicate.0.trait_ref.self_ty(),
|
||||
|impl_def_id| {
|
||||
self.probe(|this, snapshot| { /* [1] */
|
||||
|
|
|
|||
|
|
@ -300,7 +300,8 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
|
|||
-> Rc<specialization_graph::Graph> {
|
||||
let mut sg = specialization_graph::Graph::new();
|
||||
|
||||
let mut trait_impls: Vec<DefId> = tcx.trait_impls_of(trait_id).iter().collect();
|
||||
let mut trait_impls = Vec::new();
|
||||
tcx.for_each_impl(trait_id, |impl_did| trait_impls.push(impl_did));
|
||||
|
||||
// The coherence checking implementation seems to rely on impls being
|
||||
// iterated over (roughly) in definition order, so we are sorting by
|
||||
|
|
|
|||
|
|
@ -11,14 +11,15 @@
|
|||
//! type context book-keeping
|
||||
|
||||
use dep_graph::DepGraph;
|
||||
use errors::DiagnosticBuilder;
|
||||
use session::Session;
|
||||
use lint;
|
||||
use middle;
|
||||
use hir::TraitMap;
|
||||
use hir::def::{Def, ExportMap};
|
||||
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use hir::map as hir_map;
|
||||
use hir::map::DefPathHash;
|
||||
use lint::{self, Lint};
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use middle::lang_items;
|
||||
use middle::resolve_lifetime;
|
||||
|
|
@ -58,6 +59,7 @@ use std::rc::Rc;
|
|||
use syntax::abi;
|
||||
use syntax::ast::{self, Name, NodeId};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::MultiSpan;
|
||||
use syntax::symbol::{Symbol, keywords};
|
||||
use syntax_pos::Span;
|
||||
|
||||
|
|
@ -258,9 +260,6 @@ pub struct TypeckTables<'tcx> {
|
|||
/// *from* expression of the cast, not the cast itself.
|
||||
pub cast_kinds: NodeMap<ty::cast::CastKind>,
|
||||
|
||||
/// Lints for the body of this fn generated by typeck.
|
||||
pub lints: lint::LintTable,
|
||||
|
||||
/// Set of trait imports actually used in the method resolution.
|
||||
/// This is used for warning unused imports.
|
||||
pub used_trait_imports: DefIdSet,
|
||||
|
|
@ -291,7 +290,6 @@ impl<'tcx> TypeckTables<'tcx> {
|
|||
liberated_fn_sigs: NodeMap(),
|
||||
fru_field_types: NodeMap(),
|
||||
cast_kinds: NodeMap(),
|
||||
lints: lint::LintTable::new(),
|
||||
used_trait_imports: DefIdSet(),
|
||||
tainted_by_errors: false,
|
||||
free_region_map: FreeRegionMap::new(),
|
||||
|
|
@ -1529,6 +1527,59 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
{
|
||||
self.mk_substs(iter::once(s).chain(t.into_iter().cloned()).map(Kind::from))
|
||||
}
|
||||
|
||||
pub fn lint_node<S: Into<MultiSpan>>(self,
|
||||
lint: &'static Lint,
|
||||
id: NodeId,
|
||||
span: S,
|
||||
msg: &str) {
|
||||
self.struct_span_lint_node(lint, id, span.into(), msg).emit()
|
||||
}
|
||||
|
||||
pub fn lint_level_at_node(self, lint: &'static Lint, mut id: NodeId)
|
||||
-> (lint::Level, lint::LintSource)
|
||||
{
|
||||
// Right now we insert a `with_ignore` node in the dep graph here to
|
||||
// ignore the fact that `lint_levels` below depends on the entire crate.
|
||||
// For now this'll prevent false positives of recompiling too much when
|
||||
// anything changes.
|
||||
//
|
||||
// Once red/green incremental compilation lands we should be able to
|
||||
// remove this because while the crate changes often the lint level map
|
||||
// will change rarely.
|
||||
self.dep_graph.with_ignore(|| {
|
||||
let sets = self.lint_levels(LOCAL_CRATE);
|
||||
loop {
|
||||
let hir_id = self.hir.definitions().node_to_hir_id(id);
|
||||
if let Some(pair) = sets.level_and_source(lint, hir_id) {
|
||||
return pair
|
||||
}
|
||||
let next = self.hir.get_parent_node(id);
|
||||
if next == id {
|
||||
bug!("lint traversal reached the root of the crate");
|
||||
}
|
||||
id = next;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn struct_span_lint_node<S: Into<MultiSpan>>(self,
|
||||
lint: &'static Lint,
|
||||
id: NodeId,
|
||||
span: S,
|
||||
msg: &str)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
let (level, src) = self.lint_level_at_node(lint, id);
|
||||
lint::struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg)
|
||||
}
|
||||
|
||||
pub fn struct_lint_node(self, lint: &'static Lint, id: NodeId, msg: &str)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
let (level, src) = self.lint_level_at_node(lint, id);
|
||||
lint::struct_lint_level(self.sess, lint, level, src, None, msg)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait InternAs<T: ?Sized, R> {
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
match self.sty {
|
||||
TyAdt(def, substs) => {
|
||||
{
|
||||
let mut substs_set = visited.entry(def.did).or_insert(FxHashSet::default());
|
||||
let substs_set = visited.entry(def.did).or_insert(FxHashSet::default());
|
||||
if !substs_set.insert(substs) {
|
||||
// We are already calculating the inhabitedness of this type.
|
||||
// The type must contain a reference to itself. Break the
|
||||
|
|
@ -193,7 +193,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
}
|
||||
}
|
||||
let ret = def.uninhabited_from(visited, tcx, substs);
|
||||
let mut substs_set = visited.get_mut(&def.did).unwrap();
|
||||
let substs_set = visited.get_mut(&def.did).unwrap();
|
||||
substs_set.remove(substs);
|
||||
ret
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use dep_graph::{DepConstructor, DepNode, DepNodeIndex};
|
|||
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use hir::def::Def;
|
||||
use hir;
|
||||
use lint;
|
||||
use middle::const_val;
|
||||
use middle::cstore::{ExternCrate, LinkagePreference};
|
||||
use middle::privacy::AccessLevels;
|
||||
|
|
@ -470,12 +471,6 @@ impl<'tcx> QueryDescription for queries::trait_impls_of<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription for queries::relevant_trait_impls_for<'tcx> {
|
||||
fn describe(tcx: TyCtxt, (def_id, ty): (DefId, SimplifiedType)) -> String {
|
||||
format!("relevant impls for: `({}, {:?})`", tcx.item_path_str(def_id), ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription for queries::is_object_safe<'tcx> {
|
||||
fn describe(tcx: TyCtxt, def_id: DefId) -> String {
|
||||
format!("determine object safety of trait `{}`", tcx.item_path_str(def_id))
|
||||
|
|
@ -512,6 +507,12 @@ impl<'tcx> QueryDescription for queries::extern_crate<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription for queries::lint_levels<'tcx> {
|
||||
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
|
||||
format!("computing the lint levels for items in this crate")
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_maps {
|
||||
(<$tcx:tt>
|
||||
$($(#[$attr:meta])*
|
||||
|
|
@ -977,10 +978,7 @@ define_maps! { <'tcx>
|
|||
[] const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
|
||||
[] is_mir_available: IsMirAvailable(DefId) -> bool,
|
||||
|
||||
[] trait_impls_of: TraitImpls(DefId) -> ty::trait_def::TraitImpls,
|
||||
// Note that TraitDef::for_each_relevant_impl() will do type simplication for you.
|
||||
[] relevant_trait_impls_for: relevant_trait_impls_for((DefId, SimplifiedType))
|
||||
-> ty::trait_def::TraitImpls,
|
||||
[] trait_impls_of: TraitImpls(DefId) -> Rc<ty::trait_def::TraitImpls>,
|
||||
[] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
|
||||
[] is_object_safe: ObjectSafety(DefId) -> bool,
|
||||
|
||||
|
|
@ -1008,6 +1006,8 @@ define_maps! { <'tcx>
|
|||
[] is_panic_runtime: IsPanicRuntime(DefId) -> bool,
|
||||
|
||||
[] extern_crate: ExternCrate(DefId) -> Rc<Option<ExternCrate>>,
|
||||
|
||||
[] lint_levels: lint_levels(CrateNum) -> Rc<lint::LintLevelMap>,
|
||||
}
|
||||
|
||||
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
|
||||
|
|
@ -1060,10 +1060,6 @@ fn crate_variances<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
|||
DepConstructor::CrateVariances
|
||||
}
|
||||
|
||||
fn relevant_trait_impls_for<'tcx>((def_id, t): (DefId, SimplifiedType)) -> DepConstructor<'tcx> {
|
||||
DepConstructor::RelevantTraitImpls(def_id, t)
|
||||
}
|
||||
|
||||
fn is_copy_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
|
||||
DepConstructor::IsCopy
|
||||
}
|
||||
|
|
@ -1083,3 +1079,7 @@ fn needs_drop_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstruct
|
|||
fn layout_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'tcx> {
|
||||
DepConstructor::Layout
|
||||
}
|
||||
|
||||
fn lint_levels<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
||||
DepConstructor::LintLevels
|
||||
}
|
||||
|
|
|
|||
|
|
@ -494,6 +494,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
TypeVariants::TyFnPtr(..) |
|
||||
TypeVariants::TyDynamic(..) |
|
||||
TypeVariants::TyClosure(..) |
|
||||
TypeVariants::TyInfer(..) |
|
||||
TypeVariants::TyProjection(..) => false,
|
||||
_ => true,
|
||||
}
|
||||
|
|
@ -2515,7 +2516,6 @@ pub fn provide(providers: &mut ty::maps::Providers) {
|
|||
param_env,
|
||||
trait_of_item,
|
||||
trait_impls_of: trait_def::trait_impls_of_provider,
|
||||
relevant_trait_impls_for: trait_def::relevant_trait_impls_provider,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
|
@ -2525,7 +2525,6 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
|
|||
adt_sized_constraint,
|
||||
adt_dtorck_constraint,
|
||||
trait_impls_of: trait_def::trait_impls_of_provider,
|
||||
relevant_trait_impls_for: trait_def::relevant_trait_impls_provider,
|
||||
param_env,
|
||||
..*providers
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,14 +8,17 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use hir;
|
||||
use hir::def_id::DefId;
|
||||
use hir::map::DefPathHash;
|
||||
use traits::specialization_graph;
|
||||
use ty::fast_reject;
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::{Ty, TyCtxt};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use std::rc::Rc;
|
||||
use hir;
|
||||
|
||||
/// A trait's definition with type information.
|
||||
pub struct TraitDef {
|
||||
|
|
@ -36,60 +39,12 @@ pub struct TraitDef {
|
|||
pub def_path_hash: DefPathHash,
|
||||
}
|
||||
|
||||
// We don't store the list of impls in a flat list because each cached list of
|
||||
// `relevant_impls_for` we would then duplicate all blanket impls. By keeping
|
||||
// blanket and non-blanket impls separate, we can share the list of blanket
|
||||
// impls.
|
||||
#[derive(Clone)]
|
||||
pub struct TraitImpls {
|
||||
blanket_impls: Rc<Vec<DefId>>,
|
||||
non_blanket_impls: Rc<Vec<DefId>>,
|
||||
blanket_impls: Vec<DefId>,
|
||||
/// Impls indexed by their simplified self-type, for fast lookup.
|
||||
non_blanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
|
||||
}
|
||||
|
||||
impl TraitImpls {
|
||||
pub fn iter(&self) -> TraitImplsIter {
|
||||
TraitImplsIter {
|
||||
blanket_impls: self.blanket_impls.clone(),
|
||||
non_blanket_impls: self.non_blanket_impls.clone(),
|
||||
index: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TraitImplsIter {
|
||||
blanket_impls: Rc<Vec<DefId>>,
|
||||
non_blanket_impls: Rc<Vec<DefId>>,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl Iterator for TraitImplsIter {
|
||||
type Item = DefId;
|
||||
|
||||
fn next(&mut self) -> Option<DefId> {
|
||||
if self.index < self.blanket_impls.len() {
|
||||
let bi_index = self.index;
|
||||
self.index += 1;
|
||||
Some(self.blanket_impls[bi_index])
|
||||
} else {
|
||||
let nbi_index = self.index - self.blanket_impls.len();
|
||||
if nbi_index < self.non_blanket_impls.len() {
|
||||
self.index += 1;
|
||||
Some(self.non_blanket_impls[nbi_index])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let items_left = (self.blanket_impls.len() + self.non_blanket_impls.len()) - self.index;
|
||||
(items_left, Some(items_left))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for TraitImplsIter {}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TraitDef {
|
||||
pub fn new(def_id: DefId,
|
||||
unsafety: hir::Unsafety,
|
||||
|
|
@ -111,20 +66,36 @@ impl<'a, 'gcx, 'tcx> TraitDef {
|
|||
-> specialization_graph::Ancestors {
|
||||
specialization_graph::ancestors(tcx, self.def_id, of_impl)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, mut f: F) {
|
||||
for impl_def_id in tcx.trait_impls_of(self.def_id).iter() {
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn for_each_impl<F: FnMut(DefId)>(self, def_id: DefId, mut f: F) {
|
||||
let impls = self.trait_impls_of(def_id);
|
||||
|
||||
for &impl_def_id in impls.blanket_impls.iter() {
|
||||
f(impl_def_id);
|
||||
}
|
||||
|
||||
for v in impls.non_blanket_impls.values() {
|
||||
for &impl_def_id in v {
|
||||
f(impl_def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over every impl that could possibly match the
|
||||
/// self-type `self_ty`.
|
||||
pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
pub fn for_each_relevant_impl<F: FnMut(DefId)>(self,
|
||||
def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
mut f: F)
|
||||
{
|
||||
let impls = self.trait_impls_of(def_id);
|
||||
|
||||
for &impl_def_id in impls.blanket_impls.iter() {
|
||||
f(impl_def_id);
|
||||
}
|
||||
|
||||
// simplify_type(.., false) basically replaces type parameters and
|
||||
// projections with infer-variables. This is, of course, done on
|
||||
// the impl trait-ref when it is instantiated, but not on the
|
||||
|
|
@ -137,15 +108,31 @@ impl<'a, 'gcx, 'tcx> TraitDef {
|
|||
// replace `S` with anything - this impl of course can't be
|
||||
// selected, and as there are hundreds of similar impls,
|
||||
// considering them would significantly harm performance.
|
||||
let relevant_impls = if let Some(simplified_self_ty) =
|
||||
fast_reject::simplify_type(tcx, self_ty, true) {
|
||||
tcx.relevant_trait_impls_for((self.def_id, simplified_self_ty))
|
||||
} else {
|
||||
tcx.trait_impls_of(self.def_id)
|
||||
};
|
||||
|
||||
for impl_def_id in relevant_impls.iter() {
|
||||
f(impl_def_id);
|
||||
// This depends on the set of all impls for the trait. That is
|
||||
// unfortunate. When we get red-green recompilation, we would like
|
||||
// to have a way of knowing whether the set of relevant impls
|
||||
// changed. The most naive
|
||||
// way would be to compute the Vec of relevant impls and see whether
|
||||
// it differs between compilations. That shouldn't be too slow by
|
||||
// itself - we do quite a bit of work for each relevant impl anyway.
|
||||
//
|
||||
// If we want to be faster, we could have separate queries for
|
||||
// blanket and non-blanket impls, and compare them separately.
|
||||
//
|
||||
// I think we'll cross that bridge when we get to it.
|
||||
if let Some(simp) = fast_reject::simplify_type(self, self_ty, true) {
|
||||
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
|
||||
for &impl_def_id in impls {
|
||||
f(impl_def_id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for v in impls.non_blanket_impls.values() {
|
||||
for &impl_def_id in v {
|
||||
f(impl_def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -153,7 +140,7 @@ impl<'a, 'gcx, 'tcx> TraitDef {
|
|||
// Query provider for `trait_impls_of`.
|
||||
pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
trait_id: DefId)
|
||||
-> TraitImpls {
|
||||
-> Rc<TraitImpls> {
|
||||
let remote_impls = if trait_id.is_local() {
|
||||
// Traits defined in the current crate can't have impls in upstream
|
||||
// crates, so we don't bother querying the cstore.
|
||||
|
|
@ -163,7 +150,7 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
};
|
||||
|
||||
let mut blanket_impls = Vec::new();
|
||||
let mut non_blanket_impls = Vec::new();
|
||||
let mut non_blanket_impls = FxHashMap();
|
||||
|
||||
let local_impls = tcx.hir
|
||||
.trait_impls(trait_id)
|
||||
|
|
@ -176,47 +163,20 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
continue
|
||||
}
|
||||
|
||||
if fast_reject::simplify_type(tcx, impl_self_ty, false).is_some() {
|
||||
non_blanket_impls.push(impl_def_id);
|
||||
if let Some(simplified_self_ty) =
|
||||
fast_reject::simplify_type(tcx, impl_self_ty, false)
|
||||
{
|
||||
non_blanket_impls
|
||||
.entry(simplified_self_ty)
|
||||
.or_insert(vec![])
|
||||
.push(impl_def_id);
|
||||
} else {
|
||||
blanket_impls.push(impl_def_id);
|
||||
}
|
||||
}
|
||||
|
||||
TraitImpls {
|
||||
blanket_impls: Rc::new(blanket_impls),
|
||||
non_blanket_impls: Rc::new(non_blanket_impls),
|
||||
}
|
||||
}
|
||||
|
||||
// Query provider for `relevant_trait_impls_for`.
|
||||
pub(super) fn relevant_trait_impls_provider<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
(trait_id, self_ty): (DefId, fast_reject::SimplifiedType))
|
||||
-> TraitImpls
|
||||
{
|
||||
let all_trait_impls = tcx.trait_impls_of(trait_id);
|
||||
|
||||
let relevant: Vec<DefId> = all_trait_impls
|
||||
.non_blanket_impls
|
||||
.iter()
|
||||
.cloned()
|
||||
.filter(|&impl_def_id| {
|
||||
let impl_self_ty = tcx.type_of(impl_def_id);
|
||||
let impl_simple_self_ty = fast_reject::simplify_type(tcx,
|
||||
impl_self_ty,
|
||||
false).unwrap();
|
||||
impl_simple_self_ty == self_ty
|
||||
})
|
||||
.collect();
|
||||
|
||||
if all_trait_impls.non_blanket_impls.len() == relevant.len() {
|
||||
// If we didn't filter anything out, re-use the existing vec.
|
||||
all_trait_impls
|
||||
} else {
|
||||
TraitImpls {
|
||||
blanket_impls: all_trait_impls.blanket_impls.clone(),
|
||||
non_blanket_impls: Rc::new(relevant),
|
||||
}
|
||||
}
|
||||
Rc::new(TraitImpls {
|
||||
blanket_impls: blanket_impls,
|
||||
non_blanket_impls: non_blanket_impls,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
let mut dtor_did = None;
|
||||
let ty = self.type_of(adt_did);
|
||||
self.trait_def(drop_trait).for_each_relevant_impl(self, ty, |impl_did| {
|
||||
self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
|
||||
if let Some(item) = self.associated_items(impl_did).next() {
|
||||
if let Ok(()) = validate(self, impl_did) {
|
||||
dtor_did = Some(item.def_id);
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ impl<'a> AllocFnFactory<'a> {
|
|||
fn arg_ty(&self,
|
||||
ty: &AllocatorTy,
|
||||
args: &mut Vec<Arg>,
|
||||
mut ident: &mut FnMut() -> Ident) -> P<Expr> {
|
||||
ident: &mut FnMut() -> Ident) -> P<Expr> {
|
||||
match *ty {
|
||||
AllocatorTy::Layout => {
|
||||
let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
|
||||
|
|
@ -263,7 +263,7 @@ impl<'a> AllocFnFactory<'a> {
|
|||
fn ret_ty(&self,
|
||||
ty: &AllocatorTy,
|
||||
args: &mut Vec<Arg>,
|
||||
mut ident: &mut FnMut() -> Ident,
|
||||
ident: &mut FnMut() -> Ident,
|
||||
expr: P<Expr>) -> (P<Ty>, P<Expr>)
|
||||
{
|
||||
match *ty {
|
||||
|
|
|
|||
|
|
@ -434,20 +434,40 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
|||
//! For mutable loans of content whose mutability derives
|
||||
//! from a local variable, mark the mutability decl as necessary.
|
||||
|
||||
match loan_path.kind {
|
||||
LpVar(local_id) |
|
||||
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
|
||||
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
|
||||
}
|
||||
LpDowncast(ref base, _) |
|
||||
LpExtend(ref base, mc::McInherited, _) |
|
||||
LpExtend(ref base, mc::McDeclared, _) => {
|
||||
self.mark_loan_path_as_mutated(&base);
|
||||
}
|
||||
LpExtend(_, mc::McImmutable, _) => {
|
||||
// Nothing to do.
|
||||
let mut wrapped_path = Some(loan_path);
|
||||
let mut through_borrow = false;
|
||||
|
||||
while let Some(current_path) = wrapped_path {
|
||||
wrapped_path = match current_path.kind {
|
||||
LpVar(local_id) => {
|
||||
if !through_borrow {
|
||||
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
|
||||
}
|
||||
None
|
||||
}
|
||||
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
|
||||
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
|
||||
None
|
||||
}
|
||||
LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) |
|
||||
LpExtend(ref base, mc::McDeclared, LpDeref(pointer_kind)) => {
|
||||
if pointer_kind != mc::Unique {
|
||||
through_borrow = true;
|
||||
}
|
||||
Some(base)
|
||||
}
|
||||
LpDowncast(ref base, _) |
|
||||
LpExtend(ref base, mc::McInherited, _) |
|
||||
LpExtend(ref base, mc::McDeclared, _) => {
|
||||
Some(base)
|
||||
}
|
||||
LpExtend(_, mc::McImmutable, _) => {
|
||||
// Nothing to do.
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn compute_gen_scope(&self,
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
|
|||
let tables = tcx.typeck_tables_of(owner_def_id);
|
||||
let region_maps = tcx.region_maps(owner_def_id);
|
||||
let body = tcx.hir.body(body_id);
|
||||
let mut bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id, body };
|
||||
let bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id, body };
|
||||
|
||||
// Eventually, borrowck will always read the MIR, but at the
|
||||
// moment we do not. So, for now, we always force MIR to be
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use rustc::session::Session;
|
|||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::lint;
|
||||
use rustc_errors::{Diagnostic, Level, DiagnosticBuilder};
|
||||
use rustc_errors::DiagnosticBuilder;
|
||||
|
||||
use rustc::hir::def::*;
|
||||
use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
|
||||
|
|
@ -351,12 +351,10 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
|||
match arm_index {
|
||||
// The arm with the user-specified pattern.
|
||||
0 => {
|
||||
let mut diagnostic = Diagnostic::new(Level::Warning,
|
||||
"unreachable pattern");
|
||||
diagnostic.set_span(pat.span);
|
||||
cx.tcx.sess.add_lint_diagnostic(
|
||||
cx.tcx.lint_node(
|
||||
lint::builtin::UNREACHABLE_PATTERNS,
|
||||
hir_pat.id, diagnostic);
|
||||
hir_pat.id, pat.span,
|
||||
"unreachable pattern");
|
||||
},
|
||||
// The arm with the wildcard pattern.
|
||||
1 => {
|
||||
|
|
@ -371,16 +369,18 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
|||
|
||||
hir::MatchSource::ForLoopDesugar |
|
||||
hir::MatchSource::Normal => {
|
||||
let mut diagnostic = Diagnostic::new(Level::Warning,
|
||||
"unreachable pattern");
|
||||
diagnostic.set_span(pat.span);
|
||||
let mut err = cx.tcx.struct_span_lint_node(
|
||||
lint::builtin::UNREACHABLE_PATTERNS,
|
||||
hir_pat.id,
|
||||
pat.span,
|
||||
"unreachable pattern",
|
||||
);
|
||||
// if we had a catchall pattern, hint at that
|
||||
if let Some(catchall) = catchall {
|
||||
diagnostic.span_label(pat.span, "this is an unreachable pattern");
|
||||
diagnostic.span_note(catchall, "this pattern matches any value");
|
||||
err.span_label(pat.span, "this is an unreachable pattern");
|
||||
err.span_note(catchall, "this pattern matches any value");
|
||||
}
|
||||
cx.tcx.sess.add_lint_diagnostic(lint::builtin::UNREACHABLE_PATTERNS,
|
||||
hir_pat.id, diagnostic);
|
||||
err.emit();
|
||||
},
|
||||
|
||||
// Unreachable patterns in try expressions occur when one of the arms
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ impl<'a, A: Array> Drop for Drain<'a, A> {
|
|||
let start = source_array_vec.len();
|
||||
let tail = self.tail_start;
|
||||
{
|
||||
let mut arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
|
||||
let arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
|
||||
let src = arr.as_ptr().offset(tail as isize);
|
||||
let dst = arr.as_mut_ptr().offset(start as isize);
|
||||
ptr::copy(src, dst, self.tail_len);
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ impl BitMatrix {
|
|||
pub fn add(&mut self, source: usize, target: usize) -> bool {
|
||||
let (start, _) = self.range(source);
|
||||
let (word, mask) = word_mask(target);
|
||||
let mut vector = &mut self.vector[..];
|
||||
let vector = &mut self.vector[..];
|
||||
let v1 = vector[start + word];
|
||||
let v2 = v1 | mask;
|
||||
vector[start + word] = v2;
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> {
|
|||
type IntoIter = slice::IterMut<'a, T>;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(mut self) -> slice::IterMut<'a, T> {
|
||||
fn into_iter(self) -> slice::IterMut<'a, T> {
|
||||
self.raw.iter_mut()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ pub fn compile_input(sess: &Session,
|
|||
// large chunks of memory alive and we want to free them as soon as
|
||||
// possible to keep the peak memory usage low
|
||||
let (outputs, trans) = {
|
||||
let krate = match phase_1_parse_input(sess, input) {
|
||||
let krate = match phase_1_parse_input(control, sess, input) {
|
||||
Ok(krate) => krate,
|
||||
Err(mut parse_error) => {
|
||||
parse_error.emit();
|
||||
|
|
@ -296,9 +296,13 @@ pub struct CompileController<'a> {
|
|||
pub after_llvm: PhaseController<'a>,
|
||||
pub compilation_done: PhaseController<'a>,
|
||||
|
||||
// FIXME we probably want to group the below options together and offer a
|
||||
// better API, rather than this ad-hoc approach.
|
||||
pub make_glob_map: MakeGlobMap,
|
||||
// Whether the compiler should keep the ast beyond parsing.
|
||||
pub keep_ast: bool,
|
||||
// -Zcontinue-parse-after-error
|
||||
pub continue_parse_after_error: bool,
|
||||
}
|
||||
|
||||
impl<'a> CompileController<'a> {
|
||||
|
|
@ -312,6 +316,7 @@ impl<'a> CompileController<'a> {
|
|||
compilation_done: PhaseController::basic(),
|
||||
make_glob_map: MakeGlobMap::No,
|
||||
keep_ast: false,
|
||||
continue_parse_after_error: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -484,10 +489,10 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn state_when_compilation_done(input: &'a Input,
|
||||
session: &'tcx Session,
|
||||
out_dir: &'a Option<PathBuf>,
|
||||
out_file: &'a Option<PathBuf>)
|
||||
-> Self {
|
||||
session: &'tcx Session,
|
||||
out_dir: &'a Option<PathBuf>,
|
||||
out_file: &'a Option<PathBuf>)
|
||||
-> Self {
|
||||
CompileState {
|
||||
out_file: out_file.as_ref().map(|s| &**s),
|
||||
..CompileState::empty(input, session, out_dir)
|
||||
|
|
@ -495,9 +500,11 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn phase_1_parse_input<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
|
||||
let continue_after_error = sess.opts.debugging_opts.continue_parse_after_error;
|
||||
sess.diagnostic().set_continue_after_error(continue_after_error);
|
||||
pub fn phase_1_parse_input<'a>(control: &CompileController,
|
||||
sess: &'a Session,
|
||||
input: &Input)
|
||||
-> PResult<'a, ast::Crate> {
|
||||
sess.diagnostic().set_continue_after_error(control.continue_parse_after_error);
|
||||
|
||||
let krate = time(sess.time_passes(), "parsing", || {
|
||||
match *input {
|
||||
|
|
@ -638,7 +645,6 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
|
|||
super::describe_lints(&sess.lint_store.borrow(), true);
|
||||
return Err(CompileIncomplete::Stopped);
|
||||
}
|
||||
sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;
|
||||
|
||||
// Currently, we ignore the name resolution data structures for the purposes of dependency
|
||||
// tracking. Instead we will run name resolution and include its output in the hash of each
|
||||
|
|
@ -708,8 +714,8 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
|
|||
missing_fragment_specifiers.sort();
|
||||
for span in missing_fragment_specifiers {
|
||||
let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
|
||||
let msg = "missing fragment specifier".to_string();
|
||||
sess.add_lint(lint, ast::CRATE_NODE_ID, span, msg);
|
||||
let msg = "missing fragment specifier";
|
||||
sess.buffer_lint(lint, ast::CRATE_NODE_ID, span, msg);
|
||||
}
|
||||
if ecx.parse_sess.span_diagnostic.err_count() - ecx.resolve_err_count > err_count {
|
||||
ecx.parse_sess.span_diagnostic.abort_if_errors();
|
||||
|
|
@ -772,10 +778,6 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
|
|||
"checking for inline asm in case the target doesn't support it",
|
||||
|| no_asm::check_crate(sess, &krate));
|
||||
|
||||
time(time_passes,
|
||||
"early lint checks",
|
||||
|| lint::check_ast_crate(sess, &krate));
|
||||
|
||||
time(time_passes,
|
||||
"AST validation",
|
||||
|| ast_validation::check_crate(sess, &krate));
|
||||
|
|
@ -800,6 +802,10 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
|
|||
})
|
||||
})?;
|
||||
|
||||
time(time_passes,
|
||||
"early lint checks",
|
||||
|| lint::check_ast_crate(sess, &krate));
|
||||
|
||||
// Lower ast -> hir.
|
||||
let hir_forest = time(time_passes, "lowering ast -> hir", || {
|
||||
let hir_crate = lower_crate(sess, &krate, &mut resolver);
|
||||
|
|
@ -908,6 +914,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
|||
rustc_const_eval::provide(&mut local_providers);
|
||||
middle::region::provide(&mut local_providers);
|
||||
cstore::provide_local(&mut local_providers);
|
||||
lint::provide(&mut local_providers);
|
||||
|
||||
let mut extern_providers = ty::maps::Providers::default();
|
||||
cstore::provide(&mut extern_providers);
|
||||
|
|
@ -1198,10 +1205,10 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
|
|||
}
|
||||
Some(ref n) if *n == "bin" => Some(config::CrateTypeExecutable),
|
||||
Some(_) => {
|
||||
session.add_lint(lint::builtin::UNKNOWN_CRATE_TYPES,
|
||||
ast::CRATE_NODE_ID,
|
||||
a.span,
|
||||
"invalid `crate_type` value".to_string());
|
||||
session.buffer_lint(lint::builtin::UNKNOWN_CRATE_TYPES,
|
||||
ast::CRATE_NODE_ID,
|
||||
a.span,
|
||||
"invalid `crate_type` value");
|
||||
None
|
||||
}
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ fn show_content_with_pager(content: &String) {
|
|||
|
||||
match Command::new(pager_name).stdin(Stdio::piped()).spawn() {
|
||||
Ok(mut pager) => {
|
||||
if let Some(mut pipe) = pager.stdin.as_mut() {
|
||||
if let Some(pipe) = pager.stdin.as_mut() {
|
||||
if pipe.write_all(content.as_bytes()).is_err() {
|
||||
fallback_to_println = true;
|
||||
}
|
||||
|
|
@ -518,7 +518,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||
-> CompileController<'a> {
|
||||
let mut control = CompileController::basic();
|
||||
|
||||
control.keep_ast = sess.opts.debugging_opts.keep_ast || save_analysis(sess);
|
||||
control.keep_ast = sess.opts.debugging_opts.keep_ast;
|
||||
control.continue_parse_after_error = sess.opts.debugging_opts.continue_parse_after_error;
|
||||
|
||||
if let Some((ppm, opt_uii)) = parse_pretty(sess, matches) {
|
||||
if ppm.needs_ast_map(&opt_uii) {
|
||||
|
|
@ -574,19 +575,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||
}
|
||||
|
||||
if save_analysis(sess) {
|
||||
control.after_analysis.callback = box |state| {
|
||||
time(state.session.time_passes(), "save analysis", || {
|
||||
save::process_crate(state.tcx.unwrap(),
|
||||
state.expanded_crate.unwrap(),
|
||||
state.analysis.unwrap(),
|
||||
state.crate_name.unwrap(),
|
||||
None,
|
||||
DumpHandler::new(state.out_dir,
|
||||
state.crate_name.unwrap()))
|
||||
});
|
||||
};
|
||||
control.after_analysis.run_callback_on_error = true;
|
||||
control.make_glob_map = resolve::MakeGlobMap::Yes;
|
||||
enable_save_analysis(&mut control);
|
||||
}
|
||||
|
||||
if sess.print_fuel_crate.is_some() {
|
||||
|
|
@ -603,6 +592,23 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn enable_save_analysis(control: &mut CompileController) {
|
||||
control.keep_ast = true;
|
||||
control.after_analysis.callback = box |state| {
|
||||
time(state.session.time_passes(), "save analysis", || {
|
||||
save::process_crate(state.tcx.unwrap(),
|
||||
state.expanded_crate.unwrap(),
|
||||
state.analysis.unwrap(),
|
||||
state.crate_name.unwrap(),
|
||||
None,
|
||||
DumpHandler::new(state.out_dir,
|
||||
state.crate_name.unwrap()))
|
||||
});
|
||||
};
|
||||
control.after_analysis.run_callback_on_error = true;
|
||||
control.make_glob_map = resolve::MakeGlobMap::Yes;
|
||||
}
|
||||
|
||||
fn save_analysis(sess: &Session) -> bool {
|
||||
sess.opts.debugging_opts.save_analysis
|
||||
}
|
||||
|
|
@ -1215,7 +1221,7 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
|
|||
Registry::new(&all_errors)
|
||||
}
|
||||
|
||||
fn get_args() -> Vec<String> {
|
||||
pub fn get_args() -> Vec<String> {
|
||||
env::args_os().enumerate()
|
||||
.map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
|
||||
early_error(ErrorOutputType::default(),
|
||||
|
|
|
|||
|
|
@ -119,7 +119,9 @@ fn test_env<F>(source_string: &str,
|
|||
name: driver::anon_src(),
|
||||
input: source_string.to_string(),
|
||||
};
|
||||
let krate = driver::phase_1_parse_input(&sess, &input).unwrap();
|
||||
let krate = driver::phase_1_parse_input(&driver::CompileController::basic(),
|
||||
&sess,
|
||||
&input).unwrap();
|
||||
let driver::ExpansionResult { defs, resolutions, mut hir_forest, .. } = {
|
||||
driver::phase_2_configure_and_expand(&sess,
|
||||
&cstore,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ use rustc::ty::{self, Ty};
|
|||
use rustc::traits::{self, Reveal};
|
||||
use rustc::hir::map as hir_map;
|
||||
use util::nodemap::NodeSet;
|
||||
use lint::{Level, LateContext, LintContext, LintArray};
|
||||
use lint::{LateContext, LintContext, LintArray};
|
||||
use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext};
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
|
@ -542,9 +542,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
|
|||
};
|
||||
|
||||
if self.impling_types.is_none() {
|
||||
let debug_def = cx.tcx.trait_def(debug);
|
||||
let mut impls = NodeSet();
|
||||
debug_def.for_each_impl(cx.tcx, |d| {
|
||||
cx.tcx.for_each_impl(debug, |d| {
|
||||
if let Some(ty_def) = cx.tcx.type_of(d).ty_to_def_id() {
|
||||
if let Some(node_id) = cx.tcx.hir.as_local_node_id(ty_def) {
|
||||
impls.insert(node_id);
|
||||
|
|
@ -877,16 +876,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
|
|||
let mut db = cx.struct_span_lint(UNCONDITIONAL_RECURSION,
|
||||
sp,
|
||||
"function cannot return without recurring");
|
||||
|
||||
// FIXME #19668: these could be span_lint_note's instead of this manual guard.
|
||||
if cx.current_level(UNCONDITIONAL_RECURSION) != Level::Allow {
|
||||
// offer some help to the programmer.
|
||||
for call in &self_call_spans {
|
||||
db.span_note(*call, "recursive call site");
|
||||
}
|
||||
db.help("a `loop` may express intention \
|
||||
better if this is on purpose");
|
||||
// offer some help to the programmer.
|
||||
for call in &self_call_spans {
|
||||
db.span_note(*call, "recursive call site");
|
||||
}
|
||||
db.help("a `loop` may express intention \
|
||||
better if this is on purpose");
|
||||
db.emit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,22 +145,38 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
|||
}
|
||||
|
||||
let t = cx.tables.expr_ty(&expr);
|
||||
let warned = match t.sty {
|
||||
ty::TyTuple(ref tys, _) if tys.is_empty() => return,
|
||||
ty::TyNever => return,
|
||||
ty::TyBool => return,
|
||||
ty::TyAdt(def, _) => check_must_use(cx, def.did, s.span),
|
||||
let ty_warned = match t.sty {
|
||||
ty::TyAdt(def, _) => check_must_use(cx, def.did, s.span, ""),
|
||||
_ => false,
|
||||
};
|
||||
if !warned {
|
||||
|
||||
let mut fn_warned = false;
|
||||
let maybe_def = match expr.node {
|
||||
hir::ExprCall(ref callee, _) => {
|
||||
match callee.node {
|
||||
hir::ExprPath(ref qpath) => Some(cx.tables.qpath_def(qpath, callee.id)),
|
||||
_ => None
|
||||
}
|
||||
},
|
||||
hir::ExprMethodCall(..) => {
|
||||
cx.tables.type_dependent_defs.get(&expr.id).cloned()
|
||||
},
|
||||
_ => { None }
|
||||
};
|
||||
if let Some(def) = maybe_def {
|
||||
let def_id = def.def_id();
|
||||
fn_warned = check_must_use(cx, def_id, s.span, "return value of ");
|
||||
}
|
||||
|
||||
if !(ty_warned || fn_warned) {
|
||||
cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
|
||||
}
|
||||
|
||||
fn check_must_use(cx: &LateContext, def_id: DefId, sp: Span) -> bool {
|
||||
fn check_must_use(cx: &LateContext, def_id: DefId, sp: Span, describe_path: &str) -> bool {
|
||||
for attr in cx.tcx.get_attrs(def_id).iter() {
|
||||
if attr.check_name("must_use") {
|
||||
let mut msg = format!("unused `{}` which must be used",
|
||||
cx.tcx.item_path_str(def_id));
|
||||
let mut msg = format!("unused {}`{}` which must be used",
|
||||
describe_path, cx.tcx.item_path_str(def_id));
|
||||
// check for #[must_use="..."]
|
||||
if let Some(s) = attr.value_str() {
|
||||
msg.push_str(": ");
|
||||
|
|
|
|||
|
|
@ -480,7 +480,7 @@ impl CrateStore for cstore::CStore {
|
|||
_ => {},
|
||||
}
|
||||
|
||||
let mut bfs_queue = &mut VecDeque::new();
|
||||
let bfs_queue = &mut VecDeque::new();
|
||||
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
|
||||
let child = child.def.def_id();
|
||||
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||
self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty);
|
||||
}
|
||||
|
||||
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, mut f: &mut F)
|
||||
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F)
|
||||
where F: FnMut(&mut Self, Mutability, Name, NodeId, Span, Ty<'tcx>)
|
||||
{
|
||||
match *pattern.kind {
|
||||
|
|
|
|||
|
|
@ -244,8 +244,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
|||
let mut span = None;
|
||||
|
||||
self.tcx
|
||||
.trait_def(drop_trait_id)
|
||||
.for_each_relevant_impl(self.tcx, self.mir.return_ty, |impl_did| {
|
||||
.for_each_relevant_impl(drop_trait_id, self.mir.return_ty, |impl_did| {
|
||||
self.tcx.hir
|
||||
.as_local_node_id(impl_did)
|
||||
.and_then(|impl_node_id| self.tcx.hir.find(impl_node_id))
|
||||
|
|
|
|||
|
|
@ -770,7 +770,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
value,
|
||||
obligations);
|
||||
|
||||
let mut fulfill_cx = &mut self.fulfillment_cx;
|
||||
let fulfill_cx = &mut self.fulfillment_cx;
|
||||
for obligation in obligations {
|
||||
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,10 +237,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
self.check_trait_fn_not_const(sig.constness);
|
||||
if block.is_none() {
|
||||
self.check_decl_no_pat(&sig.decl, |span, _| {
|
||||
self.session.add_lint(lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
trait_item.id, span,
|
||||
"patterns aren't allowed in methods \
|
||||
without bodies".to_string());
|
||||
self.session.buffer_lint(
|
||||
lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
trait_item.id, span,
|
||||
"patterns aren't allowed in methods \
|
||||
without bodies");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -252,7 +253,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
if item.attrs.iter().any(|attr| attr.check_name("warn_directory_ownership")) {
|
||||
let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
|
||||
let msg = "cannot declare a new module at this location";
|
||||
self.session.add_lint(lint, item.id, item.span, msg.to_string());
|
||||
self.session.buffer_lint(lint, item.id, item.span, msg);
|
||||
}
|
||||
}
|
||||
ItemKind::Union(ref vdata, _) => {
|
||||
|
|
|
|||
|
|
@ -76,12 +76,12 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
|
|||
ErroneousReferencedConstant(_) => {}
|
||||
TypeckError => {}
|
||||
_ => {
|
||||
self.tcx.sess.add_lint(CONST_ERR,
|
||||
expr.id,
|
||||
expr.span,
|
||||
format!("constant evaluation error: {}. This will \
|
||||
become a HARD ERROR in the future",
|
||||
err.description().into_oneline()))
|
||||
self.tcx.lint_node(CONST_ERR,
|
||||
expr.id,
|
||||
expr.span,
|
||||
&format!("constant evaluation error: {}. This will \
|
||||
become a HARD ERROR in the future",
|
||||
err.description().into_oneline()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -260,10 +260,10 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
|
|||
kind: LayoutError(ty::layout::LayoutError::Unknown(_)), ..
|
||||
}) => {}
|
||||
Err(msg) => {
|
||||
self.tcx.sess.add_lint(CONST_ERR,
|
||||
ex.id,
|
||||
msg.span,
|
||||
msg.description().into_oneline().into_owned())
|
||||
self.tcx.lint_node(CONST_ERR,
|
||||
ex.id,
|
||||
msg.span,
|
||||
&msg.description().into_oneline().into_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,6 +223,40 @@ To fix this, add a label specifying which loop is being broken out of:
|
|||
```
|
||||
'foo: while break 'foo {}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0571: r##"
|
||||
A `break` statement with an argument appeared in a non-`loop` loop.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0571
|
||||
# let mut i = 1;
|
||||
# fn satisfied(n: usize) -> bool { n % 23 == 0 }
|
||||
let result = while true {
|
||||
if satisfied(i) {
|
||||
break 2*i; // error: `break` with value from a `while` loop
|
||||
}
|
||||
i += 1;
|
||||
};
|
||||
```
|
||||
|
||||
The `break` statement can take an argument (which will be the value of the loop
|
||||
expression if the `break` statement is executed) in `loop` loops, but not
|
||||
`for`, `while`, or `while let` loops.
|
||||
|
||||
Make sure `break value;` statements only occur in `loop` loops:
|
||||
|
||||
```
|
||||
# let mut i = 1;
|
||||
# fn satisfied(n: usize) -> bool { n % 23 == 0 }
|
||||
let result = loop { // ok!
|
||||
if satisfied(i) {
|
||||
break 2*i;
|
||||
}
|
||||
i += 1;
|
||||
};
|
||||
```
|
||||
"##
|
||||
}
|
||||
|
||||
|
|
@ -230,5 +264,4 @@ register_diagnostics! {
|
|||
E0226, // only a single explicit lifetime bound is permitted
|
||||
E0472, // asm! is unsupported on this target
|
||||
E0561, // patterns aren't allowed in function pointer types
|
||||
E0571, // `break` with a value in a non-`loop`-loop
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,6 +142,146 @@ pub fn find(name: &str) -> Option<Intrinsic> {
|
|||
output: &::U32x4,
|
||||
definition: Named("llvm.ppc.altivec.vminuw")
|
||||
},
|
||||
"_vec_subsbs" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
|
||||
output: &::I8x16,
|
||||
definition: Named("llvm.ppc.altivec.vsubsbs")
|
||||
},
|
||||
"_vec_sububs" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
|
||||
output: &::U8x16,
|
||||
definition: Named("llvm.ppc.altivec.vsububs")
|
||||
},
|
||||
"_vec_subshs" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
|
||||
output: &::I16x8,
|
||||
definition: Named("llvm.ppc.altivec.vsubshs")
|
||||
},
|
||||
"_vec_subuhs" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
|
||||
output: &::U16x8,
|
||||
definition: Named("llvm.ppc.altivec.vsubuhs")
|
||||
},
|
||||
"_vec_subsws" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
|
||||
output: &::I32x4,
|
||||
definition: Named("llvm.ppc.altivec.vsubsws")
|
||||
},
|
||||
"_vec_subuws" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
|
||||
output: &::U32x4,
|
||||
definition: Named("llvm.ppc.altivec.vsubuws")
|
||||
},
|
||||
"_vec_subc" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
|
||||
output: &::U32x4,
|
||||
definition: Named("llvm.ppc.altivec.vsubcuw")
|
||||
},
|
||||
"_vec_addsbs" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
|
||||
output: &::I8x16,
|
||||
definition: Named("llvm.ppc.altivec.vaddsbs")
|
||||
},
|
||||
"_vec_addubs" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
|
||||
output: &::U8x16,
|
||||
definition: Named("llvm.ppc.altivec.vaddubs")
|
||||
},
|
||||
"_vec_addshs" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
|
||||
output: &::I16x8,
|
||||
definition: Named("llvm.ppc.altivec.vaddshs")
|
||||
},
|
||||
"_vec_adduhs" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
|
||||
output: &::U16x8,
|
||||
definition: Named("llvm.ppc.altivec.vadduhs")
|
||||
},
|
||||
"_vec_addsws" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
|
||||
output: &::I32x4,
|
||||
definition: Named("llvm.ppc.altivec.vaddsws")
|
||||
},
|
||||
"_vec_adduws" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
|
||||
output: &::U32x4,
|
||||
definition: Named("llvm.ppc.altivec.vadduws")
|
||||
},
|
||||
"_vec_addc" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
|
||||
output: &::U32x4,
|
||||
definition: Named("llvm.ppc.altivec.vaddcuw")
|
||||
},
|
||||
"_vec_mulesb" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
|
||||
output: &::I16x8,
|
||||
definition: Named("llvm.ppc.altivec.vmulesb")
|
||||
},
|
||||
"_vec_muleub" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
|
||||
output: &::U16x8,
|
||||
definition: Named("llvm.ppc.altivec.vmuleub")
|
||||
},
|
||||
"_vec_mulesh" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
|
||||
output: &::I32x4,
|
||||
definition: Named("llvm.ppc.altivec.vmulesh")
|
||||
},
|
||||
"_vec_muleuh" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
|
||||
output: &::U32x4,
|
||||
definition: Named("llvm.ppc.altivec.vmuleuh")
|
||||
},
|
||||
"_vec_mulosb" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
|
||||
output: &::I16x8,
|
||||
definition: Named("llvm.ppc.altivec.vmulosb")
|
||||
},
|
||||
"_vec_muloub" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
|
||||
output: &::U16x8,
|
||||
definition: Named("llvm.ppc.altivec.vmuloub")
|
||||
},
|
||||
"_vec_mulosh" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
|
||||
output: &::I32x4,
|
||||
definition: Named("llvm.ppc.altivec.vmulosh")
|
||||
},
|
||||
"_vec_mulouh" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
|
||||
output: &::U32x4,
|
||||
definition: Named("llvm.ppc.altivec.vmulouh")
|
||||
},
|
||||
"_vec_avgsb" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I8x16, &::I8x16]; &INPUTS },
|
||||
output: &::I8x16,
|
||||
definition: Named("llvm.ppc.altivec.vavgsb")
|
||||
},
|
||||
"_vec_avgub" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U8x16, &::U8x16]; &INPUTS },
|
||||
output: &::U8x16,
|
||||
definition: Named("llvm.ppc.altivec.vavgub")
|
||||
},
|
||||
"_vec_avgsh" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I16x8, &::I16x8]; &INPUTS },
|
||||
output: &::I16x8,
|
||||
definition: Named("llvm.ppc.altivec.vavgsh")
|
||||
},
|
||||
"_vec_avguh" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U16x8, &::U16x8]; &INPUTS },
|
||||
output: &::U16x8,
|
||||
definition: Named("llvm.ppc.altivec.vavguh")
|
||||
},
|
||||
"_vec_avgsw" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::I32x4, &::I32x4]; &INPUTS },
|
||||
output: &::I32x4,
|
||||
definition: Named("llvm.ppc.altivec.vavgsw")
|
||||
},
|
||||
"_vec_avguw" => Intrinsic {
|
||||
inputs: { static INPUTS: [&'static Type; 2] = [&::U32x4, &::U32x4]; &INPUTS },
|
||||
output: &::U32x4,
|
||||
definition: Named("llvm.ppc.altivec.vavguw")
|
||||
},
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -781,7 +781,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
|||
hir::ItemTrait(.., ref trait_item_refs) => {
|
||||
self.check_item(item.id).generics().predicates();
|
||||
for trait_item_ref in trait_item_refs {
|
||||
let mut check = self.check_item(trait_item_ref.id.node_id);
|
||||
let check = self.check_item(trait_item_ref.id.node_id);
|
||||
check.generics().predicates();
|
||||
if trait_item_ref.kind != hir::AssociatedItemKind::Type ||
|
||||
trait_item_ref.defaultness.has_value() {
|
||||
|
|
@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
|
||||
{
|
||||
let mut check = self.check_item(item.id);
|
||||
let check = self.check_item(item.id);
|
||||
check.ty().generics().predicates();
|
||||
if trait_ref.is_some() {
|
||||
check.impl_trait_ref();
|
||||
|
|
@ -1345,11 +1345,11 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
|||
"private trait can't be public"))
|
||||
.emit();
|
||||
} else {
|
||||
self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||
node_id,
|
||||
self.span,
|
||||
format!("private trait `{}` in public \
|
||||
interface (error E0445)", trait_ref));
|
||||
self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||
node_id,
|
||||
self.span,
|
||||
&format!("private trait `{}` in public \
|
||||
interface (error E0445)", trait_ref));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1393,11 +1393,11 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
|
|||
err.span_label(self.span, "can't leak private type");
|
||||
err.emit();
|
||||
} else {
|
||||
self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||
node_id,
|
||||
self.span,
|
||||
format!("private type `{}` in public \
|
||||
interface (error E0446)", ty));
|
||||
self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||
node_id,
|
||||
self.span,
|
||||
&format!("private type `{}` in public \
|
||||
interface (error E0446)", ty));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,13 +122,13 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
|
|||
directive.span.source_equal(&DUMMY_SP) => {}
|
||||
ImportDirectiveSubclass::ExternCrate => {
|
||||
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
|
||||
let msg = "unused extern crate".to_string();
|
||||
resolver.session.add_lint(lint, directive.id, directive.span, msg);
|
||||
let msg = "unused extern crate";
|
||||
; resolver.session.buffer_lint(lint, directive.id, directive.span, msg)
|
||||
}
|
||||
ImportDirectiveSubclass::MacroUse => {
|
||||
let lint = lint::builtin::UNUSED_IMPORTS;
|
||||
let msg = "unused `#[macro_use]` import".to_string();
|
||||
resolver.session.add_lint(lint, directive.id, directive.span, msg);
|
||||
let msg = "unused `#[macro_use]` import";
|
||||
resolver.session.buffer_lint(lint, directive.id, directive.span, msg);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -160,9 +160,6 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
|
|||
} else {
|
||||
String::new()
|
||||
});
|
||||
visitor.session.add_lint(lint::builtin::UNUSED_IMPORTS,
|
||||
*id,
|
||||
ms,
|
||||
msg);
|
||||
visitor.session.buffer_lint(lint::builtin::UNUSED_IMPORTS, *id, ms, &msg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2552,9 +2552,10 @@ impl<'a> Resolver<'a> {
|
|||
= self.struct_constructors.get(&def_id).cloned() {
|
||||
if is_expected(ctor_def) && self.is_accessible(ctor_vis) {
|
||||
let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
|
||||
self.session.add_lint(lint, id, span,
|
||||
self.session.buffer_lint(lint, id, span,
|
||||
"private struct constructors are not usable through \
|
||||
reexports in outer modules".to_string());
|
||||
reexports in outer modules",
|
||||
);
|
||||
res = Some(PathResolution::new(ctor_def));
|
||||
}
|
||||
}
|
||||
|
|
@ -2748,7 +2749,7 @@ impl<'a> Resolver<'a> {
|
|||
};
|
||||
if result.base_def() == unqualified_result {
|
||||
let lint = lint::builtin::UNUSED_QUALIFICATIONS;
|
||||
self.session.add_lint(lint, id, span, "unnecessary qualification".to_string());
|
||||
self.session.buffer_lint(lint, id, span, "unnecessary qualification")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3486,7 +3487,7 @@ impl<'a> Resolver<'a> {
|
|||
span.push_span_label(b1.span, msg1);
|
||||
span.push_span_label(b2.span, msg2);
|
||||
let msg = format!("`{}` is ambiguous", name);
|
||||
self.session.add_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
|
||||
self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, &msg);
|
||||
} else {
|
||||
let mut err =
|
||||
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name));
|
||||
|
|
@ -3607,8 +3608,8 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
fn warn_legacy_self_import(&self, directive: &'a ImportDirective<'a>) {
|
||||
let (id, span) = (directive.id, directive.span);
|
||||
let msg = "`self` no longer imports values".to_string();
|
||||
self.session.add_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
|
||||
let msg = "`self` no longer imports values";
|
||||
self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
|
||||
}
|
||||
|
||||
fn check_proc_macro_attrs(&mut self, attrs: &[ast::Attribute]) {
|
||||
|
|
|
|||
|
|
@ -319,8 +319,8 @@ impl<'a> base::Resolver for Resolver<'a> {
|
|||
};
|
||||
if let Some((id, span)) = id_span {
|
||||
let lint = lint::builtin::UNUSED_MACROS;
|
||||
let msg = "unused macro definition".to_string();
|
||||
self.session.add_lint(lint, id, span, msg);
|
||||
let msg = "unused macro definition";
|
||||
self.session.buffer_lint(lint, id, span, msg);
|
||||
} else {
|
||||
bug!("attempted to create unused macro error, but span not available");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ impl<'a> Resolver<'a> {
|
|||
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
|
||||
// during which the resolution might end up getting re-defined via a glob cycle.
|
||||
let (binding, t) = {
|
||||
let mut resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
|
||||
let resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
|
||||
let old_binding = resolution.binding();
|
||||
|
||||
let t = f(self, resolution);
|
||||
|
|
@ -745,8 +745,10 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
|||
let msg = format!("extern crate `{}` is private, and cannot be reexported \
|
||||
(error E0365), consider declaring with `pub`",
|
||||
ident);
|
||||
self.session.add_lint(PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
||||
directive.id, directive.span, msg);
|
||||
self.session.buffer_lint(PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
||||
directive.id,
|
||||
directive.span,
|
||||
&msg);
|
||||
} else if ns == TypeNS {
|
||||
struct_span_err!(self.session, directive.span, E0365,
|
||||
"`{}` is private, and cannot be reexported", ident)
|
||||
|
|
|
|||
|
|
@ -1464,7 +1464,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
|
|||
let mut output = i.to_string(scx.tcx());
|
||||
output.push_str(" @@");
|
||||
let mut empty = Vec::new();
|
||||
let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
|
||||
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
|
||||
cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone());
|
||||
cgus.dedup();
|
||||
for &(ref cgu_name, (linkage, _)) in cgus.iter() {
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>,
|
|||
CodegenUnit::empty(codegen_unit_name.clone())
|
||||
};
|
||||
|
||||
let mut codegen_unit = codegen_units.entry(codegen_unit_name.clone())
|
||||
let codegen_unit = codegen_units.entry(codegen_unit_name.clone())
|
||||
.or_insert_with(make_codegen_unit);
|
||||
|
||||
let (linkage, visibility) = match trans_item.explicit_linkage(tcx) {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ impl TimeGraph {
|
|||
{
|
||||
let mut table = self.data.lock().unwrap();
|
||||
|
||||
let mut data = table.entry(timeline).or_insert(PerThread {
|
||||
let data = table.entry(timeline).or_insert(PerThread {
|
||||
timings: Vec::new(),
|
||||
open_work_package: None,
|
||||
});
|
||||
|
|
@ -90,7 +90,7 @@ impl TimeGraph {
|
|||
let end = Instant::now();
|
||||
|
||||
let mut table = self.data.lock().unwrap();
|
||||
let mut data = table.get_mut(&timeline).unwrap();
|
||||
let data = table.get_mut(&timeline).unwrap();
|
||||
|
||||
if let Some((start, work_package_kind)) = data.open_work_package {
|
||||
data.timings.push(Timing {
|
||||
|
|
|
|||
|
|
@ -985,9 +985,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
.span_label(data.span, "only traits may use parentheses")
|
||||
.emit();
|
||||
} else {
|
||||
let msg = "parenthesized parameters may only be used with a trait".to_string();
|
||||
self.tcx().sess.add_lint(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
|
||||
ast::CRATE_NODE_ID, data.span, msg);
|
||||
let msg = "parenthesized parameters may only be used with a trait";
|
||||
self.tcx().lint_node(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
|
||||
ast::CRATE_NODE_ID, data.span, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -291,25 +291,25 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
let t_cast = self.cast_ty;
|
||||
let t_expr = self.expr_ty;
|
||||
if t_cast.is_numeric() && t_expr.is_numeric() {
|
||||
fcx.tables.borrow_mut().lints.add_lint(
|
||||
fcx.tcx.lint_node(
|
||||
lint::builtin::TRIVIAL_NUMERIC_CASTS,
|
||||
self.expr.id,
|
||||
self.span,
|
||||
format!("trivial numeric cast: `{}` as `{}`. Cast can be \
|
||||
replaced by coercion, this might require type \
|
||||
ascription or a temporary variable",
|
||||
fcx.ty_to_string(t_expr),
|
||||
fcx.ty_to_string(t_cast)));
|
||||
&format!("trivial numeric cast: `{}` as `{}`. Cast can be \
|
||||
replaced by coercion, this might require type \
|
||||
ascription or a temporary variable",
|
||||
fcx.ty_to_string(t_expr),
|
||||
fcx.ty_to_string(t_cast)));
|
||||
} else {
|
||||
fcx.tables.borrow_mut().lints.add_lint(
|
||||
fcx.tcx.lint_node(
|
||||
lint::builtin::TRIVIAL_CASTS,
|
||||
self.expr.id,
|
||||
self.span,
|
||||
format!("trivial cast: `{}` as `{}`. Cast can be \
|
||||
replaced by coercion, this might require type \
|
||||
ascription or a temporary variable",
|
||||
fcx.ty_to_string(t_expr),
|
||||
fcx.ty_to_string(t_cast)));
|
||||
&format!("trivial cast: `{}` as `{}`. Cast can be \
|
||||
replaced by coercion, this might require type \
|
||||
ascription or a temporary variable",
|
||||
fcx.ty_to_string(t_expr),
|
||||
fcx.ty_to_string(t_cast)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1204,7 +1204,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(mut augment_error) = augment_error {
|
||||
if let Some(augment_error) = augment_error {
|
||||
augment_error(&mut db);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,9 @@ pub enum MethodError<'tcx> {
|
|||
ClosureAmbiguity(// DefId of fn trait
|
||||
DefId),
|
||||
|
||||
// Found an applicable method, but it is not visible.
|
||||
PrivateMatch(Def),
|
||||
// Found an applicable method, but it is not visible. The second argument contains a list of
|
||||
// not-in-scope traits which may work.
|
||||
PrivateMatch(Def, Vec<DefId>),
|
||||
|
||||
// Found a `Self: Sized` bound where `Self` is a trait object, also the caller may have
|
||||
// forgotten to import a trait.
|
||||
|
|
|
|||
|
|
@ -556,7 +556,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
// We can't use normalize_associated_types_in as it will pollute the
|
||||
// fcx's fulfillment context after this probe is over.
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
let mut selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let traits::Normalized { value: xform_self_ty, obligations } =
|
||||
traits::normalize(selcx, self.param_env, cause, &xform_self_ty);
|
||||
debug!("assemble_inherent_impl_probe: xform_self_ty = {:?}",
|
||||
|
|
@ -738,10 +738,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
import_id: Option<ast::NodeId>,
|
||||
trait_def_id: DefId,
|
||||
item: ty::AssociatedItem) {
|
||||
let trait_def = self.tcx.trait_def(trait_def_id);
|
||||
|
||||
// FIXME(arielb1): can we use for_each_relevant_impl here?
|
||||
trait_def.for_each_impl(self.tcx, |impl_def_id| {
|
||||
self.tcx.for_each_impl(trait_def_id, |impl_def_id| {
|
||||
debug!("assemble_extension_candidates_for_trait_impl: trait_def_id={:?} \
|
||||
impl_def_id={:?}",
|
||||
trait_def_id,
|
||||
|
|
@ -769,7 +767,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
// as it will pollute the fcx's fulfillment context after this probe
|
||||
// is over.
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
let mut selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let traits::Normalized { value: xform_self_ty, obligations } =
|
||||
traits::normalize(selcx, self.param_env, cause, &xform_self_ty);
|
||||
|
||||
|
|
@ -1059,7 +1057,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
};
|
||||
|
||||
if let Some(def) = private_candidate {
|
||||
return Err(MethodError::PrivateMatch(def));
|
||||
return Err(MethodError::PrivateMatch(def, out_of_scope_traits));
|
||||
}
|
||||
|
||||
Err(MethodError::NoMatch(NoMatchData::new(static_candidates,
|
||||
|
|
|
|||
|
|
@ -311,9 +311,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
self.sess().span_err(span, &msg);
|
||||
}
|
||||
|
||||
MethodError::PrivateMatch(def) => {
|
||||
struct_span_err!(self.tcx.sess, span, E0624,
|
||||
"{} `{}` is private", def.kind_name(), item_name).emit();
|
||||
MethodError::PrivateMatch(def, out_of_scope_traits) => {
|
||||
let mut err = struct_span_err!(self.tcx.sess, span, E0624,
|
||||
"{} `{}` is private", def.kind_name(), item_name);
|
||||
self.suggest_valid_traits(&mut err, out_of_scope_traits);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
MethodError::IllegalSizedBound(candidates) => {
|
||||
|
|
@ -353,13 +355,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
err.note(&msg[..]);
|
||||
}
|
||||
|
||||
fn suggest_traits_to_import(&self,
|
||||
err: &mut DiagnosticBuilder,
|
||||
span: Span,
|
||||
rcvr_ty: Ty<'tcx>,
|
||||
item_name: ast::Name,
|
||||
rcvr_expr: Option<&hir::Expr>,
|
||||
valid_out_of_scope_traits: Vec<DefId>) {
|
||||
fn suggest_valid_traits(&self,
|
||||
err: &mut DiagnosticBuilder,
|
||||
valid_out_of_scope_traits: Vec<DefId>) -> bool {
|
||||
if !valid_out_of_scope_traits.is_empty() {
|
||||
let mut candidates = valid_out_of_scope_traits;
|
||||
candidates.sort();
|
||||
|
|
@ -379,6 +377,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
});
|
||||
|
||||
self.suggest_use_candidates(err, msg, candidates);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_traits_to_import(&self,
|
||||
err: &mut DiagnosticBuilder,
|
||||
span: Span,
|
||||
rcvr_ty: Ty<'tcx>,
|
||||
item_name: ast::Name,
|
||||
rcvr_expr: Option<&hir::Expr>,
|
||||
valid_out_of_scope_traits: Vec<DefId>) {
|
||||
if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1754,10 +1754,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
|
||||
|
||||
self.tables.borrow_mut().lints.add_lint(
|
||||
self.tcx().lint_node(
|
||||
lint::builtin::UNREACHABLE_CODE,
|
||||
id, span,
|
||||
format!("unreachable {}", kind));
|
||||
&format!("unreachable {}", kind));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4073,7 +4073,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
Ok(def) => def,
|
||||
Err(error) => {
|
||||
let def = match error {
|
||||
method::MethodError::PrivateMatch(def) => def,
|
||||
method::MethodError::PrivateMatch(def, _) => def,
|
||||
_ => Def::Err,
|
||||
};
|
||||
if item_name != keywords::Invalid.name() {
|
||||
|
|
@ -4240,8 +4240,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
|
||||
|
||||
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
|
||||
let mut ctxt = enclosing_breakables.find_breakable(blk.id);
|
||||
let mut coerce = ctxt.coerce.as_mut().unwrap();
|
||||
let ctxt = enclosing_breakables.find_breakable(blk.id);
|
||||
let coerce = ctxt.coerce.as_mut().unwrap();
|
||||
if let Some(tail_expr_ty) = tail_expr_ty {
|
||||
let tail_expr = tail_expr.unwrap();
|
||||
let cause = self.cause(tail_expr.span,
|
||||
|
|
@ -4286,8 +4286,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
ty
|
||||
}
|
||||
|
||||
/// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether it is
|
||||
/// `fn main` if it is a method, `None` otherwise.
|
||||
/// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether a
|
||||
/// suggetion can be made, `None` otherwise.
|
||||
pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
|
||||
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
|
||||
// `while` before reaching it, as block tail returns are not available in them.
|
||||
|
|
@ -4298,14 +4298,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
name, node: hir::ItemFn(ref decl, ..), ..
|
||||
}) = parent {
|
||||
decl.clone().and_then(|decl| {
|
||||
// This is less than ideal, it will not present the return type span on any
|
||||
// method called `main`, regardless of whether it is actually the entry point.
|
||||
Some((decl, name == Symbol::intern("main")))
|
||||
// This is less than ideal, it will not suggest a return type span on any
|
||||
// method called `main`, regardless of whether it is actually the entry point,
|
||||
// but it will still present it as the reason for the expected type.
|
||||
Some((decl, name != Symbol::intern("main")))
|
||||
})
|
||||
} else if let Node::NodeTraitItem(&hir::TraitItem {
|
||||
node: hir::TraitItemKind::Method(hir::MethodSig {
|
||||
ref decl, ..
|
||||
}, ..), ..
|
||||
}) = parent {
|
||||
decl.clone().and_then(|decl| {
|
||||
Some((decl, true))
|
||||
})
|
||||
} else if let Node::NodeImplItem(&hir::ImplItem {
|
||||
node: hir::ImplItemKind::Method(hir::MethodSig {
|
||||
ref decl, ..
|
||||
}, ..), ..
|
||||
}) = parent {
|
||||
decl.clone().and_then(|decl| {
|
||||
Some((decl, false))
|
||||
|
|
@ -4332,11 +4341,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
blk_id: ast::NodeId) {
|
||||
self.suggest_missing_semicolon(err, expression, expected, cause_span);
|
||||
|
||||
if let Some((fn_decl, is_main)) = self.get_fn_decl(blk_id) {
|
||||
// `fn main()` must return `()`, do not suggest changing return type
|
||||
if !is_main {
|
||||
self.suggest_missing_return_type(err, &fn_decl, found);
|
||||
}
|
||||
if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
|
||||
self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4392,20 +4398,37 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
fn suggest_missing_return_type(&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
fn_decl: &hir::FnDecl,
|
||||
ty: Ty<'tcx>) {
|
||||
|
||||
// Only recommend changing the return type for methods that
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
can_suggest: bool) {
|
||||
// Only suggest changing the return type for methods that
|
||||
// haven't set a return type at all (and aren't `fn main()` or an impl).
|
||||
if let &hir::FnDecl {
|
||||
output: hir::FunctionRetTy::DefaultReturn(span), ..
|
||||
} = fn_decl {
|
||||
if ty.is_suggestable() {
|
||||
match (&fn_decl.output, found.is_suggestable(), can_suggest) {
|
||||
(&hir::FunctionRetTy::DefaultReturn(span), true, true) => {
|
||||
err.span_suggestion(span,
|
||||
"try adding a return type",
|
||||
format!("-> {} ", ty));
|
||||
} else {
|
||||
format!("-> {} ", found));
|
||||
}
|
||||
(&hir::FunctionRetTy::DefaultReturn(span), false, true) => {
|
||||
err.span_label(span, "possibly return type missing here?");
|
||||
}
|
||||
(&hir::FunctionRetTy::DefaultReturn(span), _, _) => {
|
||||
// `fn main()` must return `()`, do not suggest changing return type
|
||||
err.span_label(span, "expected `()` because of default return type");
|
||||
}
|
||||
(&hir::FunctionRetTy::Return(ref ty), _, _) => {
|
||||
// Only point to return type if the expected type is the return type, as if they
|
||||
// are not, the expectation must have been caused by something else.
|
||||
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
|
||||
let sp = ty.span;
|
||||
let ty = AstConv::ast_ty_to_ty(self, ty);
|
||||
debug!("suggest_missing_return_type: return type sty {:?}", ty.sty);
|
||||
debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty);
|
||||
if ty.sty == expected.sty {
|
||||
err.span_label(sp, format!("expected `{}` because of return type",
|
||||
expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4803,8 +4826,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
} else {
|
||||
let mut multispan = MultiSpan::from_span(lifetimes[0].span);
|
||||
multispan.push_span_label(span_late, note_msg.to_string());
|
||||
self.tcx.sess.add_lint(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||
lifetimes[0].id, multispan, primary_msg.to_string());
|
||||
self.tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||
lifetimes[0].id, multispan, primary_msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
lhs_expr: &'gcx hir::Expr,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
rhs_ty: Ty<'tcx>,
|
||||
mut err: &mut errors::DiagnosticBuilder) -> bool {
|
||||
err: &mut errors::DiagnosticBuilder) -> bool {
|
||||
// If this function returns true it means a note was printed, so we don't need
|
||||
// to print the normal "implementation of `std::ops::Add` might be missing" note
|
||||
let mut is_string_addition = false;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
wbcx.visit_fru_field_types();
|
||||
wbcx.visit_anon_types();
|
||||
wbcx.visit_cast_types();
|
||||
wbcx.visit_lints();
|
||||
wbcx.visit_free_region_map();
|
||||
wbcx.visit_generator_sigs();
|
||||
wbcx.visit_generator_interiors();
|
||||
|
|
@ -237,10 +236,6 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
|||
self.fcx.tables.borrow().cast_kinds.iter().map(|(&key, &value)| (key, value)));
|
||||
}
|
||||
|
||||
fn visit_lints(&mut self) {
|
||||
self.fcx.tables.borrow_mut().lints.transfer(&mut self.tables.lints);
|
||||
}
|
||||
|
||||
fn visit_free_region_map(&mut self) {
|
||||
let free_region_map = self.tcx().lift_to_global(&self.fcx.tables.borrow().free_region_map);
|
||||
let free_region_map = free_region_map.expect("all regions in free-region-map are global");
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ impl<'a, 'tcx> CheckVisitor<'a, 'tcx> {
|
|||
} else {
|
||||
"unused import".to_string()
|
||||
};
|
||||
self.tcx.sess.add_lint(lint::builtin::UNUSED_IMPORTS, id, span, msg);
|
||||
self.tcx.lint_node(lint::builtin::UNUSED_IMPORTS, id, span, &msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -999,12 +999,12 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
if !allow_defaults && p.default.is_some() {
|
||||
if !tcx.sess.features.borrow().default_type_parameter_fallback {
|
||||
tcx.sess.add_lint(
|
||||
tcx.lint_node(
|
||||
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
|
||||
p.id,
|
||||
p.span,
|
||||
format!("defaults for type parameters are only allowed in `struct`, \
|
||||
`enum`, `type`, or `trait` definitions."));
|
||||
&format!("defaults for type parameters are only allowed in `struct`, \
|
||||
`enum`, `type`, or `trait` definitions."));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,7 +155,9 @@ pub fn run_core(search_paths: SearchPaths,
|
|||
target_features::add_configuration(&mut cfg, &sess);
|
||||
sess.parse_sess.config = cfg;
|
||||
|
||||
let krate = panictry!(driver::phase_1_parse_input(&sess, &input));
|
||||
let krate = panictry!(driver::phase_1_parse_input(&driver::CompileController::basic(),
|
||||
&sess,
|
||||
&input));
|
||||
|
||||
let name = link::find_crate_name(Some(&sess), &krate.attrs, &input);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ use std::ascii::AsciiExt;
|
|||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::default::Default;
|
||||
use std::ffi::CString;
|
||||
use std::fmt::{self, Write};
|
||||
use std::str;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
|
|
@ -529,8 +528,8 @@ extern {
|
|||
fn hoedown_document_free(md: *mut hoedown_document);
|
||||
|
||||
fn hoedown_buffer_new(unit: libc::size_t) -> *mut hoedown_buffer;
|
||||
fn hoedown_buffer_puts(b: *mut hoedown_buffer, c: *const libc::c_char);
|
||||
fn hoedown_buffer_free(b: *mut hoedown_buffer);
|
||||
fn hoedown_buffer_put(b: *mut hoedown_buffer, c: *const u8, len: libc::size_t);
|
||||
}
|
||||
|
||||
impl hoedown_buffer {
|
||||
|
|
@ -620,8 +619,7 @@ pub fn render(w: &mut fmt::Formatter,
|
|||
Some("rust-example-rendered"),
|
||||
None,
|
||||
playground_button.as_ref().map(String::as_str)));
|
||||
let output = CString::new(s).unwrap();
|
||||
hoedown_buffer_puts(ob, output.as_ptr());
|
||||
hoedown_buffer_put(ob, s.as_ptr(), s.len());
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -630,7 +628,7 @@ pub fn render(w: &mut fmt::Formatter,
|
|||
level: libc::c_int, data: *const hoedown_renderer_data,
|
||||
_: libc::size_t) {
|
||||
// hoedown does this, we may as well too
|
||||
unsafe { hoedown_buffer_puts(ob, "\n\0".as_ptr() as *const _); }
|
||||
unsafe { hoedown_buffer_put(ob, "\n".as_ptr(), 1); }
|
||||
|
||||
// Extract the text provided
|
||||
let s = if text.is_null() {
|
||||
|
|
@ -681,8 +679,7 @@ pub fn render(w: &mut fmt::Formatter,
|
|||
<a href='#{id}'>{sec}{}</a></h{lvl}>",
|
||||
s, lvl = level, id = id, sec = sec);
|
||||
|
||||
let text = CString::new(text).unwrap();
|
||||
unsafe { hoedown_buffer_puts(ob, text.as_ptr()) }
|
||||
unsafe { hoedown_buffer_put(ob, text.as_ptr(), text.len()); }
|
||||
}
|
||||
|
||||
extern fn codespan(
|
||||
|
|
@ -700,8 +697,9 @@ pub fn render(w: &mut fmt::Formatter,
|
|||
};
|
||||
|
||||
let content = format!("<code>{}</code>", Escape(&content));
|
||||
let element = CString::new(content).unwrap();
|
||||
unsafe { hoedown_buffer_puts(ob, element.as_ptr()); }
|
||||
unsafe {
|
||||
hoedown_buffer_put(ob, content.as_ptr(), content.len());
|
||||
}
|
||||
// Return anything except 0, which would mean "also print the code span verbatim".
|
||||
1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,9 @@ pub fn run(input: &str,
|
|||
sess.parse_sess.config =
|
||||
config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
|
||||
|
||||
let krate = panictry!(driver::phase_1_parse_input(&sess, &input));
|
||||
let krate = panictry!(driver::phase_1_parse_input(&driver::CompileController::basic(),
|
||||
&sess,
|
||||
&input));
|
||||
let driver::ExpansionResult { defs, mut hir_forest, .. } = {
|
||||
phase_2_configure_and_expand(
|
||||
&sess, &cstore, krate, None, "rustdoc-test", None, MakeGlobMap::No, |_| Ok(())
|
||||
|
|
|
|||
|
|
@ -1618,7 +1618,7 @@ impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
|
|||
type Item = (&'a K, &'a mut V);
|
||||
type IntoIter = IterMut<'a, K, V>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, K, V> {
|
||||
fn into_iter(self) -> IterMut<'a, K, V> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -563,7 +563,7 @@ impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
|
|||
///
|
||||
/// This works similarly to `put`, building an `EmptyBucket` out of the
|
||||
/// taken bucket.
|
||||
pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
|
||||
pub fn take(self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
|
||||
self.table.size -= 1;
|
||||
|
||||
unsafe {
|
||||
|
|
|
|||
|
|
@ -514,7 +514,7 @@ mod tests {
|
|||
#[test]
|
||||
fn downcasting() {
|
||||
let mut a = A;
|
||||
let mut a = &mut a as &mut (Error + 'static);
|
||||
let a = &mut a as &mut (Error + 'static);
|
||||
assert_eq!(a.downcast_ref::<A>(), Some(&A));
|
||||
assert_eq!(a.downcast_ref::<B>(), None);
|
||||
assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_slice_reader() {
|
||||
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
|
||||
let mut reader = &mut &in_buf[..];
|
||||
let reader = &mut &in_buf[..];
|
||||
let mut buf = [];
|
||||
assert_eq!(reader.read(&mut buf).unwrap(), 0);
|
||||
let mut buf = [0];
|
||||
|
|
|
|||
|
|
@ -14,6 +14,16 @@
|
|||
//! library. Each macro is available for use when linking against the standard
|
||||
//! library.
|
||||
|
||||
#[macro_export]
|
||||
// This stability attribute is totally useless.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(stage0)]
|
||||
macro_rules! __rust_unstable_column {
|
||||
() => {
|
||||
column!()
|
||||
}
|
||||
}
|
||||
|
||||
/// The entry point for panic of Rust threads.
|
||||
///
|
||||
/// This macro is used to inject panic into a Rust thread, causing the thread to
|
||||
|
|
@ -48,7 +58,8 @@ macro_rules! panic {
|
|||
($msg:expr) => ({
|
||||
$crate::rt::begin_panic($msg, {
|
||||
// static requires less code at runtime, more constant data
|
||||
static _FILE_LINE_COL: (&'static str, u32, u32) = (file!(), line!(), column!());
|
||||
static _FILE_LINE_COL: (&'static str, u32, u32) = (file!(), line!(),
|
||||
__rust_unstable_column!());
|
||||
&_FILE_LINE_COL
|
||||
})
|
||||
});
|
||||
|
|
@ -58,7 +69,8 @@ macro_rules! panic {
|
|||
// used inside a dead function. Just `#[allow(dead_code)]` is
|
||||
// insufficient, since the user may have
|
||||
// `#[forbid(dead_code)]` and which cannot be overridden.
|
||||
static _FILE_LINE_COL: (&'static str, u32, u32) = (file!(), line!(), column!());
|
||||
static _FILE_LINE_COL: (&'static str, u32, u32) = (file!(), line!(),
|
||||
__rust_unstable_column!());
|
||||
&_FILE_LINE_COL
|
||||
})
|
||||
});
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ impl Barrier {
|
|||
BarrierWaitResult(false)
|
||||
} else {
|
||||
lock.count = 0;
|
||||
lock.generation_id += 1;
|
||||
lock.generation_id = lock.generation_id.wrapping_add(1);
|
||||
self.cvar.notify_all();
|
||||
BarrierWaitResult(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ impl Once {
|
|||
#[cold]
|
||||
fn call_inner(&'static self,
|
||||
ignore_poisoning: bool,
|
||||
mut init: &mut FnMut(bool)) {
|
||||
init: &mut FnMut(bool)) {
|
||||
let mut state = self.state.load(Ordering::SeqCst);
|
||||
|
||||
'outer: loop {
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ pub use self::imp::OsRng;
|
|||
|
||||
use mem;
|
||||
|
||||
fn next_u32(mut fill_buf: &mut FnMut(&mut [u8])) -> u32 {
|
||||
fn next_u32(fill_buf: &mut FnMut(&mut [u8])) -> u32 {
|
||||
let mut buf: [u8; 4] = [0; 4];
|
||||
fill_buf(&mut buf);
|
||||
unsafe { mem::transmute::<[u8; 4], u32>(buf) }
|
||||
}
|
||||
|
||||
fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
|
||||
fn next_u64(fill_buf: &mut FnMut(&mut [u8])) -> u64 {
|
||||
let mut buf: [u8; 8] = [0; 8];
|
||||
fill_buf(&mut buf);
|
||||
unsafe { mem::transmute::<[u8; 8], u64>(buf) }
|
||||
|
|
|
|||
|
|
@ -768,8 +768,8 @@ fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> {
|
|||
|
||||
unsafe {
|
||||
let mut data = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
||||
let mut db = data.as_mut_ptr()
|
||||
as *mut c::REPARSE_MOUNTPOINT_DATA_BUFFER;
|
||||
let db = data.as_mut_ptr()
|
||||
as *mut c::REPARSE_MOUNTPOINT_DATA_BUFFER;
|
||||
let buf = &mut (*db).ReparseTarget as *mut _;
|
||||
let mut i = 0;
|
||||
// FIXME: this conversion is very hacky
|
||||
|
|
|
|||
|
|
@ -12,9 +12,32 @@
|
|||
|
||||
#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
|
||||
|
||||
/// The version of [Unicode](http://www.unicode.org/)
|
||||
/// that the unicode parts of `CharExt` and `UnicodeStrPrelude` traits are based on.
|
||||
pub const UNICODE_VERSION: (u64, u64, u64) = (10, 0, 0);
|
||||
/// Represents a Unicode Version.
|
||||
///
|
||||
/// See also: <http://www.unicode.org/versions/>
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct UnicodeVersion {
|
||||
/// Major version.
|
||||
pub major: u32,
|
||||
|
||||
/// Minor version.
|
||||
pub minor: u32,
|
||||
|
||||
/// Micro (or Update) version.
|
||||
pub micro: u32,
|
||||
|
||||
// Private field to keep struct expandable.
|
||||
_priv: (),
|
||||
}
|
||||
|
||||
/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
|
||||
/// `CharExt` and `UnicodeStrPrelude` traits are based on.
|
||||
pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {
|
||||
major: 10,
|
||||
minor: 0,
|
||||
micro: 0,
|
||||
_priv: (),
|
||||
};
|
||||
|
||||
|
||||
// BoolTrie is a trie for representing a set of Unicode codepoints. It is
|
||||
|
|
|
|||
|
|
@ -560,9 +560,32 @@ if __name__ == "__main__":
|
|||
pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
|
||||
unicode_version = re.search(pattern, readme.read()).groups()
|
||||
rf.write("""
|
||||
/// The version of [Unicode](http://www.unicode.org/)
|
||||
/// that the unicode parts of `CharExt` and `UnicodeStrPrelude` traits are based on.
|
||||
pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
|
||||
/// Represents a Unicode Version.
|
||||
///
|
||||
/// See also: <http://www.unicode.org/versions/>
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct UnicodeVersion {
|
||||
/// Major version.
|
||||
pub major: u32,
|
||||
|
||||
/// Minor version.
|
||||
pub minor: u32,
|
||||
|
||||
/// Micro (or Update) version.
|
||||
pub micro: u32,
|
||||
|
||||
// Private field to keep struct expandable.
|
||||
_priv: (),
|
||||
}
|
||||
|
||||
/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
|
||||
/// `CharExt` and `UnicodeStrPrelude` traits are based on.
|
||||
pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {
|
||||
major: %s,
|
||||
minor: %s,
|
||||
micro: %s,
|
||||
_priv: (),
|
||||
};
|
||||
""" % unicode_version)
|
||||
(canon_decomp, compat_decomp, gencats, combines,
|
||||
to_upper, to_lower, to_title) = load_unicode_data("UnicodeData.txt")
|
||||
|
|
|
|||
|
|
@ -162,6 +162,63 @@ For more information about the cfg attribute, read:
|
|||
https://doc.rust-lang.org/reference.html#conditional-compilation
|
||||
"##,
|
||||
|
||||
E0552: r##"
|
||||
A unrecognized representation attribute was used.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0552
|
||||
#[repr(D)] // error: unrecognized representation hint
|
||||
struct MyStruct {
|
||||
my_field: usize
|
||||
}
|
||||
```
|
||||
|
||||
You can use a `repr` attribute to tell the compiler how you want a struct or
|
||||
enum to be laid out in memory.
|
||||
|
||||
Make sure you're using one of the supported options:
|
||||
|
||||
```
|
||||
#[repr(C)] // ok!
|
||||
struct MyStruct {
|
||||
my_field: usize
|
||||
}
|
||||
```
|
||||
|
||||
For more information about specifying representations, see the ["Alternative
|
||||
Representations" section] of the Rustonomicon.
|
||||
|
||||
["Alternative Representations" section]: https://doc.rust-lang.org/nomicon/other-reprs.html
|
||||
"##,
|
||||
|
||||
E0554: r##"
|
||||
Feature attributes are only allowed on the nightly release channel. Stable or
|
||||
beta compilers will not comply.
|
||||
|
||||
Example of erroneous code (on a stable compiler):
|
||||
|
||||
```ignore (depends on release channel)
|
||||
#![feature(non_ascii_idents)] // error: #![feature] may not be used on the
|
||||
// stable release channel
|
||||
```
|
||||
|
||||
If you need the feature, make sure to use a nightly release of the compiler
|
||||
(but be warned that the feature may be removed or altered in the future).
|
||||
"##,
|
||||
|
||||
E0557: r##"
|
||||
A feature attribute named a feature that has been removed.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0557
|
||||
#![feature(managed_boxes)] // error: feature has been removed
|
||||
```
|
||||
|
||||
Delete the offending feature attribute.
|
||||
"##,
|
||||
|
||||
E0558: r##"
|
||||
The `export_name` attribute was malformed.
|
||||
|
||||
|
|
@ -300,11 +357,8 @@ register_diagnostics! {
|
|||
E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
|
||||
E0550, // multiple deprecated attributes
|
||||
E0551, // incorrect meta item
|
||||
E0552, // unrecognized representation hint
|
||||
E0554, // #[feature] may not be used on the [] release channel
|
||||
E0555, // malformed feature attribute, expected #![feature(...)]
|
||||
E0556, // malformed feature, expected just one word
|
||||
E0557, // feature has been removed
|
||||
E0584, // file for module `..` found at both .. and ..
|
||||
E0589, // invalid `repr(align)` attribute
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,16 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
|||
base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
|
||||
}
|
||||
|
||||
/* __rust_unstable_column!(): expands to the current column number */
|
||||
pub fn expand_column_gated(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
if sp.allows_unstable() {
|
||||
expand_column(cx, sp, tts)
|
||||
} else {
|
||||
cx.span_fatal(sp, "the __rust_unstable_column macro is unstable");
|
||||
}
|
||||
}
|
||||
|
||||
/// file!(): expands to the current filename */
|
||||
/// The filemap (`loc.file`) contains a bunch more information we could spit
|
||||
/// out if we wanted.
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ pub enum NamedMatch {
|
|||
|
||||
fn nameize<I: Iterator<Item=NamedMatch>>(sess: &ParseSess, ms: &[TokenTree], mut res: I)
|
||||
-> NamedParseResult {
|
||||
fn n_rec<I: Iterator<Item=NamedMatch>>(sess: &ParseSess, m: &TokenTree, mut res: &mut I,
|
||||
fn n_rec<I: Iterator<Item=NamedMatch>>(sess: &ParseSess, m: &TokenTree, res: &mut I,
|
||||
ret_val: &mut HashMap<Ident, Rc<NamedMatch>>)
|
||||
-> Result<(), (syntax_pos::Span, String)> {
|
||||
match *m {
|
||||
|
|
@ -445,7 +445,7 @@ pub fn parse(sess: &ParseSess,
|
|||
/* error messages here could be improved with links to orig. rules */
|
||||
if token_name_eq(&parser.token, &token::Eof) {
|
||||
if eof_items.len() == 1 {
|
||||
let matches = eof_items[0].matches.iter_mut().map(|mut dv| {
|
||||
let matches = eof_items[0].matches.iter_mut().map(|dv| {
|
||||
Rc::make_mut(dv).pop().unwrap()
|
||||
});
|
||||
return nameize(sess, ms, matches);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
|
|||
|
||||
fn trace_macros_note(cx: &mut ExtCtxt, sp: Span, message: String) {
|
||||
let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp);
|
||||
let mut values: &mut Vec<String> = cx.expansions.entry(sp).or_insert_with(Vec::new);
|
||||
let values: &mut Vec<String> = cx.expansions.entry(sp).or_insert_with(Vec::new);
|
||||
values.push(message);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1611,7 +1611,7 @@ fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate,
|
|||
if attr.check_name("feature") {
|
||||
let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
|
||||
span_err!(span_handler, attr.span, E0554,
|
||||
"#[feature] may not be used on the {} release channel",
|
||||
"#![feature] may not be used on the {} release channel",
|
||||
release_channel);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -9,15 +9,16 @@
|
|||
// except according to those terms.
|
||||
|
||||
// Characters and their corresponding confusables were collected from
|
||||
// http://www.unicode.org/Public/security/revision-06/confusables.txt
|
||||
// http://www.unicode.org/Public/security/10.0.0/confusables.txt
|
||||
|
||||
use syntax_pos::{Span, NO_EXPANSION};
|
||||
use errors::DiagnosticBuilder;
|
||||
use super::StringReader;
|
||||
|
||||
const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
||||
(' ', "No-Break Space", ' '),
|
||||
(' ', "Ogham Space Mark", ' '),
|
||||
('
', "Line Separator", ' '),
|
||||
('
', "Paragraph Separator", ' '),
|
||||
(' ', "Ogham Space mark", ' '),
|
||||
(' ', "En Quad", ' '),
|
||||
(' ', "Em Quad", ' '),
|
||||
(' ', "En Space", ' '),
|
||||
|
|
@ -25,39 +26,63 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
(' ', "Three-Per-Em Space", ' '),
|
||||
(' ', "Four-Per-Em Space", ' '),
|
||||
(' ', "Six-Per-Em Space", ' '),
|
||||
(' ', "Figure Space", ' '),
|
||||
(' ', "Punctuation Space", ' '),
|
||||
(' ', "Thin Space", ' '),
|
||||
(' ', "Hair Space", ' '),
|
||||
(' ', "Narrow No-Break Space", ' '),
|
||||
(' ', "Medium Mathematical Space", ' '),
|
||||
(' ', "No-Break Space", ' '),
|
||||
(' ', "Figure Space", ' '),
|
||||
(' ', "Narrow No-Break Space", ' '),
|
||||
(' ', "Ideographic Space", ' '),
|
||||
|
||||
('ߺ', "Nko Lajanyalan", '_'),
|
||||
('﹍', "Dashed Low Line", '_'),
|
||||
('﹎', "Centreline Low Line", '_'),
|
||||
('﹏', "Wavy Low Line", '_'),
|
||||
('_', "Fullwidth Low Line", '_'),
|
||||
|
||||
('‐', "Hyphen", '-'),
|
||||
('‑', "Non-Breaking Hyphen", '-'),
|
||||
('‒', "Figure Dash", '-'),
|
||||
('–', "En Dash", '-'),
|
||||
('—', "Em Dash", '-'),
|
||||
('﹘', "Small Em Dash", '-'),
|
||||
('۔', "Arabic Full Stop", '-'),
|
||||
('⁃', "Hyphen Bullet", '-'),
|
||||
('˗', "Modifier Letter Minus Sign", '-'),
|
||||
('−', "Minus Sign", '-'),
|
||||
('➖', "Heavy Minus Sign", '-'),
|
||||
('Ⲻ', "Coptic Letter Dialect-P Ni", '-'),
|
||||
('ー', "Katakana-Hiragana Prolonged Sound Mark", '-'),
|
||||
('-', "Fullwidth Hyphen-Minus", '-'),
|
||||
('―', "Horizontal Bar", '-'),
|
||||
('─', "Box Drawings Light Horizontal", '-'),
|
||||
('━', "Box Drawings Heavy Horizontal", '-'),
|
||||
('㇐', "CJK Stroke H", '-'),
|
||||
('ꟷ', "Latin Epigraphic Letter Dideways", '-'),
|
||||
('ᅳ', "Hangul Jungseong Eu", '-'),
|
||||
('ㅡ', "Hangul Letter Eu", '-'),
|
||||
('一', "CJK Unified Ideograph-4E00", '-'),
|
||||
('⼀', "Kangxi Radical One", '-'),
|
||||
|
||||
('؍', "Arabic Date Separator", ','),
|
||||
('٫', "Arabic Decimal Separator", ','),
|
||||
('‚', "Single Low-9 Quotation Mark", ','),
|
||||
('¸', "Cedilla", ','),
|
||||
('ꓹ', "Lisu Letter Tone Na Po", ','),
|
||||
(',', "Fullwidth Comma", ','),
|
||||
|
||||
(';', "Greek Question Mark", ';'),
|
||||
(';', "Fullwidth Semicolon", ';'),
|
||||
('︔', "Presentation Form For Vertical Semicolon", ';'),
|
||||
|
||||
('ः', "Devanagari Sign Visarga", ':'),
|
||||
('ઃ', "Gujarati Sign Visarga", ':'),
|
||||
(':', "Fullwidth Colon", ':'),
|
||||
('։', "Armenian Full Stop", ':'),
|
||||
('܃', "Syriac Supralinear Colon", ':'),
|
||||
('܄', "Syriac Sublinear Colon", ':'),
|
||||
('᛬', "Runic Multiple Ponctuation", ':'),
|
||||
('︰', "Presentation Form For Vertical Two Dot Leader", ':'),
|
||||
('᠃', "Mongolian Full Stop", ':'),
|
||||
('᠉', "Mongolian Manchu Full Stop", ':'),
|
||||
|
|
@ -68,25 +93,48 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
('∶', "Ratio", ':'),
|
||||
('ː', "Modifier Letter Triangular Colon", ':'),
|
||||
('ꓽ', "Lisu Letter Tone Mya Jeu", ':'),
|
||||
('︓', "Presentation Form For Vertical Colon", ':'),
|
||||
|
||||
('!', "Fullwidth Exclamation Mark", '!'),
|
||||
('ǃ', "Latin Letter Retroflex Click", '!'),
|
||||
('ⵑ', "Tifinagh Letter Tuareg Yang", '!'),
|
||||
('︕', "Presentation Form For Vertical Exclamation Mark", '!'),
|
||||
|
||||
('ʔ', "Latin Letter Glottal Stop", '?'),
|
||||
('Ɂ', "Latin Capital Letter Glottal Stop", '?'),
|
||||
('ॽ', "Devanagari Letter Glottal Stop", '?'),
|
||||
('Ꭾ', "Cherokee Letter He", '?'),
|
||||
('ꛫ', "Bamum Letter Ntuu", '?'),
|
||||
('?', "Fullwidth Question Mark", '?'),
|
||||
('︖', "Presentation Form For Vertical Question Mark", '?'),
|
||||
|
||||
('𝅭', "Musical Symbol Combining Augmentation Dot", '.'),
|
||||
('․', "One Dot Leader", '.'),
|
||||
('۔', "Arabic Full Stop", '.'),
|
||||
('܁', "Syriac Supralinear Full Stop", '.'),
|
||||
('܂', "Syriac Sublinear Full Stop", '.'),
|
||||
('꘎', "Vai Full Stop", '.'),
|
||||
('𐩐', "Kharoshthi Punctuation Dot", '.'),
|
||||
('·', "Middle Dot", '.'),
|
||||
('٠', "Arabic-Indic Digit Zero", '.'),
|
||||
('۰', "Extended Arabic-Indic Digit Zero", '.'),
|
||||
('ꓸ', "Lisu Letter Tone Mya Ti", '.'),
|
||||
('。', "Ideographic Full Stop", '.'),
|
||||
('·', "Middle Dot", '.'),
|
||||
('・', "Katakana Middle Dot", '.'),
|
||||
('・', "Halfwidth Katakana Middle Dot", '.'),
|
||||
('᛫', "Runic Single Punctuation", '.'),
|
||||
('·', "Greek Ano Teleia", '.'),
|
||||
('⸱', "Word Separator Middle Dot", '.'),
|
||||
('𐄁', "Aegean Word Separator Dot", '.'),
|
||||
('•', "Bullet", '.'),
|
||||
('‧', "Hyphenation Point", '.'),
|
||||
('∙', "Bullet Operator", '.'),
|
||||
('⋅', "Dot Operator", '.'),
|
||||
('ꞏ', "Latin Letter Sinological Dot", '.'),
|
||||
('ᐧ', "Canadian Syllabics Final Middle Dot", '.'),
|
||||
('ᐧ', "Canadian Syllabics Final Middle Dot", '.'),
|
||||
('.', "Fullwidth Full Stop", '.'),
|
||||
('。', "Ideographic Full Stop", '.'),
|
||||
('︒', "Presentation Form For Vertical Ideographic Full Stop", '.'),
|
||||
|
||||
('՝', "Armenian Comma", '\''),
|
||||
(''', "Fullwidth Apostrophe", '\''),
|
||||
('‘', "Left Single Quotation Mark", '\''),
|
||||
|
|
@ -96,8 +144,10 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
('‵', "Reversed Prime", '\''),
|
||||
('՚', "Armenian Apostrophe", '\''),
|
||||
('׳', "Hebrew Punctuation Geresh", '\''),
|
||||
('`', "Greek Accent", '\''),
|
||||
('`', "Greek Varia", '\''),
|
||||
('`', "Fullwidth Grave Accent", '\''),
|
||||
('´', "Acute Accent", '\''),
|
||||
('΄', "Greek Tonos", '\''),
|
||||
('´', "Greek Oxia", '\''),
|
||||
('᾽', "Greek Koronis", '\''),
|
||||
|
|
@ -105,6 +155,7 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
('῾', "Greek Dasia", '\''),
|
||||
('ʹ', "Modifier Letter Prime", '\''),
|
||||
('ʹ', "Greek Numeral Sign", '\''),
|
||||
('ˈ', "Modifier Letter Vertical Line", '\''),
|
||||
('ˊ', "Modifier Letter Acute Accent", '\''),
|
||||
('ˋ', "Modifier Letter Grave Accent", '\''),
|
||||
('˴', "Modifier Letter Middle Grave Accent", '\''),
|
||||
|
|
@ -116,6 +167,12 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
('י', "Hebrew Letter Yod", '\''),
|
||||
('ߴ', "Nko High Tone Apostrophe", '\''),
|
||||
('ߵ', "Nko Low Tone Apostrophe", '\''),
|
||||
('ᑊ', "Canadian Syllabics West-Cree P", '\''),
|
||||
('ᛌ', "Runic Letter Short-Twig-Sol S", '\''),
|
||||
('𖽑', "Miao Sign Aspiration", '\''),
|
||||
('𖽒', "Miao Sign Reformed Voicing", '\''),
|
||||
|
||||
('᳓', "Vedic Sign Nihshvasa", '"'),
|
||||
('"', "Fullwidth Quotation Mark", '"'),
|
||||
('“', "Left Double Quotation Mark", '"'),
|
||||
('”', "Right Double Quotation Mark", '"'),
|
||||
|
|
@ -132,12 +189,15 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
('ײ', "Hebrew Ligature Yiddish Double Yod", '"'),
|
||||
('❞', "Heavy Double Comma Quotation Mark Ornament", '"'),
|
||||
('❝', "Heavy Double Turned Comma Quotation Mark Ornament", '"'),
|
||||
|
||||
('(', "Fullwidth Left Parenthesis", '('),
|
||||
('❨', "Medium Left Parenthesis Ornament", '('),
|
||||
('﴾', "Ornate Left Parenthesis", '('),
|
||||
('(', "Fullwidth Left Parenthesis", '('),
|
||||
|
||||
(')', "Fullwidth Right Parenthesis", ')'),
|
||||
('❩', "Medium Right Parenthesis Ornament", ')'),
|
||||
('﴿', "Ornate Right Parenthesis", ')'),
|
||||
(')', "Fullwidth Right Parenthesis", ')'),
|
||||
|
||||
('[', "Fullwidth Left Square Bracket", '['),
|
||||
('❲', "Light Left Tortoise Shell Bracket Ornament", '['),
|
||||
('「', "Left Corner Bracket", '['),
|
||||
|
|
@ -147,6 +207,7 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
('〖', "Left White Lenticular Bracket", '['),
|
||||
('〘', "Left White Tortoise Shell Bracket", '['),
|
||||
('〚', "Left White Square Bracket", '['),
|
||||
|
||||
(']', "Fullwidth Right Square Bracket", ']'),
|
||||
('❳', "Light Right Tortoise Shell Bracket Ornament", ']'),
|
||||
('」', "Right Corner Bracket", ']'),
|
||||
|
|
@ -156,11 +217,20 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
('〗', "Right White Lenticular Bracket", ']'),
|
||||
('〙', "Right White Tortoise Shell Bracket", ']'),
|
||||
('〛', "Right White Square Bracket", ']'),
|
||||
|
||||
('❴', "Medium Left Curly Bracket Ornament", '{'),
|
||||
('𝄔', "Musical Symbol Brace", '{'),
|
||||
('{', "Fullwidth Left Curly Bracket", '{'),
|
||||
|
||||
('❵', "Medium Right Curly Bracket Ornament", '}'),
|
||||
('}', "Fullwidth Right Curly Bracket", '}'),
|
||||
|
||||
('⁎', "Low Asterisk", '*'),
|
||||
('٭', "Arabic Five Pointed Star", '*'),
|
||||
('∗', "Asterisk Operator", '*'),
|
||||
('𐌟', "Old Italic Letter Ess", '*'),
|
||||
('*', "Fullwidth Asterisk", '*'),
|
||||
|
||||
('᜵', "Philippine Single Punctuation", '/'),
|
||||
('⁁', "Caret Insertion Point", '/'),
|
||||
('∕', "Division Slash", '/'),
|
||||
|
|
@ -168,37 +238,73 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
|
|||
('╱', "Box Drawings Light Diagonal Upper Right To Lower Left", '/'),
|
||||
('⟋', "Mathematical Rising Diagonal", '/'),
|
||||
('⧸', "Big Solidus", '/'),
|
||||
('㇓', "Cjk Stroke Sp", '/'),
|
||||
('𝈺', "Greek Instrumental Notation Symbol-47", '/'),
|
||||
('㇓', "CJK Stroke Sp", '/'),
|
||||
('〳', "Vertical Kana Repeat Mark Upper Half", '/'),
|
||||
('丿', "Cjk Unified Ideograph-4E3F", '/'),
|
||||
('Ⳇ', "Coptic Capital Letter Old Coptic Esh", '/'),
|
||||
('ノ', "Katakana Letter No", '/'),
|
||||
('丿', "CJK Unified Ideograph-4E3F", '/'),
|
||||
('⼃', "Kangxi Radical Slash", '/'),
|
||||
('/', "Fullwidth Solidus", '/'),
|
||||
|
||||
('\', "Fullwidth Reverse Solidus", '\\'),
|
||||
('﹨', "Small Reverse Solidus", '\\'),
|
||||
('∖', "Set Minus", '\\'),
|
||||
('⟍', "Mathematical Falling Diagonal", '\\'),
|
||||
('⧵', "Reverse Solidus Operator", '\\'),
|
||||
('⧹', "Big Reverse Solidus", '\\'),
|
||||
('⧹', "Greek Vocal Notation Symbol-16", '\\'),
|
||||
('⧹', "Greek Instrumental Symbol-48", '\\'),
|
||||
('㇔', "CJK Stroke D", '\\'),
|
||||
('丶', "CJK Unified Ideograph-4E36", '\\'),
|
||||
('⼂', "Kangxi Radical Dot", '\\'),
|
||||
('、', "Ideographic Comma", '\\'),
|
||||
('ヽ', "Katakana Iteration Mark", '\\'),
|
||||
('㇔', "Cjk Stroke D", '\\'),
|
||||
('丶', "Cjk Unified Ideograph-4E36", '\\'),
|
||||
('⼂', "Kangxi Radical Dot", '\\'),
|
||||
|
||||
('ꝸ', "Latin Small Letter Um", '&'),
|
||||
('&', "Fullwidth Ampersand", '&'),
|
||||
|
||||
('᛭', "Runic Cros Punctuation", '+'),
|
||||
('➕', "Heavy Plus Sign", '+'),
|
||||
('𐊛', "Lycian Letter H", '+'),
|
||||
('﬩', "Hebrew Letter Alternative Plus Sign", '+'),
|
||||
('+', "Fullwidth Plus Sign", '+'),
|
||||
|
||||
('‹', "Single Left-Pointing Angle Quotation Mark", '<'),
|
||||
('❮', "Heavy Left-Pointing Angle Quotation Mark Ornament", '<'),
|
||||
('˂', "Modifier Letter Left Arrowhead", '<'),
|
||||
('𝈶', "Greek Instrumental Symbol-40", '<'),
|
||||
('ᐸ', "Canadian Syllabics Pa", '<'),
|
||||
('ᚲ', "Runic Letter Kauna", '<'),
|
||||
('❬', "Medium Left-Pointing Angle Bracket Ornament", '<'),
|
||||
('⟨', "Mathematical Left Angle Bracket", '<'),
|
||||
('〈', "Left-Pointing Angle Bracket", '<'),
|
||||
('〈', "Left Angle Bracket", '<'),
|
||||
('㇛', "CJK Stroke Pd", '<'),
|
||||
('く', "Hiragana Letter Ku", '<'),
|
||||
('𡿨', "CJK Unified Ideograph-21FE8", '<'),
|
||||
('《', "Left Double Angle Bracket", '<'),
|
||||
('<', "Fullwidth Less-Than Sign", '<'),
|
||||
|
||||
('᐀', "Canadian Syllabics Hyphen", '='),
|
||||
('⹀', "Double Hyphen", '='),
|
||||
('゠', "Katakana-Hiragana Double Hyphen", '='),
|
||||
('꓿', "Lisu Punctuation Full Stop", '='),
|
||||
('=', "Fullwidth Equals Sign", '='),
|
||||
|
||||
('›', "Single Right-Pointing Angle Quotation Mark", '>'),
|
||||
('❯', "Heavy Right-Pointing Angle Quotation Mark Ornament", '>'),
|
||||
('˃', "Modifier Letter Right Arrowhead", '>'),
|
||||
('𝈷', "Greek Instrumental Symbol-42", '>'),
|
||||
('ᐳ', "Canadian Syllabics Po", '>'),
|
||||
('𖼿', "Miao Letter Archaic Zza", '>'),
|
||||
('❭', "Medium Right-Pointing Angle Bracket Ornament", '>'),
|
||||
('⟩', "Mathematical Right Angle Bracket", '>'),
|
||||
('〉', "Right-Pointing Angle Bracket", '>'),
|
||||
('〉', "Right Angle Bracket", '>'),
|
||||
('》', "Right Double Angle Bracket", '>'),
|
||||
('Ⲻ', "Coptic Capital Letter Dialect-P Ni", '-'),
|
||||
('Ɂ', "Latin Capital Letter Glottal Stop", '?'),
|
||||
('Ⳇ', "Coptic Capital Letter Old Coptic Esh", '/'), ];
|
||||
('>', "Fullwidth Greater-Than Sign", '>'), ];
|
||||
|
||||
|
||||
const ASCII_ARRAY: &'static [(char, &'static str)] = &[
|
||||
(' ', "Space"),
|
||||
|
|
|
|||
|
|
@ -5526,12 +5526,11 @@ impl<'a> Parser<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parse a static item from a foreign module
|
||||
/// Parse a static item from a foreign module.
|
||||
/// Assumes that the `static` keyword is already parsed.
|
||||
fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
|
||||
-> PResult<'a, ForeignItem> {
|
||||
self.expect_keyword(keywords::Static)?;
|
||||
let mutbl = self.eat_keyword(keywords::Mut);
|
||||
|
||||
let ident = self.parse_ident()?;
|
||||
self.expect(&token::Colon)?;
|
||||
let ty = self.parse_ty()?;
|
||||
|
|
@ -6005,19 +6004,23 @@ impl<'a> Parser<'a> {
|
|||
let lo = self.span;
|
||||
let visibility = self.parse_visibility(false)?;
|
||||
|
||||
if self.check_keyword(keywords::Static) {
|
||||
// FOREIGN STATIC ITEM
|
||||
// FOREIGN STATIC ITEM
|
||||
// Treat `const` as `static` for error recovery, but don't add it to expected tokens.
|
||||
if self.check_keyword(keywords::Static) || self.token.is_keyword(keywords::Const) {
|
||||
if self.token.is_keyword(keywords::Const) {
|
||||
self.diagnostic()
|
||||
.struct_span_err(self.span, "extern items cannot be `const`")
|
||||
.span_suggestion(self.span, "instead try using", "static".to_owned())
|
||||
.emit();
|
||||
}
|
||||
self.bump(); // `static` or `const`
|
||||
return Ok(Some(self.parse_item_foreign_static(visibility, lo, attrs)?));
|
||||
}
|
||||
// FOREIGN FUNCTION ITEM
|
||||
if self.check_keyword(keywords::Fn) {
|
||||
// FOREIGN FUNCTION ITEM
|
||||
return Ok(Some(self.parse_item_foreign_fn(visibility, lo, attrs)?));
|
||||
}
|
||||
|
||||
if self.check_keyword(keywords::Const) {
|
||||
return Err(self.span_fatal(self.span, "extern items cannot be `const`"));
|
||||
}
|
||||
|
||||
// FIXME #5668: this will occur for a macro invocation:
|
||||
match self.parse_macro_use_or_failure(attrs, true, false, lo, visibility)? {
|
||||
Some(item) => {
|
||||
|
|
|
|||
|
|
@ -529,7 +529,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
|
||||
/// Actually builds the expression which the format_args! block will be
|
||||
/// expanded to
|
||||
fn into_expr(mut self) -> P<ast::Expr> {
|
||||
fn into_expr(self) -> P<ast::Expr> {
|
||||
let mut locals = Vec::new();
|
||||
let mut counts = Vec::new();
|
||||
let mut pats = Vec::new();
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver,
|
|||
use syntax::ext::source_util::*;
|
||||
register! {
|
||||
line: expand_line,
|
||||
__rust_unstable_column: expand_column_gated,
|
||||
column: expand_column,
|
||||
file: expand_file,
|
||||
stringify: expand_stringify,
|
||||
|
|
|
|||
|
|
@ -278,10 +278,12 @@ static Optional<Reloc::Model> fromRust(LLVMRustRelocMode RustReloc) {
|
|||
return Reloc::RWPI;
|
||||
case LLVMRustRelocMode::ROPIRWPI:
|
||||
return Reloc::ROPI_RWPI;
|
||||
#endif
|
||||
#else
|
||||
default:
|
||||
llvm_unreachable("Bad RelocModel.");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
llvm_unreachable("Bad RelocModel.");
|
||||
}
|
||||
|
||||
#if LLVM_RUSTLLVM
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue