From: bors Date: Fri, 4 May 2018 08:22:13 +0000 (+0000) Subject: Auto merge of #50409 - KiChjang:issue-50343, r=nikomatsakis X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=22a41e45157869b9a4d2ab7a21c7142a93d35cb1;hp=4bc48480c08b9749e6b7f1701a1e03529496382d;p=rust.git Auto merge of #50409 - KiChjang:issue-50343, r=nikomatsakis Skip checking for unused mutable locals that have no name Fixes #50343. --- diff --git a/src/Cargo.lock b/src/Cargo.lock index a6f78a7e6b4..ccdb24d7375 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -996,9 +996,10 @@ dependencies = [ [[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)", @@ -1623,7 +1624,7 @@ dependencies = [ [[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)", @@ -1632,7 +1633,7 @@ dependencies = [ "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)", @@ -1644,7 +1645,7 @@ dependencies = [ "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)", @@ -1728,7 +1729,6 @@ dependencies = [ "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", @@ -1740,16 +1740,17 @@ dependencies = [ [[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)", @@ -1757,53 +1758,66 @@ dependencies = [ "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)", @@ -1872,15 +1886,6 @@ dependencies = [ "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" @@ -2026,7 +2031,6 @@ dependencies = [ "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", @@ -2053,7 +2057,6 @@ version = "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", @@ -2154,7 +2157,6 @@ dependencies = [ "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", @@ -2205,7 +2207,6 @@ dependencies = [ "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", @@ -2235,20 +2236,22 @@ dependencies = [ [[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)", @@ -3063,7 +3066,7 @@ source = "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" @@ -3134,12 +3137,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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" diff --git a/src/Cargo.toml b/src/Cargo.toml index 814c054c51e..35858ee2868 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -40,14 +40,6 @@ members = [ "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] diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 1b4b2c5fb2a..7175f6a6764 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -325,6 +325,14 @@ struct TomlTarget { } 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; @@ -348,9 +356,9 @@ pub fn default_opts() -> Config { 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)); diff --git a/src/doc/unstable-book/src/language-features/fn-must-use.md b/src/doc/unstable-book/src/language-features/fn-must-use.md deleted file mode 100644 index 71b6cd663a0..00000000000 --- a/src/doc/unstable-book/src/language-features/fn-must-use.md +++ /dev/null @@ -1,30 +0,0 @@ -# `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) -} - -``` diff --git a/src/doc/unstable-book/src/language-features/tool-attributes.md b/src/doc/unstable-book/src/language-features/tool-attributes.md new file mode 100644 index 00000000000..15fc84a3e2a --- /dev/null +++ b/src/doc/unstable-book/src/language-features/tool-attributes.md @@ -0,0 +1,26 @@ +# `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(); +} +``` diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0493f92bc52..da4b76a4d52 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -96,7 +96,7 @@ #![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)] @@ -122,7 +122,7 @@ #![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)] diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 32272169307..1c8ff316e55 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -25,7 +25,7 @@ #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(exact_chunks)] -#![feature(inclusive_range_fields)] +#![feature(inclusive_range_methods)] extern crate alloc_system; extern crate core; diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 99d9c51efc7..6fd0b33f02a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1282,6 +1282,7 @@ fn test_box_slice_clone() { } #[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; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 0e21a3327fd..04dd42583d4 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -76,7 +76,6 @@ #![feature(doc_cfg)] #![feature(doc_spotlight)] #![feature(extern_types)] -#![feature(fn_must_use)] #![feature(fundamental)] #![feature(intrinsics)] #![feature(iterator_flatten)] @@ -103,6 +102,7 @@ #![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))] @@ -114,6 +114,7 @@ #![cfg_attr(stage0, feature(target_feature))] #![cfg_attr(stage0, feature(cfg_target_feature))] +#![cfg_attr(stage0, feature(fn_must_use))] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index f9371ed0575..c830c22ee5f 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -606,8 +606,8 @@ macro_rules! option_env { #[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. diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index d70f7ae66f9..b01a769eda7 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -318,9 +318,9 @@ pub fn contains(&self, item: &U) -> bool /// # 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]; @@ -331,14 +331,88 @@ pub fn contains(&self, item: &U) -> bool #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { + // 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 RangeInclusive { + /// 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 fmt::Debug for RangeInclusive { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/libcore/slice/memchr.rs b/src/libcore/slice/memchr.rs index 69c9cb37dcf..469404f7f6b 100644 --- a/src/libcore/slice/memchr.rs +++ b/src/libcore/slice/memchr.rs @@ -39,21 +39,10 @@ fn repeat_byte(b: u8) -> usize { (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`. diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index e4d27717938..f6750c590b3 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -44,7 +44,7 @@ #![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; diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index bed08f86d72..d66193b1687 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -50,21 +50,21 @@ fn test_full_range() { #[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); } diff --git a/src/libcore/unicode/bool_trie.rs b/src/libcore/unicode/bool_trie.rs index 3e45b08f399..0e6437fded5 100644 --- a/src/libcore/unicode/bool_trie.rs +++ b/src/libcore/unicode/bool_trie.rs @@ -42,15 +42,15 @@ pub struct BoolTrie { } 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]) } } @@ -63,14 +63,14 @@ pub struct SmallBoolTrie { 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 } diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 357ebb89fb6..af108188ce0 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -19,7 +19,6 @@ log = { version = "0.4", features = ["release_max_level_info", "std"] } 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" } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index cad6ff8ae9f..24a1256c9d3 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -153,10 +153,7 @@ fn check_repr(&self, item: &hir::Item, target: Target) { // ``` 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(); @@ -311,7 +308,7 @@ fn check_expr_attributes(&self, expr: &hir::Expr) { 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"); } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e4b9fc1385d..51f0c1d7047 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3119,6 +3119,20 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr { ExprKind::Index(ref el, ref er) => { hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er))) } + // Desugar `..=` to `std::ops::RangeInclusive::new(, )` + 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::*; @@ -3128,7 +3142,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr { (&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(), diff --git a/src/librustc/ich/impls_const_math.rs b/src/librustc/ich/impls_const_math.rs deleted file mode 100644 index 5f3ff461c0c..00000000000 --- a/src/librustc/ich/impls_const_math.rs +++ /dev/null @@ -1,44 +0,0 @@ -// 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 or the MIT license -// , 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 -}); diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 437626ff536..33f43e53394 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -227,27 +227,6 @@ fn hash_stable(&self, } } -impl<'a, 'gcx> HashStable> -for mir::AssertMessage<'gcx> { - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher) { - 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> diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index c1e86473996..1cf9b7bf478 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -199,8 +199,7 @@ fn hash_stable(&self, 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(); @@ -211,12 +210,23 @@ fn hash_stable(&self, } } +impl<'a> HashStable> for ast::Path { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + self.segments.len().hash_stable(hcx, hasher); + for segment in &self.segments { + segment.ident.name.hash_stable(hcx, hasher); + } + } +} + impl<'a> HashStable> for ast::Attribute { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { // 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 { @@ -229,10 +239,7 @@ fn hash_stable(&self, } = *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); } diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 5ab8d6eb7b3..a40d8e09277 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -505,9 +505,6 @@ fn hash_stable(&self, 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); } @@ -528,16 +525,26 @@ fn hash_stable(&self, predicates }); + impl<'a, 'gcx> HashStable> for ::mir::interpret::EvalError<'gcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + self.kind.hash_stable(hcx, hasher) + } +} + +impl<'a, 'gcx, O: HashStable>> HashStable> +for ::mir::interpret::EvalErrorKind<'gcx, O> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { 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 | @@ -568,8 +575,12 @@ fn hash_stable(&self, 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); @@ -588,14 +599,9 @@ fn hash_stable(&self, }, 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), @@ -668,6 +674,7 @@ fn hash_stable(&self, 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), } } } diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index 1b77a2e7c82..a0c6bbbb239 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -18,7 +18,6 @@ mod caching_codemap_view; mod hcx; -mod impls_const_math; mod impls_cstore; mod impls_hir; mod impls_mir; diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 096aed85f55..ccba5a09cf6 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -407,7 +407,7 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { 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), @@ -424,7 +424,7 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { } 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); diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index c35cdf91fe7..b8437e39ddc 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -62,7 +62,7 @@ pub fn higher_ranked_sub(&mut self, a: &Binder, b: &Binder, a_is_expect // 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); @@ -114,7 +114,7 @@ pub fn higher_ranked_match(&mut self, // 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); @@ -587,14 +587,13 @@ fn region_vars_confined_to_snapshot(&self, /// /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html pub fn skolemize_late_bound_regions(&self, - binder: &ty::Binder, - snapshot: &CombinedSnapshot<'a, 'tcx>) + binder: &ty::Binder) -> (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={:?})", @@ -779,7 +778,8 @@ pub fn pop_skolemized(&self, 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); diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 00b2ac7449f..5984a831e6f 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -15,7 +15,7 @@ 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}; @@ -37,7 +37,7 @@ /// 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>, @@ -47,7 +47,7 @@ pub fn resolve<'tcx>( let mut errors = vec![]; let mut resolver = LexicalResolver { region_rels, - var_origins, + var_infos, data, }; let values = resolver.infer_variable_values(&mut errors); @@ -103,7 +103,7 @@ struct RegionAndOrigin<'tcx> { struct LexicalResolver<'cx, 'gcx: 'tcx, 'tcx: 'cx> { region_rels: &'cx RegionRelations<'cx, 'gcx, 'tcx>, - var_origins: VarOrigins, + var_infos: VarInfos, data: RegionConstraintData<'tcx>, } @@ -132,7 +132,7 @@ fn infer_variable_values( } fn num_vars(&self) -> usize { - self.var_origins.len() + self.var_infos.len() } /// Initially, the value for all variables is set to `'empty`, the @@ -279,7 +279,7 @@ fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> (&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, @@ -576,7 +576,7 @@ fn region_order_key(x: &RegionAndOrigin) -> u8 { 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: {:?}", @@ -598,7 +598,7 @@ fn region_order_key(x: &RegionAndOrigin) -> u8 { } 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={:?}", diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 553926dba8f..c62e7f8d9b6 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -42,7 +42,7 @@ 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; @@ -183,6 +183,17 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // 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)>>, + + /// 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, } /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized @@ -455,6 +466,7 @@ pub fn enter(&'tcx mut self, f: F) -> R err_count_on_creation: tcx.sess.err_count(), in_snapshot: Cell::new(false), region_obligations: RefCell::new(vec![]), + universe: Cell::new(ty::UniverseIndex::ROOT), })) } } @@ -489,6 +501,7 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> { float_snapshot: ut::Snapshot>, region_constraints_snapshot: RegionSnapshot, region_obligations_snapshot: usize, + universe: ty::UniverseIndex, was_in_snapshot: bool, _in_progress_tables: Option>>, } @@ -618,6 +631,7 @@ fn start_snapshot(&self) -> CombinedSnapshot<'a, '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. @@ -635,10 +649,12 @@ fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>) { 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() @@ -667,6 +683,7 @@ fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) { float_snapshot, region_constraints_snapshot, region_obligations_snapshot: _, + universe: _, was_in_snapshot, _in_progress_tables } = snapshot; @@ -811,7 +828,7 @@ pub fn subtype_predicate(&self, 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)?; @@ -828,7 +845,7 @@ pub fn region_outlives_predicate(&self, { 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)); @@ -841,7 +858,7 @@ pub fn region_outlives_predicate(&self, 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> { @@ -872,12 +889,14 @@ pub fn next_float_var_id(&self) -> FloatVid { /// 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. @@ -909,7 +928,8 @@ pub fn type_var_for_def(&self, -> 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) @@ -1004,12 +1024,12 @@ fn resolve_regions_and_report_errors_inner( 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()); @@ -1057,13 +1077,13 @@ pub fn with_region_constraints( /// 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 { @@ -1356,6 +1376,10 @@ pub fn clear_caches(&self) { self.evaluation_cache.clear(); self.projection_cache.borrow_mut().clear(); } + + fn universe(&self) -> ty::UniverseIndex { + self.universe.get() + } } impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> { diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 4113a2dd417..c388fa21371 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -22,18 +22,16 @@ 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, + var_infos: IndexVec, data: RegionConstraintData<'tcx>, @@ -47,9 +45,6 @@ pub struct RegionConstraintCollector<'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, @@ -76,7 +71,7 @@ pub struct RegionConstraintCollector<'tcx> { unification_table: ut::UnificationTable>, } -pub type VarOrigins = IndexVec; +pub type VarInfos = IndexVec; /// The full set of region constraints gathered up by the collector. /// Describes constraints between the region variables and other @@ -230,10 +225,15 @@ enum CombineMapType { type CombineMap<'tcx> = FxHashMap, RegionVid>; +#[derive(Debug, Clone, Copy)] +pub struct RegionVariableInfo { + pub origin: RegionVariableOrigin, + pub universe: ty::UniverseIndex, +} + pub struct RegionSnapshot { length: usize, region_snapshot: ut::Snapshot>, - skolemization_count: u32, } /// When working with skolemized regions, we often wish to find all of @@ -273,19 +273,18 @@ pub fn both() -> Self { 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> { @@ -295,9 +294,9 @@ 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 @@ -319,18 +318,15 @@ pub fn take_and_reset_data(&mut self) -> RegionConstraintData<'tcx> { // 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 @@ -343,7 +339,7 @@ pub fn take_and_reset_data(&mut self) -> RegionConstraintData<'tcx> { // 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 }); } @@ -365,7 +361,6 @@ pub fn start_snapshot(&mut self) -> RegionSnapshot { RegionSnapshot { length, region_snapshot: self.unification_table.snapshot(), - skolemization_count: self.skolemization_count, } } @@ -373,12 +368,6 @@ pub fn commit(&mut self, snapshot: RegionSnapshot) { 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); @@ -398,7 +387,6 @@ pub fn rollback_to(&mut self, snapshot: RegionSnapshot) { } let c = self.undo_log.pop().unwrap(); assert!(c == OpenSnapshot); - self.skolemization_count = snapshot.skolemization_count; self.unification_table.rollback_to(snapshot.region_snapshot); } @@ -411,8 +399,8 @@ fn rollback_undo_entry(&mut self, undo_entry: UndoLogEntry<'tcx>) { // 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); @@ -433,8 +421,13 @@ fn rollback_undo_entry(&mut self, undo_entry: UndoLogEntry<'tcx>) { } } - 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 }); @@ -450,44 +443,14 @@ pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid { 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 @@ -496,7 +459,7 @@ pub fn push_skolemized( /// created in that time. pub fn pop_skolemized( &mut self, - _tcx: TyCtxt<'_, '_, 'tcx>, + skolemization_count: ty::UniverseIndex, skols: &FxHashSet>, snapshot: &RegionSnapshot, ) { @@ -505,36 +468,28 @@ pub fn pop_skolemized( 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 } @@ -551,7 +506,6 @@ pub fn pop_skolemized( self.rollback_undo_entry(undo_entry); } - self.skolemization_count = snapshot.skolemization_count; return; fn kill_constraint<'tcx>( @@ -805,7 +759,10 @@ fn combine_vars( 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)); @@ -821,6 +778,24 @@ fn combine_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 { self.undo_log[mark.length..] .iter() @@ -865,12 +840,7 @@ pub fn tainted( 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) } } diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 5e96f4eb576..d40e1b3760f 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -78,10 +78,12 @@ struct TypeVariableData { #[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> { match *self { TypeVariableValue::Unknown { .. } => None, @@ -181,10 +183,11 @@ pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) { /// 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); @@ -437,7 +440,16 @@ fn unify_values(value1: &Self, value2: &Self) -> Result { (&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 }) + } } } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 24892dfcc8f..879d38c4894 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -69,7 +69,7 @@ #![feature(trusted_len)] #![feature(catch_expr)] #![feature(test)] -#![feature(inclusive_range_fields)] +#![feature(inclusive_range_methods)] #![recursion_limit="512"] @@ -85,7 +85,6 @@ 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; diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index e8b536d5267..d158f52c643 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -198,7 +198,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush { "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, }; @@ -221,7 +221,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush { 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); @@ -260,7 +260,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush { 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(); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 0d4fd99995f..d6c6f9dc0f6 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -507,7 +507,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session, 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) diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 19a7576b7ce..0ecab50dda2 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -11,7 +11,6 @@ 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; @@ -62,7 +61,6 @@ pub enum ErrKind<'tcx> { UnimplementedConstVal(&'static str), IndexOutOfBounds { len: u64, index: u64 }, - Math(ConstMathErr), LayoutError(layout::LayoutError<'tcx>), TypeckError, @@ -76,15 +74,6 @@ pub struct FrameInfo { pub location: String, } -impl<'tcx> From 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>), @@ -122,7 +111,6 @@ macro_rules! simple { len, index) } - Math(ref err) => Simple(err.description().into_cow()), LayoutError(ref err) => Simple(err.to_string().into_cow()), TypeckError => simple!("type-checking failed"), diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 5f4efbeeaa8..bfc9ff6660d 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -690,21 +690,22 @@ pub fn nearest_common_ancestor(&self, // 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); } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 328b2db2b58..279908d2b67 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -205,7 +205,7 @@ fn annotate(&mut self, id: NodeId, attrs: &[Attribute], } 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 \ diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index 1ed5a22257c..41ba526b73f 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -68,7 +68,7 @@ fn calculate_predecessors(mir: &Mir) -> IndexVec> { 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); } } diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index b919f4d15a8..1e1d50c3fc0 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -1,4 +1,3 @@ -use std::error::Error; use std::{fmt, env}; use mir; @@ -8,18 +7,16 @@ 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, } -impl<'tcx> From> for EvalError<'tcx> { - fn from(kind: EvalErrorKind<'tcx>) -> Self { +impl<'tcx> From> 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 @@ -31,8 +28,10 @@ fn from(kind: EvalErrorKind<'tcx>) -> Self { } } -#[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), @@ -60,10 +59,12 @@ pub enum EvalErrorKind<'tcx> { 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, @@ -121,14 +122,16 @@ pub enum EvalErrorKind<'tcx> { /// Cannot compute this constant because it depends on another one /// which already produced an error ReferencedConstant, + GeneratorResumedAfterReturn, + GeneratorResumedAfterPanic, } pub type EvalResult<'tcx, T = ()> = Result>; -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", @@ -175,14 +178,10 @@ fn description(&self) -> &str { "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(..) => @@ -232,7 +231,7 @@ fn description(&self) -> &str { "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", @@ -240,14 +239,33 @@ fn description(&self) -> &str { "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" }, @@ -275,14 +293,12 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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) => diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index c9eed0e4a28..546c7a920d5 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -8,7 +8,7 @@ macro_rules! err { 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}; @@ -23,7 +23,7 @@ macro_rules! err { 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), @@ -31,13 +31,13 @@ pub enum Lock { ReadLock(Vec), } -#[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, // "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, @@ -88,12 +88,12 @@ fn overflowing_offset(self, val: u64, i: u64) -> (u64, bool) { 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 { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index c26b3014e53..55bfbed0b39 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -15,7 +15,6 @@ 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}; @@ -26,7 +25,7 @@ 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}; @@ -37,12 +36,16 @@ 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; @@ -859,12 +862,17 @@ pub enum TerminatorKind<'tcx> { }, } +pub type Successors<'a> = + iter::Chain, slice::Iter<'a, BasicBlock>>; +pub type SuccessorsMut<'a> = + iter::Chain, 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() } @@ -885,72 +893,71 @@ pub fn if_<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, cond: Operand<'tcx>, } } - 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], } } @@ -1070,18 +1077,18 @@ pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> { 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, ", ")?; } @@ -1130,26 +1137,7 @@ pub fn fmt_head(&self, fmt: &mut W) -> fmt::Result { 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"), @@ -1204,17 +1192,6 @@ pub fn fmt_successor_labels(&self) -> Vec> { } } -#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] -pub enum AssertMessage<'tcx> { - BoundsCheck { - len: Operand<'tcx>, - index: Operand<'tcx> - }, - Math(ConstMathErr), - GeneratorResumedAfterReturn, - GeneratorResumedAfterPanic, -} - /////////////////////////////////////////////////////////////////////////// // Statements @@ -1915,12 +1892,13 @@ fn fmt_const_val(fmt: &mut W, const_val: &ty::Const) -> fmt::Result { pub fn print_miri_value(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) => @@ -1969,7 +1947,7 @@ fn predecessors<'graph>(&'graph self, node: Self::Node) fn successors<'graph>(&'graph self, node: Self::Node) -> >::Iter { - self.basic_blocks[node].terminator().successors().into_owned().into_iter() + self.basic_blocks[node].terminator().successors().cloned() } } @@ -1980,7 +1958,7 @@ impl<'a, 'b> GraphPredecessors<'b> for Mir<'a> { impl<'a, 'b> GraphSuccessors<'b> for Mir<'a> { type Item = BasicBlock; - type Iter = IntoIter; + type Iter = iter::Cloned>; } #[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] @@ -2279,8 +2257,8 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) } }, 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), } @@ -2329,7 +2307,7 @@ fn super_visit_with>(&self, visitor: &mut V) -> bool { }, 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 diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index 666ca5eabe8..92888ed99e4 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -8,8 +8,6 @@ // 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; @@ -67,7 +65,7 @@ fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { 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); } } @@ -110,7 +108,7 @@ impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {} pub struct Postorder<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, visited: BitVector, - visit_stack: Vec<(BasicBlock, vec::IntoIter)> + visit_stack: Vec<(BasicBlock, Successors<'a>)> } impl<'a, 'tcx> Postorder<'a, 'tcx> { @@ -126,10 +124,7 @@ pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> 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(); } @@ -186,7 +181,7 @@ fn traverse_successor(&mut self) { // 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; @@ -197,8 +192,7 @@ fn traverse_successor(&mut self) { 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())); } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index a3fdb6f73ab..59b6f369754 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -511,17 +511,13 @@ fn super_terminator_kind(&mut self, 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); } } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 06922d986b3..dc97c941567 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1053,6 +1053,8 @@ fn parse_lto(slot: &mut Lto, v: Option<&str>) -> bool { 2 = full debug info with variable and type information"), opt_level: Option = (None, parse_opt_string, [TRACKED], "optimize with possible levels 0-3, s, or z"), + force_frame_pointers: Option = (None, parse_opt_bool, [TRACKED], + "force use of the frame pointers"), debug_assertions: Option = (None, parse_opt_bool, [TRACKED], "explicitly enable the cfg(debug_assertions) directive"), inline_threshold: Option = (None, parse_opt_uint, [TRACKED], @@ -1681,7 +1683,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> ast::CrateConfig { early_error(ErrorOutputType::default(), &msg) } - (meta_item.ident.name, meta_item.value_str()) + (meta_item.name(), meta_item.value_str()) }) .collect::() } @@ -2965,6 +2967,10 @@ fn test_codegen_options_tracking_hash() { 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()); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 37a6b2e79f7..2ab72ba20bf 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -20,7 +20,7 @@ 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}; @@ -658,8 +658,11 @@ pub fn crt_static_feature(&self) -> bool { } 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, diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index d1fd70ae02d..3cf7af30b3d 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -190,7 +190,7 @@ pub fn evaluate(&self, 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 diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 0c35e20324c..45fa588bbf5 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -188,7 +188,7 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>( 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) { @@ -409,7 +409,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc 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 { diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 5e0a4ca3305..f074e061653 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -196,7 +196,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc 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 { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 4ba3655bb64..54b2cf28082 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1509,7 +1509,7 @@ fn match_projection_obligation_against_definition_bounds( 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, @@ -2338,7 +2338,7 @@ fn collect_predicates_for_types(&mut self, 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, @@ -2559,7 +2559,7 @@ fn vtable_auto_impl(&mut self, 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, @@ -3142,8 +3142,7 @@ fn match_impl(&mut self, } 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, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c28fcfe8805..ce4439e7c54 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2119,7 +2119,7 @@ macro_rules! intern_method { $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 { { @@ -2137,7 +2137,7 @@ 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) @@ -2165,7 +2165,7 @@ pub fn $method(self, v: $alloc) -> &$lt_tcx $ty { } 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 @@ -2180,7 +2180,10 @@ fn hash(&self, s: &mut H) { } } - 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 + );)+ } } @@ -2189,12 +2192,7 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool { } 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> ); diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 650ac4e6f6d..1793b5e1edb 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -91,6 +91,9 @@ fn has_infer_types(&self) -> bool { 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) } @@ -111,15 +114,6 @@ fn has_erasable_regions(&self) -> bool { 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 diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 55137e28911..a319b341ebb 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -19,7 +19,6 @@ use std::fmt; use std::i128; use std::mem; -use std::ops::RangeInclusive; use ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, @@ -149,7 +148,7 @@ fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { /// - 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>) @@ -492,7 +491,7 @@ enum StructKind { 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)) } @@ -506,7 +505,7 @@ enum StructKind { 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); @@ -524,7 +523,7 @@ enum StructKind { } 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)) @@ -751,8 +750,8 @@ enum StructKind { 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(); } } _ => {} @@ -788,18 +787,15 @@ enum StructKind { } } } - 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)? { @@ -944,11 +940,15 @@ enum StructKind { // 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. @@ -1659,10 +1659,10 @@ fn find_niche(self, layout: TyLayout<'tcx>, count: u128) 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. @@ -1670,11 +1670,11 @@ fn find_niche(self, layout: TyLayout<'tcx>, count: u128) 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)) }; @@ -1744,14 +1744,14 @@ fn hash_stable(&self, } 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); @@ -1814,10 +1814,10 @@ impl<'a> HashStable> for Scalar { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - 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); } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 5a121d3edbe..c4fe112a9e9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -69,7 +69,7 @@ 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::*; @@ -1370,15 +1370,13 @@ pub fn is_empty(&self) -> bool { /// 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`: @@ -1392,7 +1390,21 @@ pub fn root() -> UniverseIndex { /// 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 for UniverseIndex { + fn from(index: u32) -> Self { + UniverseIndex(index) } } @@ -1476,7 +1488,11 @@ pub fn and>(self, value: T) -> ParamEnvAnd<'tcx, T> { } 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, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 9b20fce6673..d4ed6c60e0e 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -473,9 +473,19 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option Lift<'tcx> for interpret::EvalError<'a> { type Lifted = interpret::EvalError<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + 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, >::Lifted>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { 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)?, @@ -504,10 +514,11 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option 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, @@ -568,10 +579,12 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option 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, }) } } @@ -585,7 +598,6 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option 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) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index e9c1e87676b..382db571b52 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1021,7 +1021,7 @@ pub enum RegionKind { /// 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 @@ -1075,11 +1075,6 @@ pub struct FloatVid { 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), @@ -1171,13 +1166,6 @@ pub fn is_late_bound(&self) -> bool { } } - 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, @@ -1195,20 +1183,29 @@ pub fn from_depth(&self, depth: u32) -> RegionKind { } } + 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(..) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index b777f513e6d..894a18b79cc 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -808,8 +808,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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"), diff --git a/src/librustc_apfloat/ppc.rs b/src/librustc_apfloat/ppc.rs index dec88eb62cc..e662088e82f 100644 --- a/src/librustc_apfloat/ppc.rs +++ b/src/librustc_apfloat/ppc.rs @@ -20,7 +20,7 @@ pub struct DoubleFloat(F, F); pub type DoubleDouble = DoubleFloat; -// 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. diff --git a/src/librustc_const_math/Cargo.toml b/src/librustc_const_math/Cargo.toml deleted file mode 100644 index 41310ede3e0..00000000000 --- a/src/librustc_const_math/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[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" } diff --git a/src/librustc_const_math/err.rs b/src/librustc_const_math/err.rs deleted file mode 100644 index bd0a332436e..00000000000 --- a/src/librustc_const_math/err.rs +++ /dev/null @@ -1,87 +0,0 @@ -// 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 or the MIT license -// , 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", - } - } -} diff --git a/src/librustc_const_math/float.rs b/src/librustc_const_math/float.rs deleted file mode 100644 index 9d820ea8cbe..00000000000 --- a/src/librustc_const_math/float.rs +++ /dev/null @@ -1,213 +0,0 @@ -// 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 or the MIT license -// , 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 { - 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 { - let bits = match ty { - ast::FloatTy::F32 => { - let rust_bits = num.parse::()?.to_bits() as u128; - let apfloat = num.parse::().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::()?.to_bits() as u128; - let apfloat = num.parse::().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 { - 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 { - 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; - fn $func(self, rhs: Self) -> Result { - 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); diff --git a/src/librustc_const_math/lib.rs b/src/librustc_const_math/lib.rs deleted file mode 100644 index 499c330be1d..00000000000 --- a/src/librustc_const_math/lib.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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 or the MIT license -// , 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}; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3f166daac71..a1052ca6c3c 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1060,7 +1060,7 @@ fn print_crate_info(trans: &TransCrate, 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, }); diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 57311a7b588..38e891008f7 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -110,7 +110,7 @@ fn argument(&self, attr: &ast::Attribute) -> Option { 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), diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 91ce6f3854a..f06062fa4ac 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -675,9 +675,8 @@ fn get_lints(&self) -> LintArray { 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, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 65b340d6568..4f6d23dce6d 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -30,7 +30,6 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] -#[macro_use] extern crate syntax; #[macro_use] extern crate rustc; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 5ec8305de78..8df40b62ddd 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -8,6 +8,7 @@ // 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; @@ -72,54 +73,59 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { 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"); } @@ -186,8 +192,6 @@ fn get_lints(&self) -> LintArray { 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 { @@ -207,6 +211,7 @@ fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) { } } + let name = attr.name(); if !attr::is_used(attr) { debug!("Emitting warning for: {:?}", attr); cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute"); diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index a1b348774b1..62964745b6f 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -16,7 +16,6 @@ log = "0.4" 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" } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 4b714100816..c619f350f58 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -18,7 +18,7 @@ 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}; @@ -586,18 +586,14 @@ fn visit_terminator_entry( 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, + ); } } diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index d5e11a312ec..56e388a5b60 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -193,7 +193,6 @@ fn find(&mut self) -> Option { block_data .terminator() .successors() - .iter() .map(|&basic_block| Location { statement_index: 0, block: basic_block, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dfs.rs b/src/librustc_mir/borrow_check/nll/region_infer/dfs.rs index 4fcd3118f91..f68394d6149 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/dfs.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/dfs.rs @@ -95,7 +95,6 @@ pub(super) fn dfs( block_data .terminator() .successors() - .iter() .map(|&basic_block| Location { statement_index: 0, block: basic_block, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 08391401cc6..4d1f3e2b430 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -16,7 +16,7 @@ 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; @@ -256,19 +256,19 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// 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 { diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index a811b2c147e..a21b9196bad 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -22,6 +22,7 @@ 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}; @@ -928,7 +929,7 @@ fn check_terminator( 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) } diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 9e217908511..19ec13324d6 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -14,6 +14,7 @@ use build::expr::category::Category; use hair::*; use rustc::mir::*; +use rustc::mir::interpret::EvalErrorKind::BoundsCheck; use rustc_data_structures::indexed_vec::Idx; @@ -73,7 +74,7 @@ fn expr_as_place(&mut self, 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)) }; diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index b7f402f61a9..9e96fdf8214 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -10,7 +10,6 @@ //! 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; @@ -21,7 +20,7 @@ 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> { @@ -86,9 +85,8 @@ fn expr_as_rvalue(&mut self, 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)) } @@ -311,19 +309,10 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock, 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 { @@ -332,11 +321,11 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock, // 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 @@ -346,7 +335,7 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock, 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. @@ -371,7 +360,7 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock, 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); } } diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index 07585c08f6a..9096ac1444c 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -73,8 +73,8 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>( pub struct Edge { source: BasicBlock, index: usize } fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec { - 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> @@ -285,6 +285,6 @@ fn source(&self, edge: &Edge) -> Node { 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() } } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index e6aa2d3abb7..5890ea5c9d0 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -30,9 +30,9 @@ 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> { @@ -170,12 +170,11 @@ pub fn const_eval_literal( 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)"); }) }; @@ -213,26 +212,14 @@ pub fn const_eval_literal( }, 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)), diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index c2da8c11d87..623e0de478b 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -28,13 +28,13 @@ 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 { @@ -792,7 +792,7 @@ fn const_to_pat( 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) @@ -1053,24 +1053,22 @@ pub fn compare_const_vals<'a, 'tcx>( b: &ConstVal, ty: Ty<'tcx>, ) -> Option { - 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"); @@ -1148,26 +1146,14 @@ enum Int { 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)), @@ -1175,7 +1161,36 @@ enum Int { Ok(ConstVal::Value(lit)) } -fn parse_float<'tcx>(num: &str, fty: ast::FloatTy) - -> Result { - ConstFloat::from_str(num, fty).map_err(|_| ()) +pub fn parse_float( + num: Symbol, + fty: ast::FloatTy, + neg: bool, +) -> Result { + let num = num.as_str(); + use rustc_apfloat::ieee::{Single, Double}; + use rustc_apfloat::Float; + let bits = match fty { + ast::FloatTy::F32 => { + num.parse::().map_err(|_| ())?; + let mut f = num.parse::().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::().map_err(|_| ())?; + let mut f = num.parse::().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))) } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index e654142d216..002b5eb187d 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -2,10 +2,9 @@ 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> { @@ -50,8 +49,10 @@ fn cast_from_int( 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)), diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index f6e9994b5da..bea29b6926a 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -513,7 +513,7 @@ pub(super) fn eval_rvalue_into_place( // 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)); } } @@ -917,8 +917,8 @@ pub fn read_discriminant_value( 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); @@ -984,7 +984,7 @@ pub fn write_discriminant_value( 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)?; } @@ -1340,9 +1340,7 @@ pub fn try_read_value(&self, ptr: Pointer, ptr_align: Align, ty: Ty<'tcx>) -> Ev 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))); diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index dfc0c4a824a..ef6deab0477 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -1,9 +1,10 @@ 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}; @@ -125,31 +126,6 @@ pub fn binary_op( 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 bool> = match bin_op { Lt => Some(i128::lt), @@ -164,7 +140,8 @@ pub fn binary_op( return Ok((PrimVal::from_bool(op(&l, &r)), false)); } let op: Option (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), @@ -199,7 +176,31 @@ pub fn binary_op( } 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 @@ -221,7 +222,8 @@ pub fn binary_op( 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!(), @@ -269,7 +271,7 @@ pub fn unary_op( (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, }; diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index aa80ee7af18..0e0d91f4724 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -148,23 +148,24 @@ pub(super) fn eval_terminator( 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!(), }; } } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 75b7a10097d..95cf3b8ddc6 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -31,7 +31,7 @@ #![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))] @@ -50,8 +50,6 @@ 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; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 47b2f430bc7..e1db216b6bb 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -328,7 +328,7 @@ fn const_prop( } 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; } @@ -478,12 +478,12 @@ fn visit_terminator_kind( .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 { @@ -504,6 +504,8 @@ fn visit_terminator_kind( index, ) }, + // Need proper const propagator for these + _ => return, }; self.tcx.lint_node( ::rustc::lint::builtin::CONST_ERR, diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 95fe99a1bec..fba60c7e8dc 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -29,7 +29,6 @@ //! (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; @@ -41,26 +40,8 @@ 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 { diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index 503354ebc4f..8b2b9ef7e81 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -8,7 +8,6 @@ // 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; @@ -19,26 +18,8 @@ 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 { diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index f63a5ef301a..8b771fcf493 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -15,7 +15,6 @@ 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; @@ -42,14 +41,7 @@ fn run_pass<'a, 'tcx>(&self, { 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 = { diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 0ff73569433..36735586e81 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -738,12 +738,17 @@ fn create_generator_resume_function<'a, 'tcx>( 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); diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 2e2f8494146..ee6d42b1fe5 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -330,7 +330,7 @@ fn should_inline(&self, } if !is_drop { - for &succ in &term.successors()[..] { + for &succ in term.successors() { work_list.push(succ); } } diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index 6d365012525..bcc8fef18f0 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -78,7 +78,7 @@ fn is_nop_landing_pad(&self, bb: BasicBlock, mir: &Mir, nop_landing_pads: &BitVe TerminatorKind::SwitchInt { .. } | TerminatorKind::FalseEdges { .. } | TerminatorKind::FalseUnwind { .. } => { - terminator.successors().iter().all(|succ| { + terminator.successors().all(|succ| { nop_landing_pads.contains(succ.index()) }) }, diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 2c6ed1f19b7..691fdd130e5 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -91,7 +91,7 @@ pub fn new(mir: &'a mut Mir<'tcx>) -> Self { 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; } } @@ -219,10 +219,10 @@ fn simplify_branch(&mut self, terminator: &mut Terminator<'tcx>) -> bool { }; 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 diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 85b66c29be1..22e2b1b0b09 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -125,7 +125,7 @@ fn write_edges(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result 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)?; } diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 42ddabddd2d..cfb1a2cd28b 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -138,7 +138,7 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness 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); diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 4bab24ae139..2babb93eedb 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -12,7 +12,6 @@ crate-type = ["dylib"] 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" } diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index e65c9de8df1..b6b5edc0940 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -23,7 +23,6 @@ #[macro_use] extern crate rustc; extern crate rustc_mir; -extern crate rustc_const_math; extern crate rustc_data_structures; #[macro_use] diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index a4e056c6b58..45c6e89321d 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -18,6 +18,7 @@ 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}; @@ -133,14 +134,18 @@ fn visit_assert_message(&mut self, 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); } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 14ceb5f59a3..ef5cc958283 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -17,7 +17,7 @@ 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}; @@ -71,7 +71,6 @@ fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> struct LegacyMacroImports { import_all: Option, imports: Vec<(Name, Span)>, - reexports: Vec<(Name, Span)>, } impl<'a> Resolver<'a> { @@ -175,7 +174,11 @@ fn build_reduced_graph_for_use_tree(&mut self, 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( @@ -621,7 +624,7 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expa 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"); @@ -669,17 +672,6 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expa } } } - 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 } @@ -714,28 +706,13 @@ fn legacy_macro_imports(&mut self, attrs: &[ast::Attribute]) -> LegacyMacroImpor 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 diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index a0fc5533f8e..232a32deb86 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1395,35 +1395,6 @@ macro_rules! get_pimientos { 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. @@ -1496,48 +1467,6 @@ macro_rules! drink { ``` "##, -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. @@ -1715,6 +1644,8 @@ fn main() { // E0421, merged into 531 E0531, // unresolved pattern path kind `name` // E0427, merged into 530 +// E0467, removed +// E0470, removed E0573, E0574, E0575, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 127331152c1..d4b212a15d8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -700,7 +700,7 @@ pub enum Namespace { pub struct PerNS { value_ns: T, type_ns: T, - macro_ns: Option, + macro_ns: T, } impl ::std::ops::Index for PerNS { @@ -709,7 +709,7 @@ fn index(&self, ns: Namespace) -> &T { match ns { ValueNS => &self.value_ns, TypeNS => &self.type_ns, - MacroNS => self.macro_ns.as_ref().unwrap(), + MacroNS => &self.macro_ns, } } } @@ -719,7 +719,7 @@ fn index_mut(&mut self, ns: Namespace) -> &mut T { match ns { ValueNS => &mut self.value_ns, TypeNS => &mut self.type_ns, - MacroNS => self.macro_ns.as_mut().unwrap(), + MacroNS => &mut self.macro_ns, } } } @@ -1407,6 +1407,7 @@ pub struct Resolver<'a> { graph_root: Module<'a>, prelude: Option>, + extern_prelude: FxHashSet, /// n.b. This is used only for better diagnostics, not name resolution itself. has_self: FxHashSet, @@ -1715,6 +1716,7 @@ pub fn new(session: &'a Session, // AST. graph_root, prelude: None, + extern_prelude: session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect(), has_self: FxHashSet(), field_names: FxHashMap(), @@ -1726,7 +1728,7 @@ pub fn new(session: &'a Session, 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(), @@ -1806,14 +1808,11 @@ pub fn arenas() -> ResolverArenas<'a> { } /// Runs the function on each namespace. - fn per_ns T>(&mut self, mut f: F) -> PerNS { - 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(&mut self, mut f: F) { + f(self, TypeNS); + f(self, ValueNS); + if self.use_extern_macros { + f(self, MacroNS); } } @@ -1970,13 +1969,32 @@ fn resolve_ident_in_lexical_scope(&mut self, } } - 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) @@ -3587,8 +3605,9 @@ fn lookup_typo_candidate(&mut self, // 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); } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 3d20f922ac0..4afc621ad8b 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -209,7 +209,7 @@ fn resolve_imports(&mut self) { fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec, allow_derive: bool) -> Option { 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) { @@ -231,7 +231,7 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec, allow_deri // 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| { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index e2a7f5668d2..17aa510b565 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -33,7 +33,7 @@ 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)] @@ -89,6 +89,8 @@ enum SingleImports<'a> { 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, } @@ -101,21 +103,28 @@ fn default() -> Self { } 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 => {} } } @@ -199,23 +208,50 @@ pub fn resolve_ident_in_module_unadjusted(&mut self, } // 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 = @@ -281,7 +317,7 @@ pub fn add_import_directive(&mut self, 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, @@ -575,7 +611,7 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool { 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() => { diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 346e5667a7b..fd1f779f9ec 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -326,9 +326,9 @@ fn add_assign(&mut self, other: Size) { } /// 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(28 - 1), which is limited by LLVM to a i32, -/// with a maximum capacity of 231 - 1 or 2147483647. +/// Each field is a power of two, giving the alignment a maximum value +/// of 2(28 - 1), which is limited by LLVM to a +/// maximum capacity of 229 or 536870912. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct Align { abi_pow2: u8, @@ -356,7 +356,7 @@ pub fn from_bytes(abi: u64, pref: u64) -> Result { } 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) @@ -555,8 +555,8 @@ pub fn valid_range_exclusive(&self, cx: C) -> Range { 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) diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 927d5c7e15a..45f2ee13bbd 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -29,7 +29,7 @@ #![feature(const_fn)] #![feature(fs_read_write)] #![feature(inclusive_range)] -#![feature(inclusive_range_fields)] +#![feature(inclusive_range_methods)] #![feature(slice_patterns)] #[macro_use] diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs index acbbab313fe..46bb01e7c42 100644 --- a/src/librustc_target/spec/apple_ios_base.rs +++ b/src/librustc_target/spec/apple_ios_base.rs @@ -98,6 +98,7 @@ pub fn opts(arch: Arch) -> Result { 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 diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs index 06ea1e4649b..d17789dfcc0 100644 --- a/src/librustc_target/spec/i686_apple_darwin.rs +++ b/src/librustc_target/spec/i686_apple_darwin.rs @@ -16,6 +16,7 @@ pub fn target() -> TargetResult { 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(), diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 5f4daf0d568..ba31ce2692f 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -193,14 +193,38 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( .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) => { diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 32432d6cc83..a4dd02e97b2 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -21,7 +21,6 @@ rustc-demangle = "0.1.4" 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" } diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 1d0d7ec601f..1838dae049a 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -388,8 +388,8 @@ fn unadjusted(cx: &CodegenCx<'a, 'tcx>, 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); } } diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index f455c19cc0b..5baed57092d 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -69,8 +69,6 @@ pub fn naked(val: ValueRef, is_naked: bool) { } 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, diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 123b9cf7931..2fc6c9d4433 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -1236,7 +1236,7 @@ fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, 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![ diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 193db15303f..30676b91620 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -271,7 +271,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } None => {} }; - if sig.output().is_never() { + if cx.layout_of(sig.output()).abi == ty::layout::Abi::Uninhabited { flags = flags | DIFlags::FlagNoReturn; } diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index bbe4e18b18c..97721ffbf06 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -23,6 +23,7 @@ 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}; @@ -133,8 +134,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, 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); } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 96a10e8b99d..7a152d6ded4 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -29,7 +29,7 @@ #![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; @@ -43,7 +43,6 @@ 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; diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 0fe7163da7a..9e5298eb736 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -322,7 +322,7 @@ fn propagate<'tcx>(result: &mut IndexVec, 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); diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index e5fdc26eeaf..b666c2b2115 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -13,6 +13,7 @@ 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; @@ -311,10 +312,7 @@ fn trans_terminator(&mut self, // 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); } } @@ -354,7 +352,7 @@ fn trans_terminator(&mut self, // 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(); @@ -366,26 +364,8 @@ fn trans_terminator(&mut self, (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, diff --git a/src/librustc_trans/mir/place.rs b/src/librustc_trans/mir/place.rs index 8532c0b149d..79859aee64d 100644 --- a/src/librustc_trans/mir/place.rs +++ b/src/librustc_trans/mir/place.rs @@ -99,7 +99,7 @@ pub fn load(&self, bx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> { 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); } _ => {} @@ -287,7 +287,7 @@ pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> Value .. } => { 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. @@ -296,13 +296,13 @@ pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> Value 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)) @@ -352,7 +352,7 @@ pub fn trans_set_discr(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) { 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 { diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 79e906ca975..0cd823391b9 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -15,7 +15,6 @@ 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; @@ -301,7 +300,7 @@ pub fn trans_rvalue_operand(&mut self, 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`. @@ -309,7 +308,7 @@ pub fn trans_rvalue_operand(&mut self, 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()) )); } } @@ -805,6 +804,10 @@ fn cast_int_to_float(bx: &Builder, 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); diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index 70c13e9b7d6..c426533779c 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -15,7 +15,6 @@ syntax = { path = "../libsyntax" } 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" } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 476ae680973..907c80f0daf 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1485,7 +1485,10 @@ fn to_unadjusted_pick(&self) -> Pick<'tcx> { // 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()) } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 6e0d7dd8508..802e5375b6b 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -107,7 +107,7 @@ fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> { 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); } @@ -431,7 +431,7 @@ fn visit_node_id(&mut self, span: Span, hir_id: hir::HirId) { 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); } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 958960d3a36..350b53a406b 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -92,7 +92,6 @@ 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; diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 7f89b3e6b3a..d5e0f95ddf4 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -67,7 +67,7 @@ fn parse_nested(nested_cfg: &NestedMetaItem) -> Result { /// 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 { - 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 { @@ -436,6 +436,42 @@ fn name_value_cfg(name: &str, value: &str) -> Cfg { 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(|| { @@ -561,15 +597,11 @@ fn test_cfg_or() { #[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, @@ -578,111 +610,24 @@ fn test_parse_ok() { }; 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"))); }) } @@ -691,97 +636,36 @@ fn test_parse_ok() { 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()); }) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bd64ac67ac9..d124a17b421 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3661,7 +3661,7 @@ fn clean(&self, cx: &DocContext) -> Vec { // #[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, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 4e9781cc560..21de2db1dfe 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1427,7 +1427,7 @@ fn add_aliases(&mut self, item: &clean::Item) { } 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")) @@ -3284,7 +3284,7 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } fn render_attribute(attr: &ast::MetaItem) -> Option { - let name = attr.ident.name; + let name = attr.name(); if attr.is_word() { Some(format!("{}", name)) @@ -3319,7 +3319,7 @@ fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { 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; } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index bcad2eb19f5..6d80145b29c 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1996,7 +1996,7 @@ 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") { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 8efb51bccd8..059d4169895 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -31,7 +31,6 @@ 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; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 967c50e62db..6db02cc6cc1 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -49,7 +49,6 @@ pub struct RustdocVisitor<'a, 'tcx: 'a, 'rcx: 'a> { inlining: bool, /// Is the current module and all of its parents public? inside_public_path: bool, - reexported_macros: FxHashSet, exact_paths: Option>>, } @@ -66,7 +65,6 @@ pub fn new(cstore: &'a CrateStore, view_item_stack: stack, inlining: false, inside_public_path: true, - reexported_macros: FxHashSet(), exact_paths: Some(FxHashMap()), cstore, } @@ -221,7 +219,7 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec bool { 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. diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 8164f52d3c3..7c358aafa9b 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -988,6 +988,7 @@ pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { /// 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(); @@ -1003,6 +1004,7 @@ pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { /// 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(); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 41992193135..fc05833e285 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -273,7 +273,6 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] -#![feature(macro_reexport)] #![feature(macro_vis_matcher)] #![feature(needs_panic_runtime)] #![feature(never_type)] @@ -313,6 +312,7 @@ #![feature(unboxed_closures)] #![feature(untagged_unions)] #![feature(unwind_attributes)] +#![feature(use_extern_macros)] #![feature(vec_push_all)] #![feature(doc_cfg)] #![feature(doc_masked)] @@ -347,15 +347,14 @@ #[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)] @@ -450,6 +449,8 @@ #[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; diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 6902ec82047..d1274a40900 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -450,8 +450,8 @@ macro_rules! option_env { #[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. diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 955a6af1ae6..696711a70d4 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -87,7 +87,6 @@ use iter::{self, FusedIterator}; use ops::{self, Deref}; use rc::Rc; -use str::FromStr; use sync::Arc; use ffi::{OsStr, OsString}; @@ -1441,32 +1440,6 @@ fn from(s: String) -> PathBuf { } } -/// 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 { - Ok(PathBuf::from(s)) - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl> iter::FromIterator

