Merge remote-tracking branch 'origin/master' into gen

This commit is contained in:
Alex Crichton 2017-08-10 14:05:58 -07:00
commit b8aa595e6d
168 changed files with 2634 additions and 1443 deletions

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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] */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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
}
_ => {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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