[[package]]
name = "languageserver-types"
-version = "0.36.0"
+version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "rls"
-version = "0.126.0"
+version = "0.127.0"
dependencies = [
"cargo 0.28.0",
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "languageserver-types 0.36.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "languageserver-types 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly 0.6.0",
+ "rustfmt-nightly 0.6.1",
"serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc_macro 0.0.0",
"rustc_apfloat 0.0.0",
- "rustc_const_math 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_target 0.0.0",
[[package]]
name = "rustc-ap-rustc_cratesio_shim"
-version = "110.0.0"
+version = "113.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-ap-rustc_data_structures"
-version = "110.0.0"
+version = "113.0.0"
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)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-ap-rustc_errors"
-version = "110.0.0"
+version = "113.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "rustc-ap-rustc_target"
+version = "113.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "rustc-ap-serialize"
-version = "110.0.0"
+version = "113.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-ap-syntax"
-version = "110.0.0"
+version = "113.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-ap-syntax_pos"
-version = "110.0.0"
+version = "113.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rustc-ap-rustc_data_structures 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax_pos 0.0.0",
]
-[[package]]
-name = "rustc_const_math"
-version = "0.0.0"
-dependencies = [
- "rustc_apfloat 0.0.0",
- "serialize 0.0.0",
- "syntax 0.0.0",
-]
-
[[package]]
name = "rustc_cratesio_shim"
version = "0.0.0"
"log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_apfloat 0.0.0",
- "rustc_const_math 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_target 0.0.0",
dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
- "rustc_const_math 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_mir 0.0.0",
"rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_allocator 0.0.0",
"rustc_apfloat 0.0.0",
- "rustc_const_math 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_incremental 0.0.0",
"fmt_macros 0.0.0",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
- "rustc_const_math 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_platform_intrinsics 0.0.0",
[[package]]
name = "rustfmt-nightly"
-version = "0.6.0"
+version = "0.6.1"
dependencies = [
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"derive-new 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be"
"checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-"checksum languageserver-types 0.36.0 (registry+https://github.com/rust-lang/crates.io-index)" = "174cdfb8bed13225bb419bec66ee1c970099c875688645f9c4a82e3af43ba69d"
+"checksum languageserver-types 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4cdd5e52d71aca47050e5b25f03082609c63a1e76b7362ebdd010895b3f854"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
"checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea"
"checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
"checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb"
-"checksum rustc-ap-rustc_cratesio_shim 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0256e318ad99c467d24bd7188f2d4a3028360621bb92d769b4b65fc44717d514"
-"checksum rustc-ap-rustc_data_structures 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83430df7f76ea85c1f70fe145041576eee8fd5d77053bf426df24b480918d185"
-"checksum rustc-ap-rustc_errors 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b03f874277103039816f6467b1ff30a81b1d6a29d4de6efccefe4c488f6535a"
-"checksum rustc-ap-serialize 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2e47cf949f06b0c7ab7566c2f69d49f28cb3ecf1bb8bf0bda48b1ba5b7945ae"
-"checksum rustc-ap-syntax 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "625e6fb41fde299082cda3bceb08f81c9ba56b14a2ec737b4366f9c3c9be07d8"
-"checksum rustc-ap-syntax_pos 110.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "474a23ef1a1245ae02c5fd6a1e9a0725ce6fd25ca2294703c03bddce041f867b"
+"checksum rustc-ap-rustc_cratesio_shim 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a01334797c5c4cf56cc40bb9636d7b4c4a076665b9b9b7f100fd666cf0a02ffc"
+"checksum rustc-ap-rustc_data_structures 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03d6f8f7da0de905f6ef80dc14dce3bbc372430622b6aeb421cf13190bc70e8a"
+"checksum rustc-ap-rustc_errors 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dfd6183804a685c48601651d8c8c7b0daa8f83b0b5e24edfbcb6a0337085127"
+"checksum rustc-ap-rustc_target 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f223157f51bf0e0621bef099de862468892ee4c4b83056f48f63e1bc00ccb72"
+"checksum rustc-ap-serialize 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2104a55a87d65cba8a845656f1f19a35da52af403863cd2a4bd5876ba522d879"
+"checksum rustc-ap-syntax 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b50671adb9b0a7c57a4690ac6a40cb614879f543b64aada42f55b66212492323"
+"checksum rustc-ap-syntax_pos 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55793c2a775230c42661194c48d44b35d4c8439d79ad8528e56651e854c48c63"
"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
"tools/rls/test_data/workspace_symbol",
]
-# Curiously, compiletest will segfault if compiled with opt-level=3 on 64-bit
-# MSVC when running the compile-fail test suite when a should-fail test panics.
-# But hey if this is removed and it gets past the bots, sounds good to me.
-[profile.release]
-opt-level = 2
-[profile.bench]
-opt-level = 2
-
# These options are controlled from our rustc wrapper script, so turn them off
# here and have them controlled elsewhere.
[profile.dev]
}
impl Config {
+ fn path_from_python(var_key: &str) -> PathBuf {
+ match env::var_os(var_key) {
+ // Do not trust paths from Python and normalize them slightly (#49785).
+ Some(var_val) => Path::new(&var_val).components().collect(),
+ _ => panic!("expected '{}' to be set", var_key),
+ }
+ }
+
pub fn default_opts() -> Config {
let mut config = Config::default();
config.llvm_enabled = true;
config.deny_warnings = true;
// set by bootstrap.py
- config.src = env::var_os("SRC").map(PathBuf::from).expect("'SRC' to be set");
config.build = INTERNER.intern_str(&env::var("BUILD").expect("'BUILD' to be set"));
- config.out = env::var_os("BUILD_DIR").map(PathBuf::from).expect("'BUILD_DIR' set");
+ config.src = Config::path_from_python("SRC");
+ config.out = Config::path_from_python("BUILD_DIR");
let stage0_root = config.out.join(&config.build).join("stage0/bin");
config.initial_rustc = stage0_root.join(exe("rustc", &config.build));
+++ /dev/null
-# `fn_must_use`
-
-The tracking issue for this feature is [#43302].
-
-[#43302]: https://github.com/rust-lang/rust/issues/43302
-
-------------------------
-
-The `fn_must_use` feature allows functions and methods to be annotated with
-`#[must_use]`, indicating that the `unused_must_use` lint should require their
-return values to be used (similarly to how types annotated with `must_use`,
-most notably `Result`, are linted if not used).
-
-## Examples
-
-```rust
-#![feature(fn_must_use)]
-
-#[must_use]
-fn double(x: i32) -> i32 {
- 2 * x
-}
-
-fn main() {
- double(4); // warning: unused return value of `double` which must be used
-
- let _ = double(4); // (no warning)
-}
-
-```
--- /dev/null
+# `tool_attributes`
+
+The tracking issue for this feature is: [#44690]
+
+[#44690]: https://github.com/rust-lang/rust/issues/44690
+
+------------------------
+
+Tool attributes let you use scoped attributes to control the behavior
+of certain tools.
+
+Currently tool names which can be appear in scoped attributes are restricted to
+`clippy` and `rustfmt`.
+
+## An example
+
+```rust
+#![feature(tool_attributes)]
+
+#[rustfmt::skip]
+fn foo() { println!("hello, world"); }
+
+fn main() {
+ foo();
+}
+```
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
-#![feature(fn_must_use)]
+#![cfg_attr(stage0, feature(fn_must_use))]
#![feature(from_ref)]
#![feature(fundamental)]
#![feature(lang_items)]
#![feature(on_unimplemented)]
#![feature(exact_chunks)]
#![feature(pointer_methods)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
#![cfg_attr(stage0, feature(generic_param_attrs))]
#![feature(rustc_const_unstable)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(exact_chunks)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
extern crate alloc_system;
extern crate core;
}
#[test]
+#[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_box_slice_clone_panics() {
use std::sync::Arc;
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
#![feature(extern_types)]
-#![feature(fn_must_use)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(iterator_flatten)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(doc_alias)]
+#![feature(inclusive_range_methods)]
#![cfg_attr(not(stage0), feature(mmx_target_feature))]
#![cfg_attr(not(stage0), feature(tbm_target_feature))]
#![cfg_attr(stage0, feature(target_feature))]
#![cfg_attr(stage0, feature(cfg_target_feature))]
+#![cfg_attr(stage0, feature(fn_must_use))]
#[prelude_import]
#[allow(unused)]
#[macro_export]
#[cfg(dox)]
macro_rules! concat_idents {
- ($($e:ident),*) => ({ /* compiler built-in */ });
- ($($e:ident,)*) => ({ /* compiler built-in */ });
+ ($($e:ident),+) => ({ /* compiler built-in */ });
+ ($($e:ident,)+) => ({ /* compiler built-in */ });
}
/// Concatenates literals into a static string slice.
/// # Examples
///
/// ```
-/// #![feature(inclusive_range_fields)]
+/// #![feature(inclusive_range_methods)]
///
-/// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 });
+/// assert_eq!((3..=5), std::ops::RangeInclusive::new(3, 5));
/// assert_eq!(3 + 4 + 5, (3..=5).sum());
///
/// let arr = [0, 1, 2, 3];
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "inclusive_range", since = "1.26.0")]
pub struct RangeInclusive<Idx> {
+ // FIXME: The current representation follows RFC 1980,
+ // but it is known that LLVM is not able to optimize loops following that RFC.
+ // Consider adding an extra `bool` field to indicate emptiness of the range.
+ // See #45222 for performance test cases.
+ #[cfg(not(stage0))]
+ pub(crate) start: Idx,
+ #[cfg(not(stage0))]
+ pub(crate) end: Idx,
/// The lower bound of the range (inclusive).
+ #[cfg(stage0)]
#[unstable(feature = "inclusive_range_fields", issue = "49022")]
pub start: Idx,
/// The upper bound of the range (inclusive).
+ #[cfg(stage0)]
#[unstable(feature = "inclusive_range_fields", issue = "49022")]
pub end: Idx,
}
+impl<Idx> RangeInclusive<Idx> {
+ /// Creates a new inclusive range. Equivalent to writing `start..=end`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(inclusive_range_methods)]
+ /// use std::ops::RangeInclusive;
+ ///
+ /// assert_eq!(3..=5, RangeInclusive::new(3, 5));
+ /// ```
+ #[unstable(feature = "inclusive_range_methods", issue = "49022")]
+ #[inline]
+ pub const fn new(start: Idx, end: Idx) -> Self {
+ Self { start, end }
+ }
+
+ /// Returns the lower bound of the range (inclusive).
+ ///
+ /// When using an inclusive range for iteration, the values of `start()` and
+ /// [`end()`] are unspecified after the iteration ended. To determine
+ /// whether the inclusive range is empty, use the [`is_empty()`] method
+ /// instead of comparing `start() > end()`.
+ ///
+ /// [`end()`]: #method.end
+ /// [`is_empty()`]: #method.is_empty
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(inclusive_range_methods)]
+ ///
+ /// assert_eq!((3..=5).start(), &3);
+ /// ```
+ #[unstable(feature = "inclusive_range_methods", issue = "49022")]
+ #[inline]
+ pub fn start(&self) -> &Idx {
+ &self.start
+ }
+
+ /// Returns the upper bound of the range (inclusive).
+ ///
+ /// When using an inclusive range for iteration, the values of [`start()`]
+ /// and `end()` are unspecified after the iteration ended. To determine
+ /// whether the inclusive range is empty, use the [`is_empty()`] method
+ /// instead of comparing `start() > end()`.
+ ///
+ /// [`start()`]: #method.start
+ /// [`is_empty()`]: #method.is_empty
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(inclusive_range_methods)]
+ ///
+ /// assert_eq!((3..=5).end(), &5);
+ /// ```
+ #[unstable(feature = "inclusive_range_methods", issue = "49022")]
+ #[inline]
+ pub fn end(&self) -> &Idx {
+ &self.end
+ }
+}
+
#[stable(feature = "inclusive_range", since = "1.26.0")]
impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
(b as usize) << 8 | b as usize
}
-#[cfg(target_pointer_width = "32")]
+#[cfg(not(target_pointer_width = "16"))]
#[inline]
fn repeat_byte(b: u8) -> usize {
- let mut rep = (b as usize) << 8 | b as usize;
- rep = rep << 16 | rep;
- rep
-}
-
-#[cfg(target_pointer_width = "64")]
-#[inline]
-fn repeat_byte(b: u8) -> usize {
- let mut rep = (b as usize) << 8 | b as usize;
- rep = rep << 16 | rep;
- rep = rep << 32 | rep;
- rep
+ (b as usize) * (::usize::MAX / 255)
}
/// Return the first index matching the byte `x` in `text`.
#![feature(exact_chunks)]
#![cfg_attr(stage0, feature(atomic_nand))]
#![feature(reverse_bits)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
#![feature(iterator_find_map)]
extern crate core;
#[test]
fn test_range_inclusive() {
- let mut r = RangeInclusive { start: 1i8, end: 2 };
+ let mut r = RangeInclusive::new(1i8, 2);
assert_eq!(r.next(), Some(1));
assert_eq!(r.next(), Some(2));
assert_eq!(r.next(), None);
- r = RangeInclusive { start: 127i8, end: 127 };
+ r = RangeInclusive::new(127i8, 127);
assert_eq!(r.next(), Some(127));
assert_eq!(r.next(), None);
- r = RangeInclusive { start: -128i8, end: -128 };
+ r = RangeInclusive::new(-128i8, -128);
assert_eq!(r.next_back(), Some(-128));
assert_eq!(r.next_back(), None);
// degenerate
- r = RangeInclusive { start: 1, end: -1 };
+ r = RangeInclusive::new(1, -1);
assert_eq!(r.size_hint(), (0, Some(0)));
assert_eq!(r.next(), None);
}
}
impl BoolTrie {
pub fn lookup(&self, c: char) -> bool {
- let c = c as usize;
+ let c = c as u32;
if c < 0x800 {
- trie_range_leaf(c, self.r1[c >> 6])
+ trie_range_leaf(c, self.r1[(c >> 6) as usize])
} else if c < 0x10000 {
- let child = self.r2[(c >> 6) - 0x20];
+ let child = self.r2[(c >> 6) as usize - 0x20];
trie_range_leaf(c, self.r3[child as usize])
} else {
- let child = self.r4[(c >> 12) - 0x10];
- let leaf = self.r5[((child as usize) << 6) + ((c >> 6) & 0x3f)];
+ let child = self.r4[(c >> 12) as usize - 0x10];
+ let leaf = self.r5[((child as usize) << 6) + ((c >> 6) as usize & 0x3f)];
trie_range_leaf(c, self.r6[leaf as usize])
}
}
impl SmallBoolTrie {
pub fn lookup(&self, c: char) -> bool {
- let c = c as usize;
- match self.r1.get(c >> 6) {
+ let c = c as u32;
+ match self.r1.get((c >> 6) as usize) {
Some(&child) => trie_range_leaf(c, self.r2[child as usize]),
None => false,
}
}
}
-fn trie_range_leaf(c: usize, bitmap_chunk: u64) -> bool {
+fn trie_range_leaf(c: u32, bitmap_chunk: u64) -> bool {
((bitmap_chunk >> (c & 63)) & 1) != 0
}
proc_macro = { path = "../libproc_macro" }
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_target = { path = "../librustc_target" }
-rustc_const_math = { path = "../librustc_const_math" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" }
serialize = { path = "../libserialize" }
// ```
let hints: Vec<_> = item.attrs
.iter()
- .filter(|attr| match attr.name() {
- Some(name) => name == "repr",
- None => false,
- })
+ .filter(|attr| attr.name() == "repr")
.filter_map(|attr| attr.meta_item_list())
.flat_map(|hints| hints)
.collect();
fn check_used(&self, item: &hir::Item, target: Target) {
for attr in &item.attrs {
- if attr.name().map(|name| name == "used").unwrap_or(false) && target != Target::Static {
+ if attr.name() == "used" && target != Target::Static {
self.tcx.sess
.span_err(attr.span, "attribute must be applied to a `static` variable");
}
ExprKind::Index(ref el, ref er) => {
hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
}
+ // Desugar `<start>..=<end>` to `std::ops::RangeInclusive::new(<start>, <end>)`
+ ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
+ // FIXME: Use e.span directly after RangeInclusive::new() is stabilized in stage0.
+ let span = self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
+ let id = self.next_id();
+ let e1 = self.lower_expr(e1);
+ let e2 = self.lower_expr(e2);
+ let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], false));
+ let ty = self.ty_path(id, span, hir::QPath::Resolved(None, ty_path));
+ let new_seg = P(hir::PathSegment::from_name(Symbol::intern("new")));
+ let new_path = hir::QPath::TypeRelative(ty, new_seg);
+ let new = P(self.expr(span, hir::ExprPath(new_path), ThinVec::new()));
+ hir::ExprCall(new, hir_vec![e1, e2])
+ }
ExprKind::Range(ref e1, ref e2, lims) => {
use syntax::ast::RangeLimits::*;
(&None, &Some(..), HalfOpen) => "RangeTo",
(&Some(..), &Some(..), HalfOpen) => "Range",
(&None, &Some(..), Closed) => "RangeToInclusive",
- (&Some(..), &Some(..), Closed) => "RangeInclusive",
+ (&Some(..), &Some(..), Closed) => unreachable!(),
(_, &None, Closed) => self.diagnostic()
.span_fatal(e.span, "inclusive range with no end")
.raise(),
+++ /dev/null
-// 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.
-
-//! This module contains `HashStable` implementations for various data types
-//! from `rustc_const_math` in no particular order.
-
-impl_stable_hash_for!(struct ::rustc_const_math::ConstFloat {
- ty,
- bits
-});
-
-impl_stable_hash_for!(enum ::rustc_const_math::ConstMathErr {
- NotInRange,
- CmpBetweenUnequalTypes,
- UnequalTypes(op),
- Overflow(op),
- ShiftNegative,
- DivisionByZero,
- RemainderByZero,
- UnsignedNegation,
- ULitOutOfRange(int_ty),
- LitOutOfRange(int_ty)
-});
-
-impl_stable_hash_for!(enum ::rustc_const_math::Op {
- Add,
- Sub,
- Mul,
- Div,
- Rem,
- Shr,
- Shl,
- Neg,
- BitAnd,
- BitOr,
- BitXor
-});
}
}
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for mir::AssertMessage<'gcx> {
- fn hash_stable<W: StableHasherResult>(&self,
- hcx: &mut StableHashingContext<'a>,
- hasher: &mut StableHasher<W>) {
- mem::discriminant(self).hash_stable(hcx, hasher);
-
- match *self {
- mir::AssertMessage::BoundsCheck { ref len, ref index } => {
- len.hash_stable(hcx, hasher);
- index.hash_stable(hcx, hasher);
- }
- mir::AssertMessage::Math(ref const_math_err) => {
- const_math_err.hash_stable(hcx, hasher);
- }
- mir::AssertMessage::GeneratorResumedAfterReturn => (),
- mir::AssertMessage::GeneratorResumedAfterPanic => (),
- }
- }
-}
-
impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
let filtered: AccumulateVec<[&ast::Attribute; 8]> = self
.iter()
.filter(|attr| {
- !attr.is_sugared_doc &&
- attr.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)
+ !attr.is_sugared_doc && !hcx.is_ignored_attr(attr.name())
})
.collect();
}
}
+impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
+ fn hash_stable<W: StableHasherResult>(&self,
+ hcx: &mut StableHashingContext<'a>,
+ hasher: &mut StableHasher<W>) {
+ self.segments.len().hash_stable(hcx, hasher);
+ for segment in &self.segments {
+ segment.ident.name.hash_stable(hcx, hasher);
+ }
+ }
+}
+
impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
// Make sure that these have been filtered out.
- debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true));
+ debug_assert!(!hcx.is_ignored_attr(self.name()));
debug_assert!(!self.is_sugared_doc);
let ast::Attribute {
} = *self;
style.hash_stable(hcx, hasher);
- path.segments.len().hash_stable(hcx, hasher);
- for segment in &path.segments {
- segment.ident.name.hash_stable(hcx, hasher);
- }
+ path.hash_stable(hcx, hasher);
for tt in tokens.trees() {
tt.hash_stable(hcx, hasher);
}
len.hash_stable(hcx, hasher);
index.hash_stable(hcx, hasher);
}
- Math(ref const_math_err) => {
- const_math_err.hash_stable(hcx, hasher);
- }
LayoutError(ref layout_error) => {
layout_error.hash_stable(hcx, hasher);
}
predicates
});
+
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ::mir::interpret::EvalError<'gcx> {
+ fn hash_stable<W: StableHasherResult>(&self,
+ hcx: &mut StableHashingContext<'a>,
+ hasher: &mut StableHasher<W>) {
+ self.kind.hash_stable(hcx, hasher)
+ }
+}
+
+impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
+for ::mir::interpret::EvalErrorKind<'gcx, O> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use mir::interpret::EvalErrorKind::*;
- mem::discriminant(&self.kind).hash_stable(hcx, hasher);
+ mem::discriminant(&self).hash_stable(hcx, hasher);
- match self.kind {
+ match *self {
DanglingPointerDeref |
DoubleFree |
InvalidMemoryAccess |
TypeckError |
DerefFunctionPointer |
ExecuteMemory |
- ReferencedConstant |
- OverflowingMath => {}
+ OverflowNeg |
+ RemainderByZero |
+ DivisionByZero |
+ GeneratorResumedAfterReturn |
+ GeneratorResumedAfterPanic |
+ ReferencedConstant => {}
MachineError(ref err) => err.hash_stable(hcx, hasher),
FunctionPointerTyMismatch(a, b) => {
a.hash_stable(hcx, hasher);
},
InvalidBoolOp(bop) => bop.hash_stable(hcx, hasher),
Unimplemented(ref s) => s.hash_stable(hcx, hasher),
- ArrayIndexOutOfBounds(sp, a, b) => {
- sp.hash_stable(hcx, hasher);
- a.hash_stable(hcx, hasher);
- b.hash_stable(hcx, hasher)
- },
- Math(sp, ref err) => {
- sp.hash_stable(hcx, hasher);
- err.hash_stable(hcx, hasher)
+ BoundsCheck { ref len, ref index } => {
+ len.hash_stable(hcx, hasher);
+ index.hash_stable(hcx, hasher)
},
Intrinsic(ref s) => s.hash_stable(hcx, hasher),
InvalidChar(c) => c.hash_stable(hcx, hasher),
Layout(lay) => lay.hash_stable(hcx, hasher),
HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
PathNotFound(ref v) => v.hash_stable(hcx, hasher),
+ Overflow(op) => op.hash_stable(hcx, hasher),
}
}
}
mod caching_codemap_view;
mod hcx;
-mod impls_const_math;
mod impls_cstore;
mod impls_hir;
mod impls_mir;
drop(variables);
self.relate(&u, &u)
}
- TypeVariableValue::Unknown { .. } => {
+ TypeVariableValue::Unknown { universe } => {
match self.ambient_variance {
// Invariant: no need to make a fresh type variable.
ty::Invariant => return Ok(t),
}
let origin = *variables.var_origin(vid);
- let new_var_id = variables.new_var(false, origin);
+ let new_var_id = variables.new_var(universe, false, origin);
let u = self.tcx().mk_var(new_var_id);
debug!("generalize: replacing original vid={:?} with new={:?}",
vid, u);
// Second, we instantiate each bound region in the supertype with a
// fresh concrete region.
let (b_prime, skol_map) =
- self.infcx.skolemize_late_bound_regions(b, snapshot);
+ self.infcx.skolemize_late_bound_regions(b);
debug!("a_prime={:?}", a_prime);
debug!("b_prime={:?}", b_prime);
// First, we instantiate each bound region in the matcher
// with a skolemized region.
let ((a_match, a_value), skol_map) =
- self.infcx.skolemize_late_bound_regions(a_pair, snapshot);
+ self.infcx.skolemize_late_bound_regions(a_pair);
debug!("higher_ranked_match: a_match={:?}", a_match);
debug!("higher_ranked_match: skol_map={:?}", skol_map);
///
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
pub fn skolemize_late_bound_regions<T>(&self,
- binder: &ty::Binder<T>,
- snapshot: &CombinedSnapshot<'a, 'tcx>)
+ binder: &ty::Binder<T>)
-> (T, SkolemizationMap<'tcx>)
where T : TypeFoldable<'tcx>
{
let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
- self.borrow_region_constraints()
- .push_skolemized(self.tcx, br, &snapshot.region_constraints_snapshot)
+ self.universe.set(self.universe().subuniverse());
+ self.tcx.mk_region(ty::ReSkolemized(self.universe(), br))
});
debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})",
debug!("pop_skolemized({:?})", skol_map);
let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect();
self.borrow_region_constraints()
- .pop_skolemized(self.tcx, &skol_regions, &snapshot.region_constraints_snapshot);
+ .pop_skolemized(self.universe(), &skol_regions, &snapshot.region_constraints_snapshot);
+ self.universe.set(snapshot.universe);
if !skol_map.is_empty() {
self.projection_cache.borrow_mut().rollback_skolemized(
&snapshot.projection_cache_snapshot);
use infer::region_constraints::Constraint;
use infer::region_constraints::GenericKind;
use infer::region_constraints::RegionConstraintData;
-use infer::region_constraints::VarOrigins;
+use infer::region_constraints::VarInfos;
use infer::region_constraints::VerifyBound;
use middle::free_region::RegionRelations;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
/// all the variables as well as a set of errors that must be reported.
pub fn resolve<'tcx>(
region_rels: &RegionRelations<'_, '_, 'tcx>,
- var_origins: VarOrigins,
+ var_infos: VarInfos,
data: RegionConstraintData<'tcx>,
) -> (
LexicalRegionResolutions<'tcx>,
let mut errors = vec![];
let mut resolver = LexicalResolver {
region_rels,
- var_origins,
+ var_infos,
data,
};
let values = resolver.infer_variable_values(&mut errors);
struct LexicalResolver<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
region_rels: &'cx RegionRelations<'cx, 'gcx, 'tcx>,
- var_origins: VarOrigins,
+ var_infos: VarInfos,
data: RegionConstraintData<'tcx>,
}
}
fn num_vars(&self) -> usize {
- self.var_origins.len()
+ self.var_infos.len()
}
/// Initially, the value for all variables is set to `'empty`, the
(&ReVar(v_id), _) | (_, &ReVar(v_id)) => {
span_bug!(
- self.var_origins[v_id].span(),
+ self.var_infos[v_id].origin.span(),
"lub_concrete_regions invoked with non-concrete \
regions: {:?}, {:?}",
a,
if !self.region_rels
.is_subregion_of(lower_bound.region, upper_bound.region)
{
- let origin = self.var_origins[node_idx].clone();
+ let origin = self.var_infos[node_idx].origin.clone();
debug!(
"region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
sup: {:?}",
}
span_bug!(
- self.var_origins[node_idx].span(),
+ self.var_infos[node_idx].origin.span(),
"collect_error_for_expanding_node() could not find \
error for var {:?}, lower_bounds={:?}, \
upper_bounds={:?}",
use self::combine::CombineFields;
use self::higher_ranked::HrMatchResult;
use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
-use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarOrigins};
+use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarInfos};
use self::lexical_region_resolve::LexicalRegionResolutions;
use self::outlives::env::OutlivesEnvironment;
use self::type_variable::TypeVariableOrigin;
// obligations within. This is expected to be done 'late enough'
// that all type inference variables have been bound and so forth.
pub region_obligations: RefCell<Vec<(ast::NodeId, RegionObligation<'tcx>)>>,
+
+ /// What is the innermost universe we have created? Starts out as
+ /// `UniverseIndex::root()` but grows from there as we enter
+ /// universal quantifiers.
+ ///
+ /// NB: At present, we exclude the universal quantifiers on the
+ /// item we are type-checking, and just consider those names as
+ /// part of the root universe. So this would only get incremented
+ /// when we enter into a higher-ranked (`for<..>`) type or trait
+ /// bound.
+ universe: Cell<ty::UniverseIndex>,
}
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
err_count_on_creation: tcx.sess.err_count(),
in_snapshot: Cell::new(false),
region_obligations: RefCell::new(vec![]),
+ universe: Cell::new(ty::UniverseIndex::ROOT),
}))
}
}
float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
region_constraints_snapshot: RegionSnapshot,
region_obligations_snapshot: usize,
+ universe: ty::UniverseIndex,
was_in_snapshot: bool,
_in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
}
float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(),
region_obligations_snapshot: self.region_obligations.borrow().len(),
+ universe: self.universe(),
was_in_snapshot: in_snapshot,
// Borrow tables "in progress" (i.e. during typeck)
// to ban writes from within a snapshot to them.
float_snapshot,
region_constraints_snapshot,
region_obligations_snapshot,
+ universe,
was_in_snapshot,
_in_progress_tables } = snapshot;
self.in_snapshot.set(was_in_snapshot);
+ self.universe.set(universe);
self.projection_cache
.borrow_mut()
float_snapshot,
region_constraints_snapshot,
region_obligations_snapshot: _,
+ universe: _,
was_in_snapshot,
_in_progress_tables } = snapshot;
Some(self.commit_if_ok(|snapshot| {
let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) =
- self.skolemize_late_bound_regions(predicate, snapshot);
+ self.skolemize_late_bound_regions(predicate);
let cause_span = cause.span;
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
{
self.commit_if_ok(|snapshot| {
let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
- self.skolemize_late_bound_regions(predicate, snapshot);
+ self.skolemize_late_bound_regions(predicate);
let origin =
SubregionOrigin::from_obligation_cause(cause,
|| RelateRegionParamBound(cause.span));
pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
self.type_variables
.borrow_mut()
- .new_var(diverging, origin)
+ .new_var(self.universe(), diverging, origin)
}
pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
/// during diagnostics / error-reporting.
pub fn next_region_var(&self, origin: RegionVariableOrigin)
-> ty::Region<'tcx> {
- self.tcx.mk_region(ty::ReVar(self.borrow_region_constraints().new_region_var(origin)))
+ let region_var = self.borrow_region_constraints()
+ .new_region_var(self.universe(), origin);
+ self.tcx.mk_region(ty::ReVar(region_var))
}
/// Number of region variables created so far.
pub fn num_region_vars(&self) -> usize {
- self.borrow_region_constraints().var_origins().len()
+ self.borrow_region_constraints().num_region_vars()
}
/// Just a convenient wrapper of `next_region_var` for using during NLL.
-> Ty<'tcx> {
let ty_var_id = self.type_variables
.borrow_mut()
- .new_var(false,
+ .new_var(self.universe(),
+ false,
TypeVariableOrigin::TypeParameterDefinition(span, def.name));
self.tcx.mk_var(ty_var_id)
region_context,
region_map,
outlives_env.free_region_map());
- let (var_origins, data) = self.region_constraints.borrow_mut()
+ let (var_infos, data) = self.region_constraints.borrow_mut()
.take()
.expect("regions already resolved")
- .into_origins_and_data();
+ .into_infos_and_data();
let (lexical_region_resolutions, errors) =
- lexical_region_resolve::resolve(region_rels, var_origins, data);
+ lexical_region_resolve::resolve(region_rels, var_infos, data);
let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
assert!(old_value.is_none());
/// hence that `resolve_regions_and_report_errors` can never be
/// called. This is used only during NLL processing to "hand off" ownership
/// of the set of region vairables into the NLL region context.
- pub fn take_region_var_origins(&self) -> VarOrigins {
- let (var_origins, data) = self.region_constraints.borrow_mut()
+ pub fn take_region_var_origins(&self) -> VarInfos {
+ let (var_infos, data) = self.region_constraints.borrow_mut()
.take()
.expect("regions already resolved")
- .into_origins_and_data();
+ .into_infos_and_data();
assert!(data.is_empty());
- var_origins
+ var_infos
}
pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
self.evaluation_cache.clear();
self.projection_cache.borrow_mut().clear();
}
+
+ fn universe(&self) -> ty::UniverseIndex {
+ self.universe.get()
+ }
}
impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
use ty::{self, Ty, TyCtxt};
use ty::{Region, RegionVid};
use ty::ReStatic;
-use ty::{BrFresh, ReLateBound, ReSkolemized, ReVar};
+use ty::{BrFresh, ReLateBound, ReVar};
use std::collections::BTreeMap;
-use std::fmt;
-use std::mem;
-use std::u32;
+use std::{cmp, fmt, mem, u32};
mod taint;
pub struct RegionConstraintCollector<'tcx> {
/// For each `RegionVid`, the corresponding `RegionVariableOrigin`.
- var_origins: IndexVec<RegionVid, RegionVariableOrigin>,
+ var_infos: IndexVec<RegionVid, RegionVariableInfo>,
data: RegionConstraintData<'tcx>,
/// exist). This prevents us from making many such regions.
glbs: CombineMap<'tcx>,
- /// Number of skolemized variables currently active.
- skolemization_count: u32,
-
/// Global counter used during the GLB algorithm to create unique
/// names for fresh bound regions
bound_count: u32,
unification_table: ut::UnificationTable<ut::InPlace<ty::RegionVid>>,
}
-pub type VarOrigins = IndexVec<RegionVid, RegionVariableOrigin>;
+pub type VarInfos = IndexVec<RegionVid, RegionVariableInfo>;
/// The full set of region constraints gathered up by the collector.
/// Describes constraints between the region variables and other
type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
+#[derive(Debug, Clone, Copy)]
+pub struct RegionVariableInfo {
+ pub origin: RegionVariableOrigin,
+ pub universe: ty::UniverseIndex,
+}
+
pub struct RegionSnapshot {
length: usize,
region_snapshot: ut::Snapshot<ut::InPlace<ty::RegionVid>>,
- skolemization_count: u32,
}
/// When working with skolemized regions, we often wish to find all of
impl<'tcx> RegionConstraintCollector<'tcx> {
pub fn new() -> RegionConstraintCollector<'tcx> {
RegionConstraintCollector {
- var_origins: VarOrigins::default(),
+ var_infos: VarInfos::default(),
data: RegionConstraintData::default(),
lubs: FxHashMap(),
glbs: FxHashMap(),
- skolemization_count: 0,
bound_count: 0,
undo_log: Vec::new(),
unification_table: ut::UnificationTable::new(),
}
}
- pub fn var_origins(&self) -> &VarOrigins {
- &self.var_origins
+ pub fn num_region_vars(&self) -> usize {
+ self.var_infos.len()
}
pub fn region_constraint_data(&self) -> &RegionConstraintData<'tcx> {
/// Once all the constraints have been gathered, extract out the final data.
///
/// Not legal during a snapshot.
- pub fn into_origins_and_data(self) -> (VarOrigins, RegionConstraintData<'tcx>) {
+ pub fn into_infos_and_data(self) -> (VarInfos, RegionConstraintData<'tcx>) {
assert!(!self.in_snapshot());
- (self.var_origins, self.data)
+ (self.var_infos, self.data)
}
/// Takes (and clears) the current set of constraints. Note that
// should think carefully about whether it needs to be cleared
// or updated in some way.
let RegionConstraintCollector {
- var_origins,
+ var_infos,
data,
lubs,
glbs,
- skolemization_count,
bound_count: _,
undo_log: _,
unification_table,
} = self;
- assert_eq!(*skolemization_count, 0);
-
// Clear the tables of (lubs, glbs), so that we will create
// fresh regions if we do a LUB operation. As it happens,
// LUB/GLB are not performed by the MIR type-checker, which is
// also insert `a <= b` and a `b <= a` edges, so the
// `RegionConstraintData` contains the relationship here.
*unification_table = ut::UnificationTable::new();
- for vid in var_origins.indices() {
+ for vid in var_infos.indices() {
unification_table.new_key(unify_key::RegionVidKey { min_vid: vid });
}
RegionSnapshot {
length,
region_snapshot: self.unification_table.snapshot(),
- skolemization_count: self.skolemization_count,
}
}
debug!("RegionConstraintCollector: commit({})", snapshot.length);
assert!(self.undo_log.len() > snapshot.length);
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
- assert!(
- self.skolemization_count == snapshot.skolemization_count,
- "failed to pop skolemized regions: {} now vs {} at start",
- self.skolemization_count,
- snapshot.skolemization_count
- );
if snapshot.length == 0 {
self.undo_log.truncate(0);
}
let c = self.undo_log.pop().unwrap();
assert!(c == OpenSnapshot);
- self.skolemization_count = snapshot.skolemization_count;
self.unification_table.rollback_to(snapshot.region_snapshot);
}
// nothing to do here
}
AddVar(vid) => {
- self.var_origins.pop().unwrap();
- assert_eq!(self.var_origins.len(), vid.index() as usize);
+ self.var_infos.pop().unwrap();
+ assert_eq!(self.var_infos.len(), vid.index() as usize);
}
AddConstraint(ref constraint) => {
self.data.constraints.remove(constraint);
}
}
- pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid {
- let vid = self.var_origins.push(origin.clone());
+ pub fn new_region_var(&mut self,
+ universe: ty::UniverseIndex,
+ origin: RegionVariableOrigin) -> RegionVid {
+ let vid = self.var_infos.push(RegionVariableInfo {
+ origin,
+ universe,
+ });
let u_vid = self.unification_table
.new_key(unify_key::RegionVidKey { min_vid: vid });
return vid;
}
- /// Returns the origin for the given variable.
- pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
- self.var_origins[vid].clone()
+ /// Returns the universe for the given variable.
+ pub fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex {
+ self.var_infos[vid].universe
}
- /// Creates a new skolemized region. Skolemized regions are fresh
- /// regions used when performing higher-ranked computations. They
- /// must be used in a very particular way and are never supposed
- /// to "escape" out into error messages or the code at large.
- ///
- /// The idea is to always create a snapshot. Skolemized regions
- /// can be created in the context of this snapshot, but before the
- /// snapshot is committed or rolled back, they must be popped
- /// (using `pop_skolemized_regions`), so that their numbers can be
- /// recycled. Normally you don't have to think about this: you use
- /// the APIs in `higher_ranked/mod.rs`, such as
- /// `skolemize_late_bound_regions` and `plug_leaks`, which will
- /// guide you on this path (ensure that the `SkolemizationMap` is
- /// consumed and you are good). For more info on how skolemization
- /// for HRTBs works, see the [rustc guide].
- ///
- /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
- ///
- /// The `snapshot` argument to this function is not really used;
- /// it's just there to make it explicit which snapshot bounds the
- /// skolemized region that results. It should always be the top-most snapshot.
- pub fn push_skolemized(
- &mut self,
- tcx: TyCtxt<'_, '_, 'tcx>,
- br: ty::BoundRegion,
- snapshot: &RegionSnapshot,
- ) -> Region<'tcx> {
- assert!(self.in_snapshot());
- assert!(self.undo_log[snapshot.length] == OpenSnapshot);
-
- let sc = self.skolemization_count;
- self.skolemization_count = sc + 1;
- tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br))
+ /// Returns the origin for the given variable.
+ pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
+ self.var_infos[vid].origin
}
/// Removes all the edges to/from the skolemized regions that are
/// created in that time.
pub fn pop_skolemized(
&mut self,
- _tcx: TyCtxt<'_, '_, 'tcx>,
+ skolemization_count: ty::UniverseIndex,
skols: &FxHashSet<ty::Region<'tcx>>,
snapshot: &RegionSnapshot,
) {
assert!(self.in_snapshot());
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
assert!(
- self.skolemization_count as usize >= skols.len(),
+ skolemization_count.as_usize() >= skols.len(),
"popping more skolemized variables than actually exist, \
- sc now = {}, skols.len = {}",
- self.skolemization_count,
+ sc now = {:?}, skols.len = {:?}",
+ skolemization_count,
skols.len()
);
- let last_to_pop = self.skolemization_count;
- let first_to_pop = last_to_pop - (skols.len() as u32);
+ let last_to_pop = skolemization_count.subuniverse();
+ let first_to_pop = ty::UniverseIndex::from(last_to_pop.as_u32() - skols.len() as u32);
- assert!(
- first_to_pop >= snapshot.skolemization_count,
- "popping more regions than snapshot contains, \
- sc now = {}, sc then = {}, skols.len = {}",
- self.skolemization_count,
- snapshot.skolemization_count,
- skols.len()
- );
debug_assert! {
skols.iter()
.all(|&k| match *k {
- ty::ReSkolemized(index, _) =>
- index.index >= first_to_pop &&
- index.index < last_to_pop,
+ ty::ReSkolemized(universe, _) =>
+ universe >= first_to_pop &&
+ universe < last_to_pop,
_ =>
false
}),
- "invalid skolemization keys or keys out of range ({}..{}): {:?}",
- snapshot.skolemization_count,
- self.skolemization_count,
+ "invalid skolemization keys or keys out of range ({:?}..{:?}): {:?}",
+ first_to_pop,
+ last_to_pop,
skols
}
self.rollback_undo_entry(undo_entry);
}
- self.skolemization_count = snapshot.skolemization_count;
return;
fn kill_constraint<'tcx>(
if let Some(&c) = self.combine_map(t).get(&vars) {
return tcx.mk_region(ReVar(c));
}
- let c = self.new_region_var(MiscVariable(origin.span()));
+ let a_universe = self.universe(a);
+ let b_universe = self.universe(b);
+ let c_universe = cmp::max(a_universe, b_universe);
+ let c = self.new_region_var(c_universe, MiscVariable(origin.span()));
self.combine_map(t).insert(vars, c);
if self.in_snapshot() {
self.undo_log.push(AddCombination(t, vars));
new_r
}
+ fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex {
+ match *region {
+ ty::ReScope(..) |
+ ty::ReStatic |
+ ty::ReEmpty |
+ ty::ReErased |
+ ty::ReFree(..) |
+ ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT,
+ ty::ReSkolemized(universe, _) => universe,
+ ty::ReClosureBound(vid) |
+ ty::ReVar(vid) => self.var_universe(vid),
+ ty::ReLateBound(..) =>
+ bug!("universe(): encountered bound region {:?}", region),
+ ty::ReCanonical(..) =>
+ bug!("region_universe(): encountered canonical region {:?}", region),
+ }
+ }
+
pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec<RegionVid> {
self.undo_log[mark.length..]
.iter()
impl fmt::Debug for RegionSnapshot {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(
- f,
- "RegionSnapshot(length={},skolemization={})",
- self.length,
- self.skolemization_count
- )
+ write!(f, "RegionSnapshot(length={})", self.length)
}
}
#[derive(Copy, Clone, Debug)]
pub enum TypeVariableValue<'tcx> {
Known { value: Ty<'tcx> },
- Unknown,
+ Unknown { universe: ty::UniverseIndex },
}
impl<'tcx> TypeVariableValue<'tcx> {
+ /// If this value is known, returns the type it is known to be.
+ /// Otherwise, `None`.
pub fn known(&self) -> Option<Ty<'tcx>> {
match *self {
TypeVariableValue::Unknown { .. } => None,
/// The code in this module doesn't care, but it can be useful
/// for improving error messages.
pub fn new_var(&mut self,
+ universe: ty::UniverseIndex,
diverging: bool,
origin: TypeVariableOrigin)
-> ty::TyVid {
- let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown);
+ let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown { universe });
let sub_key = self.sub_relations.new_key(());
assert_eq!(eq_key.vid, sub_key);
(&TypeVariableValue::Unknown { .. }, &TypeVariableValue::Known { .. }) => Ok(*value2),
// If both sides are *unknown*, it hardly matters, does it?
- (&TypeVariableValue::Unknown, &TypeVariableValue::Unknown) => Ok(*value1),
+ (&TypeVariableValue::Unknown { universe: universe1 },
+ &TypeVariableValue::Unknown { universe: universe2 }) => {
+ // If we unify two unbound variables, ?T and ?U, then whatever
+ // value they wind up taking (which must be the same value) must
+ // be nameable by both universes. Therefore, the resulting
+ // universe is the minimum of the two universes, because that is
+ // the one which contains the fewest names in scope.
+ let universe = cmp::min(universe1, universe2);
+ Ok(TypeVariableValue::Unknown { universe })
+ }
}
}
}
#![feature(trusted_len)]
#![feature(catch_expr)]
#![feature(test)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
#![recursion_limit="512"]
extern crate rustc_target;
#[macro_use] extern crate rustc_data_structures;
extern crate serialize;
-extern crate rustc_const_math;
extern crate rustc_errors as errors;
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
"malformed lint attribute");
};
for attr in attrs {
- let level = match attr.name().and_then(|name| Level::from_str(&name.as_str())) {
+ let level = match Level::from_str(&attr.name().as_str()) {
None => continue,
Some(lvl) => lvl,
};
continue
}
};
- let name = word.ident.name;
+ let name = word.name();
match store.check_lint_name(&name.as_str()) {
CheckLintNameResult::Ok(ids) => {
let src = LintSource::Node(name, li.span);
Some(li.span.into()),
&msg);
if name.as_str().chars().any(|c| c.is_uppercase()) {
- let name_lower = name.as_str().to_lowercase();
+ let name_lower = name.as_str().to_lowercase().to_string();
if let CheckLintNameResult::NoLint =
store.check_lint_name(&name_lower) {
db.emit();
let explanation = if lint_id == LintId::of(::lint::builtin::UNSTABLE_NAME_COLLISION) {
"once this method is added to the standard library, \
- there will be ambiguity here, which will cause a hard error!"
+ the ambiguity may cause an error or change in behavior!"
.to_owned()
} else if let Some(edition) = future_incompatible.edition {
format!("{} in the {} edition!", STANDARD_MESSAGE, edition)
use hir::def_id::DefId;
use ty::{self, TyCtxt, layout};
use ty::subst::Substs;
-use rustc_const_math::*;
use mir::interpret::{Value, PrimVal};
use errors::DiagnosticBuilder;
UnimplementedConstVal(&'static str),
IndexOutOfBounds { len: u64, index: u64 },
- Math(ConstMathErr),
LayoutError(layout::LayoutError<'tcx>),
TypeckError,
pub location: String,
}
-impl<'tcx> From<ConstMathErr> for ErrKind<'tcx> {
- fn from(err: ConstMathErr) -> ErrKind<'tcx> {
- match err {
- ConstMathErr::UnsignedNegation => ErrKind::TypeckError,
- _ => ErrKind::Math(err)
- }
- }
-}
-
#[derive(Clone, Debug)]
pub enum ConstEvalErrDescription<'a, 'tcx: 'a> {
Simple(Cow<'a, str>),
len, index)
}
- Math(ref err) => Simple(err.description().into_cow()),
LayoutError(ref err) => Simple(err.to_string().into_cow()),
TypeckError => simple!("type-checking failed"),
// the start. So this algorithm is faster.
let mut ma = Some(scope_a);
let mut mb = Some(scope_b);
- let mut seen: SmallVec<[Scope; 32]> = SmallVec::new();
+ let mut seen_a: SmallVec<[Scope; 32]> = SmallVec::new();
+ let mut seen_b: SmallVec<[Scope; 32]> = SmallVec::new();
loop {
if let Some(a) = ma {
- if seen.iter().position(|s| *s == a).is_some() {
+ if seen_b.iter().position(|s| *s == a).is_some() {
return a;
}
- seen.push(a);
+ seen_a.push(a);
ma = self.parent_map.get(&a).map(|s| *s);
}
if let Some(b) = mb {
- if seen.iter().position(|s| *s == b).is_some() {
+ if seen_a.iter().position(|s| *s == b).is_some() {
return b;
}
- seen.push(b);
+ seen_b.push(b);
mb = self.parent_map.get(&b).map(|s| *s);
}
} else {
// Emit errors for non-staged-api crates.
for attr in attrs {
- let tag = unwrap_or!(attr.name(), continue);
+ let tag = attr.name();
if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" {
attr::mark_used(attr);
self.tcx.sess.span_err(attr.span(), "stability attributes may not be used \
let mut result = IndexVec::from_elem(vec![], mir.basic_blocks());
for (bb, data) in mir.basic_blocks().iter_enumerated() {
if let Some(ref term) = data.terminator {
- for &tgt in term.successors().iter() {
+ for &tgt in term.successors() {
result[tgt].push(bb);
}
}
-use std::error::Error;
use std::{fmt, env};
use mir;
MemoryPointer, Lock, AccessKind
};
-use rustc_const_math::ConstMathErr;
-use syntax::codemap::Span;
use backtrace::Backtrace;
#[derive(Debug, Clone)]
pub struct EvalError<'tcx> {
- pub kind: EvalErrorKind<'tcx>,
+ pub kind: EvalErrorKind<'tcx, u64>,
pub backtrace: Option<Backtrace>,
}
-impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
- fn from(kind: EvalErrorKind<'tcx>) -> Self {
+impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
+ fn from(kind: EvalErrorKind<'tcx, u64>) -> Self {
let backtrace = match env::var("MIRI_BACKTRACE") {
Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()),
_ => None
}
}
-#[derive(Debug, Clone)]
-pub enum EvalErrorKind<'tcx> {
+pub type AssertMessage<'tcx> = EvalErrorKind<'tcx, mir::Operand<'tcx>>;
+
+#[derive(Clone, RustcEncodable, RustcDecodable)]
+pub enum EvalErrorKind<'tcx, O> {
/// This variant is used by machines to signal their own errors that do not
/// match an existing variant
MachineError(String),
Unimplemented(String),
DerefFunctionPointer,
ExecuteMemory,
- ArrayIndexOutOfBounds(Span, u64, u64),
- Math(Span, ConstMathErr),
+ BoundsCheck { len: O, index: O },
+ Overflow(mir::BinOp),
+ OverflowNeg,
+ DivisionByZero,
+ RemainderByZero,
Intrinsic(String),
- OverflowingMath,
InvalidChar(u128),
StackFrameLimitReached,
OutOfTls,
/// Cannot compute this constant because it depends on another one
/// which already produced an error
ReferencedConstant,
+ GeneratorResumedAfterReturn,
+ GeneratorResumedAfterPanic,
}
pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;
-impl<'tcx> Error for EvalError<'tcx> {
- fn description(&self) -> &str {
+impl<'tcx, O> EvalErrorKind<'tcx, O> {
+ pub fn description(&self) -> &str {
use self::EvalErrorKind::*;
- match self.kind {
+ match *self {
MachineError(ref inner) => inner,
FunctionPointerTyMismatch(..) =>
"tried to call a function through a function pointer of a different type",
"tried to dereference a function pointer",
ExecuteMemory =>
"tried to treat a memory pointer as a function pointer",
- ArrayIndexOutOfBounds(..) =>
+ BoundsCheck{..} =>
"array index out of bounds",
- Math(..) =>
- "mathematical operation failed",
Intrinsic(..) =>
"intrinsic failed",
- OverflowingMath =>
- "attempted to do overflowing math",
NoMirFor(..) =>
"mir not found",
InvalidChar(..) =>
"the evaluated program panicked",
ReadFromReturnPointer =>
"tried to read from the return pointer",
- EvalErrorKind::PathNotFound(_) =>
+ PathNotFound(_) =>
"a path could not be resolved, maybe the crate is not loaded",
UnimplementedTraitSelection =>
"there were unresolved type arguments during trait selection",
"encountered constants with type errors, stopping evaluation",
ReferencedConstant =>
"referenced constant has errors",
+ Overflow(mir::BinOp::Add) => "attempt to add with overflow",
+ Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
+ Overflow(mir::BinOp::Mul) => "attempt to multiply with overflow",
+ Overflow(mir::BinOp::Div) => "attempt to divide with overflow",
+ Overflow(mir::BinOp::Rem) => "attempt to calculate the remainder with overflow",
+ OverflowNeg => "attempt to negate with overflow",
+ Overflow(mir::BinOp::Shr) => "attempt to shift right with overflow",
+ Overflow(mir::BinOp::Shl) => "attempt to shift left with overflow",
+ Overflow(op) => bug!("{:?} cannot overflow", op),
+ DivisionByZero => "attempt to divide by zero",
+ RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
+ GeneratorResumedAfterReturn => "generator resumed after completion",
+ GeneratorResumedAfterPanic => "generator resumed after panicking",
}
}
}
impl<'tcx> fmt::Display for EvalError<'tcx> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:?}", self.kind)
+ }
+}
+
+impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::EvalErrorKind::*;
- match self.kind {
+ match *self {
PointerOutOfBounds { ptr, access, allocation_size } => {
write!(f, "{} at offset {}, outside bounds of allocation {} which has size {}",
if access { "memory access" } else { "pointer computed" },
NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
FunctionPointerTyMismatch(sig, got) =>
write!(f, "tried to call a function with sig {} through a function pointer of type {}", sig, got),
- ArrayIndexOutOfBounds(span, len, index) =>
- write!(f, "index out of bounds: the len is {} but the index is {} at {:?}", len, index, span),
+ BoundsCheck { ref len, ref index } =>
+ write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
ReallocatedWrongMemoryKind(ref old, ref new) =>
write!(f, "tried to reallocate memory from {} to {}", old, new),
DeallocatedWrongMemoryKind(ref old, ref new) =>
write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
- Math(_, ref err) =>
- write!(f, "{}", err.description()),
Intrinsic(ref err) =>
write!(f, "{}", err),
InvalidChar(c) =>
mod error;
mod value;
-pub use self::error::{EvalError, EvalResult, EvalErrorKind};
+pub use self::error::{EvalError, EvalResult, EvalErrorKind, AssertMessage};
pub use self::value::{PrimVal, PrimValKind, Value, Pointer};
use syntax::ast::Mutability;
use rustc_serialize::{Encoder, Decoder, Decodable, Encodable};
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Lock {
NoLock,
WriteLock(DynamicLifetime),
ReadLock(Vec<DynamicLifetime>),
}
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct DynamicLifetime {
pub frame: usize,
pub region: Option<region::Scope>, // "None" indicates "until the function ends"
}
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum AccessKind {
Read,
Write,
fn signed_offset<'tcx>(self, val: u64, i: i64) -> EvalResult<'tcx, u64> {
let (res, over) = self.overflowing_signed_offset(val, i as i128);
- if over { err!(OverflowingMath) } else { Ok(res) }
+ if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
}
fn offset<'tcx>(self, val: u64, i: u64) -> EvalResult<'tcx, u64> {
let (res, over) = self.overflowing_offset(val, i);
- if over { err!(OverflowingMath) } else { Ok(res) }
+ if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
}
fn wrapping_signed_offset(self, val: u64, i: i64) -> u64 {
use graphviz::IntoCow;
use middle::const_val::ConstVal;
use middle::region;
-use rustc_const_math::ConstMathErr;
use rustc_data_structures::sync::{Lrc};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
use hir::def::CtorKind;
use hir::def_id::DefId;
use mir::visit::MirVisitable;
-use mir::interpret::{Value, PrimVal};
+use mir::interpret::{Value, PrimVal, EvalErrorKind};
use ty::subst::{Subst, Substs};
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use std::borrow::{Cow};
use rustc_data_structures::sync::ReadGuard;
use std::fmt::{self, Debug, Formatter, Write};
-use std::{iter, mem, u32};
+use std::{iter, mem, option, u32};
use std::ops::{Index, IndexMut};
use std::vec::IntoIter;
use syntax::ast::{self, Name};
use syntax::symbol::InternedString;
use syntax_pos::{Span, DUMMY_SP};
+use rustc_apfloat::ieee::{Single, Double};
+use rustc_apfloat::Float;
+
+pub use mir::interpret::AssertMessage;
mod cache;
pub mod tcx;
},
}
+pub type Successors<'a> =
+ iter::Chain<option::IntoIter<&'a BasicBlock>, slice::Iter<'a, BasicBlock>>;
+pub type SuccessorsMut<'a> =
+ iter::Chain<option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;
+
impl<'tcx> Terminator<'tcx> {
- pub fn successors(&self) -> Cow<[BasicBlock]> {
+ pub fn successors(&self) -> Successors {
self.kind.successors()
}
- pub fn successors_mut(&mut self) -> Vec<&mut BasicBlock> {
+ pub fn successors_mut(&mut self) -> SuccessorsMut {
self.kind.successors_mut()
}
}
}
- pub fn successors(&self) -> Cow<[BasicBlock]> {
+ pub fn successors(&self) -> Successors {
use self::TerminatorKind::*;
match *self {
- Goto { target: ref b } => slice::from_ref(b).into_cow(),
- SwitchInt { targets: ref b, .. } => b[..].into_cow(),
- Resume | Abort | GeneratorDrop => (&[]).into_cow(),
- Return => (&[]).into_cow(),
- Unreachable => (&[]).into_cow(),
- Call { destination: Some((_, t)), cleanup: Some(c), .. } => vec![t, c].into_cow(),
- Call { destination: Some((_, ref t)), cleanup: None, .. } =>
- slice::from_ref(t).into_cow(),
- Call { destination: None, cleanup: Some(ref c), .. } => slice::from_ref(c).into_cow(),
- Call { destination: None, cleanup: None, .. } => (&[]).into_cow(),
- Yield { resume: t, drop: Some(c), .. } => vec![t, c].into_cow(),
- Yield { resume: ref t, drop: None, .. } => slice::from_ref(t).into_cow(),
- DropAndReplace { target, unwind: Some(unwind), .. } |
- Drop { target, unwind: Some(unwind), .. } => {
- vec![target, unwind].into_cow()
+ Resume | Abort | GeneratorDrop | Return | Unreachable |
+ Call { destination: None, cleanup: None, .. } => {
+ None.into_iter().chain(&[])
+ }
+ Goto { target: ref t } |
+ Call { destination: None, cleanup: Some(ref t), .. } |
+ Call { destination: Some((_, ref t)), cleanup: None, .. } |
+ Yield { resume: ref t, drop: None, .. } |
+ DropAndReplace { target: ref t, unwind: None, .. } |
+ Drop { target: ref t, unwind: None, .. } |
+ Assert { target: ref t, cleanup: None, .. } |
+ FalseUnwind { real_target: ref t, unwind: None } => {
+ Some(t).into_iter().chain(&[])
}
- DropAndReplace { ref target, unwind: None, .. } |
- Drop { ref target, unwind: None, .. } => {
- slice::from_ref(target).into_cow()
+ Call { destination: Some((_, ref t)), cleanup: Some(ref u), .. } |
+ Yield { resume: ref t, drop: Some(ref u), .. } |
+ DropAndReplace { target: ref t, unwind: Some(ref u), .. } |
+ Drop { target: ref t, unwind: Some(ref u), .. } |
+ Assert { target: ref t, cleanup: Some(ref u), .. } |
+ FalseUnwind { real_target: ref t, unwind: Some(ref u) } => {
+ Some(t).into_iter().chain(slice::from_ref(u))
+ }
+ SwitchInt { ref targets, .. } => {
+ None.into_iter().chain(&targets[..])
}
- Assert { target, cleanup: Some(unwind), .. } => vec![target, unwind].into_cow(),
- Assert { ref target, .. } => slice::from_ref(target).into_cow(),
FalseEdges { ref real_target, ref imaginary_targets } => {
- let mut s = vec![*real_target];
- s.extend_from_slice(imaginary_targets);
- s.into_cow()
+ Some(real_target).into_iter().chain(&imaginary_targets[..])
}
- FalseUnwind { real_target: t, unwind: Some(u) } => vec![t, u].into_cow(),
- FalseUnwind { real_target: ref t, unwind: None } => slice::from_ref(t).into_cow(),
}
}
- // FIXME: no mootable cow. I’m honestly not sure what a “cow” between `&mut [BasicBlock]` and
- // `Vec<&mut BasicBlock>` would look like in the first place.
- pub fn successors_mut(&mut self) -> Vec<&mut BasicBlock> {
+ pub fn successors_mut(&mut self) -> SuccessorsMut {
use self::TerminatorKind::*;
match *self {
- Goto { target: ref mut b } => vec![b],
- SwitchInt { targets: ref mut b, .. } => b.iter_mut().collect(),
- Resume | Abort | GeneratorDrop => Vec::new(),
- Return => Vec::new(),
- Unreachable => Vec::new(),
- Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut c), .. } => vec![t, c],
- Call { destination: Some((_, ref mut t)), cleanup: None, .. } => vec![t],
- Call { destination: None, cleanup: Some(ref mut c), .. } => vec![c],
- Call { destination: None, cleanup: None, .. } => vec![],
- Yield { resume: ref mut t, drop: Some(ref mut c), .. } => vec![t, c],
- Yield { resume: ref mut t, drop: None, .. } => vec![t],
- DropAndReplace { ref mut target, unwind: Some(ref mut unwind), .. } |
- Drop { ref mut target, unwind: Some(ref mut unwind), .. } => vec![target, unwind],
- DropAndReplace { ref mut target, unwind: None, .. } |
- Drop { ref mut target, unwind: None, .. } => {
- vec![target]
+ Resume | Abort | GeneratorDrop | Return | Unreachable |
+ Call { destination: None, cleanup: None, .. } => {
+ None.into_iter().chain(&mut [])
+ }
+ Goto { target: ref mut t } |
+ Call { destination: None, cleanup: Some(ref mut t), .. } |
+ Call { destination: Some((_, ref mut t)), cleanup: None, .. } |
+ Yield { resume: ref mut t, drop: None, .. } |
+ DropAndReplace { target: ref mut t, unwind: None, .. } |
+ Drop { target: ref mut t, unwind: None, .. } |
+ Assert { target: ref mut t, cleanup: None, .. } |
+ FalseUnwind { real_target: ref mut t, unwind: None } => {
+ Some(t).into_iter().chain(&mut [])
+ }
+ Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. } |
+ Yield { resume: ref mut t, drop: Some(ref mut u), .. } |
+ DropAndReplace { target: ref mut t, unwind: Some(ref mut u), .. } |
+ Drop { target: ref mut t, unwind: Some(ref mut u), .. } |
+ Assert { target: ref mut t, cleanup: Some(ref mut u), .. } |
+ FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } => {
+ Some(t).into_iter().chain(slice::from_ref_mut(u))
+ }
+ SwitchInt { ref mut targets, .. } => {
+ None.into_iter().chain(&mut targets[..])
}
- Assert { ref mut target, cleanup: Some(ref mut unwind), .. } => vec![target, unwind],
- Assert { ref mut target, .. } => vec![target],
FalseEdges { ref mut real_target, ref mut imaginary_targets } => {
- let mut s = vec![real_target];
- s.extend(imaginary_targets.iter_mut());
- s
+ Some(real_target).into_iter().chain(&mut imaginary_targets[..])
}
- FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } => vec![t, u],
- FalseUnwind { ref mut real_target, unwind: None } => vec![real_target],
}
}
impl<'tcx> Debug for TerminatorKind<'tcx> {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.fmt_head(fmt)?;
- let successors = self.successors();
+ let successor_count = self.successors().count();
let labels = self.fmt_successor_labels();
- assert_eq!(successors.len(), labels.len());
+ assert_eq!(successor_count, labels.len());
- match successors.len() {
+ match successor_count {
0 => Ok(()),
- 1 => write!(fmt, " -> {:?}", successors[0]),
+ 1 => write!(fmt, " -> {:?}", self.successors().nth(0).unwrap()),
_ => {
write!(fmt, " -> [")?;
- for (i, target) in successors.iter().enumerate() {
+ for (i, target) in self.successors().enumerate() {
if i > 0 {
write!(fmt, ", ")?;
}
if !expected {
write!(fmt, "!")?;
}
- write!(fmt, "{:?}, ", cond)?;
-
- match *msg {
- AssertMessage::BoundsCheck { ref len, ref index } => {
- write!(fmt, "{:?}, {:?}, {:?}",
- "index out of bounds: the len is {} but the index is {}",
- len, index)?;
- }
- AssertMessage::Math(ref err) => {
- write!(fmt, "{:?}", err.description())?;
- }
- AssertMessage::GeneratorResumedAfterReturn => {
- write!(fmt, "{:?}", "generator resumed after completion")?;
- }
- AssertMessage::GeneratorResumedAfterPanic => {
- write!(fmt, "{:?}", "generator resumed after panicking")?;
- }
- }
-
- write!(fmt, ")")
+ write!(fmt, "{:?}, \"{:?}\")", cond, msg)
},
FalseEdges { .. } => write!(fmt, "falseEdges"),
FalseUnwind { .. } => write!(fmt, "falseUnwind"),
}
}
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-pub enum AssertMessage<'tcx> {
- BoundsCheck {
- len: Operand<'tcx>,
- index: Operand<'tcx>
- },
- Math(ConstMathErr),
- GeneratorResumedAfterReturn,
- GeneratorResumedAfterPanic,
-}
-
///////////////////////////////////////////////////////////////////////////
// Statements
pub fn print_miri_value<W: Write>(value: Value, ty: Ty, f: &mut W) -> fmt::Result {
use ty::TypeVariants::*;
- use rustc_const_math::ConstFloat;
match (value, &ty.sty) {
(Value::ByVal(PrimVal::Bytes(0)), &TyBool) => write!(f, "false"),
(Value::ByVal(PrimVal::Bytes(1)), &TyBool) => write!(f, "true"),
- (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(fty)) =>
- write!(f, "{}", ConstFloat { bits, ty: fty }),
+ (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F32)) =>
+ write!(f, "{}f32", Single::from_bits(bits)),
+ (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F64)) =>
+ write!(f, "{}f64", Double::from_bits(bits)),
(Value::ByVal(PrimVal::Bytes(n)), &TyUint(ui)) => write!(f, "{:?}{}", n, ui),
(Value::ByVal(PrimVal::Bytes(n)), &TyInt(i)) => write!(f, "{:?}{}", n as i128, i),
(Value::ByVal(PrimVal::Bytes(n)), &TyChar) =>
fn successors<'graph>(&'graph self, node: Self::Node)
-> <Self as GraphSuccessors<'graph>>::Iter
{
- self.basic_blocks[node].terminator().successors().into_owned().into_iter()
+ self.basic_blocks[node].terminator().successors().cloned()
}
}
impl<'a, 'b> GraphSuccessors<'b> for Mir<'a> {
type Item = BasicBlock;
- type Iter = IntoIter<BasicBlock>;
+ type Iter = iter::Cloned<Successors<'b>>;
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
}
},
Assert { ref cond, expected, ref msg, target, cleanup } => {
- let msg = if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
- AssertMessage::BoundsCheck {
+ let msg = if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
+ EvalErrorKind::BoundsCheck {
len: len.fold_with(folder),
index: index.fold_with(folder),
}
},
Assert { ref cond, ref msg, .. } => {
if cond.visit_with(visitor) {
- if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
+ if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
len.visit_with(visitor) || index.visit_with(visitor)
} else {
false
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::vec;
-
use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_vec::Idx;
let data = &self.mir[idx];
if let Some(ref term) = data.terminator {
- for &succ in term.successors().iter() {
+ for &succ in term.successors() {
self.worklist.push(succ);
}
}
pub struct Postorder<'a, 'tcx: 'a> {
mir: &'a Mir<'tcx>,
visited: BitVector,
- visit_stack: Vec<(BasicBlock, vec::IntoIter<BasicBlock>)>
+ visit_stack: Vec<(BasicBlock, Successors<'a>)>
}
impl<'a, 'tcx> Postorder<'a, 'tcx> {
if let Some(ref term) = data.terminator {
po.visited.insert(root.index());
-
- let succs = term.successors().into_owned().into_iter();
-
- po.visit_stack.push((root, succs));
+ po.visit_stack.push((root, term.successors()));
po.traverse_successor();
}
// two iterations yield `C` and finally `A` for a final traversal of [E, D, B, C, A]
loop {
let bb = if let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() {
- if let Some(bb) = iter.next() {
+ if let Some(&bb) = iter.next() {
bb
} else {
break;
if self.visited.insert(bb.index()) {
if let Some(ref term) = self.mir[bb].terminator {
- let succs = term.successors().into_owned().into_iter();
- self.visit_stack.push((bb, succs));
+ self.visit_stack.push((bb, term.successors()));
}
}
}
fn super_assert_message(&mut self,
msg: & $($mutability)* AssertMessage<'tcx>,
location: Location) {
- match *msg {
- AssertMessage::BoundsCheck {
+ use mir::interpret::EvalErrorKind::*;
+ if let BoundsCheck {
ref $($mutability)* len,
ref $($mutability)* index
- } => {
- self.visit_operand(len, location);
- self.visit_operand(index, location);
- }
- AssertMessage::Math(_) => {},
- AssertMessage::GeneratorResumedAfterReturn => {},
- AssertMessage::GeneratorResumedAfterPanic => {},
+ } = *msg {
+ self.visit_operand(len, location);
+ self.visit_operand(index, location);
}
}
2 = full debug info with variable and type information"),
opt_level: Option<String> = (None, parse_opt_string, [TRACKED],
"optimize with possible levels 0-3, s, or z"),
+ force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
+ "force use of the frame pointers"),
debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
"explicitly enable the cfg(debug_assertions) directive"),
inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
early_error(ErrorOutputType::default(), &msg)
}
- (meta_item.ident.name, meta_item.value_str())
+ (meta_item.name(), meta_item.value_str())
})
.collect::<ast::CrateConfig>()
}
opts.cg.debuginfo = Some(0xba5eba11);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
+ opts = reference.clone();
+ opts.cg.force_frame_pointers = Some(false);
+ assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
+
opts = reference.clone();
opts.cg.debug_assertions = Some(true);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
use middle::allocator::AllocatorKind;
use middle::dependency_format;
use session::search_paths::PathKind;
-use session::config::{DebugInfoLevel, OutputType};
+use session::config::{OutputType};
use ty::tls;
use util::nodemap::{FxHashSet};
use util::common::{duration_to_secs_str, ErrorReported};
}
pub fn must_not_eliminate_frame_pointers(&self) -> bool {
- self.opts.debuginfo != DebugInfoLevel::NoDebugInfo
- || !self.target.target.options.eliminate_frame_pointer
+ if let Some(x) = self.opts.cg.force_frame_pointers {
+ x
+ } else {
+ !self.target.target.options.eliminate_frame_pointer
+ }
}
/// Returns the symbol name for the registrar function,
for command in self.subcommands.iter().chain(Some(self)).rev() {
if let Some(ref condition) = command.condition {
if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
- options.contains(&(c.ident.name.as_str().to_string(),
+ options.contains(&(c.name().as_str().to_string(),
match c.value_str().map(|s| s.as_str().to_string()) {
Some(s) => Some(s),
None => None
let infcx = selcx.infcx();
infcx.commit_if_ok(|snapshot| {
let (skol_predicate, skol_map) =
- infcx.skolemize_late_bound_regions(&obligation.predicate, snapshot);
+ infcx.skolemize_late_bound_regions(&obligation.predicate);
let skol_obligation = obligation.with(skol_predicate);
let r = match project_and_unify_type(selcx, &skol_obligation) {
if let ConstVal::Unevaluated(def_id, substs) = constant.val {
let tcx = self.selcx.tcx().global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
- if substs.needs_infer() {
+ if substs.needs_infer() || substs.has_skol() {
let identity_substs = Substs::identity_for_item(tcx, def_id);
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
if let Some(instance) = instance {
if let ConstVal::Unevaluated(def_id, substs) = constant.val {
let tcx = self.infcx.tcx.global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
- if substs.needs_infer() {
+ if substs.needs_infer() || substs.has_skol() {
let identity_substs = Substs::identity_for_item(tcx, def_id);
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
if let Some(instance) = instance {
let poly_trait_predicate =
self.infcx().resolve_type_vars_if_possible(&obligation.predicate);
let (skol_trait_predicate, skol_map) =
- self.infcx().skolemize_late_bound_regions(&poly_trait_predicate, snapshot);
+ self.infcx().skolemize_late_bound_regions(&poly_trait_predicate);
debug!("match_projection_obligation_against_definition_bounds: \
skol_trait_predicate={:?} skol_map={:?}",
skol_trait_predicate,
self.in_snapshot(|this, snapshot| {
let (skol_ty, skol_map) =
- this.infcx().skolemize_late_bound_regions(&ty, snapshot);
+ this.infcx().skolemize_late_bound_regions(&ty);
let Normalized { value: normalized_ty, mut obligations } =
project::normalize_with_depth(this,
param_env,
let trait_obligations = self.in_snapshot(|this, snapshot| {
let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
let (trait_ref, skol_map) =
- this.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot);
+ this.infcx().skolemize_late_bound_regions(&poly_trait_ref);
let cause = obligation.derived_cause(ImplDerivedObligation);
this.impl_or_trait_obligations(cause,
obligation.recursion_depth + 1,
}
let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions(
- &obligation.predicate,
- snapshot);
+ &obligation.predicate);
let skol_obligation_trait_ref = skol_obligation.trait_ref;
let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span,
$alloc_method:ident,
$alloc_to_key:expr,
$alloc_to_ret:expr,
- $needs_infer:expr) -> $ty:ty) => {
+ $keep_in_local_tcx:expr) -> $ty:ty) => {
impl<'a, 'gcx, $lt_tcx> TyCtxt<'a, 'gcx, $lt_tcx> {
pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
{
// HACK(eddyb) Depend on flags being accurate to
// determine that all contents are in the global tcx.
// See comments on Lift for why we can't use that.
- if !($needs_infer)(&v) {
+ if !($keep_in_local_tcx)(&v) {
if !self.is_global() {
let v = unsafe {
mem::transmute(v)
}
macro_rules! direct_interners {
- ($lt_tcx:tt, $($name:ident: $method:ident($needs_infer:expr) -> $ty:ty),+) => {
+ ($lt_tcx:tt, $($name:ident: $method:ident($keep_in_local_tcx:expr) -> $ty:ty),+) => {
$(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
- intern_method!($lt_tcx, $name: $method($ty, alloc, |x| x, |x| x, $needs_infer) -> $ty);)+
+ intern_method!(
+ $lt_tcx,
+ $name: $method($ty, alloc, |x| x, |x| x, $keep_in_local_tcx) -> $ty
+ );)+
}
}
}
direct_interners!('tcx,
- region: mk_region(|r| {
- match r {
- &ty::ReVar(_) | &ty::ReSkolemized(..) => true,
- _ => false
- }
- }) -> RegionKind,
+ region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
const_: mk_const(|c: &Const| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>
);
fn needs_infer(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
}
+ fn has_skol(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_RE_SKOL)
+ }
fn needs_subst(&self) -> bool {
self.has_type_flags(TypeFlags::NEEDS_SUBST)
}
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
}
- fn is_normalized_for_trans(&self) -> bool {
- !self.has_type_flags(TypeFlags::HAS_RE_INFER |
- TypeFlags::HAS_FREE_REGIONS |
- TypeFlags::HAS_TY_INFER |
- TypeFlags::HAS_PARAMS |
- TypeFlags::HAS_NORMALIZABLE_PROJECTION |
- TypeFlags::HAS_TY_ERR |
- TypeFlags::HAS_SELF)
- }
/// Indicates whether this value references only 'global'
/// types/lifetimes that are the same regardless of what fn we are
/// in. This is used for caching. Errs on the side of returning
use std::fmt;
use std::i128;
use std::mem;
-use std::ops::RangeInclusive;
use ich::StableHashingContext;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
/// - For a slice, this is the length.
pub const FAT_PTR_EXTRA: usize = 1;
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
SizeOverflow(Ty<'tcx>)
ty::TyFloat(FloatTy::F64) => scalar(F64),
ty::TyFnPtr(_) => {
let mut ptr = scalar_unit(Pointer);
- ptr.valid_range.start = 1;
+ ptr.valid_range = 1..=*ptr.valid_range.end();
tcx.intern_layout(LayoutDetails::scalar(self, ptr))
}
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
let mut data_ptr = scalar_unit(Pointer);
if !ty.is_unsafe_ptr() {
- data_ptr.valid_range.start = 1;
+ data_ptr.valid_range = 1..=*data_ptr.valid_range.end();
}
let pointee = tcx.normalize_erasing_regions(param_env, pointee);
}
ty::TyDynamic(..) => {
let mut vtable = scalar_unit(Pointer);
- vtable.valid_range.start = 1;
+ vtable.valid_range = 1..=*vtable.valid_range.end();
vtable
}
_ => return Err(LayoutError::Unknown(unsized_part))
match st.abi {
Abi::Scalar(ref mut scalar) |
Abi::ScalarPair(ref mut scalar, _) => {
- if scalar.valid_range.start == 0 {
- scalar.valid_range.start = 1;
+ if *scalar.valid_range.start() == 0 {
+ scalar.valid_range = 1..=*scalar.valid_range.end();
}
}
_ => {}
}
}
}
- if niche_variants.start > v {
- niche_variants.start = v;
- }
- niche_variants.end = v;
+ niche_variants = *niche_variants.start().min(&v)..=v;
}
- if niche_variants.start > niche_variants.end {
+ if niche_variants.start() > niche_variants.end() {
dataful_variant = None;
}
if let Some(i) = dataful_variant {
- let count = (niche_variants.end - niche_variants.start + 1) as u128;
+ let count = (niche_variants.end() - niche_variants.start() + 1) as u128;
for (field_index, &field) in variants[i].iter().enumerate() {
let (offset, niche, niche_start) =
match self.find_niche(field, count)? {
// We increase the size of the discriminant to avoid LLVM copying
// padding when it doesn't need to. This normally causes unaligned
// load/stores and excessive memcpy/memset operations. By using a
- // bigger integer size, LLVM can be sure about it's contents and
+ // bigger integer size, LLVM can be sure about its contents and
// won't be so conservative.
// Use the initial field alignment
- let mut ity = Integer::for_abi_align(dl, start_align).unwrap_or(min_ity);
+ let mut ity = if def.repr.c() || def.repr.int.is_some() {
+ min_ity
+ } else {
+ Integer::for_abi_align(dl, start_align).unwrap_or(min_ity)
+ };
// If the alignment is not larger than the chosen discriminant size,
// don't use the alignment as the final size.
let max_value = !0u128 >> (128 - bits);
// Find out how many values are outside the valid range.
- let niches = if v.start <= v.end {
- v.start + (max_value - v.end)
+ let niches = if v.start() <= v.end() {
+ v.start() + (max_value - v.end())
} else {
- v.start - v.end - 1
+ v.start() - v.end() - 1
};
// Give up if we can't fit `count` consecutive niches.
return None;
}
- let niche_start = v.end.wrapping_add(1) & max_value;
- let niche_end = v.end.wrapping_add(count) & max_value;
+ let niche_start = v.end().wrapping_add(1) & max_value;
+ let niche_end = v.end().wrapping_add(count) & max_value;
Some((offset, Scalar {
value,
- valid_range: v.start..=niche_end
+ valid_range: *v.start()..=niche_end
}, niche_start))
};
}
NicheFilling {
dataful_variant,
- niche_variants: RangeInclusive { start, end },
+ ref niche_variants,
ref niche,
niche_start,
ref variants,
} => {
dataful_variant.hash_stable(hcx, hasher);
- start.hash_stable(hcx, hasher);
- end.hash_stable(hcx, hasher);
+ niche_variants.start().hash_stable(hcx, hasher);
+ niche_variants.end().hash_stable(hcx, hasher);
niche.hash_stable(hcx, hasher);
niche_start.hash_stable(hcx, hasher);
variants.hash_stable(hcx, hasher);
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
- let Scalar { value, valid_range: RangeInclusive { start, end } } = *self;
+ let Scalar { value, ref valid_range } = *self;
value.hash_stable(hcx, hasher);
- start.hash_stable(hcx, hasher);
- end.hash_stable(hcx, hasher);
+ valid_range.start().hash_stable(hcx, hasher);
+ valid_range.end().hash_stable(hcx, hasher);
}
}
pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const};
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
pub use self::sty::RegionKind;
-pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
+pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid};
pub use self::sty::BoundRegion::*;
pub use self::sty::InferTy::*;
pub use self::sty::RegionKind::*;
/// type name in a non-zero universe is a skolemized type -- an
/// idealized representative of "types in general" that we use for
/// checking generic functions.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct UniverseIndex(u32);
impl UniverseIndex {
/// The root universe, where things that the user defined are
/// visible.
- pub fn root() -> UniverseIndex {
- UniverseIndex(0)
- }
+ pub const ROOT: Self = UniverseIndex(0);
/// A "subuniverse" corresponds to being inside a `forall` quantifier.
/// So, for example, suppose we have this type in universe `U`:
/// region `'a`, but that region was not nameable from `U` because
/// it was not in scope there.
pub fn subuniverse(self) -> UniverseIndex {
- UniverseIndex(self.0 + 1)
+ UniverseIndex(self.0.checked_add(1).unwrap())
+ }
+
+ pub fn as_u32(&self) -> u32 {
+ self.0
+ }
+
+ pub fn as_usize(&self) -> usize {
+ self.0 as usize
+ }
+}
+
+impl From<u32> for UniverseIndex {
+ fn from(index: u32) -> Self {
+ UniverseIndex(index)
}
}
}
Reveal::All => {
- if value.needs_infer() || value.has_param_types() || value.has_self_ty() {
+ if value.has_skol()
+ || value.needs_infer()
+ || value.has_param_types()
+ || value.has_self_ty()
+ {
ParamEnvAnd {
param_env: self,
value,
impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
type Lifted = interpret::EvalError<'tcx>;
+ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+ Some(interpret::EvalError {
+ kind: tcx.lift(&self.kind)?,
+ backtrace: self.backtrace.clone(),
+ })
+ }
+}
+
+impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
+ type Lifted = interpret::EvalErrorKind<'tcx, <O as Lift<'tcx>>::Lifted>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
use ::mir::interpret::EvalErrorKind::*;
- let kind = match self.kind {
+ Some(match *self {
MachineError(ref err) => MachineError(err.clone()),
FunctionPointerTyMismatch(a, b) => FunctionPointerTyMismatch(
tcx.lift(&a)?,
Unimplemented(ref s) => Unimplemented(s.clone()),
DerefFunctionPointer => DerefFunctionPointer,
ExecuteMemory => ExecuteMemory,
- ArrayIndexOutOfBounds(sp, a, b) => ArrayIndexOutOfBounds(sp, a, b),
- Math(sp, ref err) => Math(sp, err.clone()),
+ BoundsCheck { ref len, ref index } => BoundsCheck {
+ len: tcx.lift(len)?,
+ index: tcx.lift(index)?,
+ },
Intrinsic(ref s) => Intrinsic(s.clone()),
- OverflowingMath => OverflowingMath,
InvalidChar(c) => InvalidChar(c),
StackFrameLimitReached => StackFrameLimitReached,
OutOfTls => OutOfTls,
UnimplementedTraitSelection => UnimplementedTraitSelection,
TypeckError => TypeckError,
ReferencedConstant => ReferencedConstant,
- };
- Some(interpret::EvalError {
- kind: kind,
- backtrace: self.backtrace.clone(),
+ OverflowNeg => OverflowNeg,
+ Overflow(op) => Overflow(op),
+ DivisionByZero => DivisionByZero,
+ RemainderByZero => RemainderByZero,
+ GeneratorResumedAfterReturn => GeneratorResumedAfterReturn,
+ GeneratorResumedAfterPanic => GeneratorResumedAfterPanic,
})
}
}
NonConstPath => NonConstPath,
UnimplementedConstVal(s) => UnimplementedConstVal(s),
IndexOutOfBounds { len, index } => IndexOutOfBounds { len, index },
- Math(ref e) => Math(e.clone()),
LayoutError(ref e) => {
return tcx.lift(e).map(LayoutError)
/// A skolemized region - basically the higher-ranked version of ReFree.
/// Should not exist after typeck.
- ReSkolemized(SkolemizedRegionVid, BoundRegion),
+ ReSkolemized(ty::UniverseIndex, BoundRegion),
/// Empty lifetime is for data that is never accessed.
/// Bottom in the region lattice. We treat ReEmpty somewhat
DEBUG_FORMAT = custom,
});
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
-pub struct SkolemizedRegionVid {
- pub index: u32,
-}
-
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum InferTy {
TyVar(TyVid),
}
}
- pub fn needs_infer(&self) -> bool {
- match *self {
- ty::ReVar(..) | ty::ReSkolemized(..) => true,
- _ => false
- }
- }
-
pub fn escapes_depth(&self, depth: u32) -> bool {
match *self {
ty::ReLateBound(debruijn, _) => debruijn.depth > depth,
}
}
+ pub fn keep_in_local_tcx(&self) -> bool {
+ if let ty::ReVar(..) = self {
+ true
+ } else {
+ false
+ }
+ }
+
pub fn type_flags(&self) -> TypeFlags {
let mut flags = TypeFlags::empty();
+ if self.keep_in_local_tcx() {
+ flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
+ }
+
match *self {
ty::ReVar(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_RE_INFER;
- flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
}
ty::ReSkolemized(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
- flags = flags | TypeFlags::HAS_RE_INFER;
flags = flags | TypeFlags::HAS_RE_SKOL;
- flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
}
ty::ReLateBound(..) => { }
ty::ReEarlyBound(..) => {
write!(f, "'?{}", c.index())
}
- ty::ReSkolemized(id, ref bound_region) => {
- write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
+ ty::ReSkolemized(universe, ref bound_region) => {
+ write!(f, "ReSkolemized({:?}, {:?})", universe, bound_region)
}
ty::ReEmpty => write!(f, "ReEmpty"),
pub struct DoubleFloat<F>(F, F);
pub type DoubleDouble = DoubleFloat<ieee::Double>;
-// These are legacy semantics for the Fallback, inaccrurate implementation of
+// These are legacy semantics for the Fallback, inaccurate implementation of
// IBM double-double, if the accurate DoubleDouble doesn't handle the
// operation. It's equivalent to having an IEEE number with consecutive 106
// bits of mantissa and 11 bits of exponent.
+++ /dev/null
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_const_math"
-version = "0.0.0"
-
-[lib]
-name = "rustc_const_math"
-path = "lib.rs"
-crate-type = ["dylib"]
-
-[dependencies]
-rustc_apfloat = { path = "../librustc_apfloat" }
-serialize = { path = "../libserialize" }
-syntax = { path = "../libsyntax" }
+++ /dev/null
-// Copyright 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;
-
-#[derive(Debug, PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
-pub enum ConstMathErr {
- NotInRange,
- CmpBetweenUnequalTypes,
- UnequalTypes(Op),
- Overflow(Op),
- ShiftNegative,
- DivisionByZero,
- RemainderByZero,
- UnsignedNegation,
- ULitOutOfRange(ast::UintTy),
- LitOutOfRange(ast::IntTy),
-}
-pub use self::ConstMathErr::*;
-
-#[derive(Debug, PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
-pub enum Op {
- Add,
- Sub,
- Mul,
- Div,
- Rem,
- Shr,
- Shl,
- Neg,
- BitAnd,
- BitOr,
- BitXor,
-}
-
-impl ConstMathErr {
- pub fn description(&self) -> &'static str {
- use self::Op::*;
- match *self {
- NotInRange => "inferred value out of range",
- CmpBetweenUnequalTypes => "compared two values of different types",
- UnequalTypes(Add) => "tried to add two values of different types",
- UnequalTypes(Sub) => "tried to subtract two values of different types",
- UnequalTypes(Mul) => "tried to multiply two values of different types",
- UnequalTypes(Div) => "tried to divide two values of different types",
- UnequalTypes(Rem) => {
- "tried to calculate the remainder of two values of different types"
- },
- UnequalTypes(BitAnd) => "tried to bitand two values of different types",
- UnequalTypes(BitOr) => "tried to bitor two values of different types",
- UnequalTypes(BitXor) => "tried to xor two values of different types",
- UnequalTypes(_) => unreachable!(),
- Overflow(Add) => "attempt to add with overflow",
- Overflow(Sub) => "attempt to subtract with overflow",
- Overflow(Mul) => "attempt to multiply with overflow",
- Overflow(Div) => "attempt to divide with overflow",
- Overflow(Rem) => "attempt to calculate the remainder with overflow",
- Overflow(Neg) => "attempt to negate with overflow",
- Overflow(Shr) => "attempt to shift right with overflow",
- Overflow(Shl) => "attempt to shift left with overflow",
- Overflow(_) => unreachable!(),
- ShiftNegative => "attempt to shift by a negative amount",
- DivisionByZero => "attempt to divide by zero",
- RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
- UnsignedNegation => "unary negation of unsigned integer",
- ULitOutOfRange(ast::UintTy::U8) => "literal out of range for u8",
- ULitOutOfRange(ast::UintTy::U16) => "literal out of range for u16",
- ULitOutOfRange(ast::UintTy::U32) => "literal out of range for u32",
- ULitOutOfRange(ast::UintTy::U64) => "literal out of range for u64",
- ULitOutOfRange(ast::UintTy::U128) => "literal out of range for u128",
- ULitOutOfRange(ast::UintTy::Usize) => "literal out of range for usize",
- LitOutOfRange(ast::IntTy::I8) => "literal out of range for i8",
- LitOutOfRange(ast::IntTy::I16) => "literal out of range for i16",
- LitOutOfRange(ast::IntTy::I32) => "literal out of range for i32",
- LitOutOfRange(ast::IntTy::I64) => "literal out of range for i64",
- LitOutOfRange(ast::IntTy::I128) => "literal out of range for i128",
- LitOutOfRange(ast::IntTy::Isize) => "literal out of range for isize",
- }
- }
-}
+++ /dev/null
-// Copyright 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 std::cmp::Ordering;
-use std::num::ParseFloatError;
-
-use syntax::ast;
-
-use rustc_apfloat::{Float, FloatConvert, Status};
-use rustc_apfloat::ieee::{Single, Double};
-
-use super::err::*;
-
-// Note that equality for `ConstFloat` means that the it is the same
-// constant, not that the rust values are equal. In particular, `NaN
-// == NaN` (at least if it's the same NaN; distinct encodings for NaN
-// are considering unequal).
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-pub struct ConstFloat {
- pub ty: ast::FloatTy,
-
- // This is a bit inefficient but it makes conversions below more
- // ergonomic, and all of this will go away once `miri` is merged.
- pub bits: u128,
-}
-
-impl ConstFloat {
- /// Description of the type, not the value
- pub fn description(&self) -> &'static str {
- self.ty.ty_to_string()
- }
-
- /// Compares the values if they are of the same type
- pub fn try_cmp(self, rhs: Self) -> Result<Ordering, ConstMathErr> {
- match (self.ty, rhs.ty) {
- (ast::FloatTy::F64, ast::FloatTy::F64) => {
- let a = Double::from_bits(self.bits);
- let b = Double::from_bits(rhs.bits);
- // This is pretty bad but it is the existing behavior.
- Ok(a.partial_cmp(&b).unwrap_or(Ordering::Greater))
- }
-
- (ast::FloatTy::F32, ast::FloatTy::F32) => {
- let a = Single::from_bits(self.bits);
- let b = Single::from_bits(rhs.bits);
- Ok(a.partial_cmp(&b).unwrap_or(Ordering::Greater))
- }
-
- _ => Err(CmpBetweenUnequalTypes),
- }
- }
-
- pub fn from_i128(input: i128, ty: ast::FloatTy) -> Self {
- let bits = match ty {
- ast::FloatTy::F32 => Single::from_i128(input).value.to_bits(),
- ast::FloatTy::F64 => Double::from_i128(input).value.to_bits()
- };
- ConstFloat { bits, ty }
- }
-
- pub fn from_u128(input: u128, ty: ast::FloatTy) -> Self {
- let bits = match ty {
- ast::FloatTy::F32 => Single::from_u128(input).value.to_bits(),
- ast::FloatTy::F64 => Double::from_u128(input).value.to_bits()
- };
- ConstFloat { bits, ty }
- }
-
- pub fn from_str(num: &str, ty: ast::FloatTy) -> Result<Self, ParseFloatError> {
- let bits = match ty {
- ast::FloatTy::F32 => {
- let rust_bits = num.parse::<f32>()?.to_bits() as u128;
- let apfloat = num.parse::<Single>().unwrap_or_else(|e| {
- panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e);
- });
- let apfloat_bits = apfloat.to_bits();
- assert!(rust_bits == apfloat_bits,
- "apfloat::ieee::Single gave different result for `{}`: \
- {}({:#x}) vs Rust's {}({:#x})",
- num, apfloat, apfloat_bits,
- Single::from_bits(rust_bits), rust_bits);
- apfloat_bits
- }
- ast::FloatTy::F64 => {
- let rust_bits = num.parse::<f64>()?.to_bits() as u128;
- let apfloat = num.parse::<Double>().unwrap_or_else(|e| {
- panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e);
- });
- let apfloat_bits = apfloat.to_bits();
- assert!(rust_bits == apfloat_bits,
- "apfloat::ieee::Double gave different result for `{}`: \
- {}({:#x}) vs Rust's {}({:#x})",
- num, apfloat, apfloat_bits,
- Double::from_bits(rust_bits), rust_bits);
- apfloat_bits
- }
- };
- Ok(ConstFloat { bits, ty })
- }
-
- pub fn to_i128(self, width: usize) -> Option<i128> {
- assert!(width <= 128);
- let r = match self.ty {
- ast::FloatTy::F32 => Single::from_bits(self.bits).to_i128(width),
- ast::FloatTy::F64 => Double::from_bits(self.bits).to_i128(width)
- };
- if r.status.intersects(Status::INVALID_OP) {
- None
- } else {
- Some(r.value)
- }
- }
-
- pub fn to_u128(self, width: usize) -> Option<u128> {
- assert!(width <= 128);
- let r = match self.ty {
- ast::FloatTy::F32 => Single::from_bits(self.bits).to_u128(width),
- ast::FloatTy::F64 => Double::from_bits(self.bits).to_u128(width)
- };
- if r.status.intersects(Status::INVALID_OP) {
- None
- } else {
- Some(r.value)
- }
- }
-
- pub fn convert(self, to: ast::FloatTy) -> Self {
- let bits = match (self.ty, to) {
- (ast::FloatTy::F32, ast::FloatTy::F32) |
- (ast::FloatTy::F64, ast::FloatTy::F64) => return self,
-
- (ast::FloatTy::F32, ast::FloatTy::F64) => {
- Double::to_bits(Single::from_bits(self.bits).convert(&mut false).value)
- }
- (ast::FloatTy::F64, ast::FloatTy::F32) => {
- Single::to_bits(Double::from_bits(self.bits).convert(&mut false).value)
- }
- };
- ConstFloat { bits, ty: to }
- }
-}
-
-impl ::std::fmt::Display for ConstFloat {
- fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
- match self.ty {
- ast::FloatTy::F32 => write!(fmt, "{:#}", Single::from_bits(self.bits))?,
- ast::FloatTy::F64 => write!(fmt, "{:#}", Double::from_bits(self.bits))?,
- }
- write!(fmt, "{}", self.ty)
- }
-}
-
-impl ::std::fmt::Debug for ConstFloat {
- fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
- ::std::fmt::Display::fmt(self, fmt)
- }
-}
-
-macro_rules! derive_binop {
- ($op:ident, $func:ident) => {
- impl ::std::ops::$op for ConstFloat {
- type Output = Result<Self, ConstMathErr>;
- fn $func(self, rhs: Self) -> Result<Self, ConstMathErr> {
- let bits = match (self.ty, rhs.ty) {
- (ast::FloatTy::F32, ast::FloatTy::F32) =>{
- let a = Single::from_bits(self.bits);
- let b = Single::from_bits(rhs.bits);
- a.$func(b).value.to_bits()
- }
- (ast::FloatTy::F64, ast::FloatTy::F64) => {
- let a = Double::from_bits(self.bits);
- let b = Double::from_bits(rhs.bits);
- a.$func(b).value.to_bits()
- }
- _ => return Err(UnequalTypes(Op::$op)),
- };
- Ok(ConstFloat { bits, ty: self.ty })
- }
- }
- }
-}
-
-derive_binop!(Add, add);
-derive_binop!(Sub, sub);
-derive_binop!(Mul, mul);
-derive_binop!(Div, div);
-derive_binop!(Rem, rem);
-
-impl ::std::ops::Neg for ConstFloat {
- type Output = Self;
- fn neg(self) -> Self {
- let bits = match self.ty {
- ast::FloatTy::F32 => (-Single::from_bits(self.bits)).to_bits(),
- ast::FloatTy::F64 => (-Double::from_bits(self.bits)).to_bits(),
- };
- ConstFloat { bits, ty: self.ty }
- }
-}
-
-/// This is `f32::MAX + (0.5 ULP)` as an integer. Numbers greater or equal to this
-/// are rounded to infinity when converted to `f32`.
-///
-/// NB: Computed as maximum significand with an extra 1 bit added (for the half ULP)
-/// shifted by the maximum exponent (accounting for normalization).
-pub const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
- << (Single::MAX_EXP - Single::PRECISION as i16);
+++ /dev/null
-// Copyright 2012-2013 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.
-
-//! Rusty Mathematics
-//!
-//! # Note
-//!
-//! This API is completely unstable and subject to change.
-
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
- html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
- html_root_url = "https://doc.rust-lang.org/nightly/")]
-
-extern crate rustc_apfloat;
-
-extern crate syntax;
-
-extern crate serialize as rustc_serialize; // used by deriving
-
-mod float;
-mod err;
-
-pub use float::*;
-pub use err::{ConstMathErr, Op};
let mut cfgs = Vec::new();
for &(name, ref value) in sess.parse_sess.config.iter() {
let gated_cfg = GatedCfg::gate(&ast::MetaItem {
- ident: ast::Ident::with_empty_ctxt(name),
+ ident: ast::Path::from_ident(name.to_ident()),
node: ast::MetaItemKind::Word,
span: DUMMY_SP,
});
for list_item in attr.meta_item_list().unwrap_or_default() {
match list_item.word() {
Some(word) if value.is_none() =>
- value = Some(word.ident.name),
+ value = Some(word.name()),
_ =>
// FIXME better-encapsulate meta_item (don't directly access `node`)
span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item.node),
impl EarlyLintPass for DeprecatedAttr {
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
- let name = unwrap_or!(attr.name(), return);
for &&(n, _, ref g) in &self.depr_attrs {
- if name == n {
+ if attr.name() == n {
if let &AttributeGate::Gated(Stability::Deprecated(link),
ref name,
ref reason,
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
-#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::ty;
use rustc::ty::adjustment;
let mut fn_warned = false;
let mut op_warned = false;
- if cx.tcx.features().fn_must_use {
- let maybe_def = match expr.node {
- hir::ExprCall(ref callee, _) => {
- match callee.node {
- hir::ExprPath(ref qpath) => {
- Some(cx.tables.qpath_def(qpath, callee.hir_id))
- },
- _ => None
- }
- },
- hir::ExprMethodCall(..) => {
- cx.tables.type_dependent_defs().get(expr.hir_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 ");
- }
- let must_use_op = match expr.node {
- // Hardcoding operators here seemed more expedient than the
- // refactoring that would be needed to look up the `#[must_use]`
- // attribute which does exist on the comparison trait methods
- hir::ExprBinary(bin_op, ..) => {
- match bin_op.node {
- hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => {
- Some("comparison")
- },
- hir::BiAdd | hir::BiSub | hir::BiDiv | hir::BiMul | hir::BiRem => {
- Some("arithmetic operation")
- },
- hir::BiAnd | hir::BiOr => {
- Some("logical operation")
- },
- hir::BiBitXor | hir::BiBitAnd | hir::BiBitOr | hir::BiShl | hir::BiShr => {
- Some("bitwise operation")
- },
- }
- },
- hir::ExprUnary(..) => Some("unary operation"),
- _ => None
- };
- if let Some(must_use_op) = must_use_op {
- cx.span_lint(UNUSED_MUST_USE, expr.span,
- &format!("unused {} which must be used", must_use_op));
- op_warned = true;
- }
+ let maybe_def = match expr.node {
+ hir::ExprCall(ref callee, _) => {
+ match callee.node {
+ hir::ExprPath(ref qpath) => {
+ let def = cx.tables.qpath_def(qpath, callee.hir_id);
+ if let Def::Fn(_) = def {
+ Some(def)
+ } else { // `Def::Local` if it was a closure, for which we
+ None // do not currently support must-use linting
+ }
+ },
+ _ => None
+ }
+ },
+ hir::ExprMethodCall(..) => {
+ cx.tables.type_dependent_defs().get(expr.hir_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 ");
}
+ let must_use_op = match expr.node {
+ // Hardcoding operators here seemed more expedient than the
+ // refactoring that would be needed to look up the `#[must_use]`
+ // attribute which does exist on the comparison trait methods
+ hir::ExprBinary(bin_op, ..) => {
+ match bin_op.node {
+ hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => {
+ Some("comparison")
+ },
+ hir::BiAdd | hir::BiSub | hir::BiDiv | hir::BiMul | hir::BiRem => {
+ Some("arithmetic operation")
+ },
+ hir::BiAnd | hir::BiOr => {
+ Some("logical operation")
+ },
+ hir::BiBitXor | hir::BiBitAnd | hir::BiBitOr | hir::BiShl | hir::BiShr => {
+ Some("bitwise operation")
+ },
+ }
+ },
+ hir::ExprUnary(..) => Some("unary operation"),
+ _ => None
+ };
+
+ if let Some(must_use_op) = must_use_op {
+ cx.span_lint(UNUSED_MUST_USE, expr.span,
+ &format!("unused {} which must be used", must_use_op));
+ op_warned = true;
+ }
+
if !(ty_warned || fn_warned || op_warned) {
cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
debug!("checking attribute: {:?}", attr);
- let name = unwrap_or!(attr.name(), return);
-
// Note that check_name() marks the attribute as used if it matches.
for &(ref name, ty, _) in BUILTIN_ATTRIBUTES {
match ty {
}
}
+ let name = attr.name();
if !attr::is_used(attr) {
debug!("Emitting warning for: {:?}", attr);
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
log_settings = "0.1.1"
rustc = { path = "../librustc" }
rustc_target = { path = "../librustc_target" }
-rustc_const_math = { path = "../librustc_const_math" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" }
serialize = { path = "../libserialize" }
use rustc::ty::{self, ParamEnv, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::lint::builtin::UNUSED_MUT;
-use rustc::mir::{AssertMessage, AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
+use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{ClearCrossCrate, Local, Location, Place, Mir, Mutability, Operand};
use rustc::mir::{Projection, ProjectionElem, Rvalue, Field, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind};
cleanup: _,
} => {
self.consume_operand(ContextKind::Assert.new(loc), (cond, span), flow_state);
- match *msg {
- AssertMessage::BoundsCheck { ref len, ref index } => {
- self.consume_operand(ContextKind::Assert.new(loc), (len, span), flow_state);
- self.consume_operand(
- ContextKind::Assert.new(loc),
- (index, span),
- flow_state,
- );
- }
- AssertMessage::Math(_ /*const_math_err*/) => {}
- AssertMessage::GeneratorResumedAfterReturn => {}
- AssertMessage::GeneratorResumedAfterPanic => {}
+ use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
+ if let BoundsCheck { ref len, ref index } = *msg {
+ self.consume_operand(ContextKind::Assert.new(loc), (len, span), flow_state);
+ self.consume_operand(
+ ContextKind::Assert.new(loc),
+ (index, span),
+ flow_state,
+ );
}
}
block_data
.terminator()
.successors()
- .iter()
.map(|&basic_block| Location {
statement_index: 0,
block: basic_block,
block_data
.terminator()
.successors()
- .iter()
.map(|&basic_block| Location {
statement_index: 0,
block: basic_block,
use rustc::infer::RegionVariableOrigin;
use rustc::infer::SubregionOrigin;
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
-use rustc::infer::region_constraints::{GenericKind, VarOrigins};
+use rustc::infer::region_constraints::{GenericKind, VarInfos};
use rustc::mir::{ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
Local, Location, Mir};
use rustc::traits::ObligationCause;
/// of those will be constant regions representing the free
/// regions defined in `universal_regions`.
pub(crate) fn new(
- var_origins: VarOrigins,
+ var_infos: VarInfos,
universal_regions: UniversalRegions<'tcx>,
mir: &Mir<'tcx>,
) -> Self {
- let num_region_variables = var_origins.len();
+ let num_region_variables = var_infos.len();
let num_universal_regions = universal_regions.len();
let elements = &Rc::new(RegionValueElements::new(mir, num_universal_regions));
// Create a RegionDefinition for each inference variable.
- let definitions = var_origins
+ let definitions = var_infos
.into_iter()
- .map(|origin| RegionDefinition::new(origin))
+ .map(|info| RegionDefinition::new(info.origin))
.collect();
let mut result = Self {
use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
use rustc::mir::tcx::PlaceTy;
use rustc::mir::visit::{PlaceContext, Visitor};
+use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
use rustc::mir::*;
use rustc::traits::query::NoSolution;
use rustc::traits::{self, Normalized, TraitEngine};
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
}
- if let AssertMessage::BoundsCheck { ref len, ref index } = *msg {
+ if let BoundsCheck { ref len, ref index } = *msg {
if len.ty(mir, tcx) != tcx.types.usize {
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
}
use build::expr::category::Category;
use hair::*;
use rustc::mir::*;
+use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
use rustc_data_structures::indexed_vec::Idx;
Operand::Copy(Place::Local(idx)),
Operand::Copy(len.clone())));
- let msg = AssertMessage::BoundsCheck {
+ let msg = BoundsCheck {
len: Operand::Move(len),
index: Operand::Copy(Place::Local(idx))
};
//! See docs in build/expr/mod.rs
-use rustc_const_math::{ConstMathErr, Op};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use rustc::middle::region;
use rustc::ty::{self, Ty};
use rustc::mir::*;
-use rustc::mir::interpret::{Value, PrimVal};
+use rustc::mir::interpret::{Value, PrimVal, EvalErrorKind};
use syntax_pos::Span;
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.cfg.push_assign(block, source_info, &is_min,
Rvalue::BinaryOp(BinOp::Eq, arg.to_copy(), minval));
- let err = ConstMathErr::Overflow(Op::Neg);
block = this.assert(block, Operand::Move(is_min), false,
- AssertMessage::Math(err), expr_span);
+ EvalErrorKind::OverflowNeg, expr_span);
}
block.and(Rvalue::UnaryOp(op, arg))
}
let val = result_value.clone().field(val_fld, ty);
let of = result_value.field(of_fld, bool_ty);
- let err = ConstMathErr::Overflow(match op {
- BinOp::Add => Op::Add,
- BinOp::Sub => Op::Sub,
- BinOp::Mul => Op::Mul,
- BinOp::Shl => Op::Shl,
- BinOp::Shr => Op::Shr,
- _ => {
- bug!("MIR build_binary_op: {:?} is not checkable", op)
- }
- });
+ let err = EvalErrorKind::Overflow(op);
block = self.assert(block, Operand::Move(of), false,
- AssertMessage::Math(err), span);
+ err, span);
block.and(Rvalue::Use(Operand::Move(val)))
} else {
// and 2. there are two possible failure cases, divide-by-zero and overflow.
let (zero_err, overflow_err) = if op == BinOp::Div {
- (ConstMathErr::DivisionByZero,
- ConstMathErr::Overflow(Op::Div))
+ (EvalErrorKind::DivisionByZero,
+ EvalErrorKind::Overflow(op))
} else {
- (ConstMathErr::RemainderByZero,
- ConstMathErr::Overflow(Op::Rem))
+ (EvalErrorKind::RemainderByZero,
+ EvalErrorKind::Overflow(op))
};
// Check for / 0
Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), zero));
block = self.assert(block, Operand::Move(is_zero), false,
- AssertMessage::Math(zero_err), span);
+ zero_err, span);
// We only need to check for the overflow in one case:
// MIN / -1, and only for signed values.
Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min));
block = self.assert(block, Operand::Move(of), false,
- AssertMessage::Math(overflow_err), span);
+ overflow_err, span);
}
}
pub struct Edge { source: BasicBlock, index: usize }
fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec<Edge> {
- let succ_len = mir[bb].terminator().successors().len();
- (0..succ_len).map(|index| Edge { source: bb, index: index}).collect()
+ mir[bb].terminator().successors().enumerate()
+ .map(|(index, _)| Edge { source: bb, index: index}).collect()
}
impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
fn target(&self, edge: &Edge) -> Node {
let mir = self.mbcx.mir();
- mir[edge.source].terminator().successors()[edge.index]
+ *mir[edge.source].terminator().successors().nth(edge.index).unwrap()
}
}
use syntax::attr;
use syntax::symbol::Symbol;
use rustc::hir;
-use rustc_const_math::ConstFloat;
use rustc_data_structures::sync::Lrc;
use rustc::mir::interpret::{Value, PrimVal};
+use hair::pattern::parse_float;
#[derive(Clone)]
pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
neg: bool,
) -> Literal<'tcx> {
trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);
- let tcx = self.tcx.global_tcx();
- let parse_float = |num: &str, fty| -> ConstFloat {
- ConstFloat::from_str(num, fty).unwrap_or_else(|_| {
+ let parse_float = |num, fty| -> Value {
+ parse_float(num, fty, neg).unwrap_or_else(|_| {
// FIXME(#31407) this is only necessary because float parsing is buggy
- tcx.sess.span_fatal(sp, "could not evaluate float literal (see issue #31407)");
+ self.tcx.sess.span_fatal(sp, "could not evaluate float literal (see issue #31407)");
})
};
},
LitKind::Int(n, _) => Value::ByVal(PrimVal::Bytes(clamp(n))),
LitKind::Float(n, fty) => {
- let n = n.as_str();
- let mut f = parse_float(&n, fty);
- if neg {
- f = -f;
- }
- let bits = f.bits;
- Value::ByVal(PrimVal::Bytes(bits))
+ parse_float(n, fty)
}
LitKind::FloatUnsuffixed(n) => {
let fty = match ty.sty {
ty::TyFloat(fty) => fty,
_ => bug!()
};
- let n = n.as_str();
- let mut f = parse_float(&n, fty);
- if neg {
- f = -f;
- }
- let bits = f.bits;
- Value::ByVal(PrimVal::Bytes(bits))
+ parse_float(n, fty)
}
LitKind::Bool(b) => Value::ByVal(PrimVal::Bytes(b as u128)),
LitKind::Char(c) => Value::ByVal(PrimVal::Bytes(c as u128)),
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
use rustc_data_structures::indexed_vec::Idx;
-use rustc_const_math::ConstFloat;
use std::cmp::Ordering;
use std::fmt;
use syntax::ast;
use syntax::ptr::P;
use syntax_pos::Span;
+use syntax_pos::symbol::Symbol;
#[derive(Clone, Debug)]
pub enum PatternError {
ConstVal::Value(miri) => const_val_field(
self.tcx, self.param_env, instance,
variant_opt, field, miri, cv.ty,
- ).unwrap(),
+ ).expect("field access failed"),
_ => bug!("{:#?} is not a valid adt", cv),
};
self.const_to_pat(instance, val, id, span)
b: &ConstVal,
ty: Ty<'tcx>,
) -> Option<Ordering> {
- use rustc_const_math::ConstFloat;
trace!("compare_const_vals: {:?}, {:?}", a, b);
use rustc::mir::interpret::{Value, PrimVal};
match (a, b) {
(&ConstVal::Value(Value::ByVal(PrimVal::Bytes(a))),
&ConstVal::Value(Value::ByVal(PrimVal::Bytes(b)))) => {
+ use ::rustc_apfloat::Float;
match ty.sty {
- ty::TyFloat(ty) => {
- let l = ConstFloat {
- bits: a,
- ty,
- };
- let r = ConstFloat {
- bits: b,
- ty,
- };
- // FIXME(oli-obk): report cmp errors?
- l.try_cmp(r).ok()
+ ty::TyFloat(ast::FloatTy::F32) => {
+ let l = ::rustc_apfloat::ieee::Single::from_bits(a);
+ let r = ::rustc_apfloat::ieee::Single::from_bits(b);
+ l.partial_cmp(&r)
+ },
+ ty::TyFloat(ast::FloatTy::F64) => {
+ let l = ::rustc_apfloat::ieee::Double::from_bits(a);
+ let r = ::rustc_apfloat::ieee::Double::from_bits(b);
+ l.partial_cmp(&r)
},
ty::TyInt(_) => {
let a = interpret::sign_extend(tcx, a, ty).expect("layout error for TyInt");
Value::ByVal(PrimVal::Bytes(n))
},
LitKind::Float(n, fty) => {
- let n = n.as_str();
- let mut f = parse_float(&n, fty)?;
- if neg {
- f = -f;
- }
- let bits = f.bits;
- Value::ByVal(PrimVal::Bytes(bits))
+ parse_float(n, fty, neg)?
}
LitKind::FloatUnsuffixed(n) => {
let fty = match ty.sty {
ty::TyFloat(fty) => fty,
_ => bug!()
};
- let n = n.as_str();
- let mut f = parse_float(&n, fty)?;
- if neg {
- f = -f;
- }
- let bits = f.bits;
- Value::ByVal(PrimVal::Bytes(bits))
+ parse_float(n, fty, neg)?
}
LitKind::Bool(b) => Value::ByVal(PrimVal::Bytes(b as u128)),
LitKind::Char(c) => Value::ByVal(PrimVal::Bytes(c as u128)),
Ok(ConstVal::Value(lit))
}
-fn parse_float<'tcx>(num: &str, fty: ast::FloatTy)
- -> Result<ConstFloat, ()> {
- ConstFloat::from_str(num, fty).map_err(|_| ())
+pub fn parse_float(
+ num: Symbol,
+ fty: ast::FloatTy,
+ neg: bool,
+) -> Result<Value, ()> {
+ let num = num.as_str();
+ use rustc_apfloat::ieee::{Single, Double};
+ use rustc_apfloat::Float;
+ let bits = match fty {
+ ast::FloatTy::F32 => {
+ num.parse::<f32>().map_err(|_| ())?;
+ let mut f = num.parse::<Single>().unwrap_or_else(|e| {
+ panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
+ });
+ if neg {
+ f = -f;
+ }
+ f.to_bits()
+ }
+ ast::FloatTy::F64 => {
+ num.parse::<f64>().map_err(|_| ())?;
+ let mut f = num.parse::<Double>().unwrap_or_else(|e| {
+ panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
+ });
+ if neg {
+ f = -f;
+ }
+ f.to_bits()
+ }
+ };
+
+ Ok(Value::ByVal(PrimVal::Bytes(bits)))
}
use rustc::ty::layout::LayoutOf;
use syntax::ast::{FloatTy, IntTy, UintTy};
-use rustc_const_math::ConstFloat;
+use rustc_apfloat::ieee::{Single, Double};
use super::{EvalContext, Machine};
use rustc::mir::interpret::{PrimVal, EvalResult, MemoryPointer, PointerArithmetic};
-use rustc_apfloat::ieee::{Single, Double};
use rustc_apfloat::Float;
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
Ok(PrimVal::Bytes(v))
}
- TyFloat(fty) if signed => Ok(PrimVal::Bytes(ConstFloat::from_i128(v as i128, fty).bits)),
- TyFloat(fty) => Ok(PrimVal::Bytes(ConstFloat::from_u128(v, fty).bits)),
+ TyFloat(FloatTy::F32) if signed => Ok(PrimVal::Bytes(Single::from_i128(v as i128).value.to_bits())),
+ TyFloat(FloatTy::F64) if signed => Ok(PrimVal::Bytes(Double::from_i128(v as i128).value.to_bits())),
+ TyFloat(FloatTy::F32) => Ok(PrimVal::Bytes(Single::from_u128(v).value.to_bits())),
+ TyFloat(FloatTy::F64) => Ok(PrimVal::Bytes(Double::from_u128(v).value.to_bits())),
TyChar if v as u8 as u128 == v => Ok(PrimVal::Bytes(v)),
TyChar => err!(InvalidChar(v)),
// it emits in debug mode) is performance, but it doesn't cost us any performance in miri.
// If, however, the compiler ever starts transforming unchecked intrinsics into unchecked binops,
// we have to go back to just ignoring the overflow here.
- return err!(OverflowingMath);
+ return err!(Overflow(bin_op));
}
}
niche_start,
..
} => {
- let variants_start = niche_variants.start as u128;
- let variants_end = niche_variants.end as u128;
+ let variants_start = *niche_variants.start() as u128;
+ let variants_end = *niche_variants.end() as u128;
match raw_discr {
PrimVal::Ptr(_) => {
assert!(niche_start == 0);
if variant_index != dataful_variant {
let (niche_dest, niche) =
self.place_field(dest, mir::Field::new(0), layout)?;
- let niche_value = ((variant_index - niche_variants.start) as u128)
+ let niche_value = ((variant_index - niche_variants.start()) as u128)
.wrapping_add(niche_start);
self.write_primval(niche_dest, PrimVal::Bytes(niche_value), niche.ty)?;
}
use syntax::ast::FloatTy;
let layout = self.layout_of(ty)?;
- // do the strongest layout check of the two
- let align = layout.align.max(ptr_align);
- self.memory.check_align(ptr, align)?;
+ self.memory.check_align(ptr, ptr_align)?;
if layout.size.bytes() == 0 {
return Ok(Some(Value::ByVal(PrimVal::Undef)));
use rustc::mir;
use rustc::ty::{self, Ty};
-use rustc_const_math::ConstFloat;
use syntax::ast::FloatTy;
use std::cmp::Ordering;
use rustc::ty::layout::LayoutOf;
+use rustc_apfloat::ieee::{Double, Single};
+use rustc_apfloat::Float;
use super::{EvalContext, Place, Machine, ValTy};
return err!(Unimplemented(msg));
}
- let float_op = |op, l, r, ty| {
- let l = ConstFloat {
- bits: l,
- ty,
- };
- let r = ConstFloat {
- bits: r,
- ty,
- };
- match op {
- Eq => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Equal),
- Ne => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Equal),
- Lt => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Less),
- Le => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Greater),
- Gt => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Greater),
- Ge => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Less),
- Add => PrimVal::Bytes((l + r).unwrap().bits),
- Sub => PrimVal::Bytes((l - r).unwrap().bits),
- Mul => PrimVal::Bytes((l * r).unwrap().bits),
- Div => PrimVal::Bytes((l / r).unwrap().bits),
- Rem => PrimVal::Bytes((l % r).unwrap().bits),
- _ => bug!("invalid float op: `{:?}`", op),
- }
- };
-
if left_layout.abi.is_signed() {
let op: Option<fn(&i128, &i128) -> bool> = match bin_op {
Lt => Some(i128::lt),
return Ok((PrimVal::from_bool(op(&l, &r)), false));
}
let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
- Rem | Div if r == 0 => return Ok((PrimVal::Bytes(l), true)),
+ Div if r == 0 => return err!(DivisionByZero),
+ Rem if r == 0 => return err!(RemainderByZero),
Div => Some(i128::overflowing_div),
Rem => Some(i128::overflowing_rem),
Add => Some(i128::overflowing_add),
}
if let ty::TyFloat(fty) = left_ty.sty {
- return Ok((float_op(bin_op, l, r, fty), false));
+ macro_rules! float_math {
+ ($ty:path) => {{
+ let l = <$ty>::from_bits(l);
+ let r = <$ty>::from_bits(r);
+ let val = match bin_op {
+ Eq => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Equal),
+ Ne => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Equal),
+ Lt => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Less),
+ Le => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Greater),
+ Gt => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Greater),
+ Ge => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Less),
+ Add => PrimVal::Bytes((l + r).value.to_bits()),
+ Sub => PrimVal::Bytes((l - r).value.to_bits()),
+ Mul => PrimVal::Bytes((l * r).value.to_bits()),
+ Div => PrimVal::Bytes((l / r).value.to_bits()),
+ Rem => PrimVal::Bytes((l % r).value.to_bits()),
+ _ => bug!("invalid float op: `{:?}`", bin_op),
+ };
+ return Ok((val, false));
+ }};
+ }
+ match fty {
+ FloatTy::F32 => float_math!(Single),
+ FloatTy::F64 => float_math!(Double),
+ }
}
// only ints left
Add => u128::overflowing_add,
Sub => u128::overflowing_sub,
Mul => u128::overflowing_mul,
- Rem | Div if r == 0 => return Ok((PrimVal::Bytes(l), true)),
+ Div if r == 0 => return err!(DivisionByZero),
+ Rem if r == 0 => return err!(RemainderByZero),
Div => u128::overflowing_div,
Rem => u128::overflowing_rem,
_ => bug!(),
(Neg, ty::TyFloat(FloatTy::F32)) => Single::to_bits(-Single::from_bits(bytes)),
(Neg, ty::TyFloat(FloatTy::F64)) => Double::to_bits(-Double::from_bits(bytes)),
- (Neg, _) if bytes == (1 << (size - 1)) => return err!(OverflowingMath),
+ (Neg, _) if bytes == (1 << (size - 1)) => return err!(OverflowNeg),
(Neg, _) => (-(bytes as i128)) as u128,
};
if expected == cond_val {
self.goto_block(target);
} else {
- use rustc::mir::AssertMessage::*;
+ use rustc::mir::interpret::EvalErrorKind::*;
return match *msg {
BoundsCheck { ref len, ref index } => {
- let span = terminator.source_info.span;
let len = self.eval_operand_to_primval(len)
.expect("can't eval len")
.to_u64()?;
let index = self.eval_operand_to_primval(index)
.expect("can't eval index")
.to_u64()?;
- err!(ArrayIndexOutOfBounds(span, len, index))
- }
- Math(ref err) => {
- err!(Math(terminator.source_info.span, err.clone()))
+ err!(BoundsCheck { len, index })
}
+ Overflow(op) => Err(Overflow(op).into()),
+ OverflowNeg => Err(OverflowNeg.into()),
+ DivisionByZero => Err(DivisionByZero.into()),
+ RemainderByZero => Err(RemainderByZero.into()),
GeneratorResumedAfterReturn |
GeneratorResumedAfterPanic => unimplemented!(),
+ _ => bug!(),
};
}
}
#![feature(range_contains)]
#![feature(rustc_diagnostic_macros)]
#![feature(nonzero)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
#![feature(crate_visibility_modifier)]
#![feature(never_type)]
#![cfg_attr(stage0, feature(try_trait))]
extern crate syntax;
extern crate syntax_pos;
extern crate rustc_target;
-extern crate rustc_const_math;
-extern crate core; // for NonZero
extern crate log_settings;
extern crate rustc_apfloat;
extern crate byteorder;
} else {
if overflow {
use rustc::mir::interpret::EvalErrorKind;
- let mut err = EvalErrorKind::OverflowingMath.into();
+ let mut err = EvalErrorKind::Overflow(op).into();
ecx.report(&mut err, false, Some(span));
return None;
}
.hir
.as_local_node_id(self.source.def_id)
.expect("some part of a failing const eval must be local");
- use rustc::mir::AssertMessage::*;
+ use rustc::mir::interpret::EvalErrorKind::*;
let msg = match msg {
- // Need proper const propagator for these
- GeneratorResumedAfterReturn |
- GeneratorResumedAfterPanic => return,
- Math(ref err) => err.description().to_owned(),
+ Overflow(_) |
+ OverflowNeg |
+ DivisionByZero |
+ RemainderByZero => msg.description().to_owned(),
BoundsCheck { ref len, ref index } => {
let len = self.eval_operand(len).expect("len must be const");
let len = match len.0 {
index,
)
},
+ // Need proper const propagator for these
+ _ => return,
};
self.tcx.lint_node(
::rustc::lint::builtin::CONST_ERR,
//! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the
//! future.
-use rustc::hir;
use rustc::mir::{Constant, Local, LocalKind, Location, Place, Mir, Operand, Rvalue, StatementKind};
use rustc::mir::visit::MutVisitor;
use rustc::ty::TyCtxt;
impl MirPass for CopyPropagation {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- source: MirSource,
+ _source: MirSource,
mir: &mut Mir<'tcx>) {
- // Don't run on constant MIR, because trans might not be able to
- // evaluate the modified MIR.
- // FIXME(eddyb) Remove check after miri is merged.
- let id = tcx.hir.as_local_node_id(source.def_id).unwrap();
- match (tcx.hir.body_owner_kind(id), source.promoted) {
- (_, Some(_)) |
- (hir::BodyOwnerKind::Const, _) |
- (hir::BodyOwnerKind::Static(_), _) => return,
-
- (hir::BodyOwnerKind::Fn, _) => {
- if tcx.is_const_fn(source.def_id) {
- // Don't run on const functions, as, again, trans might not be able to evaluate
- // the optimized IR.
- return
- }
- }
- }
-
// We only run when the MIR optimization level is > 1.
// This avoids a slow pass, and messing up debug info.
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use rustc::hir;
use rustc::ty::TyCtxt;
use rustc::mir::*;
use rustc_data_structures::indexed_vec::Idx;
impl MirPass for Deaggregator {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- source: MirSource,
+ _source: MirSource,
mir: &mut Mir<'tcx>) {
- // Don't run on constant MIR, because trans might not be able to
- // evaluate the modified MIR.
- // FIXME(eddyb) Remove check after miri is merged.
- let id = tcx.hir.as_local_node_id(source.def_id).unwrap();
- match (tcx.hir.body_owner_kind(id), source.promoted) {
- (_, Some(_)) |
- (hir::BodyOwnerKind::Const, _) |
- (hir::BodyOwnerKind::Static(_), _) => return,
-
- (hir::BodyOwnerKind::Fn, _) => {
- if tcx.is_const_fn(source.def_id) {
- // Don't run on const functions, as, again, trans might not be able to evaluate
- // the optimized IR.
- return
- }
- }
- }
-
let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
let local_decls = &*local_decls;
for bb in basic_blocks {
use dataflow::{drop_flag_effects_for_location, on_lookup_result_bits};
use dataflow::MoveDataParamEnv;
use dataflow::{self, do_dataflow, DebugFormatted};
-use rustc::hir;
use rustc::ty::{self, TyCtxt};
use rustc::mir::*;
use rustc::middle::const_val::ConstVal;
{
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
- // Don't run on constant MIR, because trans might not be able to
- // evaluate the modified MIR.
- // FIXME(eddyb) Remove check after miri is merged.
let id = tcx.hir.as_local_node_id(src.def_id).unwrap();
- match (tcx.hir.body_owner_kind(id), src.promoted) {
- (hir::BodyOwnerKind::Fn, None) => {},
- _ => return
- }
let param_env = tcx.param_env(src.def_id).with_reveal_all();
let move_data = MoveData::gather_moves(mir, tcx).unwrap();
let elaborate_patch = {
let mut cases = create_cases(mir, &transform, |point| Some(point.resume));
+ use rustc::mir::interpret::EvalErrorKind::{
+ GeneratorResumedAfterPanic,
+ GeneratorResumedAfterReturn,
+ };
+
// Jump to the entry point on the 0 state
cases.insert(0, (0, BasicBlock::new(0)));
// Panic when resumed on the returned (1) state
- cases.insert(1, (1, insert_panic_block(tcx, mir, AssertMessage::GeneratorResumedAfterReturn)));
+ cases.insert(1, (1, insert_panic_block(tcx, mir, GeneratorResumedAfterReturn)));
// Panic when resumed on the poisoned (2) state
- cases.insert(2, (2, insert_panic_block(tcx, mir, AssertMessage::GeneratorResumedAfterPanic)));
+ cases.insert(2, (2, insert_panic_block(tcx, mir, GeneratorResumedAfterPanic)));
insert_switch(tcx, mir, cases, &transform, TerminatorKind::Unreachable);
}
if !is_drop {
- for &succ in &term.successors()[..] {
+ for &succ in term.successors() {
work_list.push(succ);
}
}
TerminatorKind::SwitchInt { .. } |
TerminatorKind::FalseEdges { .. } |
TerminatorKind::FalseUnwind { .. } => {
- terminator.successors().iter().all(|succ| {
+ terminator.successors().all(|succ| {
nop_landing_pads.contains(succ.index())
})
},
for (_, data) in traversal::preorder(mir) {
if let Some(ref term) = data.terminator {
- for &tgt in term.successors().iter() {
+ for &tgt in term.successors() {
pred_count[tgt] += 1;
}
}
};
let first_succ = {
- let successors = terminator.successors();
- if let Some(&first_succ) = terminator.successors().get(0) {
- if successors.iter().all(|s| *s == first_succ) {
- self.pred_count[first_succ] -= (successors.len()-1) as u32;
+ if let Some(&first_succ) = terminator.successors().nth(0) {
+ if terminator.successors().all(|s| *s == first_succ) {
+ let count = terminator.successors().count();
+ self.pred_count[first_succ] -= (count - 1) as u32;
first_succ
} else {
return false
let terminator = mir[source].terminator();
let labels = terminator.kind.fmt_successor_labels();
- for (&target, label) in terminator.successors().iter().zip(labels) {
+ for (&target, label) in terminator.successors().zip(labels) {
writeln!(w, r#" {} -> {} [label="{}"];"#, node(source), node(target), label)?;
}
for b in mir.basic_blocks().indices().rev() {
// outs[b] = ∪ {ins of successors}
bits.clear();
- for &successor in mir.basic_blocks()[b].terminator().successors().into_iter() {
+ for &successor in mir.basic_blocks()[b].terminator().successors() {
bits.union(&ins[successor]);
}
outs[b].clone_from(&bits);
log = "0.4"
rustc = { path = "../librustc" }
rustc_mir = { path = "../librustc_mir"}
-rustc_const_math = { path = "../librustc_const_math" }
rustc_data_structures = { path = "../librustc_data_structures" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
#[macro_use]
extern crate rustc;
extern crate rustc_mir;
-extern crate rustc_const_math;
extern crate rustc_data_structures;
#[macro_use]
use rustc::mir::{Mir, Operand, ProjectionElem};
use rustc::mir::{Rvalue, SourceInfo, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind, VisibilityScope, VisibilityScopeData};
+use rustc::mir::interpret::EvalErrorKind;
use rustc::mir::visit as mir_visit;
use rustc::ty::{self, ClosureSubsts, TyCtxt};
use rustc::util::nodemap::{FxHashMap};
location: Location) {
self.record("AssertMessage", msg);
self.record(match *msg {
- AssertMessage::BoundsCheck { .. } => "AssertMessage::BoundsCheck",
- AssertMessage::Math(..) => "AssertMessage::Math",
- AssertMessage::GeneratorResumedAfterReturn => {
+ EvalErrorKind::BoundsCheck { .. } => "AssertMessage::BoundsCheck",
+ EvalErrorKind::Overflow(..) => "AssertMessage::Overflow",
+ EvalErrorKind::OverflowNeg => "AssertMessage::OverflowNeg",
+ EvalErrorKind::DivisionByZero => "AssertMessage::DivisionByZero",
+ EvalErrorKind::RemainderByZero => "AssertMessage::RemainderByZero",
+ EvalErrorKind::GeneratorResumedAfterReturn => {
"AssertMessage::GeneratorResumedAfterReturn"
}
- AssertMessage::GeneratorResumedAfterPanic => {
+ EvalErrorKind::GeneratorResumedAfterPanic => {
"AssertMessage::GeneratorResumedAfterPanic"
}
+ _ => bug!(),
}, msg);
self.super_assert_message(msg, location);
}
use resolve_imports::ImportDirective;
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
-use {Resolver, ResolverArenas};
+use {PerNS, Resolver, ResolverArenas};
use Namespace::{self, TypeNS, ValueNS, MacroNS};
use {resolve_error, resolve_struct_error, ResolutionError};
struct LegacyMacroImports {
import_all: Option<Span>,
imports: Vec<(Name, Span)>,
- reexports: Vec<(Name, Span)>,
}
impl<'a> Resolver<'a> {
let subclass = SingleImport {
target: ident,
source,
- result: self.per_ns(|_, _| Cell::new(Err(Undetermined))),
+ result: PerNS {
+ type_ns: Cell::new(Err(Undetermined)),
+ value_ns: Cell::new(Err(Undetermined)),
+ macro_ns: Cell::new(Err(Undetermined)),
+ },
type_ns_only,
};
self.add_import_directive(
let legacy_imports = self.legacy_macro_imports(&item.attrs);
let mut used = legacy_imports != LegacyMacroImports::default();
- // `#[macro_use]` and `#[macro_reexport]` are only allowed at the crate root.
+ // `#[macro_use]` is only allowed at the crate root.
if self.current_module.parent.is_some() && used {
span_err!(self.session, item.span, E0468,
"an `extern crate` loading macros must be at the crate root");
}
}
}
- for (name, span) in legacy_imports.reexports {
- self.cstore.export_macros_untracked(module.def_id().unwrap().krate);
- let ident = Ident::with_empty_ctxt(name);
- let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span);
- if let Ok(binding) = result {
- let (def, vis) = (binding.def(), binding.vis);
- self.macro_exports.push(Export { ident, def, vis, span, is_import: true });
- } else {
- span_err!(self.session, span, E0470, "re-exported macro not found");
- }
- }
used
}
match attr.meta_item_list() {
Some(names) => for attr in names {
if let Some(word) = attr.word() {
- imports.imports.push((word.ident.name, attr.span()));
+ imports.imports.push((word.name(), attr.span()));
} else {
span_err!(self.session, attr.span(), E0466, "bad macro import");
}
},
None => imports.import_all = Some(attr.span),
}
- } else if attr.check_name("macro_reexport") {
- let bad_macro_reexport = |this: &mut Self, span| {
- span_err!(this.session, span, E0467, "bad macro re-export");
- };
- if let Some(names) = attr.meta_item_list() {
- for attr in names {
- if let Some(word) = attr.word() {
- imports.reexports.push((word.ident.name, attr.span()));
- } else {
- bad_macro_reexport(self, attr.span());
- }
- }
- } else {
- bad_macro_reexport(self, attr.span());
- }
}
}
imports
arguments.
"##,
-E0467: r##"
-Macro re-export declarations were empty or malformed.
-
-Erroneous code examples:
-
-```compile_fail,E0467
-#[macro_reexport] // error: no macros listed for export
-extern crate core as macros_for_good;
-
-#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
-extern crate core as other_macros_for_good;
-```
-
-This is a syntax error at the level of attribute declarations.
-
-Currently, `macro_reexport` requires at least one macro name to be listed.
-Unlike `macro_use`, listing no names does not re-export all macros from the
-given crate.
-
-Decide which macros you would like to export and list them properly.
-
-These are proper re-export declarations:
-
-```ignore (cannot-doctest-multicrate-project)
-#[macro_reexport(some_macro, another_macro)]
-extern crate macros_for_good;
-```
-"##,
-
E0468: r##"
A non-root module attempts to import macros from another crate.
```
"##,
-E0470: r##"
-A macro listed for re-export was not found.
-
-Erroneous code example:
-
-```compile_fail,E0470
-#[macro_reexport(drink, be_merry)]
-extern crate alloc;
-
-fn main() {
- // ...
-}
-```
-
-Either the listed macro is not contained in the imported crate, or it is not
-exported from the given crate.
-
-This could be caused by a typo. Did you misspell the macro's name?
-
-Double-check the names of the macros listed for re-export, and that the crate
-in question exports them.
-
-A working version:
-
-```ignore (cannot-doctest-multicrate-project)
-// In some_crate crate:
-#[macro_export]
-macro_rules! eat {
- ...
-}
-
-#[macro_export]
-macro_rules! drink {
- ...
-}
-
-// In your_crate:
-#[macro_reexport(eat, drink)]
-extern crate some_crate;
-```
-"##,
-
E0530: r##"
A binding shadowed something it shouldn't.
// E0421, merged into 531
E0531, // unresolved pattern path kind `name`
// E0427, merged into 530
+// E0467, removed
+// E0470, removed
E0573,
E0574,
E0575,
pub struct PerNS<T> {
value_ns: T,
type_ns: T,
- macro_ns: Option<T>,
+ macro_ns: T,
}
impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
match ns {
ValueNS => &self.value_ns,
TypeNS => &self.type_ns,
- MacroNS => self.macro_ns.as_ref().unwrap(),
+ MacroNS => &self.macro_ns,
}
}
}
match ns {
ValueNS => &mut self.value_ns,
TypeNS => &mut self.type_ns,
- MacroNS => self.macro_ns.as_mut().unwrap(),
+ MacroNS => &mut self.macro_ns,
}
}
}
graph_root: Module<'a>,
prelude: Option<Module<'a>>,
+ extern_prelude: FxHashSet<Name>,
/// n.b. This is used only for better diagnostics, not name resolution itself.
has_self: FxHashSet<DefId>,
// AST.
graph_root,
prelude: None,
+ extern_prelude: session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect(),
has_self: FxHashSet(),
field_names: FxHashMap(),
ribs: PerNS {
value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
type_ns: vec![Rib::new(ModuleRibKind(graph_root))],
- macro_ns: Some(vec![Rib::new(ModuleRibKind(graph_root))]),
+ macro_ns: vec![Rib::new(ModuleRibKind(graph_root))],
},
label_ribs: Vec::new(),
}
/// Runs the function on each namespace.
- fn per_ns<T, F: FnMut(&mut Self, Namespace) -> T>(&mut self, mut f: F) -> PerNS<T> {
- PerNS {
- type_ns: f(self, TypeNS),
- value_ns: f(self, ValueNS),
- macro_ns: match self.use_extern_macros {
- true => Some(f(self, MacroNS)),
- false => None,
- },
+ fn per_ns<F: FnMut(&mut Self, Namespace)>(&mut self, mut f: F) {
+ f(self, TypeNS);
+ f(self, ValueNS);
+ if self.use_extern_macros {
+ f(self, MacroNS);
}
}
}
}
- match self.prelude {
- Some(prelude) if !module.no_implicit_prelude => {
- self.resolve_ident_in_module_unadjusted(prelude, ident, ns, false, false, path_span)
- .ok().map(LexicalScopeBinding::Item)
+ if !module.no_implicit_prelude {
+ // `record_used` means that we don't try to load crates during speculative resolution
+ if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) {
+ if !self.session.features_untracked().extern_prelude {
+ feature_err(&self.session.parse_sess, "extern_prelude",
+ ident.span, GateIssue::Language,
+ "access to extern crates through prelude is experimental").emit();
+ }
+
+ let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
+ let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+ self.populate_module_if_necessary(crate_root);
+
+ let binding = (crate_root, ty::Visibility::Public,
+ ident.span, Mark::root()).to_name_binding(self.arenas);
+ return Some(LexicalScopeBinding::Item(binding));
+ }
+ if let Some(prelude) = self.prelude {
+ if let Ok(binding) = self.resolve_ident_in_module_unadjusted(prelude, ident, ns,
+ false, false, path_span) {
+ return Some(LexicalScopeBinding::Item(binding));
+ }
}
- _ => None,
}
+
+ None
}
fn hygienic_lexical_parent(&mut self, mut module: Module<'a>, span: &mut Span)
// We can see through blocks
} else {
// Items from the prelude
- if let Some(prelude) = self.prelude {
- if !module.no_implicit_prelude {
+ if !module.no_implicit_prelude {
+ names.extend(self.extern_prelude.iter().cloned());
+ if let Some(prelude) = self.prelude {
add_module_candidates(prelude, &mut names);
}
}
fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_derive: bool)
-> Option<ast::Attribute> {
for i in 0..attrs.len() {
- let name = unwrap_or!(attrs[i].name(), continue);
+ let name = attrs[i].name();
if self.session.plugin_attributes.borrow().iter()
.any(|&(ref attr_nm, _)| name == &**attr_nm) {
// Check for legacy derives
for i in 0..attrs.len() {
- let name = unwrap_or!(attrs[i].name(), continue);
+ let name = attrs[i].name();
if name == "derive" {
let result = attrs[i].parse_list(&self.session.parse_sess, |parser| {
use syntax_pos::Span;
use std::cell::{Cell, RefCell};
-use std::mem;
+use std::{mem, ptr};
/// Contains data for specific types of import directives.
#[derive(Clone, Debug)]
None,
/// Only the given single import can define the name in the namespace.
MaybeOne(&'a ImportDirective<'a>),
+ /// Only one of these two single imports can define the name in the namespace.
+ MaybeTwo(&'a ImportDirective<'a>, &'a ImportDirective<'a>),
/// At least one single import will define the name in the namespace.
AtLeastOne,
}
}
impl<'a> SingleImports<'a> {
- fn add_directive(&mut self, directive: &'a ImportDirective<'a>) {
+ fn add_directive(&mut self, directive: &'a ImportDirective<'a>, use_extern_macros: bool) {
match *self {
SingleImports::None => *self = SingleImports::MaybeOne(directive),
- // If two single imports can define the name in the namespace, we can assume that at
- // least one of them will define it since otherwise both would have to define only one
- // namespace, leading to a duplicate error.
- SingleImports::MaybeOne(_) => *self = SingleImports::AtLeastOne,
+ SingleImports::MaybeOne(directive_one) => *self = if use_extern_macros {
+ SingleImports::MaybeTwo(directive_one, directive)
+ } else {
+ SingleImports::AtLeastOne
+ },
+ // If three single imports can define the name in the namespace, we can assume that at
+ // least one of them will define it since otherwise we'd get duplicate errors in one of
+ // other namespaces.
+ SingleImports::MaybeTwo(..) => *self = SingleImports::AtLeastOne,
SingleImports::AtLeastOne => {}
};
}
- fn directive_failed(&mut self) {
+ fn directive_failed(&mut self, dir: &'a ImportDirective<'a>) {
match *self {
SingleImports::None => unreachable!(),
SingleImports::MaybeOne(_) => *self = SingleImports::None,
+ SingleImports::MaybeTwo(dir1, dir2) =>
+ *self = SingleImports::MaybeOne(if ptr::eq(dir1, dir) { dir1 } else { dir2 }),
SingleImports::AtLeastOne => {}
}
}
}
// Check if a single import can still define the name.
+ let resolve_single_import = |this: &mut Self, directive: &'a ImportDirective<'a>| {
+ let module = match directive.imported_module.get() {
+ Some(module) => module,
+ None => return false,
+ };
+ let ident = match directive.subclass {
+ SingleImport { source, .. } => source,
+ _ => unreachable!(),
+ };
+ match this.resolve_ident_in_module(module, ident, ns, false, false, path_span) {
+ Err(Determined) => {}
+ _ => return false,
+ }
+ true
+ };
match resolution.single_imports {
SingleImports::AtLeastOne => return Err(Undetermined),
- SingleImports::MaybeOne(directive) if self.is_accessible(directive.vis.get()) => {
- let module = match directive.imported_module.get() {
- Some(module) => module,
- None => return Err(Undetermined),
- };
- let ident = match directive.subclass {
- SingleImport { source, .. } => source,
- _ => unreachable!(),
- };
- match self.resolve_ident_in_module(module, ident, ns, false, false, path_span) {
- Err(Determined) => {}
- _ => return Err(Undetermined),
+ SingleImports::MaybeOne(directive) => {
+ let accessible = self.is_accessible(directive.vis.get());
+ if accessible {
+ if !resolve_single_import(self, directive) {
+ return Err(Undetermined)
+ }
+ }
+ }
+ SingleImports::MaybeTwo(directive1, directive2) => {
+ let accessible1 = self.is_accessible(directive1.vis.get());
+ let accessible2 = self.is_accessible(directive2.vis.get());
+ if accessible1 && accessible2 {
+ if !resolve_single_import(self, directive1) &&
+ !resolve_single_import(self, directive2) {
+ return Err(Undetermined)
+ }
+ } else if accessible1 {
+ if !resolve_single_import(self, directive1) {
+ return Err(Undetermined)
+ }
+ } else {
+ if !resolve_single_import(self, directive2) {
+ return Err(Undetermined)
+ }
}
}
- SingleImports::MaybeOne(_) | SingleImports::None => {},
+ SingleImports::None => {},
}
let no_unresolved_invocations =
SingleImport { target, .. } => {
self.per_ns(|this, ns| {
let mut resolution = this.resolution(current_module, target, ns).borrow_mut();
- resolution.single_imports.add_directive(directive);
+ resolution.single_imports.add_directive(directive, this.use_extern_macros);
});
}
// We don't add prelude imports to the globs since they only affect lexical scopes,
Err(Undetermined) => indeterminate = true,
Err(Determined) => {
this.update_resolution(parent, target, ns, |_, resolution| {
- resolution.single_imports.directive_failed()
+ resolution.single_imports.directive_failed(directive)
});
}
Ok(binding) if !binding.is_importable() => {
}
/// Alignment of a type in bytes, both ABI-mandated and preferred.
-/// Each field is a power of two, giving the alignment a maximum value of
-/// 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a i32,
-/// with a maximum capacity of 2<sup>31</sup> - 1 or 2147483647.
+/// Each field is a power of two, giving the alignment a maximum value
+/// of 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a
+/// maximum capacity of 2<sup>29</sup> or 536870912.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct Align {
abi_pow2: u8,
}
if bytes != 1 {
Err(format!("`{}` is not a power of 2", align))
- } else if pow > 30 {
+ } else if pow > 29 {
Err(format!("`{}` is too large", align))
} else {
Ok(pow)
let bits = self.value.size(cx).bits();
assert!(bits <= 128);
let mask = !0u128 >> (128 - bits);
- let start = self.valid_range.start;
- let end = self.valid_range.end;
+ let start = *self.valid_range.start();
+ let end = *self.valid_range.end();
assert_eq!(start, start & mask);
assert_eq!(end, end & mask);
start..(end.wrapping_add(1) & mask)
#![feature(const_fn)]
#![feature(fs_read_write)]
#![feature(inclusive_range)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
#![feature(slice_patterns)]
#[macro_use]
executables: true,
pre_link_args,
has_elf_tls: false,
+ eliminate_frame_pointer: false,
// The following line is a workaround for jemalloc 4.5 being broken on
// ios. jemalloc 5.0 is supposed to fix this.
// see https://github.com/rust-lang/rust/issues/45262
base.max_atomic_width = Some(64);
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
base.stack_probes = true;
+ base.eliminate_frame_pointer = false;
Ok(Target {
llvm_target: "i686-apple-darwin".to_string(),
.map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty))
.collect(),
- ty::TyGenerator(def_id, substs, _) => {
- // Note that the interior types are ignored here.
- // Any type reachable inside the interior must also be reachable
- // through the upvars.
- substs
- .upvar_tys(def_id, tcx)
- .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty))
- .collect()
+ ty::TyGenerator(def_id, substs, _interior) => {
+ // rust-lang/rust#49918: types can be constructed, stored
+ // in the interior, and sit idle when generator yields
+ // (and is subsequently dropped).
+ //
+ // It would be nice to descend into interior of a
+ // generator to determine what effects dropping it might
+ // have (by looking at any drop effects associated with
+ // its interior).
+ //
+ // However, the interior's representation uses things like
+ // TyGeneratorWitness that explicitly assume they are not
+ // traversed in such a manner. So instead, we will
+ // simplify things for now by treating all generators as
+ // if they were like trait objects, where its upvars must
+ // all be alive for the generator's (potential)
+ // destructor.
+ //
+ // In particular, skipping over `_interior` is safe
+ // because any side-effects from dropping `_interior` can
+ // only take place through references with lifetimes
+ // derived from lifetimes attached to the upvars, and we
+ // *do* incorporate the upvars here.
+
+ let constraint = DtorckConstraint {
+ outlives: substs.upvar_tys(def_id, tcx).map(|t| t.into()).collect(),
+ dtorck_types: vec![],
+ overflows: vec![],
+ };
+ debug!("dtorck_constraint: generator {:?} => {:?}", def_id, constraint);
+
+ Ok(constraint)
}
ty::TyAdt(def, substs) => {
rustc_allocator = { path = "../librustc_allocator" }
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_target = { path = "../librustc_target" }
-rustc_const_math = { path = "../librustc_const_math" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" }
rustc_incremental = { path = "../librustc_incremental" }
return;
}
- if scalar.valid_range.start < scalar.valid_range.end {
- if scalar.valid_range.start > 0 {
+ if scalar.valid_range.start() < scalar.valid_range.end() {
+ if *scalar.valid_range.start() > 0 {
attrs.set(ArgAttribute::NonNull);
}
}
}
pub fn set_frame_pointer_elimination(cx: &CodegenCx, llfn: ValueRef) {
- // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
- // parameter.
if cx.sess().must_not_eliminate_frame_pointers() {
llvm::AddFunctionAttrStringValue(
llfn, llvm::AttributePlace::Function,
self.layout,
self.layout.fields.offset(0),
self.layout.field(cx, 0).size);
- name.push_str(&adt.variants[niche_variants.start].name.as_str());
+ name.push_str(&adt.variants[*niche_variants.start()].name.as_str());
// Create the (singleton) list of descriptions of union members.
vec![
}
None => {}
};
- if sig.output().is_never() {
+ if cx.layout_of(sig.output()).abi == ty::layout::Abi::Uninhabited {
flags = flags | DIFlags::FlagNoReturn;
}
use llvm::{self, ValueRef};
use llvm::AttributePlace::Function;
use rustc::ty::{self, Ty};
+use rustc::ty::layout::{self, LayoutOf};
use rustc::session::config::Sanitizer;
use rustc_target::spec::PanicStrategy;
use abi::{Abi, FnType, FnTypeExt};
let fty = FnType::new(cx, sig, &[]);
let llfn = declare_raw_fn(cx, name, fty.llvm_cconv(), fty.llvm_type(cx));
- // FIXME(canndrew): This is_never should really be an is_uninhabited
- if sig.output().is_never() {
+ if cx.layout_of(sig.output()).abi == layout::Abi::Uninhabited {
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
}
#![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#![feature(optin_builtin_traits)]
-#![feature(inclusive_range_fields)]
+#![feature(inclusive_range_methods)]
use rustc::dep_graph::WorkProduct;
use syntax_pos::symbol::Symbol;
extern crate rustc_allocator;
extern crate rustc_apfloat;
extern crate rustc_target;
-extern crate rustc_const_math;
#[macro_use] extern crate rustc_data_structures;
extern crate rustc_demangle;
extern crate rustc_incremental;
debug!("cleanup_kinds: {:?}/{:?}/{:?} propagating funclet {:?}",
bb, data, result[bb], funclet);
- for &succ in data.terminator().successors().iter() {
+ for &succ in data.terminator().successors() {
let kind = result[succ];
debug!("cleanup_kinds: propagating {:?} to {:?}/{:?}",
funclet, succ, kind);
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::{self, LayoutOf};
use rustc::mir;
+use rustc::mir::interpret::EvalErrorKind;
use abi::{Abi, ArgType, ArgTypeExt, FnType, FnTypeExt, LlvmType, PassMode};
use base;
use callee;
// checked operation, just a comparison with the minimum
// value, so we have to check for the assert message.
if !bx.cx.check_overflow {
- use rustc_const_math::ConstMathErr::Overflow;
- use rustc_const_math::Op::Neg;
-
- if let mir::AssertMessage::Math(Overflow(Neg)) = *msg {
+ if let mir::interpret::EvalErrorKind::OverflowNeg = *msg {
const_cond = Some(expected);
}
}
// Put together the arguments to the panic entry point.
let (lang_item, args) = match *msg {
- mir::AssertMessage::BoundsCheck { ref len, ref index } => {
+ EvalErrorKind::BoundsCheck { ref len, ref index } => {
let len = self.trans_operand(&mut bx, len).immediate();
let index = self.trans_operand(&mut bx, index).immediate();
(lang_items::PanicBoundsCheckFnLangItem,
vec![file_line_col, index, len])
}
- mir::AssertMessage::Math(ref err) => {
- let msg_str = Symbol::intern(err.description()).as_str();
- let msg_str = C_str_slice(bx.cx, msg_str);
- let msg_file_line_col = C_struct(bx.cx,
- &[msg_str, filename, line, col],
- false);
- let msg_file_line_col = consts::addr_of(bx.cx,
- msg_file_line_col,
- align,
- "panic_loc");
- (lang_items::PanicFnLangItem,
- vec![msg_file_line_col])
- }
- mir::AssertMessage::GeneratorResumedAfterReturn |
- mir::AssertMessage::GeneratorResumedAfterPanic => {
- let str = if let mir::AssertMessage::GeneratorResumedAfterReturn = *msg {
- "generator resumed after completion"
- } else {
- "generator resumed after panicking"
- };
+ _ => {
+ let str = msg.description();
let msg_str = Symbol::intern(str).as_str();
let msg_str = C_str_slice(bx.cx, msg_str);
let msg_file_line_col = C_struct(bx.cx,
bx.range_metadata(load, range);
}
}
- layout::Pointer if vr.start < vr.end && !vr.contains(&0) => {
+ layout::Pointer if vr.start() < vr.end() && !vr.contains(&0) => {
bx.nonnull_metadata(load);
}
_ => {}
..
} => {
let niche_llty = discr.layout.immediate_llvm_type(bx.cx);
- if niche_variants.start == niche_variants.end {
+ if niche_variants.start() == niche_variants.end() {
// FIXME(eddyb) Check the actual primitive type here.
let niche_llval = if niche_start == 0 {
// HACK(eddyb) Using `C_null` as it works on all types.
C_uint_big(niche_llty, niche_start)
};
bx.select(bx.icmp(llvm::IntEQ, lldiscr, niche_llval),
- C_uint(cast_to, niche_variants.start as u64),
+ C_uint(cast_to, *niche_variants.start() as u64),
C_uint(cast_to, dataful_variant as u64))
} else {
// Rebase from niche values to discriminant values.
- let delta = niche_start.wrapping_sub(niche_variants.start as u128);
+ let delta = niche_start.wrapping_sub(*niche_variants.start() as u128);
let lldiscr = bx.sub(lldiscr, C_uint_big(niche_llty, delta));
- let lldiscr_max = C_uint(niche_llty, niche_variants.end as u64);
+ let lldiscr_max = C_uint(niche_llty, *niche_variants.end() as u64);
bx.select(bx.icmp(llvm::IntULE, lldiscr, lldiscr_max),
bx.intcast(lldiscr, cast_to, false),
C_uint(cast_to, dataful_variant as u64))
let niche = self.project_field(bx, 0);
let niche_llty = niche.layout.immediate_llvm_type(bx.cx);
- let niche_value = ((variant_index - niche_variants.start) as u128)
+ let niche_value = ((variant_index - *niche_variants.start()) as u128)
.wrapping_add(niche_start);
// FIXME(eddyb) Check the actual primitive type here.
let niche_llval = if niche_value == 0 {
use rustc::mir;
use rustc::middle::lang_items::ExchangeMallocFnLangItem;
use rustc_apfloat::{ieee, Float, Status, Round};
-use rustc_const_math::MAX_F32_PLUS_HALF_ULP;
use std::{u128, i128};
use base;
if let layout::Int(_, s) = scalar.value {
signed = s;
- if scalar.valid_range.end > scalar.valid_range.start {
+ if scalar.valid_range.end() > scalar.valid_range.start() {
// We want `table[e as usize]` to not
// have bound checks, and this is the most
// convenient place to put the `assume`.
base::call_assume(&bx, bx.icmp(
llvm::IntULE,
llval,
- C_uint_big(ll_t_in, scalar.valid_range.end)
+ C_uint_big(ll_t_in, *scalar.valid_range.end())
));
}
}
if is_u128_to_f32 {
// All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity,
// and for everything else LLVM's uitofp works just fine.
+ use rustc_apfloat::ieee::Single;
+ use rustc_apfloat::Float;
+ const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
+ << (Single::MAX_EXP - Single::PRECISION as i16);
let max = C_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);
let overflow = bx.icmp(llvm::IntUGE, x, max);
let infinity_bits = C_u32(bx.cx, ieee::Single::INFINITY.to_bits() as u32);
arena = { path = "../libarena" }
fmt_macros = { path = "../libfmt_macros" }
rustc = { path = "../librustc" }
-rustc_const_math = { path = "../librustc_const_math" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
rustc_target = { path = "../librustc_target" }
// inference variables or other artifacts. This
// means they are safe to put into the
// `WhereClausePick`.
- assert!(!trait_ref.skip_binder().substs.needs_infer());
+ assert!(
+ !trait_ref.skip_binder().substs.needs_infer()
+ && !trait_ref.skip_binder().substs.has_skol()
+ );
WhereClausePick(trait_ref.clone())
}
fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) {
debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
- assert!(!ty.needs_infer());
+ assert!(!ty.needs_infer() && !ty.has_skol());
self.tables.node_types_mut().insert(hir_id, ty);
}
if let Some(substs) = self.fcx.tables.borrow().node_substs_opt(hir_id) {
let substs = self.resolve(&substs, &span);
debug!("write_substs_to_tcx({:?}, {:?})", hir_id, substs);
- assert!(!substs.needs_infer());
+ assert!(!substs.needs_infer() && !substs.has_skol());
self.tables.node_substs_mut().insert(hir_id, substs);
}
}
extern crate arena;
#[macro_use] extern crate rustc;
extern crate rustc_platform_intrinsics as intrinsics;
-extern crate rustc_const_math;
extern crate rustc_data_structures;
extern crate rustc_errors as errors;
extern crate rustc_target;
/// If the content is not properly formatted, it will return an error indicating what and where
/// the error is.
pub fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
- let name = cfg.ident.name;
+ let name = cfg.name();
match cfg.node {
MetaItemKind::Word => Ok(Cfg::Cfg(name, None)),
MetaItemKind::NameValue(ref lit) => match lit.node {
Cfg::Cfg(Symbol::intern(name), Some(Symbol::intern(value)))
}
+ fn dummy_meta_item_word(name: &str) -> MetaItem {
+ MetaItem {
+ ident: Path::from_ident(Ident::from_str(name)),
+ node: MetaItemKind::Word,
+ span: DUMMY_SP,
+ }
+ }
+
+ macro_rules! dummy_meta_item_list {
+ ($name:ident, [$($list:ident),* $(,)*]) => {
+ MetaItem {
+ ident: Path::from_ident(Ident::from_str(stringify!($name))),
+ node: MetaItemKind::List(vec![
+ $(
+ dummy_spanned(NestedMetaItemKind::MetaItem(
+ dummy_meta_item_word(stringify!($list)),
+ )),
+ )*
+ ]),
+ span: DUMMY_SP,
+ }
+ };
+
+ ($name:ident, [$($list:expr),* $(,)*]) => {
+ MetaItem {
+ ident: Path::from_ident(Ident::from_str(stringify!($name))),
+ node: MetaItemKind::List(vec![
+ $(
+ dummy_spanned(NestedMetaItemKind::MetaItem($list)),
+ )*
+ ]),
+ span: DUMMY_SP,
+ }
+ };
+ }
+
#[test]
fn test_cfg_not() {
with_globals(|| {
#[test]
fn test_parse_ok() {
with_globals(|| {
- let mi = MetaItem {
- ident: Ident::from_str("all"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_word("all");
assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all")));
let mi = MetaItem {
- ident: Ident::from_str("all"),
+ ident: Path::from_ident(Ident::from_str("all")),
node: MetaItemKind::NameValue(dummy_spanned(LitKind::Str(
Symbol::intern("done"),
StrStyle::Cooked,
};
assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done")));
- let mi = MetaItem {
- ident: Ident::from_str("all"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("a"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("b"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(all, [a, b]);
assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b")));
- let mi = MetaItem {
- ident: Ident::from_str("any"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("a"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("b"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(any, [a, b]);
assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") | word_cfg("b")));
- let mi = MetaItem {
- ident: Ident::from_str("not"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("a"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(not, [a]);
assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a")));
- let mi = MetaItem {
- ident: Ident::from_str("not"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("any"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("a"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("all"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("b"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("c"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- })),
+ let mi = dummy_meta_item_list!(not, [
+ dummy_meta_item_list!(any, [
+ dummy_meta_item_word("a"),
+ dummy_meta_item_list!(all, [b, c]),
]),
- span: DUMMY_SP,
- };
+ ]);
assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c")))));
- let mi = MetaItem {
- ident: Ident::from_str("all"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("a"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("b"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("c"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(all, [a, b, c]);
assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b") & word_cfg("c")));
})
}
fn test_parse_err() {
with_globals(|| {
let mi = MetaItem {
- ident: Ident::from_str("foo"),
+ ident: Path::from_ident(Ident::from_str("foo")),
node: MetaItemKind::NameValue(dummy_spanned(LitKind::Bool(false))),
span: DUMMY_SP,
};
assert!(Cfg::parse(&mi).is_err());
- let mi = MetaItem {
- ident: Ident::from_str("not"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("a"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("b"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(not, [a, b]);
assert!(Cfg::parse(&mi).is_err());
- let mi = MetaItem {
- ident: Ident::from_str("not"),
- node: MetaItemKind::List(vec![]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(not, []);
assert!(Cfg::parse(&mi).is_err());
- let mi = MetaItem {
- ident: Ident::from_str("foo"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("a"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(foo, []);
assert!(Cfg::parse(&mi).is_err());
- let mi = MetaItem {
- ident: Ident::from_str("all"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("foo"),
- node: MetaItemKind::List(vec![]),
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("b"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(all, [
+ dummy_meta_item_list!(foo, []),
+ dummy_meta_item_word("b"),
+ ]);
assert!(Cfg::parse(&mi).is_err());
- let mi = MetaItem {
- ident: Ident::from_str("any"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("a"),
- node: MetaItemKind::Word,
- span: DUMMY_SP,
- })),
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("foo"),
- node: MetaItemKind::List(vec![]),
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(any, [
+ dummy_meta_item_word("a"),
+ dummy_meta_item_list!(foo, []),
+ ]);
assert!(Cfg::parse(&mi).is_err());
- let mi = MetaItem {
- ident: Ident::from_str("not"),
- node: MetaItemKind::List(vec![
- dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem {
- ident: Ident::from_str("foo"),
- node: MetaItemKind::List(vec![]),
- span: DUMMY_SP,
- })),
- ]),
- span: DUMMY_SP,
- };
+ let mi = dummy_meta_item_list!(not, [
+ dummy_meta_item_list!(foo, []),
+ ]);
assert!(Cfg::parse(&mi).is_err());
})
}
// #[doc(no_inline)] attribute is present.
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
let denied = self.vis != hir::Public || self.attrs.iter().any(|a| {
- a.name().unwrap() == "doc" && match a.meta_item_list() {
+ a.name() == "doc" && match a.meta_item_list() {
Some(l) => attr::list_contains_name(&l, "no_inline") ||
attr::list_contains_name(&l, "hidden"),
None => false,
}
if let Some(ref item_name) = item.name {
let path = self.paths.get(&item.def_id)
- .map(|p| p.0.join("::").to_string())
+ .map(|p| p.0[..p.0.len() - 1].join("::"))
.unwrap_or("std".to_owned());
for alias in item.attrs.lists("doc")
.filter(|a| a.check_name("alias"))
}
fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
- let name = attr.ident.name;
+ let name = attr.name();
if attr.is_word() {
Some(format!("{}", name))
let mut attrs = String::new();
for attr in &it.attrs.other_attrs {
- let name = attr.name().unwrap();
+ let name = attr.name();
if !ATTRIBUTE_WHITELIST.contains(&&*name.as_str()) {
continue;
}
if (e.parentNode.id === "main") {
var otherMessage;
if (hasClass(e, "type-decl")) {
- otherMessage = ' Show type declaration';
+ otherMessage = ' Show declaration';
}
e.parentNode.insertBefore(createToggle(otherMessage), e);
if (otherMessage && getCurrentValue('rustdoc-item-declarations') !== "false") {
extern crate env_logger;
extern crate rustc;
extern crate rustc_data_structures;
-extern crate rustc_const_math;
extern crate rustc_trans_utils;
extern crate rustc_driver;
extern crate rustc_resolve;
inlining: bool,
/// Is the current module and all of its parents public?
inside_public_path: bool,
- reexported_macros: FxHashSet<DefId>,
exact_paths: Option<FxHashMap<DefId, Vec<String>>>,
}
view_item_stack: stack,
inlining: false,
inside_public_path: true,
- reexported_macros: FxHashSet(),
exact_paths: Some(FxHashMap()),
cstore,
}
if let Some(exports) = self.cx.tcx.module_exports(def_id) {
for export in exports.iter().filter(|e| e.vis == Visibility::Public) {
if let Def::Macro(def_id, ..) = export.def {
- if def_id.krate == LOCAL_CRATE || self.reexported_macros.contains(&def_id) {
+ if def_id.krate == LOCAL_CRATE {
continue // These are `krate.exported_macros`, handled in `self.visit()`.
}
let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
use_attrs.lists("doc").has_word("hidden");
- // Memoize the non-inlined `pub use`'d macros so we don't push an extra
- // declaration in `visit_mod_contents()`
- if !def_did.is_local() {
- if let Def::Macro(did, _) = def {
- if please_inline { return true }
- debug!("memoizing non-inlined macro export: {:?}", def);
- self.reexported_macros.insert(did);
- return false;
- }
- }
-
// For cross-crate impl inlining we need to know whether items are
// reachable in documentation - a previously nonreachable item can be
// made reachable by cross-crate inlining which we're checking here.
/// behavior when `ptr` is used inside the `unsafe` block:
///
/// ```no_run
+ /// # #![allow(unused_must_use)]
/// use std::ffi::{CString};
///
/// let ptr = CString::new("Hello").unwrap().as_ptr();
/// To fix the problem, bind the `CString` to a local variable:
///
/// ```no_run
+ /// # #![allow(unused_must_use)]
/// use std::ffi::{CString};
///
/// let hello = CString::new("Hello").unwrap();
#![feature(libc)]
#![feature(link_args)]
#![feature(linkage)]
-#![feature(macro_reexport)]
#![feature(macro_vis_matcher)]
#![feature(needs_panic_runtime)]
#![feature(never_type)]
#![feature(unboxed_closures)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
+#![feature(use_extern_macros)]
#![feature(vec_push_all)]
#![feature(doc_cfg)]
#![feature(doc_masked)]
#[cfg(test)] extern crate test;
#[cfg(test)] extern crate rand;
-// We want to re-export a few macros from core but libcore has already been
-// imported by the compiler (via our #[no_std] attribute) In this case we just
-// add a new crate name so we can attach the re-exports to it.
-#[macro_reexport(assert_eq, assert_ne, debug_assert, debug_assert_eq,
- debug_assert_ne, unreachable, unimplemented, write, writeln, try)]
-extern crate core as __core;
+// Re-export a few macros from core
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne};
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use core::{unreachable, unimplemented, write, writeln, try};
+#[allow(unused_imports)] // macros from `alloc` are not used on all platforms
#[macro_use]
-#[macro_reexport(vec, format)]
extern crate alloc as alloc_crate;
extern crate alloc_system;
#[doc(masked)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::fmt;
#[stable(feature = "rust1", since = "1.0.0")]
+pub use alloc_crate::format;
+#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::slice;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::str;
#[unstable(feature = "concat_idents_macro", issue = "29599")]
#[macro_export]
macro_rules! concat_idents {
- ($($e:ident),*) => ({ /* compiler built-in */ });
- ($($e:ident,)*) => ({ /* compiler built-in */ });
+ ($($e:ident),+) => ({ /* compiler built-in */ });
+ ($($e:ident,)+) => ({ /* compiler built-in */ });
}
/// Concatenates literals into a static string slice.
use iter::{self, FusedIterator};
use ops::{self, Deref};
use rc::Rc;
-use str::FromStr;
use sync::Arc;
use ffi::{OsStr, OsString};
}
}
-/// Error returned from [`PathBuf::from_str`][`from_str`].
-///
-/// Note that parsing a path will never fail. This error is just a placeholder
-/// for implementing `FromStr` for `PathBuf`.
-///
-/// [`from_str`]: struct.PathBuf.html#method.from_str
-#[derive(Debug, Clone, PartialEq, Eq)]
-#[stable(feature = "path_from_str", since = "1.26.0")]
-pub enum ParsePathError {}
-
-#[stable(feature = "path_from_str", since = "1.26.0")]
-impl fmt::Display for ParsePathError {
- fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
- match *self {}
- }
-}
-
-#[stable(feature = "path_from_str", since = "1.26.0")]
-impl FromStr for PathBuf {
- type Err = ParsePathError;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- Ok(PathBuf::from(s))
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<P: AsRef<Path>> iter::FromIterator<P> for PathBuf {
fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> PathBuf {
}
}
+ #[allow(unused_must_use)]
#[test]
fn cloning() {
let (tx1, rx1) = channel::<i32>();
tx3.send(()).unwrap();
}
+ #[allow(unused_must_use)]
#[test]
fn cloning2() {
let (tx1, rx1) = channel::<i32>();
/// A spanned compile-time attribute item.
///
-/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
+/// E.g. `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct MetaItem {
- pub ident: Ident,
+ pub ident: Path,
pub node: MetaItemKind,
pub span: Span,
}
pub use self::IntType::*;
use ast;
-use ast::{AttrId, Attribute, Name, Ident};
+use ast::{AttrId, Attribute, Name, Ident, Path, PathSegment};
use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind};
-use codemap::{Spanned, respan, dummy_spanned};
+use codemap::{BytePos, Spanned, respan, dummy_spanned};
use syntax_pos::Span;
use errors::Handler;
use feature_gate::{Features, GatedCfg};
})
}
+const RUST_KNOWN_TOOL: &[&str] = &["clippy", "rustfmt"];
+
+pub fn is_known_tool(attr: &Attribute) -> bool {
+ let tool_name =
+ attr.path.segments.iter().next().expect("empty path in attribute").ident.name;
+ RUST_KNOWN_TOOL.contains(&tool_name.as_str().as_ref())
+}
+
impl NestedMetaItem {
/// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
pub fn meta_item(&self) -> Option<&MetaItem> {
/// Returns the name of the meta item, e.g. `foo` in `#[foo]`,
/// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem
pub fn name(&self) -> Option<Name> {
- self.meta_item().and_then(|meta_item| Some(meta_item.ident.name))
+ self.meta_item().and_then(|meta_item| Some(meta_item.name()))
}
/// Gets the string value if self is a MetaItem and the MetaItem is a
if meta_item_list.len() == 1 {
let nested_item = &meta_item_list[0];
if nested_item.is_literal() {
- Some((meta_item.ident.name, nested_item.literal().unwrap()))
+ Some((meta_item.name(), nested_item.literal().unwrap()))
} else {
None
}
}
}
+fn name_from_path(path: &Path) -> Name {
+ path.segments.last().expect("empty path in attribute").ident.name
+}
+
impl Attribute {
pub fn check_name(&self, name: &str) -> bool {
let matches = self.path == name;
matches
}
- pub fn name(&self) -> Option<Name> {
- match self.path.segments.len() {
- 1 => Some(self.path.segments[0].ident.name),
- _ => None,
- }
+ /// Returns the **last** segment of the name of this attribute.
+ /// E.g. `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`.
+ pub fn name(&self) -> Name {
+ name_from_path(&self.path)
}
pub fn value_str(&self) -> Option<Symbol> {
pub fn is_value_str(&self) -> bool {
self.value_str().is_some()
}
+
+ pub fn is_scoped(&self) -> bool {
+ self.path.segments.len() > 1
+ }
}
impl MetaItem {
+ pub fn name(&self) -> Name {
+ name_from_path(&self.ident)
+ }
+
pub fn value_str(&self) -> Option<Symbol> {
match self.node {
MetaItemKind::NameValue(ref v) => {
pub fn span(&self) -> Span { self.span }
pub fn check_name(&self, name: &str) -> bool {
- self.ident.name == name
+ self.name() == name
}
pub fn is_value_str(&self) -> bool {
pub fn meta(&self) -> Option<MetaItem> {
let mut tokens = self.tokens.trees().peekable();
Some(MetaItem {
- ident: match self.path.segments.len() {
- 1 => self.path.segments[0].ident,
- _ => return None,
- },
+ ident: self.path.clone(),
node: if let Some(node) = MetaItemKind::from_tokens(&mut tokens) {
if tokens.peek().is_some() {
return None;
}
pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
- if self.path.segments.len() > 1 {
- sess.span_diagnostic.span_err(self.path.span, "expected ident, found path");
- }
-
Ok(MetaItem {
- ident: self.path.segments.last().unwrap().ident,
+ ident: self.path.clone(),
node: self.parse(sess, |parser| parser.parse_meta_item_kind())?,
span: self.span,
})
}
pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem {
- MetaItem { ident, span, node: MetaItemKind::NameValue(value) }
+ MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
}
pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
- MetaItem { ident, span, node: MetaItemKind::List(items) }
+ MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
}
pub fn mk_word_item(ident: Ident) -> MetaItem {
- MetaItem { ident, span: ident.span, node: MetaItemKind::Word }
+ MetaItem { ident: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word }
}
+
pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
respan(ident.span, NestedMetaItemKind::MetaItem(mk_word_item(ident)))
}
Attribute {
id,
style: ast::AttrStyle::Inner,
- path: ast::Path::from_ident(item.ident),
+ path: item.ident,
tokens: item.node.tokens(item.span),
is_sugared_doc: false,
span: sp,
Attribute {
id,
style: ast::AttrStyle::Outer,
- path: ast::Path::from_ident(item.ident),
+ path: item.ident,
tokens: item.node.tokens(item.span),
is_sugared_doc: false,
span: sp,
Attribute {
id,
style,
- path: ast::Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
+ path: Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
tokens: MetaItemKind::NameValue(lit).tokens(span),
is_sugared_doc: true,
span,
item.check_name("feature") &&
item.meta_item_list().map(|list| {
list.iter().any(|mi| {
- mi.word().map(|w| w.ident.name == feature_name)
+ mi.word().map(|w| w.name() == feature_name)
.unwrap_or(false)
})
}).unwrap_or(false)
if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) {
gated_cfg.check_and_emit(sess, feats);
}
- sess.config.contains(&(cfg.ident.name, cfg.value_str()))
+ sess.config.contains(&(cfg.name(), cfg.value_str()))
})
}
// The unwraps below may look dangerous, but we've already asserted
// that they won't fail with the loop above.
- match &*cfg.ident.name.as_str() {
+ match &*cfg.name().as_str() {
"any" => mis.iter().any(|mi| {
eval_condition(mi.meta_item().unwrap(), sess, eval)
}),
let meta = meta.as_ref().unwrap();
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
- handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.ident.name));
+ handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
return false
}
if let Some(v) = meta.value_str() {
)+
for meta in metas {
if let Some(mi) = meta.meta_item() {
- match &*mi.ident.name.as_str() {
+ match &*mi.name().as_str() {
$(
stringify!($name)
=> if !get(mi, &mut $name) { continue 'outer },
)+
_ => {
handle_errors(diagnostic, mi.span,
- AttrError::UnknownMetaItem(mi.ident.name));
+ AttrError::UnknownMetaItem(mi.name()));
continue 'outer
}
}
}
}
- match &*meta.ident.name.as_str() {
+ match &*meta.name().as_str() {
"rustc_deprecated" => {
if rustc_depr.is_some() {
span_err!(diagnostic, item_sp, E0540,
let mut issue = None;
for meta in metas {
if let Some(mi) = meta.meta_item() {
- match &*mi.ident.name.as_str() {
+ match &*mi.name().as_str() {
"feature" => if !get(mi, &mut feature) { continue 'outer },
"reason" => if !get(mi, &mut reason) { continue 'outer },
"issue" => if !get(mi, &mut issue) { continue 'outer },
_ => {
handle_errors(diagnostic, meta.span,
- AttrError::UnknownMetaItem(mi.ident.name));
+ AttrError::UnknownMetaItem(mi.name()));
continue 'outer
}
}
let mut since = None;
for meta in metas {
if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
- match &*mi.ident.name.as_str() {
+ match &*mi.name().as_str() {
"feature" => if !get(mi, &mut feature) { continue 'outer },
"since" => if !get(mi, &mut since) { continue 'outer },
_ => {
handle_errors(diagnostic, meta.span,
- AttrError::UnknownMetaItem(mi.ident.name));
+ AttrError::UnknownMetaItem(mi.name()));
continue 'outer
}
}
depr = if let Some(metas) = attr.meta_item_list() {
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
- handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.ident.name));
+ handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
return false
}
if let Some(v) = meta.value_str() {
let mut note = None;
for meta in metas {
if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
- match &*mi.ident.name.as_str() {
+ match &*mi.name().as_str() {
"since" => if !get(mi, &mut since) { continue 'outer },
"note" => if !get(mi, &mut note) { continue 'outer },
_ => {
handle_errors(diagnostic, meta.span,
- AttrError::UnknownMetaItem(mi.ident.name));
+ AttrError::UnknownMetaItem(mi.name()));
continue 'outer
}
}
let mut recognised = false;
if let Some(mi) = item.word() {
- let word = &*mi.ident.name.as_str();
+ let word = &*mi.name().as_str();
let hint = match word {
"C" => Some(ReprC),
"packed" => Some(ReprPacked(1)),
let parse_alignment = |node: &ast::LitKind| -> Result<u32, &'static str> {
if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
if literal.is_power_of_two() {
- // rustc::ty::layout::Align restricts align to <= 2147483647
- if *literal <= 2147483647 {
+ // rustc::ty::layout::Align restricts align to <= 2^29
+ if *literal <= 1 << 29 {
Ok(*literal as u32)
} else {
- Err("larger than 2147483647")
+ Err("larger than 2^29")
}
} else {
Err("not a power of two")
}
} else {
if let Some(meta_item) = item.meta_item() {
- if meta_item.ident.name == "align" {
+ if meta_item.name() == "align" {
if let MetaItemKind::NameValue(ref value) = meta_item.node {
recognised = true;
let mut err = struct_span_err!(diagnostic, item.span, E0693,
impl MetaItem {
fn tokens(&self) -> TokenStream {
- let ident = TokenTree::Token(self.span, Token::from_ast_ident(self.ident));
- TokenStream::concat(vec![ident.into(), self.node.tokens(self.span)])
+ let mut idents = vec![];
+ let mut last_pos = BytePos(0 as u32);
+ for (i, segment) in self.ident.segments.iter().enumerate() {
+ let is_first = i == 0;
+ if !is_first {
+ let mod_sep_span = Span::new(last_pos,
+ segment.ident.span.lo(),
+ segment.ident.span.ctxt());
+ idents.push(TokenTree::Token(mod_sep_span, Token::ModSep).into());
+ }
+ idents.push(TokenTree::Token(segment.ident.span,
+ Token::from_ast_ident(segment.ident)).into());
+ last_pos = segment.ident.span.hi();
+ }
+ idents.push(self.node.tokens(self.span));
+ TokenStream::concat(idents)
}
fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
where I: Iterator<Item = TokenTree>,
{
- let (span, ident) = match tokens.next() {
- Some(TokenTree::Token(span, Token::Ident(ident, _))) => (span, ident),
+ // FIXME: Share code with `parse_path`.
+ let ident = match tokens.next() {
+ Some(TokenTree::Token(span, Token::Ident(ident, _))) => {
+ if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
+ let mut segments = vec![PathSegment::from_ident(ident.with_span_pos(span))];
+ tokens.next();
+ loop {
+ if let Some(TokenTree::Token(span,
+ Token::Ident(ident, _))) = tokens.next() {
+ segments.push(PathSegment::from_ident(ident.with_span_pos(span)));
+ } else {
+ return None;
+ }
+ if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
+ tokens.next();
+ } else {
+ break;
+ }
+ }
+ let span = span.with_hi(segments.last().unwrap().ident.span.hi());
+ Path { span, segments }
+ } else {
+ Path::from_ident(ident.with_span_pos(span))
+ }
+ }
Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 {
- token::Nonterminal::NtIdent(ident, _) => (ident.span, ident),
+ token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
+ token::Nonterminal::NtPath(ref path) => path.clone(),
_ => return None,
},
_ => return None,
let node = MetaItemKind::from_tokens(tokens)?;
let hi = match node {
MetaItemKind::NameValue(ref lit) => lit.span.hi(),
- MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(span.hi()),
- _ => span.hi(),
+ MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(ident.span.hi()),
+ _ => ident.span.hi(),
};
- Some(MetaItem { ident, node, span: span.with_hi(hi) })
+ let span = ident.span.with_hi(hi);
+ Some(MetaItem { ident, node, span })
}
}
match *self {
LitKind::Str(string, ast::StrStyle::Cooked) => {
- let mut escaped = String::new();
- for ch in string.as_str().chars() {
- escaped.extend(ch.escape_unicode());
- }
+ let escaped = string.as_str().escape_default();
Token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None)
}
LitKind::Str(string, ast::StrStyle::Raw(n)) => {
```
"##,
+E0589: r##"
+The value of `N` that was specified for `repr(align(N))` was not a power
+of two, or was greater than 2^29.
+
+```compile_fail,E0589
+#[repr(align(15))] // error: invalid `repr(align)` attribute: not a power of two
+enum Foo {
+ Bar(u64),
+}
+```
+"##,
+
E0658: r##"
An unstable feature was used.
E0555, // malformed feature attribute, expected #![feature(...)]
E0556, // malformed feature, expected just one word
E0584, // file for module `..` found at both .. and ..
- E0589, // invalid `repr(align)` attribute
E0629, // missing 'feature' (rustc_const_unstable)
E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
E0693, // incorrect `repr(align)` attribute format
+ E0694, // an unknown tool name found in scoped attributes
}
invoc.expansion_data.mark.set_expn_info(expn_info);
let span = span.with_ctxt(self.cx.backtrace());
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
- ident: keywords::Invalid.ident(),
+ ident: Path::from_ident(keywords::Invalid.ident()),
span: DUMMY_SP,
node: ast::MetaItemKind::Word,
};
fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
let features = self.cx.ecfg.features.unwrap();
for attr in attrs.iter() {
- feature_gate::check_attribute(attr, self.cx.parse_sess, features);
+ self.check_attribute_inner(attr, features);
// macros are expanded before any lint passes so this warning has to be hardcoded
if attr.path == "derive" {
fn check_attribute(&mut self, at: &ast::Attribute) {
let features = self.cx.ecfg.features.unwrap();
+ self.check_attribute_inner(at, features);
+ }
+
+ fn check_attribute_inner(&mut self, at: &ast::Attribute, features: &Features) {
feature_gate::check_attribute(at, self.cx.parse_sess, features);
}
}
"path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))),
"meta" => token::NtMeta(panictry!(p.parse_meta_item())),
"vis" => token::NtVis(panictry!(p.parse_visibility(true))),
- "lifetime" => token::NtLifetime(p.expect_lifetime().ident),
+ "lifetime" => if p.check_lifetime() {
+ token::NtLifetime(p.expect_lifetime().ident)
+ } else {
+ let token_str = pprust::token_to_string(&p.token);
+ p.fatal(&format!("expected a lifetime, found `{}`", &token_str)).emit();
+ FatalError.raise();
+ }
// this is not supposed to happen, since it has been checked
// when compiling the macro.
_ => p.span_bug(sp, "invalid fragment specifier"),
}
};
- ($((removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
+ ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
/// Represents unstable features which have since been removed (it was once Active)
- const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
- $((stringify!($feature), $ver, $issue)),+
+ const REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
+ $((stringify!($feature), $ver, $issue, $reason)),+
];
};
($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
/// Represents stable features which have since been removed (it was once Accepted)
- const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
- $((stringify!($feature), $ver, $issue)),+
+ const STABLE_REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
+ $((stringify!($feature), $ver, $issue, None)),+
];
};
($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
/// Those language feature has since been Accepted (it was once Active)
- const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
- $((stringify!($feature), $ver, $issue)),+
+ const ACCEPTED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
+ $((stringify!($feature), $ver, $issue, None)),+
];
}
}
// OIBIT specific features
(active, optin_builtin_traits, "1.0.0", Some(13231), None),
- // macro re-export needs more discussion and stabilization
- (active, macro_reexport, "1.0.0", Some(29638), None),
-
// Allows use of #[staged_api]
// rustc internal
(active, staged_api, "1.0.0", None, None),
// #[doc(include="some-file")]
(active, external_doc, "1.22.0", Some(44732), None),
- // allow `#[must_use]` on functions and comparison operators (RFC 1940)
- (active, fn_must_use, "1.21.0", Some(43302), None),
-
// Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008)
(active, non_exhaustive, "1.22.0", Some(44109), None),
(active, generic_associated_types, "1.23.0", Some(44265), None),
// Resolve absolute paths as paths from other crates
- (active, extern_absolute_paths, "1.24.0", Some(44660), None),
+ (active, extern_absolute_paths, "1.24.0", Some(44660), Some(Edition::Edition2018)),
// `foo.rs` as an alternative to `foo/mod.rs`
(active, non_modrs_mods, "1.24.0", Some(44660), Some(Edition::Edition2018)),
// #[doc(alias = "...")]
(active, doc_alias, "1.27.0", Some(50146), None),
+
+ // Access to crate names passed via `--extern` through prelude
+ (active, extern_prelude, "1.27.0", Some(44660), Some(Edition::Edition2018)),
+
+ // Scoped attributes
+ (active, tool_attributes, "1.25.0", Some(44690), None),
);
declare_features! (
- (removed, import_shadowing, "1.0.0", None, None),
- (removed, managed_boxes, "1.0.0", None, None),
+ (removed, import_shadowing, "1.0.0", None, None, None),
+ (removed, managed_boxes, "1.0.0", None, None, None),
// Allows use of unary negate on unsigned integers, e.g. -e for e: u8
- (removed, negate_unsigned, "1.0.0", Some(29645), None),
- (removed, reflect, "1.0.0", Some(27749), None),
+ (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
+ (removed, reflect, "1.0.0", Some(27749), None, None),
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
- (removed, opt_out_copy, "1.0.0", None, None),
- (removed, quad_precision_float, "1.0.0", None, None),
- (removed, struct_inherit, "1.0.0", None, None),
- (removed, test_removed_feature, "1.0.0", None, None),
- (removed, visible_private_types, "1.0.0", None, None),
- (removed, unsafe_no_drop_flag, "1.0.0", None, None),
+ (removed, opt_out_copy, "1.0.0", None, None, None),
+ (removed, quad_precision_float, "1.0.0", None, None, None),
+ (removed, struct_inherit, "1.0.0", None, None, None),
+ (removed, test_removed_feature, "1.0.0", None, None, None),
+ (removed, visible_private_types, "1.0.0", None, None, None),
+ (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
// Allows using items which are missing stability attributes
// rustc internal
- (removed, unmarked_api, "1.0.0", None, None),
- (removed, pushpop_unsafe, "1.2.0", None, None),
- (removed, allocator, "1.0.0", None, None),
- // Allows the `#[simd]` attribute -- removed in favor of `#[repr(simd)]`
- (removed, simd, "1.0.0", Some(27731), None),
- // Merged into `slice_patterns`
- (removed, advanced_slice_patterns, "1.0.0", Some(23121), None),
+ (removed, unmarked_api, "1.0.0", None, None, None),
+ (removed, pushpop_unsafe, "1.2.0", None, None, None),
+ (removed, allocator, "1.0.0", None, None, None),
+ (removed, simd, "1.0.0", Some(27731), None,
+ Some("removed in favor of `#[repr(simd)]`")),
+ (removed, advanced_slice_patterns, "1.0.0", Some(23121), None,
+ Some("merged into `#![feature(slice_patterns)]`")),
+ (removed, macro_reexport, "1.0.0", Some(29638), None,
+ Some("subsumed by `#![feature(use_extern_macros)]` and `pub use`")),
);
declare_features! (
(accepted, target_feature, "1.27.0", None, None),
// Trait object syntax with `dyn` prefix
(accepted, dyn_trait, "1.27.0", Some(44662), None),
+ // allow `#[must_use]` on functions; and, must-use operators (RFC 1940)
+ (accepted, fn_must_use, "1.27.0", Some(43302), None),
);
// If you change this, please modify src/doc/unstable-book as well. You must
("forbid", Normal, Ungated),
("deny", Normal, Ungated),
- ("macro_reexport", Normal, Ungated),
("macro_use", Normal, Ungated),
("macro_export", Normal, Ungated),
("plugin_registrar", Normal, Ungated),
impl GatedCfg {
pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
- let name = cfg.ident.name.as_str();
+ let name = cfg.name().as_str();
GATED_CFGS.iter()
.position(|info| info.0 == name)
.map(|idx| {
impl<'a> Context<'a> {
fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
debug!("check_attribute(attr = {:?})", attr);
- let name = unwrap_or!(attr.name(), return).as_str();
+ let name = attr.name().as_str();
for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES {
if name == n {
if let Gated(_, name, desc, ref has_feature) = *gateage {
// before the plugin attributes are registered
// so we skip this then
if !is_macro {
- gate_feature!(self, custom_attribute, attr.span,
- &format!("The attribute `{}` is currently \
- unknown to the compiler and \
- may have meaning \
- added to it in the future",
- attr.path));
+ if attr.is_scoped() {
+ gate_feature!(self, tool_attributes, attr.span,
+ &format!("scoped attribute `{}` is experimental", attr.path));
+ if attr::is_known_tool(attr) {
+ attr::mark_used(attr);
+ } else {
+ span_err!(
+ self.parse_sess.span_diagnostic,
+ attr.span,
+ E0694,
+ "an unknown tool name found in scoped attribute: `{}`.",
+ attr.path
+ );
+ }
+ } else {
+ gate_feature!(self, custom_attribute, attr.span,
+ &format!("The attribute `{}` is currently \
+ unknown to the compiler and \
+ may have meaning \
+ added to it in the future",
+ attr.path));
+ }
}
}
}
let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
.find(|t| t.0 == feature);
match found {
- Some(&(_, _, issue)) => issue,
+ Some(&(_, _, issue, _)) => issue,
None => panic!("Feature `{}` is not declared anywhere", feature),
}
}
gate_feature_post!(&self, underscore_imports, i.span,
"renaming extern crates with `_` is unstable");
}
- if let Some(attr) = attr::find_by_name(&i.attrs[..], "macro_reexport") {
- gate_feature_post!(&self, macro_reexport, attr.span,
- "macros re-exports are experimental \
- and possibly buggy");
- }
}
ast::ItemKind::ForeignMod(ref foreign_module) => {
function may change over time, for now \
a top-level `fn main()` is required");
}
- if let Some(attr) = attr::find_by_name(&i.attrs[..], "must_use") {
- gate_feature_post!(&self, fn_must_use, attr.span,
- "`#[must_use]` on functions is experimental",
- GateStrength::Soft);
- }
}
ast::ItemKind::Struct(..) => {
"trait aliases are not yet fully implemented");
}
- ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, ref impl_items) => {
+ ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => {
if polarity == ast::ImplPolarity::Negative {
gate_feature_post!(&self, optin_builtin_traits,
i.span,
i.span,
"specialization is unstable");
}
-
- for impl_item in impl_items {
- if let ast::ImplItemKind::Method(..) = impl_item.node {
- if let Some(attr) = attr::find_by_name(&impl_item.attrs[..], "must_use") {
- gate_feature_post!(&self, fn_must_use, attr.span,
- "`#[must_use]` on methods is experimental",
- GateStrength::Soft);
- }
- }
- }
}
ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
crate_edition: Edition) -> Features {
- fn feature_removed(span_handler: &Handler, span: Span) {
- span_err!(span_handler, span, E0557, "feature has been removed");
+ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
+ let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
+ if let Some(reason) = reason {
+ err.span_note(span, reason);
+ }
+ err.emit();
}
let mut features = Features::new();
for mi in list {
let name = if let Some(word) = mi.word() {
- word.ident.name
+ word.name()
} else {
span_err!(span_handler, mi.span, E0556,
"malformed feature, expected just one word");
set(&mut features, mi.span);
feature_checker.collect(&features, mi.span);
}
- else if let Some(&(_, _, _)) = REMOVED_FEATURES.iter()
- .find(|& &(n, _, _)| name == n)
+ else if let Some(&(.., reason)) = REMOVED_FEATURES.iter()
+ .find(|& &(n, ..)| name == n)
.or_else(|| STABLE_REMOVED_FEATURES.iter()
- .find(|& &(n, _, _)| name == n)) {
- feature_removed(span_handler, mi.span);
+ .find(|& &(n, ..)| name == n)) {
+ feature_removed(span_handler, mi.span, reason);
}
- else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter()
- .find(|& &(n, _, _)| name == n) {
+ else if let Some(&(..)) = ACCEPTED_FEATURES.iter()
+ .find(|& &(n, ..)| name == n) {
features.declared_stable_lang_features.push((name, mi.span));
} else if let Some(&edition) = ALL_EDITIONS.iter()
.find(|e| name == e.feature_name()) {
if edition <= crate_edition {
- feature_removed(span_handler, mi.span);
+ feature_removed(span_handler, mi.span, None);
} else {
for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
if let Some(f_edition) = f_edition {
#![feature(non_exhaustive)]
#![feature(const_atomic_usize_new)]
#![feature(rustc_attrs)]
+#![feature(str_escape)]
#![recursion_limit="256"]
};
Ok(if let Some(meta) = meta {
self.bump();
- (ast::Path::from_ident(meta.ident), meta.node.tokens(meta.span))
+ (meta.ident, meta.node.tokens(meta.span))
} else {
(self.parse_path(PathStyle::Mod)?, self.parse_tokens())
})
}
let lo = self.span;
- let ident = self.parse_ident()?;
+ let ident = self.parse_path(PathStyle::Mod)?;
let node = self.parse_meta_item_kind()?;
- Ok(ast::MetaItem { ident, node: node, span: lo.to(self.prev_span) })
+ let span = lo.to(self.prev_span);
+ Ok(ast::MetaItem { ident, node, span })
}
pub fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
}
}
-pub fn escape_default(s: &str) -> String {
- s.chars().map(char::escape_default).flat_map(|x| x).collect()
-}
-
/// Parse a string representing a string literal into its final form. Does
/// unescaping.
pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
- debug!("parse_str_lit: given {}", escape_default(lit));
+ debug!("str_lit: given {}", lit.escape_default());
let mut res = String::with_capacity(lit.len());
let error = |i| format!("lexer should have rejected {} at {}", lit, i);
/// Parse a string representing a raw string literal into its final form. The
/// only operation this does is convert embedded CRLF into a single LF.
pub fn raw_str_lit(lit: &str) -> String {
- debug!("raw_str_lit: given {}", escape_default(lit));
+ debug!("raw_str_lit: given {}", lit.escape_default());
let mut res = String::with_capacity(lit.len());
let mut chars = lit.chars().peekable();
let meta_ident = match self.token {
token::Interpolated(ref nt) => match nt.0 {
token::NtMeta(ref meta) => match meta.node {
- ast::MetaItemKind::Word => Some(meta.ident),
+ ast::MetaItemKind::Word => Some(meta.ident.clone()),
_ => None,
},
_ => None,
},
_ => None,
};
- if let Some(ident) = meta_ident {
+ if let Some(path) = meta_ident {
self.bump();
- return Ok(ast::Path::from_ident(ident));
+ return Ok(path);
}
self.parse_path(style)
}
})
}
- fn check_lifetime(&mut self) -> bool {
+ pub fn check_lifetime(&mut self) -> bool {
self.expected_tokens.push(TokenType::Lifetime);
self.token.is_lifetime()
}
debug!("mk_printer {}", linewidth);
Printer {
out,
- buf_len: n,
+ buf_max_len: n,
margin: linewidth as isize,
space: linewidth as isize,
left: 0,
right: 0,
- buf: vec![BufEntry { token: Token::Eof, size: 0 }; n],
+ // Initialize a single entry; advance_right() will extend it on demand
+ // up to `buf_max_len` elements.
+ buf: vec![BufEntry::default()],
left_total: 0,
right_total: 0,
scan_stack: VecDeque::new(),
pub struct Printer<'a> {
out: Box<io::Write+'a>,
- buf_len: usize,
+ buf_max_len: usize,
/// Width of lines we're constrained to
margin: isize,
/// Number of spaces left on line
size: isize,
}
+impl Default for BufEntry {
+ fn default() -> Self {
+ BufEntry { token: Token::Eof, size: 0 }
+ }
+}
+
impl<'a> Printer<'a> {
pub fn last_token(&mut self) -> Token {
self.buf[self.right].token.clone()
self.right_total = 1;
self.left = 0;
self.right = 0;
- } else { self.advance_right(); }
+ } else {
+ self.advance_right();
+ }
debug!("pp Begin({})/buffer Vec<{},{}>",
b.offset, self.left, self.right);
self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
self.right_total = 1;
self.left = 0;
self.right = 0;
- } else { self.advance_right(); }
+ } else {
+ self.advance_right();
+ }
debug!("pp Break({})/buffer Vec<{},{}>",
b.offset, self.left, self.right);
self.check_stack(0);
}
pub fn advance_right(&mut self) {
self.right += 1;
- self.right %= self.buf_len;
+ self.right %= self.buf_max_len;
+ // Extend the buf if necessary.
+ if self.right == self.buf.len() {
+ self.buf.push(BufEntry::default());
+ }
assert_ne!(self.right, self.left);
}
pub fn advance_left(&mut self) -> io::Result<()> {
}
self.left += 1;
- self.left %= self.buf_len;
+ self.left %= self.buf_max_len;
left_size = self.buf[self.left].size;
}
style: ast::StrStyle) -> io::Result<()> {
let st = match style {
ast::StrStyle::Cooked => {
- (format!("\"{}\"", parse::escape_default(st)))
+ (format!("\"{}\"", st.escape_default()))
}
ast::StrStyle::Raw(n) => {
(format!("r{delim}\"{string}\"{delim}",
Ok(())
}
+ fn print_attribute_path(&mut self, path: &ast::Path) -> io::Result<()> {
+ for (i, segment) in path.segments.iter().enumerate() {
+ if i > 0 {
+ self.writer().word("::")?
+ }
+ if segment.ident.name != keywords::CrateRoot.name() &&
+ segment.ident.name != keywords::DollarCrate.name()
+ {
+ self.writer().word(&segment.ident.name.as_str())?;
+ } else if segment.ident.name == keywords::DollarCrate.name() {
+ self.print_dollar_crate(segment.ident.span.ctxt())?;
+ }
+ }
+ Ok(())
+ }
+
fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> {
self.print_attribute_inline(attr, false)
}
if let Some(mi) = attr.meta() {
self.print_meta_item(&mi)?
} else {
- for (i, segment) in attr.path.segments.iter().enumerate() {
- if i > 0 {
- self.writer().word("::")?
- }
- if segment.ident.name != keywords::CrateRoot.name() &&
- segment.ident.name != keywords::DollarCrate.name() {
- self.writer().word(&segment.ident.name.as_str())?;
- } else if segment.ident.name == keywords::DollarCrate.name() {
- self.print_dollar_crate(segment.ident.span.ctxt())?;
- }
- }
+ self.print_attribute_path(&attr.path)?;
self.writer().space()?;
self.print_tts(attr.tokens.clone())?;
}
fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
self.ibox(INDENT_UNIT)?;
match item.node {
- ast::MetaItemKind::Word => {
- self.writer().word(&item.ident.name.as_str())?;
- }
+ ast::MetaItemKind::Word => self.print_attribute_path(&item.ident)?,
ast::MetaItemKind::NameValue(ref value) => {
- self.word_space(&item.ident.name.as_str())?;
+ self.print_attribute_path(&item.ident)?;
+ self.writer().space()?;
self.word_space("=")?;
self.print_literal(value)?;
}
ast::MetaItemKind::List(ref items) => {
- self.writer().word(&item.ident.name.as_str())?;
+ self.print_attribute_path(&item.ident)?;
self.popen()?;
self.commasep(Consistent,
&items[..],
return base::DummyResult::expr(sp);
}
+ if tts.is_empty() {
+ cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
+ return DummyResult::expr(sp);
+ }
+
let mut res_str = String::new();
for (i, e) in tts.iter().enumerate() {
if i & 1 == 1 {
impl<'a> Visitor<'a> for MarkAttrs<'a> {
fn visit_attribute(&mut self, attr: &Attribute) {
- if let Some(name) = attr.name() {
- if self.0.contains(&name) {
- mark_used(attr);
- mark_known(attr);
- }
+ if self.0.contains(&attr.name()) {
+ mark_used(attr);
+ mark_known(attr);
}
}
attrs.extend(item.attrs
.iter()
.filter(|a| {
- a.name().is_some() && match &*a.name().unwrap().as_str() {
+ match &*a.name().as_str() {
"allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
_ => false,
}
// have been unsuccessful
impl Pos for BytePos {
+ #[inline(always)]
fn from_usize(n: usize) -> BytePos { BytePos(n as u32) }
+
+ #[inline(always)]
fn to_usize(&self) -> usize { let BytePos(n) = *self; n as usize }
}
impl Add for BytePos {
type Output = BytePos;
+ #[inline(always)]
fn add(self, rhs: BytePos) -> BytePos {
BytePos((self.to_usize() + rhs.to_usize()) as u32)
}
impl Sub for BytePos {
type Output = BytePos;
+ #[inline(always)]
fn sub(self, rhs: BytePos) -> BytePos {
BytePos((self.to_usize() - rhs.to_usize()) as u32)
}
}
impl Pos for CharPos {
+ #[inline(always)]
fn from_usize(n: usize) -> CharPos { CharPos(n) }
+
+ #[inline(always)]
fn to_usize(&self) -> usize { let CharPos(n) = *self; n }
}
impl Add for CharPos {
type Output = CharPos;
+ #[inline(always)]
fn add(self, rhs: CharPos) -> CharPos {
CharPos(self.to_usize() + rhs.to_usize())
}
impl Sub for CharPos {
type Output = CharPos;
+ #[inline(always)]
fn sub(self, rhs: CharPos) -> CharPos {
CharPos(self.to_usize() - rhs.to_usize())
}
--- /dev/null
+// Copyright 2018 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.
+//
+// compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y
+
+#![crate_type="lib"]
+
+// CHECK: attributes #{{.*}} "no-frame-pointer-elim"="true"
+pub fn foo() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// compile-flags: -g -C no-prepopulate-passes
// ignore-tidy-linelength
// min-llvm-version 4.0
-// compile-flags: -g -C no-prepopulate-passes
-
-// CHECK: {{.*}}DISubprogram{{.*}}name: "foo"{{.*}}DIFlagNoReturn
+#![crate_type = "lib"]
-fn foo() -> ! {
+#[no_mangle]
+pub fn foo() -> ! {
+// CHECK: @foo() unnamed_addr #0
loop {}
}
-pub fn main() {
- foo();
+pub enum EmptyEnum {}
+
+#[no_mangle]
+pub fn bar() -> EmptyEnum {
+// CHECK: @bar() unnamed_addr #0
+ loop {}
}
+
+// CHECK: attributes #0 = {{{.*}} noreturn {{.*}}}
+
+// CHECK: DISubprogram(name: "foo", {{.*}} DIFlagNoReturn
+// CHECK: DISubprogram(name: "bar", {{.*}} DIFlagNoReturn
let copy_name = match mi.node {
ast::MetaItemKind::List(ref xs) => {
if let Some(word) = xs[0].word() {
- word.ident
+ word.ident.segments.last().unwrap().ident
} else {
cx.span_err(mi.span, "Expected word");
return;
+++ /dev/null
-// Copyright 2014 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.
-
-// Test that macro re-exports item are gated by `macro_reexport` feature gate.
-
-// aux-build:macro_reexport_1.rs
-// gate-test-macro_reexport
-
-#![crate_type = "dylib"]
-
-#[macro_reexport(reexported)]
-//~^ ERROR macros re-exports are experimental and possibly buggy
-#[macro_use] #[no_link]
-extern crate macro_reexport_1;
+++ /dev/null
-// Copyright 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.
-
-#![crate_type = "dylib"]
-
-// Since we load a serialized macro with all its attributes, accidentally
-// re-exporting a `#[macro_export] macro_rules!` is something of a concern!
-//
-// We avoid it at the moment only because of the order in which we do things.
-
-#[macro_use] #[no_link]
-extern crate macro_reexport_1;
+++ /dev/null
-// Copyright 2014 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.
-
-#![crate_type = "dylib"]
-#[macro_export]
-macro_rules! reexported {
- () => ( 3 )
-}
--- /dev/null
+// Copyright 2018 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.
+
+fn main() {
+ #[rustfmt::skip] //~ ERROR scoped attribute `rustfmt::skip` is experimental
+ let x =
+ 3;
+}
+++ /dev/null
-// Copyright 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.
-
-// aux-build:macro_reexport_1.rs
-// aux-build:macro_non_reexport_2.rs
-
-#[macro_use] #[no_link]
-extern crate macro_non_reexport_2;
-
-fn main() {
- assert_eq!(reexported!(), 3);
- //~^ ERROR cannot find macro `reexported!` in this scope
-}
--- /dev/null
+// Copyright 2018 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.
+
+// Test for issue #50381: non-lifetime passed to :lifetime.
+
+#![feature(macro_lifetime_matcher)]
+
+macro_rules! m { ($x:lifetime) => { } }
+
+fn main() {
+ m!(a);
+ //~^ ERROR expected a lifetime, found `a`
+}
+++ /dev/null
-// Copyright 2014 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.
-
-#![no_std]
-#![feature(macro_reexport)]
-
-#[allow(unused_extern_crates)]
-#[macro_reexport] //~ ERROR bad macro re-export
-extern crate std;
+++ /dev/null
-// Copyright 2014 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.
-
-#![no_std]
-#![feature(macro_reexport)]
-
-#[allow(unused_extern_crates)]
-#[macro_reexport="foo"] //~ ERROR bad macro re-export
-extern crate std;
+++ /dev/null
-// Copyright 2014 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.
-
-#![no_std]
-#![feature(macro_reexport)]
-
-#[allow(unused_extern_crates)]
-#[macro_reexport(foo="bar")] //~ ERROR bad macro re-export
-extern crate std;
+++ /dev/null
-// Copyright 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.
-
-// aux-build:macro_reexport_1.rs
-
-#![feature(macro_reexport)]
-
-#[macro_reexport(reexported)]
-#[no_link]
-extern crate macro_reexport_1;
-
-fn main() {
- assert_eq!(reexported!(), 3);
- //~^ ERROR cannot find macro
-}
+++ /dev/null
-// Copyright 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.
-
-// aux-build:two_macros.rs
-
-#![feature(macro_reexport)]
-
-#[macro_use(macro_two)]
-#[macro_reexport(no_way)] //~ ERROR re-exported macro not found
-extern crate two_macros;
-
-pub fn main() {
- macro_two!();
-}
#[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two
struct B(i32);
-#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2147483647
+#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29
struct C(i32);
+#[repr(align(536870912))] // ok: this is the largest accepted alignment
+struct D(i32);
+
fn main() {}
--- /dev/null
+// Copyright 2018 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.
+
+#![feature(tool_attributes)]
+
+#![foo::bar] //~ ERROR an unknown tool name found in scoped attribute: `foo::bar`. [E0694]
+
+#[foo::bar] //~ ERROR an unknown tool name found in scoped attribute: `foo::bar`. [E0694]
+fn main() {}
--- /dev/null
+// Copyright 2018 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.
+
+// Make sure that 'custom_attributes' feature does not allow scoped attributes.
+
+#![feature(custom_attributes)]
+
+#[foo::bar]
+//~^ ERROR scoped attribute `foo::bar` is experimental (see issue #44690) [E0658]
+//~^^ ERROR an unknown tool name found in scoped attribute: `foo::bar`. [E0694]
+fn main() {}
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) ep-lib.rs
+ $(RUSTC) ep-vec.rs
+
+ $(RUSTC) basic.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
+ $(RUSTC) shadow-mod.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
+ $(RUSTC) shadow-prelude.rs --extern Vec=$(TMPDIR)/libep_vec.rlib
+ $(RUSTC) feature-gate.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "access to extern crates through prelude is experimental"
+ $(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "unresolved import"
+ $(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "failed to resolve"
--- /dev/null
+// Copyright 2018 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.
+
+#![feature(extern_prelude)]
+
+fn main() {
+ let s = ep_lib::S; // It works
+ s.external();
+}
--- /dev/null
+// 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.
+
+#![crate_type = "rlib"]
+
+pub struct S;
+
+impl S {
+ pub fn external(&self) {}
+}
--- /dev/null
+// 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.
+
+#![crate_type = "rlib"]
+
+pub fn new(arg1: f32, arg2: ()) {}
--- /dev/null
+// Copyright 2018 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.
+
+fn main() {
+ let s = ep_lib::S; // Feature error
+}
--- /dev/null
+// Copyright 2018 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.
+
+// Extern prelude names are not available by absolute paths
+
+#![feature(extern_prelude)]
+
+use ep_lib::S;
+
+fn main() {
+ let s = ::ep_lib::S;
+}
--- /dev/null
+// Copyright 2018 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.
+
+// Local module shadows `ep_lib` from extern prelude
+
+mod ep_lib {
+ pub struct S;
+
+ impl S {
+ pub fn internal(&self) {}
+ }
+}
+
+fn main() {
+ let s = ep_lib::S;
+ s.internal(); // OK
+}
--- /dev/null
+// Copyright 2018 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.
+
+// Extern prelude shadows standard library prelude
+
+#![feature(extern_prelude)]
+
+fn main() {
+ let x = Vec::new(0f32, ()); // OK
+}
let copy_name = match mi.node {
ast::MetaItemKind::List(ref xs) => {
if let Some(word) = xs[0].word() {
- word.ident
+ word.ident.segments.last().unwrap().ident
} else {
cx.span_err(mi.span, "Expected word");
return;
+++ /dev/null
-// Copyright 2016 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.
-
-// ignore-test not a test, auxiliary
-
-#![feature(macro_reexport)]
-
-#[macro_reexport(A)]
-extern crate derive_a;
+++ /dev/null
-// Copyright 2016 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.
-
-// aux-build:derive-a.rs
-// aux-build:derive-reexport.rs
-// ignore-stage1
-
-#[macro_use]
-extern crate derive_reexport;
-
-#[derive(Debug, PartialEq, A, Eq, Copy, Clone)]
-struct A;
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 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.
-
-#![crate_type = "dylib"]
-#[macro_export]
-macro_rules! reexported {
- () => ( 3 )
-}
+++ /dev/null
-// Copyright 2014 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.
-
-#![crate_type = "dylib"]
-#![feature(macro_reexport)]
-
-#[macro_reexport(reexported)]
-#[macro_use] #[no_link]
-extern crate macro_reexport_1;
+++ /dev/null
-// Copyright 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.
-
-#![crate_type = "dylib"]
-#![feature(macro_reexport)]
-
-#[macro_reexport(reexported)]
-#[no_link]
-extern crate macro_reexport_1;
// "enable" to 0 instead.
// compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0
+// compile-flags:-Cforce-frame-pointers=yes
// ignore-pretty issue #37195
// ignore-cloudabi spawning processes is not supported
// ignore-emscripten spawning processes is not supported
--- /dev/null
+// Copyright 2014 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.
+
+// compile-flags: --extern LooksLikeExternCrate=/path/to/nowhere
+
+mod m {
+ pub struct LooksLikeExternCrate;
+}
+
+fn main() {
+ // OK, speculative resolution for `unused_qualifications` doesn't try
+ // to resolve this as an extern crate and load that crate
+ let s = m::LooksLikeExternCrate {};
+}
--- /dev/null
+// Copyright 2018 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.
+
+fn main() {
+ // -------- Simplified test case --------
+
+ let _ = || 0..=1;
+
+ // -------- Original test case --------
+
+ let full_length = 1024;
+ let range = {
+ // do some stuff, omit here
+ None
+ };
+
+ let range = range.map(|(s, t)| s..=t).unwrap_or(0..=(full_length-1));
+
+ assert_eq!(range, 0..=1023);
+}
+++ /dev/null
-// Copyright 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.
-
-// aux-build:macro_reexport_1.rs
-// aux-build:macro_reexport_2_no_use.rs
-
-#[macro_use] #[no_link]
-extern crate macro_reexport_2_no_use;
-
-fn main() {
- assert_eq!(reexported!(), 3_usize);
-}
+++ /dev/null
-// Copyright 2014 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.
-
-// aux-build:macro_reexport_1.rs
-// aux-build:macro_reexport_2.rs
-
-#[macro_use] #[no_link]
-extern crate macro_reexport_2;
-
-fn main() {
- assert_eq!(reexported!(), 3_usize);
-}
--- /dev/null
+// Copyright 2018 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.
+
+// compile-flags: -O
+
+#![allow(dead_code)]
+
+#[repr(C, u8)]
+enum ReprCu8 {
+ A(u16),
+ B,
+}
+
+#[repr(u8)]
+enum Repru8 {
+ A(u16),
+ B,
+}
+
+#[repr(C)]
+struct ReprC {
+ tag: u8,
+ padding: u8,
+ payload: u16,
+}
+
+fn main() {
+ // Test `repr(C, u8)`.
+ let r1 = ReprC { tag: 0, padding: 0, payload: 0 };
+ let r2 = ReprC { tag: 0, padding: 1, payload: 1 };
+
+ let t1: &ReprCu8 = unsafe { std::mem::transmute(&r1) };
+ let t2: &ReprCu8 = unsafe { std::mem::transmute(&r2) };
+
+ match (t1, t2) {
+ (ReprCu8::A(_), ReprCu8::A(_)) => (),
+ _ => assert!(false)
+ };
+
+ // Test `repr(u8)`.
+ let t1: &Repru8 = unsafe { std::mem::transmute(&r1) };
+ let t2: &Repru8 = unsafe { std::mem::transmute(&r2) };
+
+ match (t1, t2) {
+ (Repru8::A(_), Repru8::A(_)) => (),
+ _ => assert!(false)
+ };
+}
--- /dev/null
+// Copyright 2018 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.
+
+// Scoped attributes should not trigger an unused attributes lint.
+
+#![feature(tool_attributes)]
+#![deny(unused_attributes)]
+
+fn main() {
+ #[rustfmt::skip]
+ foo ();
+}
+
+fn foo() {
+ assert!(true);
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// ignore-order
+
const QUERY = '+';
const EXPECTED = {
'others': [
- { 'path': 'std::ops::AddAssign', 'name': 'AddAssign' },
- { 'path': 'std::ops::Add', 'name': 'Add' },
+ { 'path': 'std::ops', 'name': 'AddAssign' },
+ { 'path': 'std::ops', 'name': 'Add' },
],
};
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// ignore-order
+
const QUERY = '[';
const EXPECTED = {
'others': [
{ 'path': 'std', 'name': 'slice' },
- { 'path': 'std::ops::IndexMut', 'name': 'IndexMut' },
- { 'path': 'std::ops::Index', 'name': 'Index' },
+ { 'path': 'std::ops', 'name': 'IndexMut' },
+ { 'path': 'std::ops', 'name': 'Index' },
],
};
const EXPECTED = {
'others': [
{ 'path': 'std::string', 'name': 'String' },
- { 'path': 'std::ffi', 'name': 'OsString' },
{ 'path': 'std::ffi', 'name': 'CString' },
+ { 'path': 'std::ffi', 'name': 'OsString' },
],
'in_args': [
{ 'path': 'std::str', 'name': 'eq' },
#[doc(no_inline)]
pub use all_item_types::FOO_CONSTANT;
-// @has 'foo/index.html' '//a[@href="../all_item_types/macro.foo_macro.html"]' 'foo_macro'
+// @has 'foo/index.html' '//a[@href="../foo/macro.foo_macro.html"]' 'foo_macro'
#[doc(no_inline)]
pub use all_item_types::foo_macro;
// aux-build:pub-use-extern-macros.rs
-#![feature(use_extern_macros, macro_reexport)]
+#![feature(use_extern_macros)]
-// @has pub_use_extern_macros/macro.foo.html
-// @!has pub_use_extern_macros/index.html 'pub use macros::foo;'
-#[macro_reexport(foo)] extern crate macros;
+extern crate macros;
-// @has pub_use_extern_macros/index.html 'pub use macros::bar;'
-// @!has pub_use_extern_macros/macro.bar.html
+// @has pub_use_extern_macros/macro.bar.html
pub use macros::bar;
// @has pub_use_extern_macros/macro.baz.html
#[doc(inline)]
pub use macros::baz;
-// @!has pub_use_extern_macros/macro.quux.html
+// @has pub_use_extern_macros/macro.quux.html
// @!has pub_use_extern_macros/index.html 'pub use macros::quux;'
#[doc(hidden)]
pub use macros::quux;
--- /dev/null
+// Copyright 2018 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.
+
+// compile-pass
+#[derive(Copy, Clone, PartialEq, Eq)]
+#[repr(packed)]
+pub struct Num(u64);
+
+impl Num {
+ pub const ZERO: Self = Num(0);
+}
+
+pub fn decrement(a: Num) -> Num {
+ match a {
+ Num::ZERO => Num::ZERO,
+ a => Num(a.0 - 1)
+ }
+}
+
+fn main() {
+}
--> $DIR/index_out_of_bound.rs:11:19
|
LL | static FOO: i32 = [][0];
- | ^^^^^ index out of bounds: the len is 0 but the index is 0 at $DIR/index_out_of_bound.rs:11:19: 11:24
+ | ^^^^^ index out of bounds: the len is 0 but the index is 0
error: aborting due to previous error
--> $DIR/promoted_errors.rs:14:20
|
LL | println!("{}", 0u32 - 1);
- | ^^^^^^^^ attempted to do overflowing math
+ | ^^^^^^^^ attempt to subtract with overflow
|
= note: #[warn(const_err)] on by default
--> $DIR/promoted_errors.rs:14:20
|
LL | println!("{}", 0u32 - 1);
- | ^^^^^^^^ attempted to do overflowing math
+ | ^^^^^^^^ attempt to subtract with overflow
warning: constant evaluation error
--> $DIR/promoted_errors.rs:17:14
|
LL | let _x = 0u32 - 1;
- | ^^^^^^^^ attempted to do overflowing math
+ | ^^^^^^^^ attempt to subtract with overflow
warning: attempt to divide by zero
--> $DIR/promoted_errors.rs:19:20
--> $DIR/promoted_errors.rs:19:20
|
LL | println!("{}", 1/(1-1));
- | ^^^^^^^ attempted to do overflowing math
+ | ^^^^^^^ attempt to divide by zero
warning: attempt to divide by zero
--> $DIR/promoted_errors.rs:22:14
--> $DIR/promoted_errors.rs:22:14
|
LL | let _x = 1/(1-1);
- | ^^^^^^^ attempted to do overflowing math
+ | ^^^^^^^ attempt to divide by zero
warning: constant evaluation error
--> $DIR/promoted_errors.rs:25:20
|
LL | println!("{}", 1/(false as u32));
- | ^^^^^^^^^^^^^^^^ attempted to do overflowing math
+ | ^^^^^^^^^^^^^^^^ attempt to divide by zero
//~| const_err
//~| const_err
//~| const_err
- //~| divide by zero
}
fn main() {
--> $DIR/E0080.rs:14:9
|
LL | Y = (1 / 0) //~ ERROR E0080
- | ^^^^^^^ attempted to do overflowing math
+ | ^^^^^^^ attempt to divide by zero
error[E0080]: constant evaluation error
--> $DIR/E0080.rs:14:9
--- /dev/null
+// Copyright 2018 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.
+
+can-only-test-this-in-run-make-fulldeps //~ ERROR expected one of `!` or `::`, found `-`
--- /dev/null
+error: expected one of `!` or `::`, found `-`
+ --> $DIR/feature-gate-extern_prelude.rs:11:4
+ |
+LL | can-only-test-this-in-run-make-fulldeps //~ ERROR expected one of `!` or `::`, found `-`
+ | ^ expected one of `!` or `::` here
+
+error: aborting due to previous error
+
+++ /dev/null
-// 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.
-
-// compile-flags: --cap-lints allow
-
-// This tests that the fn_must_use feature-gate warning respects the lint
-// cap. (See discussion in Issue #44213.)
-
-#![feature(rustc_attrs)]
-
-#[must_use] // (no feature-gate warning because of the lint cap!)
-fn need_to_use_it() -> bool { true }
-
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+++ /dev/null
-error: compilation successful
- --> $DIR/feature-gate-fn_must_use-cap-lints-allow.rs:22:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
+++ /dev/null
-// 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.
-
-#![feature(rustc_attrs)]
-
-struct MyStruct;
-
-impl MyStruct {
- #[must_use] //~ WARN `#[must_use]` on methods is experimental
- fn need_to_use_method() -> bool { true }
-}
-
-#[must_use] //~ WARN `#[must_use]` on functions is experimental
-fn need_to_use_it() -> bool { true }
-
-
-// Feature gates are tidy-required to have a specially named (or
-// comment-annotated) compile-fail test (which MUST fail), but for
-// backwards-compatibility reasons, we want `#[must_use]` on functions to be
-// compilable even if the `fn_must_use` feature is absent, thus necessitating
-// the usage of `#[rustc_error]` here, pragmatically if awkwardly solving this
-// dilemma until a superior solution can be devised.
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+++ /dev/null
-warning: `#[must_use]` on methods is experimental (see issue #43302)
- --> $DIR/feature-gate-fn_must_use.rs:16:5
- |
-LL | #[must_use] //~ WARN `#[must_use]` on methods is experimental
- | ^^^^^^^^^^^
- |
- = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
-warning: `#[must_use]` on functions is experimental (see issue #43302)
- --> $DIR/feature-gate-fn_must_use.rs:20:1
- |
-LL | #[must_use] //~ WARN `#[must_use]` on functions is experimental
- | ^^^^^^^^^^^
- |
- = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
-error: compilation successful
- --> $DIR/feature-gate-fn_must_use.rs:31:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
--- /dev/null
+// Copyright 2018 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.
+
+fn main() {
+ #[rustfmt::skip] //~ ERROR scoped attribute `rustfmt::skip` is experimental
+ let x = 3
+ ;
+}
--- /dev/null
+error[E0658]: scoped attribute `rustfmt::skip` is experimental (see issue #44690)
+ --> $DIR/feature-gate-tool_attributes.rs:12:5
+ |
+LL | #[rustfmt::skip] //~ ERROR scoped attribute `rustfmt::skip` is experimental
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: add #![feature(tool_attributes)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
#![allow (x5300)] //~ WARN unknown lint: `x5300`
#![forbid (x5200)] //~ WARN unknown lint: `x5200`
#![deny (x5100)] //~ WARN unknown lint: `x5100`
-#![macro_reexport = "5000"] //~ WARN unused attribute
#![macro_use] // (allowed if no argument; see issue-43160-gating-of-macro_use.rs)
#![macro_export = "4800"] //~ WARN unused attribute
#![plugin_registrar = "4700"] //~ WARN unused attribute
//~^ WARN unknown lint: `x5100`
}
-#[macro_reexport = "5000"]
-//~^ WARN unused attribute
-mod macro_reexport {
- mod inner { #![macro_reexport="5000"] }
- //~^ WARN unused attribute
-
- #[macro_reexport = "5000"] fn f() { }
- //~^ WARN unused attribute
-
- #[macro_reexport = "5000"] struct S;
- //~^ WARN unused attribute
-
- #[macro_reexport = "5000"] type T = S;
- //~^ WARN unused attribute
-
- #[macro_reexport = "5000"] impl S { }
- //~^ WARN unused attribute
-}
-
#[macro_use]
mod macro_use {
mod inner { #![macro_use] }
mod inner { #![must_use="1400"] }
#[must_use = "1400"] fn f() { }
- //~^ WARN `#[must_use]` on functions is experimental
#[must_use = "1400"] struct S;
warning: macro_escape is a deprecated synonym for macro_use
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:513:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:1
|
LL | #[macro_escape]
| ^^^^^^^^^^^^^^^
warning: macro_escape is a deprecated synonym for macro_use
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17
|
LL | mod inner { #![macro_escape] }
| ^^^^^^^^^^^^^^^^
|
= help: consider an outer attribute, #[macro_use] mod ...
-warning: `#[must_use]` on functions is experimental (see issue #43302)
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5
- |
-LL | #[must_use = "1400"] fn f() { }
- | ^^^^^^^^^^^^^^^^^^^^
- |
- = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
warning: unknown lint: `x5400`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:49:33
|
| ^^^^^
warning: unknown lint: `x5400`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:113:8
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:112:8
|
LL | #[warn(x5400)]
| ^^^^^
warning: unknown lint: `x5400`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:116:25
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:115:25
|
LL | mod inner { #![warn(x5400)] }
| ^^^^^
warning: unknown lint: `x5400`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:119:12
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:118:12
|
LL | #[warn(x5400)] fn f() { }
| ^^^^^
warning: unknown lint: `x5400`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:122:12
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:121:12
|
LL | #[warn(x5400)] struct S;
| ^^^^^
warning: unknown lint: `x5400`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:125:12
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:124:12
|
LL | #[warn(x5400)] type T = S;
| ^^^^^
warning: unknown lint: `x5400`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:128:12
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:127:12
|
LL | #[warn(x5400)] impl S { }
| ^^^^^
warning: unknown lint: `x5300`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:132:9
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:131:9
|
LL | #[allow(x5300)]
| ^^^^^
warning: unknown lint: `x5300`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:135:26
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:134:26
|
LL | mod inner { #![allow(x5300)] }
| ^^^^^
warning: unknown lint: `x5300`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:138:13
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:137:13
|
LL | #[allow(x5300)] fn f() { }
| ^^^^^
warning: unknown lint: `x5300`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:141:13
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:140:13
|
LL | #[allow(x5300)] struct S;
| ^^^^^
warning: unknown lint: `x5300`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:144:13
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:143:13
|
LL | #[allow(x5300)] type T = S;
| ^^^^^
warning: unknown lint: `x5300`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:147:13
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:146:13
|
LL | #[allow(x5300)] impl S { }
| ^^^^^
warning: unknown lint: `x5200`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:151:10
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:150:10
|
LL | #[forbid(x5200)]
| ^^^^^
warning: unknown lint: `x5200`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:154:27
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:153:27
|
LL | mod inner { #![forbid(x5200)] }
| ^^^^^
warning: unknown lint: `x5200`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:157:14
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:156:14
|
LL | #[forbid(x5200)] fn f() { }
| ^^^^^
warning: unknown lint: `x5200`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:160:14
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:159:14
|
LL | #[forbid(x5200)] struct S;
| ^^^^^
warning: unknown lint: `x5200`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:163:14
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:162:14
|
LL | #[forbid(x5200)] type T = S;
| ^^^^^
warning: unknown lint: `x5200`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:166:14
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:165:14
|
LL | #[forbid(x5200)] impl S { }
| ^^^^^
warning: unknown lint: `x5100`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:170:8
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:169:8
|
LL | #[deny(x5100)]
| ^^^^^
warning: unknown lint: `x5100`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:173:25
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:172:25
|
LL | mod inner { #![deny(x5100)] }
| ^^^^^
warning: unknown lint: `x5100`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:12
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:175:12
|
LL | #[deny(x5100)] fn f() { }
| ^^^^^
warning: unknown lint: `x5100`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:179:12
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:178:12
|
LL | #[deny(x5100)] struct S;
| ^^^^^
warning: unknown lint: `x5100`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:182:12
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:181:12
|
LL | #[deny(x5100)] type T = S;
| ^^^^^
warning: unknown lint: `x5100`
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:185:12
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:184:12
|
LL | #[deny(x5100)] impl S { }
| ^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:5
|
-LL | mod inner { #![macro_reexport="5000"] }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[macro_use] fn f() { }
+ | ^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:44:9
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:195:5
|
-LL | #[macro_reexport = "5000"] fn f() { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:5
- |
-LL | #[macro_reexport = "5000"] struct S;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5
- |
-LL | #[macro_reexport = "5000"] type T = S;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:5
- |
-LL | #[macro_reexport = "5000"] impl S { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:189:1
- |
-LL | #[macro_reexport = "5000"]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:212:5
- |
-LL | #[macro_use] fn f() { }
- | ^^^^^^^^^^^^
-
-warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:215:5
- |
LL | #[macro_use] struct S;
| ^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:218:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:5
|
LL | #[macro_use] type T = S;
| ^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5
|
LL | #[macro_use] impl S { }
| ^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:208:17
|
LL | mod inner { #![macro_export="4800"] }
| ^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:231:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:211:5
|
LL | #[macro_export = "4800"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:234:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:214:5
|
LL | #[macro_export = "4800"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:237:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:217:5
|
LL | #[macro_export = "4800"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:240:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:220:5
|
LL | #[macro_export = "4800"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:225:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:1
|
LL | #[macro_export = "4800"]
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:247:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:17
|
LL | mod inner { #![plugin_registrar="4700"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:252:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:232:5
|
LL | #[plugin_registrar = "4700"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:255:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5
|
LL | #[plugin_registrar = "4700"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:258:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:238:5
|
LL | #[plugin_registrar = "4700"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:244:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:224:1
|
LL | #[plugin_registrar = "4700"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:265:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:17
|
LL | mod inner { #![main="4300"] }
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:270:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:250:5
|
LL | #[main = "4400"] struct S;
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:273:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:253:5
|
LL | #[main = "4400"] type T = S;
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:276:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:256:5
|
LL | #[main = "4400"] impl S { }
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:262:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:242:1
|
LL | #[main = "4400"]
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:283:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:17
|
LL | mod inner { #![start="4300"] }
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:288:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:268:5
|
LL | #[start = "4300"] struct S;
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:291:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:271:5
|
LL | #[start = "4300"] type T = S;
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:294:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:274:5
|
LL | #[start = "4300"] impl S { }
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:280:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:1
|
LL | #[start = "4300"]
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:313:17
|
LL | mod inner { #![repr="3900"] }
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:336:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:5
|
LL | #[repr = "3900"] fn f() { }
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:321:5
|
LL | #[repr = "3900"] type T = S;
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:344:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5
|
LL | #[repr = "3900"] impl S { }
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:1
|
LL | #[repr = "3900"]
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:352:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:5
|
LL | #[path = "3800"] fn f() { }
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:335:5
|
LL | #[path = "3800"] struct S;
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:358:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:5
|
LL | #[path = "3800"] type T = S;
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5
|
LL | #[path = "3800"] impl S { }
| ^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:368:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:348:17
|
LL | mod inner { #![abi="3700"] }
| ^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:351:5
|
LL | #[abi = "3700"] fn f() { }
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:354:5
|
LL | #[abi = "3700"] struct S;
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:357:5
|
LL | #[abi = "3700"] type T = S;
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:360:5
|
LL | #[abi = "3700"] impl S { }
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:365:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:1
|
LL | #[abi = "3700"]
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:17
|
LL | mod inner { #![automatically_derived="3600"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:390:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5
|
LL | #[automatically_derived = "3600"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:393:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:5
|
LL | #[automatically_derived = "3600"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:396:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:376:5
|
LL | #[automatically_derived = "3600"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:379:5
|
LL | #[automatically_derived = "3600"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:1
|
LL | #[automatically_derived = "3600"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: function is marked #[no_mangle], but not exported
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:27
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:27
|
LL | #[no_mangle = "3500"] fn f() { }
| -^^^^^^^^^
= note: #[warn(private_no_mangle_fns)] on by default
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:400:17
|
LL | mod inner { #![no_link="3400"] }
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:403:5
|
LL | #[no_link = "3400"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:406:5
|
LL | #[no_link = "3400"] struct S;
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:409:5
|
LL | #[no_link = "3400"]type T = S;
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:412:5
|
LL | #[no_link = "3400"] impl S { }
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:397:1
|
LL | #[no_link = "3400"]
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:439:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:419:17
|
LL | mod inner { #![should_panic="3200"] }
| ^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:422:5
|
LL | #[should_panic = "3200"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:425:5
|
LL | #[should_panic = "3200"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:428:5
|
LL | #[should_panic = "3200"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:431:5
|
LL | #[should_panic = "3200"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:416:1
|
LL | #[should_panic = "3200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:17
|
LL | mod inner { #![ignore="3100"] }
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:441:5
|
LL | #[ignore = "3100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:464:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:444:5
|
LL | #[ignore = "3100"] struct S;
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:467:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:447:5
|
LL | #[ignore = "3100"] type T = S;
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:450:5
|
LL | #[ignore = "3100"] impl S { }
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:455:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:435:1
|
LL | #[ignore = "3100"]
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:477:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:17
|
LL | mod inner { #![no_implicit_prelude="3000"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:460:5
|
LL | #[no_implicit_prelude = "3000"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:463:5
|
LL | #[no_implicit_prelude = "3000"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5
|
LL | #[no_implicit_prelude = "3000"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:5
|
LL | #[no_implicit_prelude = "3000"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:1
|
LL | #[no_implicit_prelude = "3000"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:17
|
LL | mod inner { #![reexport_test_harness_main="2900"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5
|
LL | #[reexport_test_harness_main = "2900"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:482:5
|
LL | #[reexport_test_harness_main = "2900"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:5
|
LL | #[reexport_test_harness_main = "2900"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:5
|
LL | #[reexport_test_harness_main = "2900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:1
|
LL | #[reexport_test_harness_main = "2900"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:5
|
LL | #[macro_escape] fn f() { }
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:522:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5
|
LL | #[macro_escape] struct S;
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5
|
LL | #[macro_escape] type T = S;
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5
|
LL | #[macro_escape] impl S { }
| ^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
|
LL | mod inner { #![no_std="2600"] }
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
|
LL | mod inner { #![no_std="2600"] }
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:520:5
|
LL | #[no_std = "2600"] fn f() { }
| ^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:520:5
|
LL | #[no_std = "2600"] fn f() { }
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5
|
LL | #[no_std = "2600"] struct S;
| ^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5
|
LL | #[no_std = "2600"] struct S;
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:548:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
|
LL | #[no_std = "2600"] type T = S;
| ^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:548:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
|
LL | #[no_std = "2600"] type T = S;
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:552:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5
|
LL | #[no_std = "2600"] impl S { }
| ^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:552:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5
|
LL | #[no_std = "2600"] impl S { }
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1
|
LL | #[no_std = "2600"]
| ^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1
|
LL | #[no_std = "2600"]
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:17
|
LL | mod inner { #![crate_name="0900"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:17
|
LL | mod inner { #![crate_name="0900"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
|
LL | #[crate_name = "0900"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
|
LL | #[crate_name = "0900"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
|
LL | #[crate_name = "0900"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
|
LL | #[crate_name = "0900"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5
|
LL | #[crate_name = "0900"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5
|
LL | #[crate_name = "0900"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5
|
LL | #[crate_name = "0900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5
|
LL | #[crate_name = "0900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1
|
LL | #[crate_name = "0900"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1
|
LL | #[crate_name = "0900"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
|
LL | mod inner { #![crate_type="0800"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
|
LL | mod inner { #![crate_type="0800"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
|
LL | #[crate_type = "0800"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
|
LL | #[crate_type = "0800"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
|
LL | #[crate_type = "0800"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
|
LL | #[crate_type = "0800"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
|
LL | #[crate_type = "0800"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
|
LL | #[crate_type = "0800"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5
|
LL | #[crate_type = "0800"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5
|
LL | #[crate_type = "0800"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1
|
LL | #[crate_type = "0800"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1
|
LL | #[crate_type = "0800"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:17
|
LL | mod inner { #![feature(x0600)] }
| ^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:17
|
LL | mod inner { #![feature(x0600)] }
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
|
LL | #[feature(x0600)] fn f() { }
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
|
LL | #[feature(x0600)] fn f() { }
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
|
LL | #[feature(x0600)] struct S;
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
|
LL | #[feature(x0600)] struct S;
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
|
LL | #[feature(x0600)] type T = S;
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
|
LL | #[feature(x0600)] type T = S;
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
|
LL | #[feature(x0600)] impl S { }
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
|
LL | #[feature(x0600)] impl S { }
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1
|
LL | #[feature(x0600)]
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1
|
LL | #[feature(x0600)]
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17
|
LL | mod inner { #![no_main="0400"] }
| ^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17
|
LL | mod inner { #![no_main="0400"] }
| ^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5
|
LL | #[no_main = "0400"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5
|
LL | #[no_main = "0400"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
|
LL | #[no_main = "0400"] struct S;
| ^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
|
LL | #[no_main = "0400"] struct S;
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
|
LL | #[no_main = "0400"] type T = S;
| ^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
|
LL | #[no_main = "0400"] type T = S;
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5
|
LL | #[no_main = "0400"] impl S { }
| ^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5
|
LL | #[no_main = "0400"] impl S { }
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:1
|
LL | #[no_main = "0400"]
| ^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:1
|
LL | #[no_main = "0400"]
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:17
|
LL | mod inner { #![recursion_limit="0200"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:17
|
LL | mod inner { #![recursion_limit="0200"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5
|
LL | #[recursion_limit="0200"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5
|
LL | #[recursion_limit="0200"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
|
LL | #[recursion_limit="0200"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
|
LL | #[recursion_limit="0200"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5
|
LL | #[recursion_limit="0200"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5
|
LL | #[recursion_limit="0200"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5
|
LL | #[recursion_limit="0200"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5
|
LL | #[recursion_limit="0200"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:1
|
LL | #[recursion_limit="0200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:1
|
LL | #[recursion_limit="0200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:17
|
LL | mod inner { #![type_length_limit="0100"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:17
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:17
|
LL | mod inner { #![type_length_limit="0100"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:835:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
|
LL | #[type_length_limit="0100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:835:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
|
LL | #[type_length_limit="0100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
|
LL | #[type_length_limit="0100"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
|
LL | #[type_length_limit="0100"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
|
LL | #[type_length_limit="0100"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
|
LL | #[type_length_limit="0100"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
|
LL | #[type_length_limit="0100"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
|
LL | #[type_length_limit="0100"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:1
|
LL | #[type_length_limit="0100"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:1
|
LL | #[type_length_limit="0100"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:53:1
- |
-LL | #![macro_reexport = "5000"] //~ WARN unused attribute
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:54:1
|
LL | #![macro_export = "4800"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:56:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1
|
LL | #![plugin_registrar = "4700"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:59:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:58:1
|
LL | #![main = "x4400"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:59:1
|
LL | #![start = "x4300"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
|
LL | #![repr = "3900"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:1
|
LL | #![path = "3800"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
|
LL | #![abi = "3700"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1
|
LL | #![automatically_derived = "3600"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:68:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1
|
LL | #![no_link = "3400"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:70:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
|
LL | #![should_panic = "3200"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:71:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:70:1
|
LL | #![ignore = "3100"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:77:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:1
|
LL | #![proc_macro_derive = "2500"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: compilation successful
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:858:1
+ --> $DIR/issue-43106-gating-of-builtin-attrs.rs:837:1
|
LL | / fn main() { //~ ERROR compilation successful
LL | | println!("Hello World");
--- /dev/null
+// 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.
+
+// compile-pass
+
+#![warn(unused_must_use)]
+
+#[derive(PartialEq, Eq)]
+struct MyStruct {
+ n: usize,
+}
+
+impl MyStruct {
+ #[must_use]
+ fn need_to_use_this_method_value(&self) -> usize {
+ self.n
+ }
+}
+
+trait EvenNature {
+ #[must_use = "no side effects"]
+ fn is_even(&self) -> bool;
+}
+
+impl EvenNature for MyStruct {
+ fn is_even(&self) -> bool {
+ self.n % 2 == 0
+ }
+}
+
+trait Replaceable {
+ fn replace(&mut self, substitute: usize) -> usize;
+}
+
+impl Replaceable for MyStruct {
+ // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation
+ // method won't work; the attribute should be on the method signature in
+ // the trait's definition.
+ #[must_use]
+ fn replace(&mut self, substitute: usize) -> usize {
+ let previously = self.n;
+ self.n = substitute;
+ previously
+ }
+}
+
+#[must_use = "it's important"]
+fn need_to_use_this_value() -> bool {
+ false
+}
+
+fn main() {
+ need_to_use_this_value(); //~ WARN unused return value
+
+ let mut m = MyStruct { n: 2 };
+ let n = MyStruct { n: 3 };
+
+ m.need_to_use_this_method_value(); //~ WARN unused return value
+ m.is_even(); // trait method!
+ //~^ WARN unused return value
+
+ m.replace(3); // won't warn (annotation needs to be in trait definition)
+
+ // comparison methods are `must_use`
+ 2.eq(&3); //~ WARN unused return value
+ m.eq(&n); //~ WARN unused return value
+
+ // lint includes comparison operators
+ 2 == 3; //~ WARN unused comparison
+ m == n; //~ WARN unused comparison
+}
--- /dev/null
+warning: unused return value of `need_to_use_this_value` which must be used: it's important
+ --> $DIR/fn_must_use.rs:60:5
+ |
+LL | need_to_use_this_value(); //~ WARN unused return value
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: lint level defined here
+ --> $DIR/fn_must_use.rs:13:9
+ |
+LL | #![warn(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
+ --> $DIR/fn_must_use.rs:65:5
+ |
+LL | m.need_to_use_this_method_value(); //~ WARN unused return value
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused return value of `EvenNature::is_even` which must be used: no side effects
+ --> $DIR/fn_must_use.rs:66:5
+ |
+LL | m.is_even(); // trait method!
+ | ^^^^^^^^^^^^
+
+warning: unused return value of `std::cmp::PartialEq::eq` which must be used
+ --> $DIR/fn_must_use.rs:72:5
+ |
+LL | 2.eq(&3); //~ WARN unused return value
+ | ^^^^^^^^^
+
+warning: unused return value of `std::cmp::PartialEq::eq` which must be used
+ --> $DIR/fn_must_use.rs:73:5
+ |
+LL | m.eq(&n); //~ WARN unused return value
+ | ^^^^^^^^^
+
+warning: unused comparison which must be used
+ --> $DIR/fn_must_use.rs:76:5
+ |
+LL | 2 == 3; //~ WARN unused comparison
+ | ^^^^^^
+
+warning: unused comparison which must be used
+ --> $DIR/fn_must_use.rs:77:5
+ |
+LL | m == n; //~ WARN unused comparison
+ | ^^^^^^
+
-error: compilation successful
- --> $DIR/borrowing.rs:15:1
+error[E0597]: `a` does not live long enough
+ --> $DIR/borrowing.rs:18:18
|
-LL | / fn main() { #![rustc_error] // rust-lang/rust#49855
-LL | | let _b = {
-LL | | let a = 3;
-LL | | unsafe { (|| yield &a).resume() }
-... |
-LL | | };
-LL | | }
- | |_^
+LL | unsafe { (|| yield &a).resume() }
+ | ^^^^^^^^^^^^^
+ | |
+ | borrowed value does not live long enough
+ | borrow may end up in a temporary, created here
+LL | //~^ ERROR: `a` does not live long enough
+LL | };
+ | -- temporary later dropped here, potentially using the reference
+ | |
+ | borrowed value only lives until here
-error: aborting due to previous error
+error[E0597]: `a` does not live long enough
+ --> $DIR/borrowing.rs:24:9
+ |
+LL | / || {
+LL | | yield &a
+LL | | //~^ ERROR: `a` does not live long enough
+LL | | }
+ | |_________^ borrowed value does not live long enough
+LL | };
+ | - borrowed value only lives until here
+LL | }
+ | - borrow later used here, when `_b` is dropped
+
+error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0597`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(generators, generator_trait, rustc_attrs)]
+#![feature(generators, generator_trait)]
use std::ops::Generator;
-fn main() { #![rustc_error] // rust-lang/rust#49855
+fn main() {
let _b = {
let a = 3;
unsafe { (|| yield &a).resume() }
-error: compilation successful
- --> $DIR/dropck.rs:16:1
+error[E0597]: `ref_` does not live long enough
+ --> $DIR/dropck.rs:22:11
|
-LL | / fn main() { #![rustc_error] // rust-lang/rust#49855
-LL | | let (cell, mut gen);
-LL | | cell = Box::new(RefCell::new(0));
-LL | | let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
-... |
-LL | | // drops the RefCell and then the Ref, leading to use-after-free
-LL | | }
- | |_^
+LL | gen = || {
+ | ___________^
+LL | | // but the generator can use it to drop a `Ref<'a, i32>`.
+LL | | let _d = ref_.take(); //~ ERROR `ref_` does not live long enough
+LL | | yield;
+LL | | };
+ | |_____^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | borrowed value only lives until here
+ | borrow later used here, when `gen` is dropped
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0597`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(generators, generator_trait, box_leak, rustc_attrs)]
+#![feature(generators, generator_trait, box_leak)]
use std::cell::RefCell;
use std::ops::Generator;
-fn main() { #![rustc_error] // rust-lang/rust#49855
+fn main() {
let (cell, mut gen);
cell = Box::new(RefCell::new(0));
let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
+ //~^ ERROR `*cell` does not live long enough [E0597]
// the upvar is the non-dropck `&mut Option<Ref<'a, i32>>`.
gen = || {
// but the generator can use it to drop a `Ref<'a, i32>`.
+error[E0597]: `*cell` does not live long enough
+ --> $DIR/dropck.rs:19:40
+ |
+LL | let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
+ | ^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `*cell` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
error[E0597]: `ref_` does not live long enough
- --> $DIR/dropck.rs:23:18
+ --> $DIR/dropck.rs:24:18
|
LL | gen = || {
| -- capture occurs here
|
= note: values in a scope are dropped in the opposite order they are created
-error: aborting due to previous error
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0597`.
error[E0597]: `b` does not live long enough
--> $DIR/ref-escapes-but-not-over-yield.rs:24:13
|
-LL | a = &b;
- | ^^ borrowed value does not live long enough
-LL | //~^ ERROR `b` does not live long enough
-LL | };
- | - borrowed value only lives until here
+LL | let mut b = move || {
+ | _________________-
+LL | | yield();
+LL | | let b = 5;
+LL | | a = &b;
+ | | ^^ borrowed value does not live long enough
+LL | | //~^ ERROR `b` does not live long enough
+LL | | };
+ | | -
+ | | |
+ | | borrowed value only lives until here
+ | |_____temporary later dropped here, potentially using the reference
+ | borrow may end up in a temporary, created here
error: aborting due to previous error
fn main() {
assert_eq!('x'.ipu_flatten(), 1);
//~^ WARN a method with this name may be added to the standard library in the future
- //~^^ WARN once this method is added to the standard library, there will be ambiguity here
+ //~^^ WARN once this method is added to the standard library, the ambiguity may cause an error
}
| ^^^^^^^^^^^
|
= note: #[warn(unstable_name_collision)] on by default
- = warning: once this method is added to the standard library, there will be ambiguity here, which will cause a hard error!
+ = warning: once this method is added to the standard library, the ambiguity may cause an error or change in behavior!
= note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
= help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_flatten(...)` to keep using the current method
= note: add #![feature(ipu_flatten)] to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten`
--- /dev/null
+// Copyright 2018 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.
+
+// compile-pass
+
+#![feature(use_extern_macros, decl_macro)]
+
+mod type_ns {
+ pub type A = u8;
+}
+mod value_ns {
+ pub const A: u8 = 0;
+}
+mod macro_ns {
+ pub macro A() {}
+}
+
+mod merge2 {
+ pub use type_ns::A;
+ pub use value_ns::A;
+}
+mod merge3 {
+ pub use type_ns::A;
+ pub use value_ns::A;
+ pub use macro_ns::A;
+}
+
+mod use2 {
+ pub use merge2::A;
+}
+mod use3 {
+ pub use merge3::A;
+}
+
+fn main() {
+ type B2 = use2::A;
+ let a2 = use2::A;
+
+ type B3 = use3::A;
+ let a3 = use3::A;
+ use3::A!();
+}
--- /dev/null
+// Copyright 2016 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.
+
+#![feature(concat_idents)]
+
+fn main() {
+ let x = concat_idents!(); //~ ERROR concat_idents! takes 1 or more arguments
+}
--- /dev/null
+error: concat_idents! takes 1 or more arguments.
+ --> $DIR/issue-50403.rs:14:13
+ |
+LL | let x = concat_idents!(); //~ ERROR concat_idents! takes 1 or more arguments
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
// compile-pass
-#![feature(fn_must_use)]
#![warn(unused_must_use)]
fn main() {
warning: unused comparison which must be used
- --> $DIR/must-use-ops.rs:23:5
+ --> $DIR/must-use-ops.rs:22:5
|
LL | val == 1;
| ^^^^^^^^
|
note: lint level defined here
- --> $DIR/must-use-ops.rs:16:9
+ --> $DIR/must-use-ops.rs:15:9
|
LL | #![warn(unused_must_use)]
| ^^^^^^^^^^^^^^^
warning: unused comparison which must be used
- --> $DIR/must-use-ops.rs:24:5
+ --> $DIR/must-use-ops.rs:23:5
|
LL | val < 1;
| ^^^^^^^
warning: unused comparison which must be used
- --> $DIR/must-use-ops.rs:25:5
+ --> $DIR/must-use-ops.rs:24:5
|
LL | val <= 1;
| ^^^^^^^^
warning: unused comparison which must be used
- --> $DIR/must-use-ops.rs:26:5
+ --> $DIR/must-use-ops.rs:25:5
|
LL | val != 1;
| ^^^^^^^^
warning: unused comparison which must be used
- --> $DIR/must-use-ops.rs:27:5
+ --> $DIR/must-use-ops.rs:26:5
|
LL | val >= 1;
| ^^^^^^^^
warning: unused comparison which must be used
- --> $DIR/must-use-ops.rs:28:5
+ --> $DIR/must-use-ops.rs:27:5
|
LL | val > 1;
| ^^^^^^^
warning: unused arithmetic operation which must be used
- --> $DIR/must-use-ops.rs:31:5
+ --> $DIR/must-use-ops.rs:30:5
|
LL | val + 2;
| ^^^^^^^
warning: unused arithmetic operation which must be used
- --> $DIR/must-use-ops.rs:32:5
+ --> $DIR/must-use-ops.rs:31:5
|
LL | val - 2;
| ^^^^^^^
warning: unused arithmetic operation which must be used
- --> $DIR/must-use-ops.rs:33:5
+ --> $DIR/must-use-ops.rs:32:5
|
LL | val / 2;
| ^^^^^^^
warning: unused arithmetic operation which must be used
- --> $DIR/must-use-ops.rs:34:5
+ --> $DIR/must-use-ops.rs:33:5
|
LL | val * 2;
| ^^^^^^^
warning: unused arithmetic operation which must be used
- --> $DIR/must-use-ops.rs:35:5
+ --> $DIR/must-use-ops.rs:34:5
|
LL | val % 2;
| ^^^^^^^
warning: unused logical operation which must be used
- --> $DIR/must-use-ops.rs:38:5
+ --> $DIR/must-use-ops.rs:37:5
|
LL | true && true;
| ^^^^^^^^^^^^
warning: unused logical operation which must be used
- --> $DIR/must-use-ops.rs:39:5
+ --> $DIR/must-use-ops.rs:38:5
|
LL | false || true;
| ^^^^^^^^^^^^^
warning: unused bitwise operation which must be used
- --> $DIR/must-use-ops.rs:42:5
+ --> $DIR/must-use-ops.rs:41:5
|
LL | 5 ^ val;
| ^^^^^^^
warning: unused bitwise operation which must be used
- --> $DIR/must-use-ops.rs:43:5
+ --> $DIR/must-use-ops.rs:42:5
|
LL | 5 & val;
| ^^^^^^^
warning: unused bitwise operation which must be used
- --> $DIR/must-use-ops.rs:44:5
+ --> $DIR/must-use-ops.rs:43:5
|
LL | 5 | val;
| ^^^^^^^
warning: unused bitwise operation which must be used
- --> $DIR/must-use-ops.rs:45:5
+ --> $DIR/must-use-ops.rs:44:5
|
LL | 5 << val;
| ^^^^^^^^
warning: unused bitwise operation which must be used
- --> $DIR/must-use-ops.rs:46:5
+ --> $DIR/must-use-ops.rs:45:5
|
LL | 5 >> val;
| ^^^^^^^^
warning: unused unary operation which must be used
- --> $DIR/must-use-ops.rs:49:5
+ --> $DIR/must-use-ops.rs:48:5
|
LL | !val;
| ^^^^
warning: unused unary operation which must be used
- --> $DIR/must-use-ops.rs:50:5
+ --> $DIR/must-use-ops.rs:49:5
|
LL | -val;
| ^^^^
warning: unused unary operation which must be used
- --> $DIR/must-use-ops.rs:51:5
+ --> $DIR/must-use-ops.rs:50:5
|
LL | *val_pointer;
| ^^^^^^^^^^^^
--- /dev/null
+// Copyright 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.
+
+// aux-build:two_macros.rs
+
+#![feature(macro_reexport)] //~ ERROR feature has been removed
+
+#[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
+extern crate two_macros;
+
+fn main() {}
--- /dev/null
+error[E0557]: feature has been removed
+ --> $DIR/macro-reexport-removed.rs:13:12
+ |
+LL | #![feature(macro_reexport)] //~ ERROR feature has been removed
+ | ^^^^^^^^^^^^^^
+ |
+note: subsumed by `#![feature(use_extern_macros)]` and `pub use`
+ --> $DIR/macro-reexport-removed.rs:13:12
+ |
+LL | #![feature(macro_reexport)] //~ ERROR feature has been removed
+ | ^^^^^^^^^^^^^^
+
+error[E0658]: The attribute `macro_reexport` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+ --> $DIR/macro-reexport-removed.rs:15:1
+ |
+LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add #![feature(custom_attribute)] to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0557, E0658.
+For more information about an error, try `rustc --explain E0557`.
--- /dev/null
+// Copyright 2018 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.
+
+// compile-flags: -Z print-type-sizes
+// compile-pass
+
+// This test makes sure that the tag is not grown for `repr(C)` or `repr(u8)`
+// variants (see https://github.com/rust-lang/rust/issues/50098 for the original bug).
+
+#![feature(start)]
+#![allow(dead_code)]
+
+#[repr(C, u8)]
+enum ReprCu8 {
+ A(u16),
+ B,
+}
+
+#[repr(u8)]
+enum Repru8 {
+ A(u16),
+ B,
+}
+
+#[start]
+fn start(_: isize, _: *const *const u8) -> isize {
+ 0
+}
--- /dev/null
+print-type-size type: `ReprCu8`: 4 bytes, alignment: 2 bytes
+print-type-size discriminant: 1 bytes
+print-type-size variant `A`: 3 bytes
+print-type-size padding: 1 bytes
+print-type-size field `.0`: 2 bytes, alignment: 2 bytes
+print-type-size variant `B`: 1 bytes
+print-type-size type: `Repru8`: 4 bytes, alignment: 2 bytes
+print-type-size discriminant: 1 bytes
+print-type-size variant `A`: 3 bytes
+print-type-size padding: 1 bytes
+print-type-size field `.0`: 2 bytes, alignment: 2 bytes
+print-type-size variant `B`: 0 bytes
+++ /dev/null
-// 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.
-
-// compile-pass
-
-#![feature(fn_must_use)]
-#![warn(unused_must_use)]
-
-#[derive(PartialEq, Eq)]
-struct MyStruct {
- n: usize,
-}
-
-impl MyStruct {
- #[must_use]
- fn need_to_use_this_method_value(&self) -> usize {
- self.n
- }
-}
-
-trait EvenNature {
- #[must_use = "no side effects"]
- fn is_even(&self) -> bool;
-}
-
-impl EvenNature for MyStruct {
- fn is_even(&self) -> bool {
- self.n % 2 == 0
- }
-}
-
-trait Replaceable {
- fn replace(&mut self, substitute: usize) -> usize;
-}
-
-impl Replaceable for MyStruct {
- // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation
- // method won't work; the attribute should be on the method signature in
- // the trait's definition.
- #[must_use]
- fn replace(&mut self, substitute: usize) -> usize {
- let previously = self.n;
- self.n = substitute;
- previously
- }
-}
-
-#[must_use = "it's important"]
-fn need_to_use_this_value() -> bool {
- false
-}
-
-fn main() {
- need_to_use_this_value(); //~ WARN unused return value
-
- let mut m = MyStruct { n: 2 };
- let n = MyStruct { n: 3 };
-
- m.need_to_use_this_method_value(); //~ WARN unused return value
- m.is_even(); // trait method!
- //~^ WARN unused return value
-
- m.replace(3); // won't warn (annotation needs to be in trait definition)
-
- // comparison methods are `must_use`
- 2.eq(&3); //~ WARN unused return value
- m.eq(&n); //~ WARN unused return value
-
- // lint includes comparison operators
- 2 == 3; //~ WARN unused comparison
- m == n; //~ WARN unused comparison
-}
+++ /dev/null
-warning: unused return value of `need_to_use_this_value` which must be used: it's important
- --> $DIR/fn_must_use.rs:61:5
- |
-LL | need_to_use_this_value(); //~ WARN unused return value
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: lint level defined here
- --> $DIR/fn_must_use.rs:14:9
- |
-LL | #![warn(unused_must_use)]
- | ^^^^^^^^^^^^^^^
-
-warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
- --> $DIR/fn_must_use.rs:66:5
- |
-LL | m.need_to_use_this_method_value(); //~ WARN unused return value
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused return value of `EvenNature::is_even` which must be used: no side effects
- --> $DIR/fn_must_use.rs:67:5
- |
-LL | m.is_even(); // trait method!
- | ^^^^^^^^^^^^
-
-warning: unused return value of `std::cmp::PartialEq::eq` which must be used
- --> $DIR/fn_must_use.rs:73:5
- |
-LL | 2.eq(&3); //~ WARN unused return value
- | ^^^^^^^^^
-
-warning: unused return value of `std::cmp::PartialEq::eq` which must be used
- --> $DIR/fn_must_use.rs:74:5
- |
-LL | m.eq(&n); //~ WARN unused return value
- | ^^^^^^^^^
-
-warning: unused comparison which must be used
- --> $DIR/fn_must_use.rs:77:5
- |
-LL | 2 == 3; //~ WARN unused comparison
- | ^^^^^^
-
-warning: unused comparison which must be used
- --> $DIR/fn_must_use.rs:78:5
- |
-LL | m == n; //~ WARN unused comparison
- | ^^^^^^
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(attr_literals)]
-
-#[repr(align(16))]
-struct Gem {
- mohs_hardness: u8,
- poofed: bool,
- weapon: Weapon,
-}
-
#[repr(simd)] //~ ERROR are experimental
struct Weapon {
name: String,
damage: u32
}
-impl Gem {
- #[must_use] fn summon_weapon(&self) -> Weapon { self.weapon }
- //~^ WARN is experimental
-}
-
-#[must_use] //~ WARN is experimental
-fn bubble(gem: Gem) -> Result<Gem, ()> {
- if gem.poofed {
- Ok(gem)
- } else {
- Err(())
- }
-}
-
fn main() {}
error[E0658]: SIMD types are experimental and possibly buggy (see issue #27731)
- --> $DIR/gated-features-attr-spans.rs:20:1
+ --> $DIR/gated-features-attr-spans.rs:11:1
|
LL | #[repr(simd)] //~ ERROR are experimental
| ^^^^^^^^^^^^^
|
= help: add #![feature(repr_simd)] to the crate attributes to enable
-warning: `#[must_use]` on methods is experimental (see issue #43302)
- --> $DIR/gated-features-attr-spans.rs:27:5
- |
-LL | #[must_use] fn summon_weapon(&self) -> Weapon { self.weapon }
- | ^^^^^^^^^^^
- |
- = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
-warning: `#[must_use]` on functions is experimental (see issue #43302)
- --> $DIR/gated-features-attr-spans.rs:31:1
- |
-LL | #[must_use] //~ WARN is experimental
- | ^^^^^^^^^^^
- |
- = help: add #![feature(fn_must_use)] to the crate attributes to enable
-
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
-Subproject commit 122fd5be5201913d42e219e132d6569493583bca
+Subproject commit af3f1cd29bc872b932a13083e531255aab233a7e
-Subproject commit 9144e223a5b90e078366275ff3dcdd406e62eae3
+Subproject commit d2f44357fef6d61f316abc403e0a5d917f2771c6
var Module = module.constructor;
var m = new Module();
m._compile(content, "tmp.js");
+ m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1;
return m.exports;
}
}
}
if (allGood === true) {
- return true;
+ return i;
}
}
- return false;
+ return null;
}
function main(argv) {
'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
const expected = loadedFile.EXPECTED;
const query = loadedFile.QUERY;
+ const ignore_order = loadedFile.ignore_order;
var results = loaded.execSearch(loaded.getQuery(query), index);
process.stdout.write('Checking "' + file + '" ... ');
var error_text = [];
break;
}
var entry = expected[key];
- var found = false;
+ var prev_pos = 0;
for (var i = 0; i < entry.length; ++i) {
- if (lookForEntry(entry[i], results[key]) === true) {
- found = true;
- } else {
+ var entry_pos = lookForEntry(entry[i], results[key]);
+ if (entry_pos === null) {
error_text.push("==> Result not found in '" + key + "': '" +
JSON.stringify(entry[i]) + "'");
+ } else if (entry_pos < prev_pos && ignore_order === false) {
+ error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " +
+ " before '" + JSON.stringify(results[key][entry_pos]) + "'");
+ } else {
+ prev_pos = entry_pos;
}
}
}
-Subproject commit 0f4ed08d0e3d180d66e46904126c3792f57668a9
+Subproject commit b6cd17f28ae314f2484ff05d3ce57652d51c5e85