for PathBuf { fn from_iter>(iter: I) -> PathBuf { diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index a9f3cea243f..9310dad9172 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -518,6 +518,7 @@ fn stress() { } } + #[allow(unused_must_use)] #[test] fn cloning() { let (tx1, rx1) = channel::(); @@ -540,6 +541,7 @@ fn cloning() { tx3.send(()).unwrap(); } + #[allow(unused_must_use)] #[test] fn cloning2() { let (tx1, rx1) = channel::(); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b590a4a6286..f8cd6103bdf 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -474,10 +474,10 @@ pub enum NestedMetaItemKind { /// 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, } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index f0557277267..ace9904e0c0 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -15,10 +15,10 @@ 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}; @@ -107,6 +107,14 @@ pub fn is_known(attr: &Attribute) -> bool { }) } +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> { @@ -137,7 +145,7 @@ pub fn check_name(&self, name: &str) -> bool { /// 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 { - 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 @@ -154,7 +162,7 @@ pub fn name_value_literal(&self) -> Option<(Name, &Lit)> { 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 } @@ -204,6 +212,10 @@ pub fn is_meta_item_list(&self) -> bool { } } +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; @@ -213,11 +225,10 @@ pub fn check_name(&self, name: &str) -> bool { matches } - pub fn name(&self) -> Option { - 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 { @@ -247,9 +258,17 @@ pub fn is_meta_item_list(&self) -> bool { 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 { match self.node { MetaItemKind::NameValue(ref v) => { @@ -279,7 +298,7 @@ pub fn is_word(&self) -> bool { 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 { @@ -296,10 +315,7 @@ impl Attribute { pub fn meta(&self) -> Option { 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; @@ -344,12 +360,8 @@ pub fn parse_list<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, } 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, }) @@ -387,16 +399,17 @@ pub fn mk_name_value_item_str(ident: Ident, value: Spanned) -> MetaItem } 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) -> 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))) } @@ -422,7 +435,7 @@ pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute 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, @@ -440,7 +453,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute 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, @@ -453,7 +466,7 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute { 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, @@ -489,7 +502,7 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool { 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) @@ -562,7 +575,7 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat 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())) }) } @@ -583,7 +596,7 @@ pub fn eval_condition(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) // 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) }), @@ -676,7 +689,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, let meta = meta.as_ref().unwrap(); let get = |meta: &MetaItem, item: &mut Option| { 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() { @@ -695,14 +708,14 @@ macro_rules! get_meta { )+ 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 } } @@ -714,7 +727,7 @@ macro_rules! get_meta { } } - match &*meta.ident.name.as_str() { + match &*meta.name().as_str() { "rustc_deprecated" => { if rustc_depr.is_some() { span_err!(diagnostic, item_sp, E0540, @@ -769,13 +782,13 @@ macro_rules! get_meta { 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 } } @@ -825,12 +838,12 @@ macro_rules! get_meta { 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 } } @@ -917,7 +930,7 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler, depr = if let Some(metas) = attr.meta_item_list() { let get = |meta: &MetaItem, item: &mut Option| { 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() { @@ -933,12 +946,12 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler, 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 } } @@ -990,7 +1003,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec 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)), @@ -1012,11 +1025,11 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec let parse_alignment = |node: &ast::LitKind| -> Result { 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") @@ -1047,7 +1060,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec } } 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, @@ -1127,18 +1140,56 @@ pub fn is_signed(self) -> bool { 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(tokens: &mut iter::Peekable) -> Option where I: Iterator, { - 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, @@ -1147,10 +1198,11 @@ fn from_tokens(tokens: &mut iter::Peekable) -> Option 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 }) } } @@ -1252,10 +1304,7 @@ fn token(&self) -> Token { 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)) => { diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index c9cac1b1142..5f940437ab3 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -244,6 +244,18 @@ fn main() { ``` "##, +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. @@ -321,8 +333,8 @@ fn main() {} 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 } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2f3b35c33f3..584b9455a93 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -810,7 +810,7 @@ fn expand_derive_invoc(&mut self, 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, }; @@ -1017,7 +1017,7 @@ fn configure(&mut self, node: T) -> Option { 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" { @@ -1030,6 +1030,10 @@ fn check_attributes(&mut self, attrs: &[ast::Attribute]) { 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); } } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index d9c3deb30da..71634ada894 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -835,7 +835,13 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { "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"), diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a4a83712a08..d8db76a95ff 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -90,24 +90,24 @@ pub fn walk_feature_fields(&self, mut f: F) } }; - ($((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)] = &[ - $((stringify!($feature), $ver, $issue)),+ + const REMOVED_FEATURES: &[(&str, &str, Option, 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)] = &[ - $((stringify!($feature), $ver, $issue)),+ + const STABLE_REMOVED_FEATURES: &[(&str, &str, Option, 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)] = &[ - $((stringify!($feature), $ver, $issue)),+ + const ACCEPTED_FEATURES: &[(&str, &str, Option, Option<&str>)] = &[ + $((stringify!($feature), $ver, $issue, None)),+ ]; } } @@ -162,9 +162,6 @@ pub fn walk_feature_fields(&self, mut f: F) // 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), @@ -369,9 +366,6 @@ pub fn walk_feature_fields(&self, mut f: F) // #[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), @@ -394,7 +388,7 @@ pub fn walk_feature_fields(&self, mut f: F) (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)), @@ -463,30 +457,38 @@ pub fn walk_feature_fields(&self, mut f: F) // #[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! ( @@ -591,6 +593,8 @@ pub fn walk_feature_fields(&self, mut f: F) (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 @@ -674,7 +678,6 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool { ("forbid", Normal, Ungated), ("deny", Normal, Ungated), - ("macro_reexport", Normal, Ungated), ("macro_use", Normal, Ungated), ("macro_export", Normal, Ungated), ("plugin_registrar", Normal, Ungated), @@ -1079,7 +1082,7 @@ pub struct GatedCfg { impl GatedCfg { pub fn gate(cfg: &ast::MetaItem) -> Option { - let name = cfg.ident.name.as_str(); + let name = cfg.name().as_str(); GATED_CFGS.iter() .position(|info| info.0 == name) .map(|idx| { @@ -1132,7 +1135,7 @@ macro_rules! gate_feature { 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 { @@ -1172,12 +1175,28 @@ fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) { // 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)); + } } } } @@ -1203,7 +1222,7 @@ fn find_lang_feature_issue(feature: &str) -> Option { 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), } } @@ -1517,11 +1536,6 @@ fn visit_item(&mut self, i: &'a ast::Item) { 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) => { @@ -1545,11 +1559,6 @@ fn visit_item(&mut self, i: &'a ast::Item) { 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(..) => { @@ -1581,7 +1590,7 @@ fn visit_item(&mut self, i: &'a ast::Item) { "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, @@ -1594,16 +1603,6 @@ fn visit_item(&mut self, i: &'a ast::Item) { 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, ..) => { @@ -1837,8 +1836,12 @@ fn visit_vis(&mut self, vis: &'a ast::Visibility) { 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(); @@ -1859,7 +1862,7 @@ fn feature_removed(span_handler: &Handler, span: Span) { 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"); @@ -1871,19 +1874,19 @@ fn feature_removed(span_handler: &Handler, span: Span) { 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 { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 870ce1926ad..f148aaf7267 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -25,6 +25,7 @@ #![feature(non_exhaustive)] #![feature(const_atomic_usize_new)] #![feature(rustc_attrs)] +#![feature(str_escape)] #![recursion_limit="256"] diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 90f08ab1468..cceed589212 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -149,7 +149,7 @@ pub fn parse_path_and_tokens(&mut self) -> PResult<'a, (ast::Path, TokenStream)> }; 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()) }) @@ -225,9 +225,10 @@ pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> { } 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> { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ff09c6aa2f0..f252020bc31 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -298,14 +298,10 @@ pub fn char_lit(lit: &str, diag: Option<(Span, &Handler)>) -> (char, isize) { } } -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); @@ -374,7 +370,7 @@ fn eat<'a>(it: &mut iter::Peekable>) { /// 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(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 324cadc84e8..bf4a68679df 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1958,16 +1958,16 @@ pub fn parse_path_allowing_meta(&mut self, style: PathStyle) -> PResult<'a, ast: 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) } @@ -2042,7 +2042,7 @@ fn parse_path_segment(&mut self, style: PathStyle, enable_warning: bool) }) } - fn check_lifetime(&mut self) -> bool { + pub fn check_lifetime(&mut self) -> bool { self.expected_tokens.push(TokenType::Lifetime); self.token.is_lifetime() } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 5c4bf47a6db..e7bd369053c 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -247,12 +247,14 @@ pub fn mk_printer<'a>(out: Box, linewidth: usize) -> Printer<'a> { 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(), @@ -263,7 +265,7 @@ pub fn mk_printer<'a>(out: Box, linewidth: usize) -> Printer<'a> { pub struct Printer<'a> { out: Box, - buf_len: usize, + buf_max_len: usize, /// Width of lines we're constrained to margin: isize, /// Number of spaces left on line @@ -297,6 +299,12 @@ struct BufEntry { 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() @@ -322,7 +330,9 @@ pub fn pretty_print(&mut self, token: Token) -> io::Result<()> { 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 }; @@ -349,7 +359,9 @@ pub fn pretty_print(&mut self, token: Token) -> io::Result<()> { 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); @@ -408,7 +420,11 @@ pub fn scan_pop_bottom(&mut self) -> usize { } 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<()> { @@ -438,7 +454,7 @@ 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; } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 88860df10e2..d8228e2b28b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -656,7 +656,7 @@ fn print_string(&mut self, st: &str, 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}", @@ -714,6 +714,22 @@ fn print_either_attributes(&mut self, 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) } @@ -735,17 +751,7 @@ fn print_attribute_inline(&mut self, attr: &ast::Attribute, 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())?; } @@ -767,16 +773,15 @@ fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) -> io::Result<()> 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[..], diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 544b1410d3d..b8345e7cf40 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -31,6 +31,11 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, 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 { diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 5fd5e299488..76da1746a03 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -22,11 +22,9 @@ 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); } } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index becd70149fd..80f65957c39 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -472,7 +472,7 @@ pub fn expand_ext(self, 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, } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 8d37b4aa396..8b4a3ea26a1 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -1150,13 +1150,17 @@ pub trait Pos { // 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) } @@ -1165,6 +1169,7 @@ fn add(self, rhs: BytePos) -> BytePos { impl Sub for BytePos { type Output = BytePos; + #[inline(always)] fn sub(self, rhs: BytePos) -> BytePos { BytePos((self.to_usize() - rhs.to_usize()) as u32) } @@ -1183,13 +1188,17 @@ fn decode(d: &mut D) -> Result { } 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()) } @@ -1198,6 +1207,7 @@ fn add(self, rhs: CharPos) -> CharPos { impl Sub for CharPos { type Output = CharPos; + #[inline(always)] fn sub(self, rhs: CharPos) -> CharPos { CharPos(self.to_usize() - rhs.to_usize()) } diff --git a/src/test/codegen/force-frame-pointers.rs b/src/test/codegen/force-frame-pointers.rs new file mode 100644 index 00000000000..f70e3667198 --- /dev/null +++ b/src/test/codegen/force-frame-pointers.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , 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() {} diff --git a/src/test/codegen/noreturnflag.rs b/src/test/codegen/noreturnflag.rs index 24a5a4e44cb..7239223ca20 100644 --- a/src/test/codegen/noreturnflag.rs +++ b/src/test/codegen/noreturnflag.rs @@ -8,17 +8,27 @@ // 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 diff --git a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs index 040f0b661be..fb0f9105b0d 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs @@ -117,7 +117,7 @@ fn expand_duplicate(cx: &mut ExtCtxt, 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; diff --git a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs deleted file mode 100644 index 8b448e401bd..00000000000 --- a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 or the MIT license -// , 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; diff --git a/src/test/compile-fail/auxiliary/macro_non_reexport_2.rs b/src/test/compile-fail/auxiliary/macro_non_reexport_2.rs deleted file mode 100644 index 910fcd2e367..00000000000 --- a/src/test/compile-fail/auxiliary/macro_non_reexport_2.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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 or the MIT license -// , 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; diff --git a/src/test/compile-fail/auxiliary/macro_reexport_1.rs b/src/test/compile-fail/auxiliary/macro_reexport_1.rs deleted file mode 100644 index aaeccc6e898..00000000000 --- a/src/test/compile-fail/auxiliary/macro_reexport_1.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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 or the MIT license -// , 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 ) -} diff --git a/src/test/compile-fail/feature-gate-tool_attributes.rs b/src/test/compile-fail/feature-gate-tool_attributes.rs new file mode 100644 index 00000000000..5a7536ca330 --- /dev/null +++ b/src/test/compile-fail/feature-gate-tool_attributes.rs @@ -0,0 +1,15 @@ +// 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 or the MIT license +// , 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; +} diff --git a/src/test/compile-fail/macro-no-implicit-reexport.rs b/src/test/compile-fail/macro-no-implicit-reexport.rs deleted file mode 100644 index 07467e06eb2..00000000000 --- a/src/test/compile-fail/macro-no-implicit-reexport.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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 or the MIT license -// , 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 -} diff --git a/src/test/compile-fail/macro-non-lifetime.rs b/src/test/compile-fail/macro-non-lifetime.rs new file mode 100644 index 00000000000..a2706e83229 --- /dev/null +++ b/src/test/compile-fail/macro-non-lifetime.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , 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` +} diff --git a/src/test/compile-fail/macro-reexport-malformed-1.rs b/src/test/compile-fail/macro-reexport-malformed-1.rs deleted file mode 100644 index 36a6fce00a1..00000000000 --- a/src/test/compile-fail/macro-reexport-malformed-1.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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 or the MIT license -// , 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; diff --git a/src/test/compile-fail/macro-reexport-malformed-2.rs b/src/test/compile-fail/macro-reexport-malformed-2.rs deleted file mode 100644 index 5f741d010de..00000000000 --- a/src/test/compile-fail/macro-reexport-malformed-2.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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 or the MIT license -// , 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; diff --git a/src/test/compile-fail/macro-reexport-malformed-3.rs b/src/test/compile-fail/macro-reexport-malformed-3.rs deleted file mode 100644 index 1a7e3b918cd..00000000000 --- a/src/test/compile-fail/macro-reexport-malformed-3.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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 or the MIT license -// , 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; diff --git a/src/test/compile-fail/macro-reexport-not-locally-visible.rs b/src/test/compile-fail/macro-reexport-not-locally-visible.rs deleted file mode 100644 index 54a74b0e134..00000000000 --- a/src/test/compile-fail/macro-reexport-not-locally-visible.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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 or the MIT license -// , 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 -} diff --git a/src/test/compile-fail/macro-reexport-undef.rs b/src/test/compile-fail/macro-reexport-undef.rs deleted file mode 100644 index 50ac89e49e0..00000000000 --- a/src/test/compile-fail/macro-reexport-undef.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 or the MIT license -// , 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!(); -} diff --git a/src/test/compile-fail/repr-align.rs b/src/test/compile-fail/repr-align.rs index 7c8eb6a2de9..9b0408de2a4 100644 --- a/src/test/compile-fail/repr-align.rs +++ b/src/test/compile-fail/repr-align.rs @@ -15,7 +15,10 @@ #[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() {} diff --git a/src/test/compile-fail/unknown-tool-name.rs b/src/test/compile-fail/unknown-tool-name.rs new file mode 100644 index 00000000000..c2192a21d90 --- /dev/null +++ b/src/test/compile-fail/unknown-tool-name.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , 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() {} diff --git a/src/test/compile-fail/unknown_tool_attributes-1.rs b/src/test/compile-fail/unknown_tool_attributes-1.rs new file mode 100644 index 00000000000..ba38c297a11 --- /dev/null +++ b/src/test/compile-fail/unknown_tool_attributes-1.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , 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() {} diff --git a/src/test/run-make-fulldeps/extern-prelude/Makefile b/src/test/run-make-fulldeps/extern-prelude/Makefile new file mode 100644 index 00000000000..aa8158c6eb3 --- /dev/null +++ b/src/test/run-make-fulldeps/extern-prelude/Makefile @@ -0,0 +1,12 @@ +-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" diff --git a/src/test/run-make-fulldeps/extern-prelude/basic.rs b/src/test/run-make-fulldeps/extern-prelude/basic.rs new file mode 100644 index 00000000000..b8d6a772e2a --- /dev/null +++ b/src/test/run-make-fulldeps/extern-prelude/basic.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , 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(); +} diff --git a/src/test/run-make-fulldeps/extern-prelude/ep-lib.rs b/src/test/run-make-fulldeps/extern-prelude/ep-lib.rs new file mode 100644 index 00000000000..dac0a3ce760 --- /dev/null +++ b/src/test/run-make-fulldeps/extern-prelude/ep-lib.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , 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) {} +} diff --git a/src/test/run-make-fulldeps/extern-prelude/ep-vec.rs b/src/test/run-make-fulldeps/extern-prelude/ep-vec.rs new file mode 100644 index 00000000000..f750a26f9e6 --- /dev/null +++ b/src/test/run-make-fulldeps/extern-prelude/ep-vec.rs @@ -0,0 +1,13 @@ +// 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 or the MIT license +// , 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: ()) {} diff --git a/src/test/run-make-fulldeps/extern-prelude/feature-gate.rs b/src/test/run-make-fulldeps/extern-prelude/feature-gate.rs new file mode 100644 index 00000000000..49763f3ba6a --- /dev/null +++ b/src/test/run-make-fulldeps/extern-prelude/feature-gate.rs @@ -0,0 +1,13 @@ +// 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 or the MIT license +// , 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 +} diff --git a/src/test/run-make-fulldeps/extern-prelude/relative-only.rs b/src/test/run-make-fulldeps/extern-prelude/relative-only.rs new file mode 100644 index 00000000000..0cd56b93de6 --- /dev/null +++ b/src/test/run-make-fulldeps/extern-prelude/relative-only.rs @@ -0,0 +1,19 @@ +// 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 or the MIT license +// , 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; +} diff --git a/src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs b/src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs new file mode 100644 index 00000000000..52213c8d4f9 --- /dev/null +++ b/src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs @@ -0,0 +1,24 @@ +// 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 or the MIT license +// , 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 +} diff --git a/src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs b/src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs new file mode 100644 index 00000000000..de1c4d16d39 --- /dev/null +++ b/src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , 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 +} diff --git a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs index 2f80408ac1c..d698af50579 100644 --- a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs +++ b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs @@ -112,7 +112,7 @@ fn expand_duplicate(cx: &mut ExtCtxt, 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; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs deleted file mode 100644 index cfaf913216a..00000000000 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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 or the MIT license -// , 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; diff --git a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs b/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs deleted file mode 100644 index 03dfeb1f5c9..00000000000 --- a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 or the MIT license -// , 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() {} diff --git a/src/test/run-pass/auxiliary/macro_reexport_1.rs b/src/test/run-pass/auxiliary/macro_reexport_1.rs deleted file mode 100644 index aaeccc6e898..00000000000 --- a/src/test/run-pass/auxiliary/macro_reexport_1.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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 or the MIT license -// , 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 ) -} diff --git a/src/test/run-pass/auxiliary/macro_reexport_2.rs b/src/test/run-pass/auxiliary/macro_reexport_2.rs deleted file mode 100644 index 3918be88d86..00000000000 --- a/src/test/run-pass/auxiliary/macro_reexport_2.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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 or the MIT license -// , 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; diff --git a/src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs b/src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs deleted file mode 100644 index 1d3dc26b0b4..00000000000 --- a/src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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 or the MIT license -// , 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; diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 2b82a894363..7bcb4e5ec2d 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -16,6 +16,7 @@ // "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 diff --git a/src/test/run-pass/extern-prelude-no-speculative.rs b/src/test/run-pass/extern-prelude-no-speculative.rs new file mode 100644 index 00000000000..ff3aec439aa --- /dev/null +++ b/src/test/run-pass/extern-prelude-no-speculative.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , 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 {}; +} diff --git a/src/test/run-pass/issue-50415.rs b/src/test/run-pass/issue-50415.rs new file mode 100644 index 00000000000..aa493ce0321 --- /dev/null +++ b/src/test/run-pass/issue-50415.rs @@ -0,0 +1,27 @@ +// 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 or the MIT license +// , 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); +} diff --git a/src/test/run-pass/macro-reexport-no-intermediate-use.rs b/src/test/run-pass/macro-reexport-no-intermediate-use.rs deleted file mode 100644 index de7df1ec021..00000000000 --- a/src/test/run-pass/macro-reexport-no-intermediate-use.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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 or the MIT license -// , 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); -} diff --git a/src/test/run-pass/macro-reexport.rs b/src/test/run-pass/macro-reexport.rs deleted file mode 100644 index b8926eca9e9..00000000000 --- a/src/test/run-pass/macro-reexport.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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 or the MIT license -// , 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); -} diff --git a/src/test/run-pass/repr_c_int_align.rs b/src/test/run-pass/repr_c_int_align.rs new file mode 100644 index 00000000000..af4eb615302 --- /dev/null +++ b/src/test/run-pass/repr_c_int_align.rs @@ -0,0 +1,55 @@ +// 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 or the MIT license +// , 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) + }; +} diff --git a/src/test/run-pass/tool_attributes.rs b/src/test/run-pass/tool_attributes.rs new file mode 100644 index 00000000000..eb13930de40 --- /dev/null +++ b/src/test/run-pass/tool_attributes.rs @@ -0,0 +1,23 @@ +// 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 or the MIT license +// , 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); +} diff --git a/src/test/rustdoc-js/alias-2.js b/src/test/rustdoc-js/alias-2.js index f31786df67c..0c5ec4fccbc 100644 --- a/src/test/rustdoc-js/alias-2.js +++ b/src/test/rustdoc-js/alias-2.js @@ -8,11 +8,13 @@ // 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' }, ], }; diff --git a/src/test/rustdoc-js/alias.js b/src/test/rustdoc-js/alias.js index a0500f24c17..e7aafe3b9e2 100644 --- a/src/test/rustdoc-js/alias.js +++ b/src/test/rustdoc-js/alias.js @@ -8,12 +8,14 @@ // 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' }, ], }; diff --git a/src/test/rustdoc-js/basic.js b/src/test/rustdoc-js/basic.js index 863437cac91..d7ba1253eab 100644 --- a/src/test/rustdoc-js/basic.js +++ b/src/test/rustdoc-js/basic.js @@ -13,8 +13,8 @@ const QUERY = 'String'; 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' }, diff --git a/src/test/rustdoc/cross-crate-links.rs b/src/test/rustdoc/cross-crate-links.rs index 15a774dc935..6078352fc0e 100644 --- a/src/test/rustdoc/cross-crate-links.rs +++ b/src/test/rustdoc/cross-crate-links.rs @@ -66,6 +66,6 @@ #[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; diff --git a/src/test/rustdoc/pub-use-extern-macros.rs b/src/test/rustdoc/pub-use-extern-macros.rs index 3f8f6f9544e..57d54585d84 100644 --- a/src/test/rustdoc/pub-use-extern-macros.rs +++ b/src/test/rustdoc/pub-use-extern-macros.rs @@ -10,14 +10,11 @@ // 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 @@ -25,7 +22,7 @@ #[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; diff --git a/src/test/ui/const-eval/ice-packed.rs b/src/test/ui/const-eval/ice-packed.rs new file mode 100644 index 00000000000..1db12a06b03 --- /dev/null +++ b/src/test/ui/const-eval/ice-packed.rs @@ -0,0 +1,28 @@ +// 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 or the MIT license +// , 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() { +} diff --git a/src/test/ui/const-eval/index_out_of_bound.stderr b/src/test/ui/const-eval/index_out_of_bound.stderr index 793e0a7ace8..d16231c72b9 100644 --- a/src/test/ui/const-eval/index_out_of_bound.stderr +++ b/src/test/ui/const-eval/index_out_of_bound.stderr @@ -2,7 +2,7 @@ error[E0080]: constant evaluation error --> $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 diff --git a/src/test/ui/const-eval/promoted_errors.stderr b/src/test/ui/const-eval/promoted_errors.stderr index a5db8cc9083..7761f192fdb 100644 --- a/src/test/ui/const-eval/promoted_errors.stderr +++ b/src/test/ui/const-eval/promoted_errors.stderr @@ -2,7 +2,7 @@ warning: constant evaluation 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 @@ -10,13 +10,13 @@ warning: constant evaluation error --> $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 @@ -28,7 +28,7 @@ warning: constant evaluation error --> $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 @@ -40,11 +40,11 @@ warning: constant evaluation error --> $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 diff --git a/src/test/ui/error-codes/E0080.rs b/src/test/ui/error-codes/E0080.rs index c8e42571128..7f3e6eaad9b 100644 --- a/src/test/ui/error-codes/E0080.rs +++ b/src/test/ui/error-codes/E0080.rs @@ -15,7 +15,6 @@ enum Enum { //~| const_err //~| const_err //~| const_err - //~| divide by zero } fn main() { diff --git a/src/test/ui/error-codes/E0080.stderr b/src/test/ui/error-codes/E0080.stderr index 500e0e83a55..5e401bd6c79 100644 --- a/src/test/ui/error-codes/E0080.stderr +++ b/src/test/ui/error-codes/E0080.stderr @@ -24,7 +24,7 @@ warning: constant evaluation error --> $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 diff --git a/src/test/ui/feature-gate-extern_prelude.rs b/src/test/ui/feature-gate-extern_prelude.rs new file mode 100644 index 00000000000..8d3a30305bd --- /dev/null +++ b/src/test/ui/feature-gate-extern_prelude.rs @@ -0,0 +1,11 @@ +// 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 or the MIT license +// , 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 `-` diff --git a/src/test/ui/feature-gate-extern_prelude.stderr b/src/test/ui/feature-gate-extern_prelude.stderr new file mode 100644 index 00000000000..5abf369baf9 --- /dev/null +++ b/src/test/ui/feature-gate-extern_prelude.stderr @@ -0,0 +1,8 @@ +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 + diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs deleted file mode 100644 index 1c04199c05f..00000000000 --- a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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 or the MIT license -// , 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 diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr deleted file mode 100644 index a2c1dedff38..00000000000 --- a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr +++ /dev/null @@ -1,8 +0,0 @@ -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 - diff --git a/src/test/ui/feature-gate-fn_must_use.rs b/src/test/ui/feature-gate-fn_must_use.rs deleted file mode 100644 index 72fdcc76cf4..00000000000 --- a/src/test/ui/feature-gate-fn_must_use.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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 or the MIT license -// , 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 diff --git a/src/test/ui/feature-gate-fn_must_use.stderr b/src/test/ui/feature-gate-fn_must_use.stderr deleted file mode 100644 index 431c57abd26..00000000000 --- a/src/test/ui/feature-gate-fn_must_use.stderr +++ /dev/null @@ -1,24 +0,0 @@ -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 - diff --git a/src/test/ui/feature-gate-tool_attributes.rs b/src/test/ui/feature-gate-tool_attributes.rs new file mode 100644 index 00000000000..2b7cf56d938 --- /dev/null +++ b/src/test/ui/feature-gate-tool_attributes.rs @@ -0,0 +1,15 @@ +// 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 or the MIT license +// , 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 + ; +} diff --git a/src/test/ui/feature-gate-tool_attributes.stderr b/src/test/ui/feature-gate-tool_attributes.stderr new file mode 100644 index 00000000000..da89c4a5ef6 --- /dev/null +++ b/src/test/ui/feature-gate-tool_attributes.stderr @@ -0,0 +1,11 @@ +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`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 21950402c8c..76fb09f27be 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -50,7 +50,6 @@ #![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 @@ -186,25 +185,6 @@ mod inner { #![deny(x5100)] } //~^ 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] } @@ -661,7 +641,6 @@ mod must_use { mod inner { #![must_use="1400"] } #[must_use = "1400"] fn f() { } - //~^ WARN `#[must_use]` on functions is experimental #[must_use = "1400"] struct S; diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 0beed627987..f8e5f58ca0e 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -1,25 +1,17 @@ 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 | @@ -51,154 +43,154 @@ LL | #![deny (x5100)] //~ WARN unknown lint: `x5100` | ^^^^^ 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 @@ -209,311 +201,275 @@ LL | #![warn(unused_attributes, unknown_lints)] 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() { } | -^^^^^^^^^ @@ -523,793 +479,787 @@ 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"); diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs new file mode 100644 index 00000000000..def23046db2 --- /dev/null +++ b/src/test/ui/fn_must_use.rs @@ -0,0 +1,78 @@ +// 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 or the MIT license +// , 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 +} diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/fn_must_use.stderr new file mode 100644 index 00000000000..5026dac0a94 --- /dev/null +++ b/src/test/ui/fn_must_use.stderr @@ -0,0 +1,48 @@ +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 + | ^^^^^^ + diff --git a/src/test/ui/generator/borrowing.nll.stderr b/src/test/ui/generator/borrowing.nll.stderr index 1801da6c8b2..243e9018585 100644 --- a/src/test/ui/generator/borrowing.nll.stderr +++ b/src/test/ui/generator/borrowing.nll.stderr @@ -1,14 +1,30 @@ -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`. diff --git a/src/test/ui/generator/borrowing.rs b/src/test/ui/generator/borrowing.rs index f80aca9fb00..e56927d8182 100644 --- a/src/test/ui/generator/borrowing.rs +++ b/src/test/ui/generator/borrowing.rs @@ -8,11 +8,11 @@ // 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() } diff --git a/src/test/ui/generator/dropck.nll.stderr b/src/test/ui/generator/dropck.nll.stderr index 72ebaab3278..c352fd6a62f 100644 --- a/src/test/ui/generator/dropck.nll.stderr +++ b/src/test/ui/generator/dropck.nll.stderr @@ -1,14 +1,20 @@ -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`. diff --git a/src/test/ui/generator/dropck.rs b/src/test/ui/generator/dropck.rs index 8f4ba64fd57..857288818c6 100644 --- a/src/test/ui/generator/dropck.rs +++ b/src/test/ui/generator/dropck.rs @@ -8,15 +8,16 @@ // 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>`. gen = || { // but the generator can use it to drop a `Ref<'a, i32>`. diff --git a/src/test/ui/generator/dropck.stderr b/src/test/ui/generator/dropck.stderr index 4a22d299701..1a6fed2dd35 100644 --- a/src/test/ui/generator/dropck.stderr +++ b/src/test/ui/generator/dropck.stderr @@ -1,5 +1,16 @@ +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 @@ -12,6 +23,6 @@ LL | } | = 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`. diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr index 08839c23c37..70870b98365 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr @@ -1,11 +1,19 @@ 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 diff --git a/src/test/ui/inference_unstable.rs b/src/test/ui/inference_unstable.rs index 816c443a06c..5a70dffd4c8 100644 --- a/src/test/ui/inference_unstable.rs +++ b/src/test/ui/inference_unstable.rs @@ -25,5 +25,5 @@ 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 } diff --git a/src/test/ui/inference_unstable.stderr b/src/test/ui/inference_unstable.stderr index 9c614d659d3..a217bc57b36 100644 --- a/src/test/ui/inference_unstable.stderr +++ b/src/test/ui/inference_unstable.stderr @@ -5,7 +5,7 @@ LL | assert_eq!('x'.ipu_flatten(), 1); | ^^^^^^^^^^^ | = 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 = 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` diff --git a/src/test/ui/issue-50187.rs b/src/test/ui/issue-50187.rs new file mode 100644 index 00000000000..87acf106393 --- /dev/null +++ b/src/test/ui/issue-50187.rs @@ -0,0 +1,49 @@ +// 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 or the MIT license +// , 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!(); +} diff --git a/src/test/ui/issue-50403.rs b/src/test/ui/issue-50403.rs new file mode 100644 index 00000000000..8d4c6c5140f --- /dev/null +++ b/src/test/ui/issue-50403.rs @@ -0,0 +1,15 @@ +// 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 or the MIT license +// , 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 +} diff --git a/src/test/ui/issue-50403.stderr b/src/test/ui/issue-50403.stderr new file mode 100644 index 00000000000..f2871c72e25 --- /dev/null +++ b/src/test/ui/issue-50403.stderr @@ -0,0 +1,8 @@ +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 + diff --git a/src/test/ui/lint/must-use-ops.rs b/src/test/ui/lint/must-use-ops.rs index 4ed82ab3b40..c0575f817c8 100644 --- a/src/test/ui/lint/must-use-ops.rs +++ b/src/test/ui/lint/must-use-ops.rs @@ -12,7 +12,6 @@ // compile-pass -#![feature(fn_must_use)] #![warn(unused_must_use)] fn main() { diff --git a/src/test/ui/lint/must-use-ops.stderr b/src/test/ui/lint/must-use-ops.stderr index f444ef09075..5703536ef48 100644 --- a/src/test/ui/lint/must-use-ops.stderr +++ b/src/test/ui/lint/must-use-ops.stderr @@ -1,131 +1,131 @@ 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; | ^^^^^^^^^^^^ diff --git a/src/test/ui/macro-reexport-removed.rs b/src/test/ui/macro-reexport-removed.rs new file mode 100644 index 00000000000..bab583da37b --- /dev/null +++ b/src/test/ui/macro-reexport-removed.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , 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() {} diff --git a/src/test/ui/macro-reexport-removed.stderr b/src/test/ui/macro-reexport-removed.stderr new file mode 100644 index 00000000000..ba0ab232e86 --- /dev/null +++ b/src/test/ui/macro-reexport-removed.stderr @@ -0,0 +1,24 @@ +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`. diff --git a/src/test/ui/print_type_sizes/repr_int_c.rs b/src/test/ui/print_type_sizes/repr_int_c.rs new file mode 100644 index 00000000000..04bb2ab26f3 --- /dev/null +++ b/src/test/ui/print_type_sizes/repr_int_c.rs @@ -0,0 +1,35 @@ +// 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 or the MIT license +// , 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 +} diff --git a/src/test/ui/print_type_sizes/repr_int_c.stdout b/src/test/ui/print_type_sizes/repr_int_c.stdout new file mode 100644 index 00000000000..254b3c7a853 --- /dev/null +++ b/src/test/ui/print_type_sizes/repr_int_c.stdout @@ -0,0 +1,12 @@ +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 diff --git a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs deleted file mode 100644 index d20ebf0b740..00000000000 --- a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs +++ /dev/null @@ -1,79 +0,0 @@ -// 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 or the MIT license -// , 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 -} diff --git a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr b/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr deleted file mode 100644 index d0a8bb525b6..00000000000 --- a/src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.stderr +++ /dev/null @@ -1,48 +0,0 @@ -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 - | ^^^^^^ - diff --git a/src/test/ui/span/gated-features-attr-spans.rs b/src/test/ui/span/gated-features-attr-spans.rs index 83a4c5d5dd2..eff1f98eb71 100644 --- a/src/test/ui/span/gated-features-attr-spans.rs +++ b/src/test/ui/span/gated-features-attr-spans.rs @@ -8,33 +8,10 @@ // 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 { - if gem.poofed { - Ok(gem) - } else { - Err(()) - } -} - fn main() {} diff --git a/src/test/ui/span/gated-features-attr-spans.stderr b/src/test/ui/span/gated-features-attr-spans.stderr index 179daf83c3c..a99530529fc 100644 --- a/src/test/ui/span/gated-features-attr-spans.stderr +++ b/src/test/ui/span/gated-features-attr-spans.stderr @@ -1,27 +1,11 @@ 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`. diff --git a/src/tools/cargo b/src/tools/cargo index 122fd5be520..af3f1cd29bc 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 122fd5be5201913d42e219e132d6569493583bca +Subproject commit af3f1cd29bc872b932a13083e531255aab233a7e diff --git a/src/tools/rls b/src/tools/rls index 9144e223a5b..d2f44357fef 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 9144e223a5b90e078366275ff3dcdd406e62eae3 +Subproject commit d2f44357fef6d61f316abc403e0a5d917f2771c6 diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 6992f2ba123..1c79443dedf 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -87,6 +87,7 @@ function loadContent(content) { 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; } @@ -130,10 +131,10 @@ function lookForEntry(entry, data) { } } if (allGood === true) { - return true; + return i; } } - return false; + return null; } function main(argv) { @@ -177,6 +178,7 @@ 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 = []; @@ -189,13 +191,17 @@ function main(argv) { 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; } } } diff --git a/src/tools/rustfmt b/src/tools/rustfmt index 0f4ed08d0e3..b6cd17f28ae 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit 0f4ed08d0e3d180d66e46904126c3792f57668a9 +Subproject commit b6cd17f28ae314f2484ff05d3ce57652d51c5e85