]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #54967 - holmgr:master, r=estebank
authorkennytm <kennytm@gmail.com>
Fri, 12 Oct 2018 14:04:16 +0000 (22:04 +0800)
committerGitHub <noreply@github.com>
Fri, 12 Oct 2018 14:04:16 +0000 (22:04 +0800)
Remove incorrect span for second label inner macro invocation

A fix for issue #54841

166 files changed:
config.toml.example
src/Cargo.lock
src/bootstrap/config.rs
src/build_helper/lib.rs
src/doc/unstable-book/src/language-features/cfg-attr-multi.md [new file with mode: 0644]
src/doc/unstable-book/src/language-features/tool-lints.md [deleted file]
src/etc/gdb_rust_pretty_printing.py
src/liballoc/collections/btree/node.rs
src/liballoc/lib.rs
src/liballoc/vec.rs
src/liballoc_system/lib.rs
src/libcore/option.rs
src/libcore/ptr.rs
src/libcore/slice/mod.rs
src/libcore/task/wake.rs
src/libcore/tests/lib.rs
src/librustc/Cargo.toml
src/librustc/ich/impls_ty.rs
src/librustc/lint/levels.rs
src/librustc/macros.rs
src/librustc/middle/region.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/traits/mod.rs
src/librustc/traits/structural_impls.rs
src/librustc/ty/context.rs
src/librustc/ty/flags.rs
src/librustc_codegen_llvm/abi.rs
src/librustc_codegen_llvm/allocator.rs
src/librustc_codegen_llvm/attributes.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/common.rs
src/librustc_codegen_llvm/consts.rs
src/librustc_codegen_llvm/context.rs
src/librustc_codegen_llvm/declare.rs
src/librustc_codegen_llvm/diagnostics.rs
src/librustc_codegen_llvm/glue.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_llvm/llvm/ffi.rs
src/librustc_codegen_llvm/llvm_util.rs
src/librustc_codegen_llvm/metadata.rs
src/librustc_codegen_llvm/mir/analyze.rs
src/librustc_codegen_llvm/mir/block.rs
src/librustc_codegen_llvm/mir/statement.rs
src/librustc_codegen_llvm/mono_item.rs
src/librustc_codegen_llvm/type_of.rs
src/librustc_codegen_llvm/value.rs
src/librustc_driver/lib.rs
src/librustc_errors/diagnostic.rs
src/librustc_lint/unused.rs
src/librustc_mir/borrow_check/move_errors.rs
src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
src/librustc_mir/interpret/operand.rs
src/librustc_target/abi/mod.rs
src/librustc_target/spec/mod.rs
src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs
src/librustc_traits/Cargo.toml
src/librustc_traits/chalk_context.rs
src/librustc_traits/lowering.rs
src/librustdoc/Cargo.toml
src/librustdoc/html/highlight.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/rustdoc.css
src/libstd/fs.rs
src/libstd/panic.rs
src/libstd/primitive_docs.rs
src/libstd/sync/once.rs
src/libsyntax/config.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/parser.rs
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.h
src/test/codegen/naked-functions.rs
src/test/codegen/no-plt.rs [new file with mode: 0644]
src/test/run-pass/macros/macro-as-fn-body.rs [new file with mode: 0644]
src/test/run-pass/tool_lints.rs
src/test/run-pass/tool_lints_2018_preview.rs
src/test/rustdoc-ui/invalid-syntax.rs [new file with mode: 0644]
src/test/rustdoc-ui/invalid-syntax.stderr [new file with mode: 0644]
src/test/ui-fulldeps/lint_tool_test.rs
src/test/ui/auxiliary/namespaced_enums.rs [deleted file]
src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.nll.stderr
src/test/ui/cfg-arg-invalid-1.rs [deleted file]
src/test/ui/cfg-arg-invalid-2.rs [deleted file]
src/test/ui/cfg-arg-invalid-3.rs [deleted file]
src/test/ui/cfg-arg-invalid-4.rs [deleted file]
src/test/ui/cfg-arg-invalid-5.rs [deleted file]
src/test/ui/cfg-attr-cfg-2.rs [deleted file]
src/test/ui/cfg-attr-cfg-2.stderr [deleted file]
src/test/ui/cfg-attr-crate-2.rs [deleted file]
src/test/ui/cfg-attr-crate-2.stderr [deleted file]
src/test/ui/cfg-attr-invalid-predicate.rs [deleted file]
src/test/ui/cfg-attr-invalid-predicate.stderr [deleted file]
src/test/ui/cfg-attr-syntax-validation.rs [deleted file]
src/test/ui/cfg-attr-syntax-validation.stderr [deleted file]
src/test/ui/cfg-attr-trailing-comma.rs [deleted file]
src/test/ui/cfg-attr-trailing-comma.stderr [deleted file]
src/test/ui/cfg-attr-unknown-attribute-macro-expansion.rs [deleted file]
src/test/ui/cfg-attr-unknown-attribute-macro-expansion.stderr [deleted file]
src/test/ui/cfg-empty-codemap.rs [deleted file]
src/test/ui/cfg-in-crate-1.rs [deleted file]
src/test/ui/cfg-in-crate-1.stderr [deleted file]
src/test/ui/cfg-non-opt-expr.rs [deleted file]
src/test/ui/cfg-non-opt-expr.stderr [deleted file]
src/test/ui/cfg_attr_path.rs [deleted file]
src/test/ui/cfg_attr_path.stderr [deleted file]
src/test/ui/chalkify/lower_trait.rs
src/test/ui/chalkify/lower_trait.stderr
src/test/ui/conditional-compilation/auxiliary/namespaced_enums.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-arg-invalid-1.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-arg-invalid-2.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-arg-invalid-3.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-arg-invalid-4.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-arg-invalid-5.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-cfg-2.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-crate-2.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-invalid-predicate.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-invalid-predicate.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-multi-false.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-multi-true.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-parse.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-parse.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-syntax-validation.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-empty-codemap.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-in-crate-1.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-in-crate-1.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-non-opt-expr.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-non-opt-expr.stderr [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg_attr_path.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg_attr_path.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-tool_lints-fail.rs [deleted file]
src/test/ui/feature-gates/feature-gate-tool_lints-fail.stderr [deleted file]
src/test/ui/feature-gates/feature-gate-tool_lints.rs [deleted file]
src/test/ui/feature-gates/feature-gate-tool_lints.stderr [deleted file]
src/test/ui/inline-asm-bad-operand.rs [new file with mode: 0644]
src/test/ui/inline-asm-bad-operand.stderr [new file with mode: 0644]
src/test/ui/issues/issue-20801.nll.stderr
src/test/ui/lint/must_use-unit.rs [new file with mode: 0644]
src/test/ui/lint/must_use-unit.stderr [new file with mode: 0644]
src/test/ui/nll/issue-52663-trait-object.rs [new file with mode: 0644]
src/test/ui/nll/issue-52663-trait-object.stderr [new file with mode: 0644]
src/test/ui/resolve/issue-54379.rs [new file with mode: 0644]
src/test/ui/resolve/issue-54379.stderr [new file with mode: 0644]
src/test/ui/span/regions-close-over-type-parameter-2.nll.stderr
src/test/ui/tool_lints-fail.rs
src/test/ui/tool_lints.rs
src/test/ui/unknown-lint-tool-name.rs

index 312270532affc7bbaaaa1001f0effeb1bd229055..1c851999130a0213ae5daded08d1e8eda4f637ae 100644 (file)
 # =============================================================================
 [rust]
 
-# Indicates that the build should be optimized for debugging Rust. Note that
-# this is typically not what you want as it takes an incredibly large amount of
-# time to have a debug-mode rustc compile any code (notably libstd). If this
-# value is set to `true` it will affect a number of configuration options below
-# as well, if unconfigured.
-#debug = false
-
-# Whether or not to optimize the compiler and standard library
+# Whether or not to optimize the compiler and standard library.
+#
 # Note: the slowness of the non optimized compiler compiling itself usually
 #       outweighs the time gains in not doing optimizations, therefore a
-#       full bootstrap takes much more time with optimize set to false.
+#       full bootstrap takes much more time with `optimize` set to false.
 #optimize = true
 
+# Indicates that the build should be configured for debugging Rust. A
+# `debug`-enabled compiler and standard library will be somewhat
+# slower (due to e.g. checking of debug assertions) but should remain
+# usable.
+#
+# Note: If this value is set to `true`, it will affect a number of
+#       configuration options below as well, if they have been left
+#       unconfigured in this file.
+#
+# Note: changes to the `debug` setting do *not* affect `optimize`
+#       above. In theory, a "maximally debuggable" environment would
+#       set `optimize` to `false` above to assist the introspection
+#       facilities of debuggers like lldb and gdb. To recreate such an
+#       environment, explicitly set `optimize` to `false` and `debug`
+#       to `true`. In practice, everyone leaves `optimize` set to
+#       `true`, because an unoptimized rustc with debugging
+#       enabled becomes *unusably slow* (e.g. rust-lang/rust#24840
+#       reported a 25x slowdown) and bootstrapping the supposed
+#       "maximally debuggable" environment (notably libstd) takes
+#       hours to build.
+#
+#debug = false
+
 # Number of codegen units to use for each compiler invocation. A value of 0
 # means "the number of cores on this machine", and 1+ is passed through to the
 # compiler.
index 6a9488226b1bdc61a35479268dcce8fee9cfaf16..c01086b3f6f2b42cc809401afbf94fbfdd979f82 100644 (file)
@@ -270,7 +270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "chalk-engine"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1269,7 +1269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "minifier"
-version = "0.0.19"
+version = "0.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1898,7 +1898,7 @@ dependencies = [
  "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "fmt_macros 0.0.0",
  "graphviz 0.0.0",
@@ -2434,7 +2434,7 @@ name = "rustc_traits"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
  "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -2484,7 +2484,7 @@ dependencies = [
 name = "rustdoc"
 version = "0.0.0"
 dependencies = [
- "minifier 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "minifier 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3195,7 +3195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1"
 "checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
 "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
-"checksum chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25ce2f28f55ed544a2a3756b7acf41dd7d6f27acffb2086439950925506af7d0"
+"checksum chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6749eb72e7d4355d944a99f15fbaea701b978c18c5e184a025fcde942b0c9779"
 "checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e"
 "checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37"
 "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
@@ -3289,7 +3289,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3b4142ab8738a78c51896f704f83c11df047ff1bda9a92a661aa6361552d93d"
 "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
-"checksum minifier 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "9908ed7c62f990c21ab41fdca53a864a3ada0da69d8729c4de727b397e27bc11"
+"checksum minifier 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "96c269bb45c39b333392b2b18ad71760b34ac65666591386b0e959ed58b3f474"
 "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
 "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226"
 "checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
index c3fbc8eeca6ba65ee428f6cff468f05283334219..a5ed096a735810b09a0304faa53686c3aa1bac33 100644 (file)
@@ -628,6 +628,9 @@ pub fn parse(args: &[String]) -> Config {
         let default = false;
         config.llvm_assertions = llvm_assertions.unwrap_or(default);
 
+        let default = true;
+        config.rust_optimize = optimize.unwrap_or(default);
+
         let default = match &config.channel[..] {
             "stable" | "beta" | "nightly" => true,
             _ => false,
@@ -640,7 +643,6 @@ pub fn parse(args: &[String]) -> Config {
         config.debug_jemalloc = debug_jemalloc.unwrap_or(default);
         config.rust_debuginfo = debuginfo.unwrap_or(default);
         config.rust_debug_assertions = debug_assertions.unwrap_or(default);
-        config.rust_optimize = optimize.unwrap_or(!default);
 
         let default = config.channel == "dev";
         config.ignore_git = ignore_git.unwrap_or(default);
index ec94f57861dbeb1efce4a827795c0dfb954f73d9..5d174719ab23e4d60ac48b14bd4f0f814b67322c 100644 (file)
@@ -91,13 +91,13 @@ pub fn try_run_suppressed(cmd: &mut Command) -> bool {
     output.status.success()
 }
 
-pub fn gnu_target(target: &str) -> String {
+pub fn gnu_target(target: &str) -> &str {
     match target {
-        "i686-pc-windows-msvc" => "i686-pc-win32".to_string(),
-        "x86_64-pc-windows-msvc" => "x86_64-pc-win32".to_string(),
-        "i686-pc-windows-gnu" => "i686-w64-mingw32".to_string(),
-        "x86_64-pc-windows-gnu" => "x86_64-w64-mingw32".to_string(),
-        s => s.to_string(),
+        "i686-pc-windows-msvc" => "i686-pc-win32",
+        "x86_64-pc-windows-msvc" => "x86_64-pc-win32",
+        "i686-pc-windows-gnu" => "i686-w64-mingw32",
+        "x86_64-pc-windows-gnu" => "x86_64-w64-mingw32",
+        s => s,
     }
 }
 
diff --git a/src/doc/unstable-book/src/language-features/cfg-attr-multi.md b/src/doc/unstable-book/src/language-features/cfg-attr-multi.md
new file mode 100644 (file)
index 0000000..6365d3e
--- /dev/null
@@ -0,0 +1,20 @@
+# `cfg_attr_multi`
+
+The tracking issue for this feature is: [#54881]
+The RFC for this feature is: [#2539]
+
+[#54881]: https://github.com/rust-lang/rust/issues/54881
+[#2539]: https://github.com/rust-lang/rfcs/pull/2539
+
+------------------------
+
+This feature flag lets you put multiple attributes into a `cfg_attr` attribute.
+
+Example:
+
+```rust,ignore
+#[cfg_attr(all(), must_use, optimize)]
+```
+
+Because `cfg_attr` resolves before procedural macros, this does not affect
+macro resolution at all.
\ No newline at end of file
diff --git a/src/doc/unstable-book/src/language-features/tool-lints.md b/src/doc/unstable-book/src/language-features/tool-lints.md
deleted file mode 100644 (file)
index 5c0d33b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-# `tool_lints`
-
-The tracking issue for this feature is: [#44690]
-
-[#44690]: https://github.com/rust-lang/rust/issues/44690
-
-------------------------
-
-Tool lints let you use scoped lints, to `allow`, `warn`, `deny` or `forbid` lints of
-certain tools.
-
-Currently `clippy` is the only available lint tool.
-
-It is recommended for lint tools to implement the scoped lints like this:
-
-- `#[_(TOOL_NAME::lintname)]`: for lint names
-- `#[_(TOOL_NAME::lintgroup)]`: for groups of lints
-- `#[_(TOOL_NAME::all)]`: for (almost[^1]) all lints
-
-## An example
-
-```rust
-#![feature(tool_lints)]
-
-#![warn(clippy::pedantic)]
-
-#[allow(clippy::filter_map)]
-fn main() {
-    let v = vec![0; 10];
-    let _ = v.into_iter().filter(|&x| x < 1).map(|x| x + 1).collect::<Vec<_>>();
-    println!("No filter_map()!");
-}
-```
-
-[^1]: Some defined lint groups can be excluded here.
index 216915dba5fe7c03116d1cf2906afd7bbafe392f..b1252f386df364dcd18708dc5bc6139fe465e0dd 100755 (executable)
@@ -322,8 +322,11 @@ class RustStdBTreeSetPrinter(object):
     def children(self):
         (length, data_ptr) = \
             rustpp.extract_length_and_ptr_from_std_btreeset(self.__val)
-        val = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(3)
-        gdb_ptr = val.get_wrapped_value()
+        leaf_node = GdbValue(data_ptr.get_wrapped_value().dereference())
+        maybe_uninit_keys = leaf_node.get_child_at_index(3)
+        manually_drop_keys = maybe_uninit_keys.get_child_at_index(1)
+        keys = manually_drop_keys.get_child_at_index(0)
+        gdb_ptr = keys.get_wrapped_value()
         for index in xrange(length):
             yield (str(index), gdb_ptr[index])
 
@@ -345,9 +348,14 @@ class RustStdBTreeMapPrinter(object):
     def children(self):
         (length, data_ptr) = \
             rustpp.extract_length_and_ptr_from_std_btreemap(self.__val)
-        keys = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(3)
+        leaf_node = GdbValue(data_ptr.get_wrapped_value().dereference())
+        maybe_uninit_keys = leaf_node.get_child_at_index(3)
+        manually_drop_keys = maybe_uninit_keys.get_child_at_index(1)
+        keys = manually_drop_keys.get_child_at_index(0)
         keys_ptr = keys.get_wrapped_value()
-        vals = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(4)
+        maybe_uninit_vals = leaf_node.get_child_at_index(4)
+        manually_drop_vals = maybe_uninit_vals.get_child_at_index(1)
+        vals = manually_drop_vals.get_child_at_index(0)
         vals_ptr = vals.get_wrapped_value()
         for index in xrange(length):
             yield (str(index), keys_ptr[index])
index 0315545262b6bc0a295953f22b4328070223356b..deca9591fbd5c499210a17f6ed67990eda11fae3 100644 (file)
@@ -42,7 +42,7 @@
 //   This implies that even an empty internal node has at least one edge.
 
 use core::marker::PhantomData;
-use core::mem;
+use core::mem::{self, MaybeUninit};
 use core::ptr::{self, Unique, NonNull};
 use core::slice;
 
@@ -58,9 +58,6 @@
 /// these should always be put behind pointers, and specifically behind `BoxedNode` in the owned
 /// case.
 ///
-/// See also rust-lang/rfcs#197, which would make this structure significantly more safe by
-/// avoiding accidentally dropping unused and uninitialized keys and values.
-///
 /// We put the metadata first so that its position is the same for every `K` and `V`, in order
 /// to statically allocate a single dummy node to avoid allocations. This struct is `repr(C)` to
 /// prevent them from being reordered.
@@ -73,7 +70,7 @@ struct LeafNode<K, V> {
     /// This node's index into the parent node's `edges` array.
     /// `*node.parent.edges[node.parent_idx]` should be the same thing as `node`.
     /// This is only guaranteed to be initialized when `parent` is nonnull.
-    parent_idx: u16,
+    parent_idx: MaybeUninit<u16>,
 
     /// The number of keys and values this node stores.
     ///
@@ -83,8 +80,8 @@ struct LeafNode<K, V> {
 
     /// The arrays storing the actual data of the node. Only the first `len` elements of each
     /// array are initialized and valid.
-    keys: [K; CAPACITY],
-    vals: [V; CAPACITY],
+    keys: MaybeUninit<[K; CAPACITY]>,
+    vals: MaybeUninit<[V; CAPACITY]>,
 }
 
 impl<K, V> LeafNode<K, V> {
@@ -94,10 +91,10 @@ unsafe fn new() -> Self {
         LeafNode {
             // As a general policy, we leave fields uninitialized if they can be, as this should
             // be both slightly faster and easier to track in Valgrind.
-            keys: mem::uninitialized(),
-            vals: mem::uninitialized(),
+            keys: MaybeUninit::uninitialized(),
+            vals: MaybeUninit::uninitialized(),
             parent: ptr::null(),
-            parent_idx: mem::uninitialized(),
+            parent_idx: MaybeUninit::uninitialized(),
             len: 0
         }
     }
@@ -115,10 +112,10 @@ unsafe impl Sync for LeafNode<(), ()> {}
 // ever take a pointer past the first key.
 static EMPTY_ROOT_NODE: LeafNode<(), ()> = LeafNode {
     parent: ptr::null(),
-    parent_idx: 0,
+    parent_idx: MaybeUninit::uninitialized(),
     len: 0,
-    keys: [(); CAPACITY],
-    vals: [(); CAPACITY],
+    keys: MaybeUninit::uninitialized(),
+    vals: MaybeUninit::uninitialized(),
 };
 
 /// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden
@@ -430,7 +427,7 @@ pub fn ascend(self) -> Result<
                     root: self.root,
                     _marker: PhantomData
                 },
-                idx: self.as_leaf().parent_idx as usize,
+                idx: unsafe { usize::from(*self.as_leaf().parent_idx.get_ref()) },
                 _marker: PhantomData
             })
         } else {
@@ -567,7 +564,7 @@ fn into_key_slice(self) -> &'a [K] {
             // the node, which is allowed by LLVM.
             unsafe {
                 slice::from_raw_parts(
-                    self.as_leaf().keys.as_ptr(),
+                    self.as_leaf().keys.as_ptr() as *const K,
                     self.len()
                 )
             }
@@ -578,7 +575,7 @@ fn into_val_slice(self) -> &'a [V] {
         debug_assert!(!self.is_shared_root());
         unsafe {
             slice::from_raw_parts(
-                self.as_leaf().vals.as_ptr(),
+                self.as_leaf().vals.as_ptr() as *const V,
                 self.len()
             )
         }
@@ -605,7 +602,7 @@ fn into_key_slice_mut(mut self) -> &'a mut [K] {
         } else {
             unsafe {
                 slice::from_raw_parts_mut(
-                    &mut self.as_leaf_mut().keys as *mut [K] as *mut K,
+                    self.as_leaf_mut().keys.get_mut() as *mut [K] as *mut K,
                     self.len()
                 )
             }
@@ -616,7 +613,7 @@ fn into_val_slice_mut(mut self) -> &'a mut [V] {
         debug_assert!(!self.is_shared_root());
         unsafe {
             slice::from_raw_parts_mut(
-                &mut self.as_leaf_mut().vals as *mut [V] as *mut V,
+                self.as_leaf_mut().vals.get_mut() as *mut [V] as *mut V,
                 self.len()
             )
         }
@@ -1013,7 +1010,7 @@ fn correct_parent_link(mut self) {
         let ptr = self.node.as_internal_mut() as *mut _;
         let mut child = self.descend();
         child.as_leaf_mut().parent = ptr;
-        child.as_leaf_mut().parent_idx = idx;
+        child.as_leaf_mut().parent_idx.set(idx);
     }
 
     /// Unsafely asserts to the compiler some static information about whether the underlying
@@ -1152,12 +1149,12 @@ pub fn split(mut self)
 
             ptr::copy_nonoverlapping(
                 self.node.keys().as_ptr().add(self.idx + 1),
-                new_node.keys.as_mut_ptr(),
+                new_node.keys.as_mut_ptr() as *mut K,
                 new_len
             );
             ptr::copy_nonoverlapping(
                 self.node.vals().as_ptr().add(self.idx + 1),
-                new_node.vals.as_mut_ptr(),
+                new_node.vals.as_mut_ptr() as *mut V,
                 new_len
             );
 
@@ -1210,12 +1207,12 @@ pub fn split(mut self)
 
             ptr::copy_nonoverlapping(
                 self.node.keys().as_ptr().add(self.idx + 1),
-                new_node.data.keys.as_mut_ptr(),
+                new_node.data.keys.as_mut_ptr() as *mut K,
                 new_len
             );
             ptr::copy_nonoverlapping(
                 self.node.vals().as_ptr().add(self.idx + 1),
-                new_node.data.vals.as_mut_ptr(),
+                new_node.data.vals.as_mut_ptr() as *mut V,
                 new_len
             );
             ptr::copy_nonoverlapping(
index 78d1958b8fb37a3270ae3eadff617e3282581b7a..987572e6b74a9c2dbb803b60aafb2e7f503798bd 100644 (file)
 #![feature(rustc_const_unstable)]
 #![feature(const_vec_new)]
 #![feature(slice_partition_dedup)]
+#![feature(maybe_uninit)]
 
 // Allow testing this library
 
index 2bc037e3fee126343715212911c8b62e1d28867e..f7a0bbdceafc93325359fbb83a51b413548db0da 100644 (file)
 /// assert_eq!(vec, [1, 2, 3, 4]);
 /// ```
 ///
-/// It can also initialize each element of a `Vec<T>` with a given value:
+/// It can also initialize each element of a `Vec<T>` with a given value.
+/// This may be more efficient than performing allocation and initialization
+/// in separate steps, especially when initializing a vector of zeros:
 ///
 /// ```
 /// let vec = vec![0; 5];
 /// assert_eq!(vec, [0, 0, 0, 0, 0]);
+///
+/// // The following is equivalent, but potentially slower:
+/// let mut vec1 = Vec::with_capacity(5);
+/// vec1.resize(5, 0);
 /// ```
 ///
 /// Use a `Vec<T>` as an efficient stack:
index 3ef03ec6d585aa268ff3e519e34aaf4a0605dc06..15283036bb49522d35aec181804831dba3fb4dce 100644 (file)
 #![feature(nll)]
 #![feature(staged_api)]
 #![feature(rustc_attrs)]
+#![cfg_attr(
+    all(target_arch = "wasm32", not(target_os = "emscripten")),
+    feature(integer_atomics, stdsimd)
+)]
 #![cfg_attr(any(unix, target_os = "cloudabi", target_os = "redox"), feature(libc))]
 #![rustc_alloc_kind = "lib"]
 
@@ -331,29 +335,76 @@ mod platform {
     use core::alloc::{GlobalAlloc, Layout};
     use System;
 
-    // No need for synchronization here as wasm is currently single-threaded
     static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT;
 
     #[stable(feature = "alloc_system_type", since = "1.28.0")]
     unsafe impl GlobalAlloc for System {
         #[inline]
         unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+            let _lock = lock::lock();
             DLMALLOC.malloc(layout.size(), layout.align())
         }
 
         #[inline]
         unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+            let _lock = lock::lock();
             DLMALLOC.calloc(layout.size(), layout.align())
         }
 
         #[inline]
         unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+            let _lock = lock::lock();
             DLMALLOC.free(ptr, layout.size(), layout.align())
         }
 
         #[inline]
         unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+            let _lock = lock::lock();
             DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size)
         }
     }
+
+    #[cfg(target_feature = "atomics")]
+    mod lock {
+        use core::arch::wasm32;
+        use core::sync::atomic::{AtomicI32, Ordering::SeqCst};
+
+        static LOCKED: AtomicI32 = AtomicI32::new(0);
+
+        pub struct DropLock;
+
+        pub fn lock() -> DropLock {
+            loop {
+                if LOCKED.swap(1, SeqCst) == 0 {
+                    return DropLock
+                }
+                unsafe {
+                    let r = wasm32::atomic::wait_i32(
+                        &LOCKED as *const AtomicI32 as *mut i32,
+                        1,  // expected value
+                        -1, // timeout
+                    );
+                    debug_assert!(r == 0 || r == 1);
+                }
+            }
+        }
+
+        impl Drop for DropLock {
+            fn drop(&mut self) {
+                let r = LOCKED.swap(0, SeqCst);
+                debug_assert_eq!(r, 1);
+                unsafe {
+                    wasm32::atomic::wake(
+                        &LOCKED as *const AtomicI32 as *mut i32,
+                        1, // only one thread
+                    );
+                }
+            }
+        }
+    }
+
+    #[cfg(not(target_feature = "atomics"))]
+    mod lock {
+        pub fn lock() {} // no atomics, no threads, that's easy!
+    }
 }
index 0255f7a0885ead6d69c17ee72a4d8b12d8f26990..cf1c77041b91fe24dcf4e92361ad7f018a26cee1 100644 (file)
@@ -867,8 +867,6 @@ pub fn take(&mut self) -> Option<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(option_replace)]
-    ///
     /// let mut x = Some(2);
     /// let old = x.replace(5);
     /// assert_eq!(x, Some(5));
@@ -880,7 +878,7 @@ pub fn take(&mut self) -> Option<T> {
     /// assert_eq!(old, None);
     /// ```
     #[inline]
-    #[unstable(feature = "option_replace", issue = "51998")]
+    #[stable(feature = "option_replace", since = "1.31.0")]
     pub fn replace(&mut self, value: T) -> Option<T> {
         mem::replace(self, Some(value))
     }
index bd58dcf4ae055fd9578608f71b87919ccbb8658b..b8d7fcffbcc0968922dc2ed3d5786a0c70efb4be 100644 (file)
@@ -2370,13 +2370,13 @@ fn mod_inv(x: usize, m: usize) -> usize {
         ///
         /// Note, that this table does not contain values where inverse does not exist (i.e. for
         /// `0⁻¹ mod 16`, `2⁻¹ mod 16`, etc.)
-        const INV_TABLE_MOD_16: [usize; 8] = [1, 11, 13, 7, 9, 3, 5, 15];
+        const INV_TABLE_MOD_16: [u8; 8] = [1, 11, 13, 7, 9, 3, 5, 15];
         /// Modulo for which the `INV_TABLE_MOD_16` is intended.
         const INV_TABLE_MOD: usize = 16;
         /// INV_TABLE_MOD²
         const INV_TABLE_MOD_SQUARED: usize = INV_TABLE_MOD * INV_TABLE_MOD;
 
-        let table_inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1];
+        let table_inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1] as usize;
         if m <= INV_TABLE_MOD {
             table_inverse & (m - 1)
         } else {
@@ -2429,36 +2429,23 @@ fn mod_inv(x: usize, m: usize) -> usize {
     let gcdpow = intrinsics::cttz_nonzero(stride).min(intrinsics::cttz_nonzero(a));
     let gcd = 1usize << gcdpow;
 
-    if gcd == 1 {
-        // This branch solves for the variable $o$ in following linear congruence equation:
-        //
-        // ⎰ p + o ≡ 0 (mod a)   # $p + o$ must be aligned to specified alignment $a$
-        // ⎱     o ≡ 0 (mod s)   # offset $o$ must be a multiple of stride $s$
-        //
-        // where
+    if p as usize & (gcd - 1) == 0 {
+        // This branch solves for the following linear congruence equation:
         //
-        // * a, s are co-prime
+        // $$ p + so ≡ 0 mod a $$
         //
-        // This gives us the formula below:
+        // $p$ here is the pointer value, $s$ – stride of `T`, $o$ offset in `T`s, and $a$ – the
+        // requested alignment.
         //
-        // o = (a - (p mod a)) * (s⁻¹ mod a) * s
+        // g = gcd(a, s)
+        // o = (a - (p mod a))/g * ((s/g)⁻¹ mod a)
         //
         // The first term is “the relative alignment of p to a”, the second term is “how does
-        // incrementing p by one s change the relative alignment of p”, the third term is
-        // translating change in units of s to a byte count.
+        // incrementing p by s bytes change the relative alignment of p”. Division by `g` is
+        // necessary to make this equation well formed if $a$ and $s$ are not co-prime.
         //
         // Furthermore, the result produced by this solution is not “minimal”, so it is necessary
-        // to take the result $o mod lcm(s, a)$. Since $s$ and $a$ are co-prime (i.e. $gcd(s, a) =
-        // 1$) and $lcm(s, a) = s * a / gcd(s, a)$, we can replace $lcm(s, a)$ with just a $s * a$.
-        //
-        // (Author note: we decided later on to express the offset in "elements" rather than bytes,
-        // which drops the multiplication by `s` on both sides of the modulo.)
-        return intrinsics::unchecked_rem(a.wrapping_sub(pmoda).wrapping_mul(mod_inv(smoda, a)), a);
-    }
-
-    if p as usize & (gcd - 1) == 0 {
-        // This can be aligned, but `a` and `stride` are not co-prime, so a somewhat adapted
-        // formula is used.
+        // to take the result $o mod lcm(s, a)$. We can replace $lcm(s, a)$ with just a $a / g$.
         let j = a.wrapping_sub(pmoda) >> gcdpow;
         let k = smoda >> gcdpow;
         return intrinsics::unchecked_rem(j.wrapping_mul(mod_inv(k, a)), a >> gcdpow);
index 76dcca0257817b6f6917345345827a69cf45ba83..c9013f589edd36eb9159d62b9a3c7bae9106d69d 100644 (file)
@@ -1932,7 +1932,7 @@ fn align_to_offsets<U>(&self) -> (usize, usize) {
         fn gcd(a: usize, b: usize) -> usize {
             // iterative stein’s algorithm
             // We should still make this `const fn` (and revert to recursive algorithm if we do)
-            // because relying on llvm to consteval all this is… well, it makes me
+            // because relying on llvm to consteval all this is… well, it makes me uncomfortable.
             let (ctz_a, mut ctz_b) = unsafe {
                 if a == 0 { return b; }
                 if b == 0 { return a; }
index 651db6356ba07e93bd727adb9ed81932a3492fc8..ab4ae50c44367f3dce204ba60a4572cf60993e7d 100644 (file)
@@ -12,7 +12,7 @@
             reason = "futures in libcore are unstable",
             issue = "50547")]
 
-use {fmt, mem};
+use fmt;
 use marker::Unpin;
 use ptr::NonNull;
 
@@ -63,6 +63,20 @@ pub fn wake(&self) {
     pub fn will_wake(&self, other: &Waker) -> bool {
         self.inner == other.inner
     }
+
+    /// Returns whether or not this `Waker` and `other` `LocalWaker` awaken
+    /// the same task.
+    ///
+    /// This function works on a best-effort basis, and may return false even
+    /// when the `Waker`s would awaken the same task. However, if this function
+    /// returns true, it is guaranteed that the `Waker`s will awaken the same
+    /// task.
+    ///
+    /// This function is primarily used for optimization purposes.
+    #[inline]
+    pub fn will_wake_local(&self, other: &LocalWaker) -> bool {
+        self.will_wake(&other.0)
+    }
 }
 
 impl Clone for Waker {
@@ -97,9 +111,8 @@ fn drop(&mut self) {
 /// Task executors can use this type to implement more optimized singlethreaded wakeup
 /// behavior.
 #[repr(transparent)]
-pub struct LocalWaker {
-    inner: NonNull<dyn UnsafeWake>,
-}
+#[derive(Clone)]
+pub struct LocalWaker(Waker);
 
 impl Unpin for LocalWaker {}
 impl !Send for LocalWaker {}
@@ -120,7 +133,16 @@ impl LocalWaker {
     /// on the current thread.
     #[inline]
     pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self {
-        LocalWaker { inner }
+        LocalWaker(Waker::new(inner))
+    }
+
+    /// Borrows this `LocalWaker` as a `Waker`.
+    ///
+    /// `Waker` is nearly identical to `LocalWaker`, but is threadsafe
+    /// (implements `Send` and `Sync`).
+    #[inline]
+    pub fn as_waker(&self) -> &Waker {
+        &self.0
     }
 
     /// Converts this `LocalWaker` into a `Waker`.
@@ -129,13 +151,13 @@ pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self {
     /// (implements `Send` and `Sync`).
     #[inline]
     pub fn into_waker(self) -> Waker {
-        self.into()
+        self.0
     }
 
     /// Wake up the task associated with this `LocalWaker`.
     #[inline]
     pub fn wake(&self) {
-        unsafe { self.inner.as_ref().wake_local() }
+        unsafe { self.0.inner.as_ref().wake_local() }
     }
 
     /// Returns whether or not this `LocalWaker` and `other` `LocalWaker` awaken the same task.
@@ -148,7 +170,7 @@ pub fn wake(&self) {
     /// This function is primarily used for optimization purposes.
     #[inline]
     pub fn will_wake(&self, other: &LocalWaker) -> bool {
-        self.inner == other.inner
+        self.0.will_wake(&other.0)
     }
 
     /// Returns whether or not this `LocalWaker` and `other` `Waker` awaken the same task.
@@ -161,45 +183,24 @@ pub fn will_wake(&self, other: &LocalWaker) -> bool {
     /// This function is primarily used for optimization purposes.
     #[inline]
     pub fn will_wake_nonlocal(&self, other: &Waker) -> bool {
-        self.inner == other.inner
+        self.0.will_wake(other)
     }
 }
 
 impl From<LocalWaker> for Waker {
     #[inline]
     fn from(local_waker: LocalWaker) -> Self {
-        let inner = local_waker.inner;
-        mem::forget(local_waker);
-        Waker { inner }
-    }
-}
-
-impl Clone for LocalWaker {
-    #[inline]
-    fn clone(&self) -> Self {
-        let waker = unsafe { self.inner.as_ref().clone_raw() };
-        let inner = waker.inner;
-        mem::forget(waker);
-        LocalWaker { inner }
+        local_waker.0
     }
 }
 
 impl fmt::Debug for LocalWaker {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("Waker")
+        f.debug_struct("LocalWaker")
             .finish()
     }
 }
 
-impl Drop for LocalWaker {
-    #[inline]
-    fn drop(&mut self) {
-        unsafe {
-            self.inner.as_ref().drop_raw()
-        }
-    }
-}
-
 /// An unsafe trait for implementing custom memory management for a `Waker` or `LocalWaker`.
 ///
 /// A `Waker` conceptually is a cloneable trait object for `Wake`, and is
index ada61d8dfd8739129a5d9cb83313dd738b393a33..0beb60a127097b18204197aa7491b321cd717792 100644 (file)
@@ -39,7 +39,6 @@
 #![feature(reverse_bits)]
 #![feature(inner_deref)]
 #![feature(slice_internals)]
-#![feature(option_replace)]
 #![feature(slice_partition_dedup)]
 #![feature(copy_within)]
 
index 6c3b52196a3a2bb03c459e4f96b8a821fda5864d..d0ec8640ce9ef3edcf4a1e9aa07e42a64cbbf398 100644 (file)
@@ -31,7 +31,7 @@ syntax_pos = { path = "../libsyntax_pos" }
 backtrace = "0.3.3"
 parking_lot = "0.6"
 byteorder = { version = "1.1", features = ["i128"]}
-chalk-engine = { version = "0.7.0", default-features=false }
+chalk-engine = { version = "0.8.0", default-features=false }
 rustc_fs_util = { path = "../librustc_fs_util" }
 smallvec = { version = "0.6.5", features = ["union"] }
 
index e8c89cb3e0e7eb17bdbb6b207855fb86699f2a18..f51a3e71d0741f9eb68aeaa1a4f8381906aabe40 100644 (file)
@@ -1370,7 +1370,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        use traits::Goal::*;
+        use traits::GoalKind::*;
 
         mem::discriminant(self).hash_stable(hcx, hasher);
         match self {
index 87d33e473e7f6cd97bc392e3f6bf926518744264..950754a07ab09787b94e05db5ca8b381a2e9ae29 100644 (file)
 use lint::{self, Lint, LintId, Level, LintSource};
 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
                                            StableHasher, StableHasherResult};
-use session::{config::nightly_options, Session};
+use session::Session;
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::MultiSpan;
-use syntax::feature_gate;
 use syntax::symbol::Symbol;
 use util::nodemap::FxHashMap;
 
@@ -228,18 +227,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                     }
                 };
                 let tool_name = if let Some(lint_tool) = word.is_scoped() {
-                    let gate_feature = !self.sess.features_untracked().tool_lints;
-                    let known_tool = attr::is_known_lint_tool(lint_tool);
-                    if gate_feature {
-                        feature_gate::emit_feature_err(
-                            &sess.parse_sess,
-                            "tool_lints",
-                            word.span,
-                            feature_gate::GateIssue::Language,
-                            &format!("scoped lint `{}` is experimental", word.ident),
-                        );
-                    }
-                    if !known_tool {
+                    if !attr::is_known_lint_tool(lint_tool) {
                         span_err!(
                             sess,
                             lint_tool.span,
@@ -247,9 +235,6 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                             "an unknown tool name found in scoped lint: `{}`",
                             word.ident
                         );
-                    }
-
-                    if gate_feature || !known_tool {
                         continue;
                     }
 
@@ -299,13 +284,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                                     "change it to",
                                     new_lint_name.to_string(),
                                     Applicability::MachineApplicable,
-                                );
-
-                                if nightly_options::is_nightly_build() {
-                                    err.emit();
-                                } else {
-                                    err.cancel();
-                                }
+                                ).emit();
 
                                 let src = LintSource::Node(Symbol::intern(&new_lint_name), li.span);
                                 for id in ids {
index 759ac1a7952f7165b0ef858f42359513049c7fce..897e9cc2a381f2305c96a59bc15b3508833637d6 100644 (file)
@@ -62,6 +62,16 @@ macro_rules! span_bug {
     })
 }
 
+#[macro_export]
+macro_rules! static_assert {
+    ($name:ident: $test:expr) => {
+        // Use the bool to access an array such that if the bool is false, the access
+        // is out-of-bounds.
+        #[allow(dead_code)]
+        static $name: () = [()][!$test as usize];
+    }
+}
+
 #[macro_export]
 macro_rules! __impl_stable_hash_field {
     ($field:ident, $ctx:expr, $hasher:expr) => ($field.hash_stable($ctx, $hasher));
index edb571da7dbc50c010d07079f9b45e93960e2dde..a90f03f536ad52d62cb4d7d419a92f14c997e4d7 100644 (file)
@@ -167,8 +167,7 @@ pub struct FirstStatementIndex { .. }
 impl_stable_hash_for!(struct ::middle::region::FirstStatementIndex { private });
 
 // compilation error if size of `ScopeData` is not the same as a `u32`
-#[allow(dead_code)]
-static ASSERT: () = [()][!(mem::size_of::<ScopeData>() == 4) as usize];
+static_assert!(ASSERT_SCOPE_DATA: mem::size_of::<ScopeData>() == 4);
 
 impl Scope {
     /// Returns a item-local id associated with this scope.
index c532b5ee56f47d2d908cf442795842f84b0182e5..d8c36f81da32427bfb86d2775babd1dced494f60 100644 (file)
@@ -1387,6 +1387,10 @@ fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool {
           "output a json file with profiler results"),
     emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
           "emits a section containing stack size metadata"),
+    plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
+          "whether to use the PLT when calling into shared libraries;
+          only has effect for PIC code on systems with ELF binaries
+          (default: PLT is disabled if full relro is enabled)"),
 }
 
 pub fn default_lib_output() -> CrateType {
index 3c209a4324675a5b0681375b7f9b75869f0d2ae0..10a506da4eab44c6cffbc8da7f5405ad357afffd 100644 (file)
@@ -40,8 +40,7 @@
 use syntax_pos::{MultiSpan, Span};
 use util::profiling::SelfProfiler;
 
-use rustc_target::spec::PanicStrategy;
-use rustc_target::spec::{Target, TargetTriple};
+use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
 use rustc_data_structures::flock;
 use jobserver::Client;
 
@@ -984,6 +983,27 @@ pub fn rust_2018(&self) -> bool {
     pub fn edition(&self) -> Edition {
         self.opts.edition
     }
+
+    /// True if we cannot skip the PLT for shared library calls.
+    pub fn needs_plt(&self) -> bool {
+        // Check if the current target usually needs PLT to be enabled.
+        // The user can use the command line flag to override it.
+        let needs_plt = self.target.target.options.needs_plt;
+
+        let dbg_opts = &self.opts.debugging_opts;
+
+        let relro_level = dbg_opts.relro_level
+            .unwrap_or(self.target.target.options.relro_level);
+
+        // Only enable this optimization by default if full relro is also enabled.
+        // In this case, lazy binding was already unavailable, so nothing is lost.
+        // This also ensures `-Wl,-z,now` is supported by the linker.
+        let full_relro = RelroLevel::Full == relro_level;
+
+        // If user didn't explicitly forced us to use / skip the PLT,
+        // then try to skip it where possible.
+        dbg_opts.plt.unwrap_or(needs_plt || !full_relro)
+    }
 }
 
 pub fn build_session(
index 286e35c5d4e9582cebe50b93dd204b5f3d2f67f2..6e4abee32c0771e3b87ef9c016a0ed0b0df48672 100644 (file)
@@ -318,31 +318,33 @@ pub enum QuantifierKind {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub enum Goal<'tcx> {
-    Implies(Clauses<'tcx>, &'tcx Goal<'tcx>),
-    And(&'tcx Goal<'tcx>, &'tcx Goal<'tcx>),
-    Not(&'tcx Goal<'tcx>),
+pub enum GoalKind<'tcx> {
+    Implies(Clauses<'tcx>, Goal<'tcx>),
+    And(Goal<'tcx>, Goal<'tcx>),
+    Not(Goal<'tcx>),
     DomainGoal(DomainGoal<'tcx>),
-    Quantified(QuantifierKind, ty::Binder<&'tcx Goal<'tcx>>),
+    Quantified(QuantifierKind, ty::Binder<Goal<'tcx>>),
     CannotProve,
 }
 
+pub type Goal<'tcx> = &'tcx GoalKind<'tcx>;
+
 pub type Goals<'tcx> = &'tcx List<Goal<'tcx>>;
 
 impl<'tcx> DomainGoal<'tcx> {
-    pub fn into_goal(self) -> Goal<'tcx> {
-        Goal::DomainGoal(self)
+    pub fn into_goal(self) -> GoalKind<'tcx> {
+        GoalKind::DomainGoal(self)
     }
 }
 
-impl<'tcx> Goal<'tcx> {
+impl<'tcx> GoalKind<'tcx> {
     pub fn from_poly_domain_goal<'a>(
         domain_goal: PolyDomainGoal<'tcx>,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    ) -> Goal<'tcx> {
+    ) -> GoalKind<'tcx> {
         match domain_goal.no_late_bound_regions() {
             Some(p) => p.into_goal(),
-            None => Goal::Quantified(
+            None => GoalKind::Quantified(
                 QuantifierKind::Universal,
                 domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal()))
             ),
index 22e79fc2638abbf1a7f9e1a712c62060a91060ef..1524f89af291d05b8738bdbe3df0b9b29152bff7 100644 (file)
@@ -469,7 +469,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 impl<'tcx> fmt::Display for traits::Goal<'tcx> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use traits::Goal::*;
+        use traits::GoalKind::*;
 
         match self {
             Implies(hypotheses, goal) => {
@@ -598,25 +598,25 @@ impl<'a, 'tcx> Lift<'tcx> for traits::DomainGoal<'a> {
 }
 
 EnumTypeFoldableImpl! {
-    impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
-        (traits::Goal::Implies)(hypotheses, goal),
-        (traits::Goal::And)(goal1, goal2),
-        (traits::Goal::Not)(goal),
-        (traits::Goal::DomainGoal)(domain_goal),
-        (traits::Goal::Quantified)(qkind, goal),
-        (traits::Goal::CannotProve),
+    impl<'tcx> TypeFoldable<'tcx> for traits::GoalKind<'tcx> {
+        (traits::GoalKind::Implies)(hypotheses, goal),
+        (traits::GoalKind::And)(goal1, goal2),
+        (traits::GoalKind::Not)(goal),
+        (traits::GoalKind::DomainGoal)(domain_goal),
+        (traits::GoalKind::Quantified)(qkind, goal),
+        (traits::GoalKind::CannotProve),
     }
 }
 
 EnumLiftImpl! {
-    impl<'a, 'tcx> Lift<'tcx> for traits::Goal<'a> {
-        type Lifted = traits::Goal<'tcx>;
-        (traits::Goal::Implies)(hypotheses, goal),
-        (traits::Goal::And)(goal1, goal2),
-        (traits::Goal::Not)(goal),
-        (traits::Goal::DomainGoal)(domain_goal),
-        (traits::Goal::Quantified)(kind, goal),
-        (traits::Goal::CannotProve),
+    impl<'a, 'tcx> Lift<'tcx> for traits::GoalKind<'a> {
+        type Lifted = traits::GoalKind<'tcx>;
+        (traits::GoalKind::Implies)(hypotheses, goal),
+        (traits::GoalKind::And)(goal1, goal2),
+        (traits::GoalKind::Not)(goal),
+        (traits::GoalKind::DomainGoal)(domain_goal),
+        (traits::GoalKind::Quantified)(kind, goal),
+        (traits::GoalKind::CannotProve),
     }
 }
 
@@ -633,7 +633,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for &'tcx traits::Goal<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         let v = (**self).fold_with(folder);
         folder.tcx().mk_goal(v)
index 46ba5f5ef362dfb30e6f5b5deb2186dbe577d255..ab1df2d4c3bb9f3eaece7df32fef18c18ff1da4b 100644 (file)
@@ -36,7 +36,7 @@
 use ty::subst::{CanonicalSubsts, Kind, Substs, Subst};
 use ty::ReprOptions;
 use traits;
-use traits::{Clause, Clauses, Goal, Goals};
+use traits::{Clause, Clauses, GoalKind, Goal, Goals};
 use ty::{self, Ty, TypeAndMut};
 use ty::{TyS, TyKind, List};
 use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const};
@@ -143,7 +143,8 @@ pub struct CtxtInterners<'tcx> {
     predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
     const_: InternedSet<'tcx, Const<'tcx>>,
     clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
-    goals: InternedSet<'tcx, List<Goal<'tcx>>>,
+    goal: InternedSet<'tcx, GoalKind<'tcx>>,
+    goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
 }
 
 impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
@@ -159,7 +160,8 @@ fn new(arena: &'tcx SyncDroplessArena) -> CtxtInterners<'tcx> {
             predicates: Default::default(),
             const_: Default::default(),
             clauses: Default::default(),
-            goals: Default::default(),
+            goal: Default::default(),
+            goal_list: Default::default(),
         }
     }
 
@@ -827,12 +829,9 @@ impl<'tcx> CommonTypes<'tcx> {
     fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
         // Ensure our type representation does not grow
         #[cfg(target_pointer_width = "64")]
-        #[allow(dead_code)]
-        static ASSERT_TY_KIND: () =
-            [()][!(::std::mem::size_of::<ty::TyKind<'_>>() <= 24) as usize];
+        static_assert!(ASSERT_TY_KIND: ::std::mem::size_of::<ty::TyKind<'_>>() <= 24);
         #[cfg(target_pointer_width = "64")]
-        #[allow(dead_code)]
-        static ASSERT_TYS: () = [()][!(::std::mem::size_of::<ty::TyS<'_>>() <= 32) as usize];
+        static_assert!(ASSERT_TYS: ::std::mem::size_of::<ty::TyS<'_>>() <= 32);
 
         let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
         let mk_region = |r| {
@@ -1731,9 +1730,9 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'t
     }
 }
 
-impl<'a, 'tcx> Lift<'tcx> for &'a Goal<'a> {
-    type Lifted = &'tcx Goal<'tcx>;
-    fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Goal<'tcx>> {
+impl<'a, 'tcx> Lift<'tcx> for Goal<'a> {
+    type Lifted = Goal<'tcx>;
+    fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Goal<'tcx>> {
         if tcx.interners.arena.in_arena(*self as *const _) {
             return Some(unsafe { mem::transmute(*self) });
         }
@@ -2304,6 +2303,12 @@ fn borrow<'a>(&'a self) -> &'a RegionKind {
     }
 }
 
+impl<'tcx: 'lcx, 'lcx> Borrow<GoalKind<'lcx>> for Interned<'tcx, GoalKind<'tcx>> {
+    fn borrow<'a>(&'a self) -> &'a GoalKind<'lcx> {
+        &self.0
+    }
+}
+
 impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]>
     for Interned<'tcx, List<ExistentialPredicate<'tcx>>> {
     fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] {
@@ -2419,7 +2424,8 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
 
 direct_interners!('tcx,
     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>
+    const_: mk_const(|c: &Const<'_>| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>,
+    goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>
 );
 
 macro_rules! slice_interners {
@@ -2438,7 +2444,7 @@ macro_rules! slice_interners {
     type_list: _intern_type_list(Ty),
     substs: _intern_substs(Kind),
     clauses: _intern_clauses(Clause),
-    goals: _intern_goals(Goal)
+    goal_list: _intern_goals(Goal)
 );
 
 // This isn't a perfect fit: CanonicalVarInfo slices are always
@@ -2818,10 +2824,6 @@ pub fn mk_goals<I: InternAs<[Goal<'tcx>], Goals<'tcx>>>(self, iter: I) -> I::Out
         iter.intern_with(|xs| self.intern_goals(xs))
     }
 
-    pub fn mk_goal(self, goal: Goal<'tcx>) -> &'tcx Goal<'_> {
-        &self.intern_goals(&[goal])[0]
-    }
-
     pub fn lint_hir<S: Into<MultiSpan>>(self,
                                         lint: &'static Lint,
                                         hir_id: HirId,
index c3d41873009a7b1d294a88e611b96e8f1d127df9..10a90dfc8a8cf936a56662820ca3300e8600c0be 100644 (file)
@@ -148,7 +148,10 @@ fn add_sty(&mut self, st: &ty::TyKind<'_>) {
                 self.add_projection_ty(data);
             }
 
-            &ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
+            &ty::UnnormalizedProjection(ref data) => {
+                self.add_flags(TypeFlags::HAS_PROJECTION);
+                self.add_projection_ty(data);
+            },
 
             &ty::Opaque(_, substs) => {
                 self.add_flags(TypeFlags::HAS_PROJECTION);
index 684f2b358858f935387d082d6b0b26607a796cb1..c8e8d0dc84ef038027ffc589c558923721a253d2 100644 (file)
@@ -150,7 +150,7 @@ fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
         // Create list of fields in the main structure
         let mut args: Vec<_> =
             self.prefix.iter().flat_map(|option_kind| option_kind.map(
-                    |kind| Reg { kind: kind, size: self.prefix_chunk }.llvm_type(cx)))
+                |kind| Reg { kind: kind, size: self.prefix_chunk }.llvm_type(cx)))
             .chain((0..rest_count).map(|_| rest_ll_unit))
             .collect();
 
@@ -259,8 +259,7 @@ fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceR
 }
 
 pub trait FnTypeExt<'tcx> {
-    fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>)
-                   -> Self;
+    fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self;
     fn new(cx: &CodegenCx<'ll, 'tcx>,
            sig: ty::FnSig<'tcx>,
            extra_args: &[Ty<'tcx>]) -> Self;
@@ -283,8 +282,7 @@ fn adjust_for_abi(&mut self,
 }
 
 impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
-    fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>)
-                       -> Self {
+    fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self {
         let fn_ty = instance.ty(cx.tcx);
         let sig = ty_fn_sig(cx, fn_ty);
         let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
@@ -292,16 +290,16 @@ fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>)
     }
 
     fn new(cx: &CodegenCx<'ll, 'tcx>,
-               sig: ty::FnSig<'tcx>,
-               extra_args: &[Ty<'tcx>]) -> Self {
+           sig: ty::FnSig<'tcx>,
+           extra_args: &[Ty<'tcx>]) -> Self {
         FnType::new_internal(cx, sig, extra_args, |ty, _| {
             ArgType::new(cx.layout_of(ty))
         })
     }
 
     fn new_vtable(cx: &CodegenCx<'ll, 'tcx>,
-                      sig: ty::FnSig<'tcx>,
-                      extra_args: &[Ty<'tcx>]) -> Self {
+                  sig: ty::FnSig<'tcx>,
+                  extra_args: &[Ty<'tcx>]) -> Self {
         FnType::new_internal(cx, sig, extra_args, |ty, arg_idx| {
             let mut layout = cx.layout_of(ty);
             // Don't pass the vtable, it's not an argument of the virtual fn.
@@ -338,7 +336,7 @@ fn new_internal(
             RustIntrinsic | PlatformIntrinsic |
             Rust | RustCall => Conv::C,
 
-            // It's the ABI's job to select this, not us.
+            // It's the ABI's job to select this, not ours.
             System => bug!("system abi should be selected elsewhere"),
 
             Stdcall => Conv::X86Stdcall,
@@ -697,14 +695,13 @@ fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value
             // If the value is a boolean, the range is 0..2 and that ultimately
             // become 0..0 when the type becomes i1, which would be rejected
             // by the LLVM verifier.
-            match scalar.value {
-                layout::Int(..) if !scalar.is_bool() => {
+            if let layout::Int(..) = scalar.value {
+                if !scalar.is_bool() {
                     let range = scalar.valid_range_exclusive(bx.cx);
                     if range.start != range.end {
                         bx.range_metadata(callsite, range);
                     }
                 }
-                _ => {}
             }
         }
         for arg in &self.args {
index 0beb8a8844c958f281f98f9e902c4b8dcb9a3fb3..7c237407c8f54b219a903b0e360392f18ff87761 100644 (file)
@@ -33,7 +33,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind
     let void = llvm::LLVMVoidTypeInContext(llcx);
 
     for method in ALLOCATOR_METHODS {
-        let mut args = Vec::new();
+        let mut args = Vec::with_capacity(method.inputs.len());
         for ty in method.inputs.iter() {
             match *ty {
                 AllocatorTy::Layout => {
index 51380db5b23df295c4f1125e5d12a3ec8f7d4c22..90ba103ca4ceb2540d0173dd0c7ae8016f6746e8 100644 (file)
@@ -94,9 +94,8 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
     // Currently stack probes seem somewhat incompatible with the address
     // sanitizer. With asan we're already protected from stack overflow anyway
     // so we don't really need stack probes regardless.
-    match cx.sess().opts.debugging_opts.sanitizer {
-        Some(Sanitizer::Address) => return,
-        _ => {}
+    if let Some(Sanitizer::Address) = cx.sess().opts.debugging_opts.sanitizer {
+        return
     }
 
     // probestack doesn't play nice either with pgo-gen.
@@ -138,6 +137,15 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
             target_cpu.as_c_str());
 }
 
+/// Sets the `NonLazyBind` LLVM attribute on a given function,
+/// assuming the codegen options allow skipping the PLT.
+pub fn non_lazy_bind(sess: &Session, llfn: &'ll Value) {
+    // Don't generate calls through PLT if it's not necessary
+    if !sess.needs_plt() {
+        Attribute::NonLazyBind.apply_llfn(Function, llfn);
+    }
+}
+
 /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
 /// attributes.
 pub fn from_fn_attrs(
@@ -280,12 +288,14 @@ pub fn provide_extern(providers: &mut Providers) {
         // `NativeLibrary` internally contains information about
         // `#[link(wasm_import_module = "...")]` for example.
         let native_libs = tcx.native_libraries(cnum);
-        let mut def_id_to_native_lib = FxHashMap();
-        for lib in native_libs.iter() {
+
+        let def_id_to_native_lib = native_libs.iter().filter_map(|lib|
             if let Some(id) = lib.foreign_module {
-                def_id_to_native_lib.insert(id, lib);
+                Some((id, lib))
+            } else {
+                None
             }
-        }
+        ).collect::<FxHashMap<_, _>>();
 
         let mut ret = FxHashMap();
         for lib in tcx.foreign_modules(cnum).iter() {
@@ -296,10 +306,10 @@ pub fn provide_extern(providers: &mut Providers) {
                 Some(s) => s,
                 None => continue,
             };
-            for id in lib.foreign_items.iter() {
+            ret.extend(lib.foreign_items.iter().map(|id| {
                 assert_eq!(id.krate, cnum);
-                ret.insert(*id, module.to_string());
-            }
+                (*id, module.to_string())
+            }));
         }
 
         Lrc::new(ret)
index 55dc43ec1fbca6d3198f22d090df582af7072fe9..c814ab4ab6710123e8e69069ad7690761134ea7d 100644 (file)
@@ -213,8 +213,8 @@ pub fn unsized_info(
                             vtable_ptr.llvm_type(cx))
         }
         _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}",
-                                     source,
-                                     target),
+                  source,
+                  target),
     }
 }
 
@@ -340,11 +340,11 @@ pub fn cast_shift_expr_rhs(
 }
 
 fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind,
-                        lhs: &'ll Value,
-                        rhs: &'ll Value,
-                        trunc: F,
-                        zext: G)
-                        -> &'ll Value
+                             lhs: &'ll Value,
+                             rhs: &'ll Value,
+                             trunc: F,
+                             zext: G)
+                             -> &'ll Value
     where F: FnOnce(&'ll Value, &'ll Type) -> &'ll Value,
           G: FnOnce(&'ll Value, &'ll Type) -> &'ll Value
 {
@@ -363,8 +363,8 @@ fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind,
         if lhs_sz < rhs_sz {
             trunc(rhs, lhs_llty)
         } else if lhs_sz > rhs_sz {
-            // FIXME (#1877: If shifting by negative
-            // values becomes not undefined then this is wrong.
+            // FIXME (#1877: If in the future shifting by negative
+            // values is no longer undefined then this is wrong.
             zext(rhs, lhs_llty)
         } else {
             rhs
@@ -495,10 +495,8 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'
     let sig = common::ty_fn_sig(cx, fn_ty);
     let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
 
-    let lldecl = match cx.instances.borrow().get(&instance) {
-        Some(&val) => val,
-        None => bug!("Instance `{:?}` not already declared", instance)
-    };
+    let lldecl = cx.instances.borrow().get(&instance).cloned().unwrap_or_else(||
+        bug!("Instance `{:?}` not already declared", instance));
 
     cx.stats.borrow_mut().n_closures += 1;
 
@@ -566,8 +564,8 @@ fn create_entry_fn(
         if declare::get_defined_value(cx, "main").is_some() {
             // FIXME: We should be smart and show a better diagnostic here.
             cx.sess().struct_span_err(sp, "entry symbol `main` defined multiple times")
-                      .help("did you use #[no_mangle] on `fn main`? Use #[start] instead")
-                      .emit();
+                     .help("did you use #[no_mangle] on `fn main`? Use #[start] instead")
+                     .emit();
             cx.sess().abort_if_errors();
             bug!();
         }
@@ -736,9 +734,9 @@ fn determine_cgu_reuse<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             rx: mpsc::Receiver<Box<dyn Any + Send>>)
-                             -> OngoingCodegen {
-
+                               rx: mpsc::Receiver<Box<dyn Any + Send>>)
+                               -> OngoingCodegen
+{
     check_for_rustc_errors_attr(tcx);
 
     if let Some(true) = tcx.sess.opts.debugging_opts.thinlto {
@@ -803,8 +801,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     // Run the monomorphization collector and partition the collected items into
     // codegen units.
-    let codegen_units =
-        tcx.collect_and_partition_mono_items(LOCAL_CRATE).1;
+    let codegen_units = tcx.collect_and_partition_mono_items(LOCAL_CRATE).1;
     let codegen_units = (*codegen_units).clone();
 
     // Force all codegen_unit queries so they are already either red or green
@@ -837,12 +834,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         .iter()
         .any(|(_, list)| {
             use rustc::middle::dependency_format::Linkage;
-            list.iter().any(|linkage| {
-                match linkage {
-                    Linkage::Dynamic => true,
-                    _ => false,
-                }
-            })
+            list.iter().any(|&linkage| linkage == Linkage::Dynamic)
         });
     let allocator_module = if any_dynamic_crate {
         None
@@ -988,7 +980,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>(
                 if mode_string != "lazy" {
                     let message = format!("Unknown codegen-item collection mode '{}'. \
                                            Falling back to 'lazy' mode.",
-                                           mode_string);
+                                          mode_string);
                     tcx.sess.warn(&message);
                 }
 
@@ -1123,7 +1115,15 @@ pub fn new(tcx: TyCtxt) -> CrateInfo {
             info.load_wasm_imports(tcx, LOCAL_CRATE);
         }
 
-        for &cnum in tcx.crates().iter() {
+        let crates = tcx.crates();
+
+        let n_crates = crates.len();
+        info.native_libraries.reserve(n_crates);
+        info.crate_name.reserve(n_crates);
+        info.used_crate_source.reserve(n_crates);
+        info.missing_lang_items.reserve(n_crates);
+
+        for &cnum in crates.iter() {
             info.native_libraries.insert(cnum, tcx.native_libraries(cnum));
             info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string());
             info.used_crate_source.insert(cnum, tcx.used_crate_source(cnum));
@@ -1165,11 +1165,12 @@ pub fn new(tcx: TyCtxt) -> CrateInfo {
     }
 
     fn load_wasm_imports(&mut self, tcx: TyCtxt, cnum: CrateNum) {
-        for (&id, module) in tcx.wasm_import_module_map(cnum).iter() {
+        self.wasm_imports.extend(tcx.wasm_import_module_map(cnum).iter().map(|(&id, module)| {
             let instance = Instance::mono(tcx, id);
             let import_name = tcx.symbol_name(instance);
-            self.wasm_imports.insert(import_name.to_string(), module.clone());
-        }
+
+            (import_name.to_string(), module.clone())
+        }));
     }
 }
 
index 77de88997e4903ebc0326203049a4d1756e670a7..df9c4e874bd95b61ce2bdf20d6690c940b7d4e41 100644 (file)
@@ -110,10 +110,10 @@ fn count_insn(&self, category: &str) {
         }
         if self.cx.sess().count_llvm_insns() {
             *self.cx.stats
-                .borrow_mut()
-                .llvm_insns
-                .entry(category.to_string())
-                .or_insert(0) += 1;
+                    .borrow_mut()
+                    .llvm_insns
+                    .entry(category.to_string())
+                    .or_insert(0) += 1;
         }
     }
 
@@ -735,9 +735,9 @@ pub fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -
     }
 
     pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
-                         inputs: &[&'ll Value], output: &'ll Type,
-                         volatile: bool, alignstack: bool,
-                         dia: AsmDialect) -> Option<&'ll Value> {
+                           inputs: &[&'ll Value], output: &'ll Type,
+                           volatile: bool, alignstack: bool,
+                           dia: AsmDialect) -> Option<&'ll Value> {
         self.count_insn("inlineasm");
 
         let volatile = if volatile { llvm::True }
@@ -1093,7 +1093,7 @@ pub fn atomic_cmpxchg(
     ) -> &'ll Value {
         unsafe {
             llvm::LLVMRustBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src,
-                                         order, failure_order, weak)
+                                             order, failure_order, weak)
         }
     }
     pub fn atomic_rmw(
@@ -1194,7 +1194,7 @@ fn check_call<'b>(&self,
             })
             .collect();
 
-        return Cow::Owned(casted_args);
+        Cow::Owned(casted_args)
     }
 
     pub fn lifetime_start(&self, ptr: &'ll Value, size: Size) {
index 53bb02ddd99d947887ad4a555fb4330114df511e..c08937fa9b9162669bcb04f021cbde86c2aa6736 100644 (file)
@@ -336,16 +336,13 @@ pub fn langcall(tcx: TyCtxt,
                 msg: &str,
                 li: LangItem)
                 -> DefId {
-    match tcx.lang_items().require(li) {
-        Ok(id) => id,
-        Err(s) => {
-            let msg = format!("{} {}", msg, s);
-            match span {
-                Some(span) => tcx.sess.span_fatal(span, &msg[..]),
-                None => tcx.sess.fatal(&msg[..]),
-            }
+    tcx.lang_items().require(li).unwrap_or_else(|s| {
+        let msg = format!("{} {}", msg, s);
+        match span {
+            Some(span) => tcx.sess.span_fatal(span, &msg[..]),
+            None => tcx.sess.fatal(&msg[..]),
         }
-    }
+    })
 }
 
 // To avoid UB from LLVM, these two functions mask RHS with an
index 522de2f15e0a95806b15fc2f3023b54a9ae3ed4b..9228870bf3a5c2105d84fe298aca420e165524fb 100644 (file)
@@ -124,7 +124,7 @@ pub fn get_static(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll Value {
     assert!(!defined_in_current_codegen_unit,
             "consts::get_static() should always hit the cache for \
              statics defined in the same CGU, but did not for `{:?}`",
-             def_id);
+            def_id);
 
     let ty = instance.ty(cx.tcx);
     let sym = cx.tcx.symbol_name(instance).as_str();
@@ -249,14 +249,13 @@ fn check_and_apply_linkage(
         // extern "C" fn() from being non-null, so we can't just declare a
         // static and call it a day. Some linkages (like weak) will make it such
         // that the static actually has a null value.
-        let llty2 = match ty.sty {
-            ty::RawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx),
-            _ => {
-                if span.is_some() {
-                    cx.sess().span_fatal(span.unwrap(), "must have type `*const T` or `*mut T`")
-                } else {
-                    bug!("must have type `*const T` or `*mut T`")
-                }
+        let llty2 = if let ty::RawPtr(ref mt) = ty.sty {
+            cx.layout_of(mt.ty).llvm_type(cx)
+        } else {
+            if let Some(span) = span {
+                cx.sess().span_fatal(span, "must have type `*const T` or `*mut T`")
+            } else {
+                bug!("must have type `*const T` or `*mut T`")
             }
         };
         unsafe {
@@ -273,9 +272,9 @@ fn check_and_apply_linkage(
             let mut real_name = "_rust_extern_with_linkage_".to_string();
             real_name.push_str(&sym);
             let g2 = declare::define_global(cx, &real_name, llty).unwrap_or_else(||{
-                if span.is_some() {
+                if let Some(span) = span {
                     cx.sess().span_fatal(
-                        span.unwrap(),
+                        span,
                         &format!("symbol `{}` is already defined", &sym)
                     )
                 } else {
index 9547f4a190e7896d721cda285efb8217b05fc674..578018c7adc8a7fa0334394c28b3fd87f81c40fa 100644 (file)
@@ -59,8 +59,8 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
     /// Cache instances of monomorphic and polymorphic items
     pub instances: RefCell<FxHashMap<Instance<'tcx>, &'a Value>>,
     /// Cache generated vtables
-    pub vtables: RefCell<FxHashMap<(Ty<'tcx>,
-                                Option<ty::PolyExistentialTraitRef<'tcx>>), &'a Value>>,
+    pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>),
+                                   &'a Value>>,
     /// Cache of constant strings,
     pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'a Value>>,
 
@@ -208,14 +208,21 @@ pub unsafe fn create_module(
         llvm::LLVMRustSetModulePIELevel(llmod);
     }
 
+    // If skipping the PLT is enabled, we need to add some module metadata
+    // to ensure intrinsic calls don't use it.
+    if !sess.needs_plt() {
+        let avoid_plt = "RtLibUseGOT\0".as_ptr() as *const _;
+        llvm::LLVMRustAddModuleFlag(llmod, avoid_plt, 1);
+    }
+
     llmod
 }
 
 impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
     crate fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-               codegen_unit: Arc<CodegenUnit<'tcx>>,
-               llvm_module: &'a ::ModuleLlvm)
-               -> CodegenCx<'a, 'tcx> {
+                 codegen_unit: Arc<CodegenUnit<'tcx>>,
+                 llvm_module: &'a ::ModuleLlvm)
+                 -> CodegenCx<'a, 'tcx> {
         // An interesting part of Windows which MSVC forces our hand on (and
         // apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
         // attributes in LLVM IR as well as native dependencies (in C these
@@ -270,8 +277,8 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
         let dbg_cx = if tcx.sess.opts.debuginfo != DebugInfo::None {
             let dctx = debuginfo::CrateDebugContext::new(llmod);
             debuginfo::metadata::compile_unit_metadata(tcx,
-                                                        &codegen_unit.name().as_str(),
-                                                        &dctx);
+                                                       &codegen_unit.name().as_str(),
+                                                       &dctx);
             Some(dctx)
         } else {
             None
@@ -318,10 +325,8 @@ pub fn get_intrinsic(&self, key: &str) -> &'b Value {
         if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
             return v;
         }
-        match declare_intrinsic(self, key) {
-            Some(v) => return v,
-            None => bug!("unknown intrinsic '{}'", key)
-        }
+
+        declare_intrinsic(self, key).unwrap_or_else(|| bug!("unknown intrinsic '{}'", key))
     }
 
     /// Generate a new symbol name with the given prefix. This symbol name must
@@ -465,9 +470,10 @@ impl LayoutOf for &'a CodegenCx<'ll, 'tcx> {
 
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
         self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty))
-            .unwrap_or_else(|e| match e {
-                LayoutError::SizeOverflow(_) => self.sess().fatal(&e.to_string()),
-                _ => bug!("failed to get layout for `{}`: {}", ty, e)
+            .unwrap_or_else(|e| if let LayoutError::SizeOverflow(_) = e {
+                self.sess().fatal(&e.to_string())
+            } else {
+                bug!("failed to get layout for `{}`: {}", ty, e)
             })
     }
 }
@@ -772,5 +778,6 @@ macro_rules! mk_struct {
         ifn!("llvm.dbg.declare", fn(Type::metadata(cx), Type::metadata(cx)) -> void);
         ifn!("llvm.dbg.value", fn(Type::metadata(cx), t_i64, Type::metadata(cx)) -> void);
     }
-    return None;
+
+    None
 }
index 7141c9ece89d7180ea0c7f85f22e1fb29afbf8e1..26969e24f0883503d9178699bd9ba32377bc351b 100644 (file)
@@ -104,6 +104,8 @@ fn declare_raw_fn(
         attributes::unwind(llfn, false);
     }
 
+    attributes::non_lazy_bind(cx.sess(), llfn);
+
     llfn
 }
 
index 242b7a1a119f7ef54b8aace01f4769ead2a40329..5721938c9c0a75a9899b34c1551f28ed176cf85e 100644 (file)
@@ -69,4 +69,15 @@ fn main() {
 ```
 "##,
 
+E0669: r##"
+Cannot convert inline assembly operand to a single LLVM value.
+
+This error usually happens when trying to pass in a value to an input inline
+assembly operand that is actually a pair of values. In particular, this can
+happen when trying to pass in a slice, for instance a `&str`. In Rust, these
+values are represented internally as a pair of values, the pointer and its
+length. When passed as an input operand, this pair of values can not be
+coerced into a register and thus we must fail with an error.
+"##,
+
 }
index ff33cec043729eaacffd4a1dddce437e147da263..842bdf3cb493ff1b01772c5d4026c8388ae440e3 100644 (file)
@@ -97,8 +97,8 @@ pub fn size_and_align_of_dst(bx: &Builder<'_, 'll, 'tcx>, t: Ty<'tcx>, info: Opt
                     C_usize(cx, std::cmp::max(sized_align, unsized_align) as u64)
                 }
                 _ => bx.select(bx.icmp(llvm::IntUGT, sized_align, unsized_align),
-                                sized_align,
-                                unsized_align)
+                               sized_align,
+                               unsized_align)
             };
 
             // Issue #27023: must add any necessary padding to `size`
index 5ec934ebd066750458e51275d6e75e24a9606862..272196afa6f92bdf6ce3ee50a99b6170abe269ff 100644 (file)
@@ -115,8 +115,8 @@ pub fn codegen_intrinsic_call(
     let llval = match name {
         _ if simple.is_some() => {
             bx.call(simple.unwrap(),
-                     &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
-                     None)
+                    &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
+                    None)
         }
         "unreachable" => {
             return;
@@ -373,7 +373,6 @@ pub fn codegen_intrinsic_call(
                     return;
                 }
             }
-
         },
         "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
             let sty = &arg_tys[0].sty;
@@ -540,10 +539,9 @@ pub fn codegen_intrinsic_call(
         }
 
         _ => {
-            let intr = match Intrinsic::find(&name) {
-                Some(intr) => intr,
-                None => bug!("unknown intrinsic '{}'", name),
-            };
+            let intr = Intrinsic::find(&name).unwrap_or_else(||
+                bug!("unknown intrinsic '{}'", name));
+
             fn one<T>(x: Vec<T>) -> T {
                 assert_eq!(x.len(), 1);
                 x.into_iter().next().unwrap()
@@ -822,8 +820,7 @@ fn codegen_msvc_try(
         let i64p = Type::i64(cx).ptr_to();
         let ptr_align = bx.tcx().data_layout.pointer_align;
         let slot = bx.alloca(i64p, "slot", ptr_align);
-        bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(),
-            None);
+        bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None);
 
         normal.ret(C_i32(cx, 0));
 
@@ -911,8 +908,7 @@ fn codegen_gnu_try(
         // being thrown.  The second value is a "selector" indicating which of
         // the landing pad clauses the exception's type had been matched to.
         // rust_try ignores the selector.
-        let lpad_ty = Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)],
-                                    false);
+        let lpad_ty = Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false);
         let vals = catch.landing_pad(lpad_ty, bx.cx.eh_personality(), 1);
         catch.add_clause(vals, C_null(Type::i8p(cx)));
         let ptr = catch.extract_value(vals, 0);
@@ -976,7 +972,7 @@ fn get_rust_try_fn<'ll, 'tcx>(
     let output = tcx.types.i32;
     let rust_try = gen_fn(cx, "__rust_try", vec![fn_ty, i8p, i8p], output, codegen);
     cx.rust_try_fn.set(Some(rust_try));
-    return rust_try
+    rust_try
 }
 
 fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
@@ -1000,11 +996,11 @@ macro_rules! emit_error {
         ($msg: tt, $($fmt: tt)*) => {
             span_invalid_monomorphization_error(
                 bx.sess(), span,
-                &format!(concat!("invalid monomorphization of `{}` intrinsic: ",
-                                 $msg),
+                &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
                          name, $($fmt)*));
         }
     }
+
     macro_rules! return_error {
         ($($fmt: tt)*) => {
             {
@@ -1021,14 +1017,13 @@ macro_rules! require {
             }
         };
     }
+
     macro_rules! require_simd {
         ($ty: expr, $position: expr) => {
             require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty)
         }
     }
 
-
-
     let tcx = bx.tcx();
     let sig = tcx.normalize_erasing_late_bound_regions(
         ty::ParamEnv::reveal_all(),
@@ -1075,11 +1070,8 @@ macro_rules! require_simd {
     }
 
     if name.starts_with("simd_shuffle") {
-        let n: usize = match name["simd_shuffle".len()..].parse() {
-            Ok(n) => n,
-            Err(_) => span_bug!(span,
-                                "bad `simd_shuffle` instruction only caught in codegen?")
-        };
+        let n: usize = name["simd_shuffle".len()..].parse().unwrap_or_else(|_|
+            span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?"));
 
         require_simd!(ret_ty, "return");
 
@@ -1121,8 +1113,8 @@ macro_rules! require_simd {
         };
 
         return Ok(bx.shuffle_vector(args[0].immediate(),
-                                     args[1].immediate(),
-                                     C_vector(&indices)))
+                                    args[1].immediate(),
+                                    C_vector(&indices)))
     }
 
     if name == "simd_insert" {
@@ -1130,8 +1122,8 @@ macro_rules! require_simd {
                  "expected inserted type `{}` (element of input `{}`), found `{}`",
                  in_elem, in_ty, arg_tys[2]);
         return Ok(bx.insert_element(args[0].immediate(),
-                                     args[2].immediate(),
-                                     args[1].immediate()))
+                                    args[2].immediate(),
+                                    args[1].immediate()))
     }
     if name == "simd_extract" {
         require!(ret_ty == in_elem,
@@ -1150,9 +1142,7 @@ macro_rules! require_simd {
         );
         match m_elem_ty.sty {
             ty::Int(_) => {},
-            _ => {
-                return_error!("mask element type is `{}`, expected `i_`", m_elem_ty);
-            }
+            _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty)
         }
         // truncate the mask to a vector of i1s
         let i1 = Type::i1(bx.cx);
@@ -1177,8 +1167,7 @@ macro_rules! emit_error {
             ($msg: tt, $($fmt: tt)*) => {
                 span_invalid_monomorphization_error(
                     bx.sess(), span,
-                    &format!(concat!("invalid monomorphization of `{}` intrinsic: ",
-                                     $msg),
+                    &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
                              name, $($fmt)*));
             }
         }
@@ -1223,63 +1212,53 @@ macro_rules! return_error {
                         &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
                         None);
         unsafe { llvm::LLVMRustSetHasUnsafeAlgebra(c) };
-        return Ok(c);
-    }
-
-    if name == "simd_fsqrt" {
-        return simd_simple_float_intrinsic("sqrt", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_fsin" {
-        return simd_simple_float_intrinsic("sin", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_fcos" {
-        return simd_simple_float_intrinsic("cos", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_fabs" {
-        return simd_simple_float_intrinsic("fabs", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_floor" {
-        return simd_simple_float_intrinsic("floor", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_ceil" {
-        return simd_simple_float_intrinsic("ceil", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_fexp" {
-        return simd_simple_float_intrinsic("exp", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_fexp2" {
-        return simd_simple_float_intrinsic("exp2", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_flog10" {
-        return simd_simple_float_intrinsic("log10", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_flog2" {
-        return simd_simple_float_intrinsic("log2", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_flog" {
-        return simd_simple_float_intrinsic("log", in_elem, in_ty, in_len, bx, span, args);
+        Ok(c)
     }
 
-    if name == "simd_fpowi" {
-        return simd_simple_float_intrinsic("powi", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_fpow"  {
-        return simd_simple_float_intrinsic("pow", in_elem, in_ty, in_len, bx, span, args);
-    }
-
-    if name == "simd_fma" {
-        return simd_simple_float_intrinsic("fma", in_elem, in_ty, in_len, bx, span, args);
+    match name {
+        "simd_fsqrt" => {
+            return simd_simple_float_intrinsic("sqrt", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_fsin" => {
+            return simd_simple_float_intrinsic("sin", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_fcos" => {
+            return simd_simple_float_intrinsic("cos", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_fabs" => {
+            return simd_simple_float_intrinsic("fabs", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_floor" => {
+            return simd_simple_float_intrinsic("floor", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_ceil" => {
+            return simd_simple_float_intrinsic("ceil", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_fexp" => {
+            return simd_simple_float_intrinsic("exp", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_fexp2" => {
+            return simd_simple_float_intrinsic("exp2", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_flog10" => {
+            return simd_simple_float_intrinsic("log10", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_flog2" => {
+            return simd_simple_float_intrinsic("log2", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_flog" => {
+            return simd_simple_float_intrinsic("log", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_fpowi" => {
+            return simd_simple_float_intrinsic("powi", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_fpow" => {
+            return simd_simple_float_intrinsic("pow", in_elem, in_ty, in_len, bx, span, args);
+        }
+        "simd_fma" => {
+            return simd_simple_float_intrinsic("fma", in_elem, in_ty, in_len, bx, span, args);
+        }
+        _ => { /* fallthrough */ }
     }
 
     // FIXME: use:
@@ -1312,7 +1291,7 @@ fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: ty::Ty, vec_len: usize,
     }
 
 
-    if name == "simd_gather"  {
+    if name == "simd_gather" {
         // simd_gather(values: <N x T>, pointers: <N x *_ T>,
         //             mask: <N x i{M}>) -> <N x T>
         // * N: number of elements in the input vectors
@@ -1360,7 +1339,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty {
         // to the element type of the first argument
         let (pointer_count, underlying_ty) = match arg_tys[1].simd_type(tcx).sty {
             ty::RawPtr(p) if p.ty == in_elem => (ptr_count(arg_tys[1].simd_type(tcx)),
-                                                   non_ptr(arg_tys[1].simd_type(tcx))),
+                                                 non_ptr(arg_tys[1].simd_type(tcx))),
             _ => {
                 require!(false, "expected element type `{}` of second argument `{}` \
                                  to be a pointer to the element type `{}` of the first \
@@ -1371,7 +1350,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty {
             }
         };
         assert!(pointer_count > 0);
-        assert!(pointer_count - 1 == ptr_count(arg_tys[0].simd_type(tcx)));
+        assert_eq!(pointer_count - 1, ptr_count(arg_tys[0].simd_type(tcx)));
         assert_eq!(underlying_ty, non_ptr(arg_tys[0].simd_type(tcx)));
 
         // The element type of the third argument must be a signed integer type of any width:
@@ -1414,7 +1393,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty {
         return Ok(v);
     }
 
-    if name == "simd_scatter"  {
+    if name == "simd_scatter" {
         // simd_scatter(values: <N x T>, pointers: <N x *mut T>,
         //             mask: <N x i{M}>) -> ()
         // * N: number of elements in the input vectors
@@ -1468,7 +1447,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty {
             }
         };
         assert!(pointer_count > 0);
-        assert!(pointer_count - 1 == ptr_count(arg_tys[0].simd_type(tcx)));
+        assert_eq!(pointer_count - 1, ptr_count(arg_tys[0].simd_type(tcx)));
         assert_eq!(underlying_ty, non_ptr(arg_tys[0].simd_type(tcx)));
 
         // The element type of the third argument must be a signed integer type of any width:
@@ -1570,7 +1549,6 @@ macro_rules! arith_red {
                                     )
                                 }
                             }
-
                         };
                         Ok(bx.$float_reduce(acc, args[0].immediate()))
                     }
@@ -1750,9 +1728,9 @@ macro_rules! arith {
                     _ => {},
                 }
                 require!(false,
-                            "unsupported operation on `{}` with element `{}`",
-                            in_ty,
-                            in_elem)
+                         "unsupported operation on `{}` with element `{}`",
+                         in_ty,
+                         in_elem)
             })*
         }
     }
index 71d739222b60a1adf17a11084af8f11da282b219..63a8ab077e5ae494c90d00c14ce0b24da08288a0 100644 (file)
@@ -306,7 +306,7 @@ fn into_compiled_module(self,
         };
         let bytecode_compressed = if emit_bc_compressed {
             Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name))
-                    .with_extension(RLIB_BYTECODE_EXTENSION))
+                        .with_extension(RLIB_BYTECODE_EXTENSION))
         } else {
             None
         };
index 8485db4210cb0b691fb2cfcbe7b6987838bf6f96..c9f51efdc50957bbb01e080c50f5165d27ae2f2c 100644 (file)
@@ -122,6 +122,7 @@ pub enum Attribute {
     SanitizeThread  = 20,
     SanitizeAddress = 21,
     SanitizeMemory  = 22,
+    NonLazyBind     = 23,
 }
 
 /// LLVMIntPredicate
index 9e8ff2047036bc6767fe75c04dd97a57f81648ef..8456cf2f4805912400e12160e8fc41183139ca33 100644 (file)
@@ -52,8 +52,9 @@ fn require_inited() {
 }
 
 unsafe fn configure_llvm(sess: &Session) {
-    let mut llvm_c_strs = Vec::new();
-    let mut llvm_args = Vec::new();
+    let n_args = sess.opts.cg.llvm_args.len();
+    let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
+    let mut llvm_args = Vec::with_capacity(n_args + 1);
 
     {
         let mut add = |arg: &str| {
index a4526a53769ba786838c7765a3266bbd19f4b80c..7752465d885bbff47574b533b7bc8cc4f669af29 100644 (file)
@@ -63,7 +63,7 @@ fn get_dylib_metadata(&self,
             let of = ObjectFile::new(mb)
                 .map(|of| OwningRef::new(box of))
                 .ok_or_else(|| format!("provided path not an object file: '{}'",
-                                        filename.display()))?;
+                                       filename.display()))?;
             let buf = of.try_map(|of| search_meta_section(of, target, filename))?;
             Ok(rustc_erase_owner!(buf))
         }
index c3e3785a724a2a7273f5b0f348f0aa7f7c2d8a4f..a0d6cc4629589da5572e08bfac18c963e6e1ab70 100644 (file)
@@ -151,9 +151,9 @@ fn visit_terminator_kind(&mut self,
     }
 
     fn visit_place(&mut self,
-                    place: &mir::Place<'tcx>,
-                    context: PlaceContext<'tcx>,
-                    location: Location) {
+                   place: &mir::Place<'tcx>,
+                   context: PlaceContext<'tcx>,
+                   location: Location) {
         debug!("visit_place(place={:?}, context={:?})", place, context);
         let cx = self.fx.cx;
 
index db95b46c38ebeee537e0948fb2bcd5d39a1589a6..5be176f75c96a7ef88ed3b31d18b5ed92d8fa29c 100644 (file)
@@ -49,9 +49,9 @@ pub fn codegen_block(&mut self, bb: mir::BasicBlock) {
     }
 
     fn codegen_terminator(&mut self,
-                        mut bx: Builder<'a, 'll, 'tcx>,
-                        bb: mir::BasicBlock,
-                        terminator: &mir::Terminator<'tcx>)
+                          mut bx: Builder<'a, 'll, 'tcx>,
+                          bb: mir::BasicBlock,
+                          terminator: &mir::Terminator<'tcx>)
     {
         debug!("codegen_terminator: {:?}", terminator);
 
index 6bd41bfe16feee3d6c23e6f8fd8eb271ecc45123..93be0074f6e9b57cd24992958ad84a72af72576d 100644 (file)
@@ -15,6 +15,7 @@
 
 use super::FunctionCx;
 use super::LocalRef;
+use super::OperandValue;
 
 impl FunctionCx<'a, 'll, 'tcx> {
     pub fn codegen_statement(&mut self,
@@ -82,14 +83,27 @@ pub fn codegen_statement(&mut self,
                     self.codegen_place(&bx, output)
                 }).collect();
 
-                let input_vals = inputs.iter().map(|input| {
-                    self.codegen_operand(&bx, input).immediate()
-                }).collect();
+                let input_vals = inputs.iter()
+                    .try_fold(Vec::with_capacity(inputs.len()), |mut acc, input| {
+                        let op = self.codegen_operand(&bx, input);
+                        if let OperandValue::Immediate(_) = op.val {
+                            acc.push(op.immediate());
+                            Ok(acc)
+                        } else {
+                            Err(op)
+                        }
+                });
 
-                let res = asm::codegen_inline_asm(&bx, asm, outputs, input_vals);
-                if !res {
-                    span_err!(bx.sess(), statement.source_info.span, E0668,
-                              "malformed inline assembly");
+                if input_vals.is_err() {
+                   span_err!(bx.sess(), statement.source_info.span, E0669,
+                             "invalid value for constraint in inline assembly");
+                } else {
+                    let input_vals = input_vals.unwrap();
+                    let res = asm::codegen_inline_asm(&bx, asm, outputs, input_vals);
+                    if !res {
+                        span_err!(bx.sess(), statement.source_info.span, E0668,
+                                  "malformed inline assembly");
+                    }
                 }
                 bx
             }
index a8502e9244768b8aee7835dd4167bfffeff311fb..dab9b147cc0708d055dba215493bbc6d58842f12 100644 (file)
@@ -108,8 +108,8 @@ fn to_raw_string(&self) -> String {
         match *self.as_mono_item() {
             MonoItem::Fn(instance) => {
                 format!("Fn({:?}, {})",
-                         instance.def,
-                         instance.substs.as_ptr() as usize)
+                        instance.def,
+                        instance.substs.as_ptr() as usize)
             }
             MonoItem::Static(id) => {
                 format!("Static({:?})", id)
index 765708aeafd94f7e2f1c257a53fb3f0b17d4a754..03ded64e642355706e8c7b5471028a0ec8a5e30e 100644 (file)
@@ -65,13 +65,12 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
             let mut name = String::with_capacity(32);
             let printer = DefPathBasedNames::new(cx.tcx, true, true);
             printer.push_type_name(layout.ty, &mut name);
-            match (&layout.ty.sty, &layout.variants) {
-                (&ty::Adt(def, _), &layout::Variants::Single { index }) => {
-                    if def.is_enum() && !def.variants.is_empty() {
-                        write!(&mut name, "::{}", def.variants[index].name).unwrap();
-                    }
+            if let (&ty::Adt(def, _), &layout::Variants::Single { index })
+                 = (&layout.ty.sty, &layout.variants)
+            {
+                if def.is_enum() && !def.variants.is_empty() {
+                    write!(&mut name, "::{}", def.variants[index].name).unwrap();
                 }
-                _ => {}
             }
             Some(name)
         }
@@ -132,7 +131,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
 
         debug!("struct_llfields: {}: {:?} offset: {:?} target_offset: {:?} \
                 effective_field_align: {}",
-            i, field, offset, target_offset, effective_field_align.abi());
+               i, field, offset, target_offset, effective_field_align.abi());
         assert!(target_offset >= offset);
         let padding = target_offset - offset;
         let padding_align = prev_effective_align.min(effective_field_align);
@@ -155,7 +154,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         debug!("struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}",
                padding, offset, layout.size);
         result.push(Type::padding_filler(cx, padding, padding_align));
-        assert!(result.len() == 1 + field_count * 2);
+        assert_eq!(result.len(), 1 + field_count * 2);
     } else {
         debug!("struct_llfields: offset: {:?} stride: {:?}",
                offset, layout.size);
index 3328948c2951e5ce18e8b500b4ce9e1189c7f6a9..4bf5b09baa6294ffbfd022bdb4bc8e5646f3cdfa 100644 (file)
@@ -34,6 +34,6 @@ impl fmt::Debug for Value {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str(&llvm::build_string(|s| unsafe {
             llvm::LLVMRustWriteValueToString(self, s);
-        }).expect("nun-UTF8 value description from LLVM"))
+        }).expect("non-UTF8 value description from LLVM"))
     }
 }
index 4405c0aef9023367201af0bc00a608e1af718e3b..0514bd20c985a2fa802ba1f879c026820be7f6cf 100644 (file)
@@ -21,7 +21,6 @@
 #![feature(box_syntax)]
 #![cfg_attr(unix, feature(libc))]
 #![feature(nll)]
-#![feature(option_replace)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(slice_sort_by_cached_key)]
index 2799f2cc81f5ab0648d078f0d19d6fdc387356ce..870eeadc081e76b856087c8d2b84c638eaaed545 100644 (file)
@@ -76,9 +76,9 @@ pub enum StringPart {
 }
 
 impl StringPart {
-    pub fn content(&self) -> String {
+    pub fn content(&self) -> &str {
         match self {
-            &StringPart::Normal(ref s) | & StringPart::Highlighted(ref s) => s.to_owned()
+            &StringPart::Normal(ref s) | & StringPart::Highlighted(ref s) => s
         }
     }
 }
@@ -398,7 +398,7 @@ pub fn get_code(&self) -> Option<DiagnosticId> {
     }
 
     pub fn message(&self) -> String {
-        self.message.iter().map(|i| i.0.to_owned()).collect::<String>()
+        self.message.iter().map(|i| i.0.as_str()).collect::<String>()
     }
 
     pub fn styled_message(&self) -> &Vec<(String, Style)> {
@@ -448,7 +448,7 @@ fn sub_with_highlights(&mut self,
 
 impl SubDiagnostic {
     pub fn message(&self) -> String {
-        self.message.iter().map(|i| i.0.to_owned()).collect::<String>()
+        self.message.iter().map(|i| i.0.as_str()).collect::<String>()
     }
 
     pub fn styled_message(&self) -> &Vec<(String, Style)> {
index ae178888b6a1cda42a65a67f3ccddb11cbce2a4a..ec3c310c63c4f80c42ec88d65cfed1f1efcd2137 100644 (file)
@@ -59,15 +59,17 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
         }
 
         let t = cx.tables.expr_ty(&expr);
-        let ty_warned = match t.sty {
-            ty::Tuple(ref tys) if tys.is_empty() => return,
-            ty::Never => return,
+        // FIXME(varkor): replace with `t.is_unit() || t.conservative_is_uninhabited()`.
+        let type_permits_no_use = match t.sty {
+            ty::Tuple(ref tys) if tys.is_empty() => true,
+            ty::Never => true,
             ty::Adt(def, _) => {
                 if def.variants.is_empty() {
-                    return;
+                    true
+                } else {
+                    check_must_use(cx, def.did, s.span, "")
                 }
-                check_must_use(cx, def.did, s.span, "")
-            },
+            }
             _ => false,
         };
 
@@ -95,7 +97,12 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
         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 ");
+        } else if type_permits_no_use {
+            // We don't warn about unused unit or uninhabited types.
+            // (See https://github.com/rust-lang/rust/issues/43806 for details.)
+            return;
         }
+
         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]`
@@ -139,7 +146,7 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
             op_warned = true;
         }
 
-        if !(ty_warned || fn_warned || op_warned) {
+        if !(type_permits_no_use || fn_warned || op_warned) {
             cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
         }
 
@@ -233,7 +240,7 @@ fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
                 .find(|&&(builtin, ty, _)| name == builtin && ty == AttributeType::CrateLevel)
                 .is_some();
 
-            // Has a plugin registered this attribute as one which must be used at
+            // Has a plugin registered this attribute as one that must be used at
             // the crate level?
             let plugin_crate = plugin_attributes.iter()
                 .find(|&&(ref x, t)| name == &**x && AttributeType::CrateLevel == t)
index 693cfea3c95f0d4b3cbabdaa44d944abfb407c83..ea62694f8be753c7c52e6b1c71fd8127b0af5282 100644 (file)
@@ -68,6 +68,7 @@ enum GroupedMoveError<'tcx> {
 enum BorrowedContentSource {
     Arc,
     Rc,
+    DerefRawPointer,
     Other,
 }
 
@@ -76,6 +77,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             BorrowedContentSource::Arc => write!(f, "an `Arc`"),
             BorrowedContentSource::Rc => write!(f, "an `Rc`"),
+            BorrowedContentSource::DerefRawPointer => write!(f, "dereference of raw pointer"),
             BorrowedContentSource::Other => write!(f, "borrowed content"),
         }
     }
@@ -279,6 +281,7 @@ fn report(&mut self, error: GroupedMoveError<'tcx>) {
                             self.prefixes(&original_path, PrefixSet::All)
                             .any(|p| p.is_upvar_field_projection(self.mir, &self.infcx.tcx)
                                  .is_some());
+                        debug!("report: ty={:?}", ty);
                         match ty.sty {
                             ty::Array(..) | ty::Slice(..) =>
                                 self.infcx.tcx.cannot_move_out_of_interior_noncopy(
@@ -582,6 +585,18 @@ fn borrowed_content_source(&self, place: &Place<'tcx>) -> BorrowedContentSource
             }
         }
 
+        // If we didn't find an `Arc` or an `Rc`, then check specifically for
+        // a dereference of a place that has the type of a raw pointer.
+        // We can't use `place.ty(..).to_ty(..)` here as that strips away the raw pointer.
+        if let Place::Projection(box Projection {
+            base,
+            elem: ProjectionElem::Deref,
+        }) = place {
+            if base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx).is_unsafe_ptr() {
+                return BorrowedContentSource::DerefRawPointer;
+            }
+        }
+
         BorrowedContentSource::Other
     }
 }
index e55469436abf0a72b08541f9d4097ae143a4a30c..307112f8ba16a26fb17dd4e4a482d4d2b5d96db7 100644 (file)
 use borrow_check::nll::region_infer::Cause;
 use borrow_check::{Context, MirBorrowckCtxt, WriteKind};
 use rustc::ty::{self, Region, TyCtxt};
-use rustc::mir::{FakeReadCause, Local, Location, Mir, Operand};
-use rustc::mir::{Place, StatementKind, TerminatorKind};
+use rustc::mir::{
+    CastKind, FakeReadCause, Local, Location, Mir, Operand, Place, Projection, ProjectionElem,
+    Rvalue, Statement, StatementKind, TerminatorKind
+};
 use rustc_errors::DiagnosticBuilder;
 use syntax_pos::Span;
 
@@ -34,6 +36,7 @@ pub(in borrow_check) enum BorrowExplanation<'tcx> {
 
 #[derive(Clone, Copy)]
 pub(in borrow_check) enum LaterUseKind {
+    TraitCapture,
     ClosureCapture,
     Call,
     FakeLetRead,
@@ -51,6 +54,7 @@ pub(in borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx>(
         match *self {
             BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => {
                 let message = match later_use_kind {
+                    LaterUseKind::TraitCapture => "borrow later captured here by trait object",
                     LaterUseKind::ClosureCapture => "borrow later captured here by closure",
                     LaterUseKind::Call =>  "borrow later used by call",
                     LaterUseKind::FakeLetRead => "borrow later stored here",
@@ -60,9 +64,10 @@ pub(in borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx>(
             },
             BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => {
                 let message = match later_use_kind {
-                    LaterUseKind::ClosureCapture => {
-                        "borrow captured here by closure, in later iteration of loop"
-                    },
+                    LaterUseKind::TraitCapture =>
+                        "borrow captured here by trait object, in later iteration of loop",
+                    LaterUseKind::ClosureCapture =>
+                        "borrow captured here by closure, in later iteration of loop",
                     LaterUseKind::Call =>  "borrow used by call, in later iteration of loop",
                     LaterUseKind::FakeLetRead => "borrow later stored here",
                     LaterUseKind::Other => "borrow used here, in later iteration of loop",
@@ -200,13 +205,13 @@ pub(in borrow_check) fn explain_why_borrow_contains_point(
                     .or_else(|| self.borrow_spans(span, location));
 
                 if self.is_borrow_location_in_loop(context.loc) {
-                    let later_use = self.later_use_kind(spans, location);
+                    let later_use = self.later_use_kind(borrow, spans, location);
                     BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1)
                 } else {
                     // Check if the location represents a `FakeRead`, and adapt the error
                     // message to the `FakeReadCause` it is from: in particular,
                     // the ones inserted in optimized `let var = <expr>` patterns.
-                    let later_use = self.later_use_kind(spans, location);
+                    let later_use = self.later_use_kind(borrow, spans, location);
                     BorrowExplanation::UsedLater(later_use.0, later_use.1)
                 }
             }
@@ -316,42 +321,184 @@ fn is_borrow_location_in_loop(
         false
     }
 
-    fn later_use_kind(&self, use_spans: UseSpans, location: Location) -> (LaterUseKind, Span) {
-        use self::LaterUseKind::*;
-
-        let block = &self.mir.basic_blocks()[location.block];
+    /// Determine how the borrow was later used.
+    fn later_use_kind(
+        &self,
+        borrow: &BorrowData<'tcx>,
+        use_spans: UseSpans,
+        location: Location
+    ) -> (LaterUseKind, Span) {
         match use_spans {
-            UseSpans::ClosureUse { var_span, .. } => (LaterUseKind::ClosureCapture, var_span),
+            UseSpans::ClosureUse { var_span, .. } => {
+                // Used in a closure.
+                (LaterUseKind::ClosureCapture, var_span)
+            },
             UseSpans::OtherUse(span) => {
-                (if let Some(stmt) = block.statements.get(location.statement_index) {
-                    match stmt.kind {
-                        StatementKind::FakeRead(FakeReadCause::ForLet, _) => FakeLetRead,
-                        _ => Other,
+                let block = &self.mir.basic_blocks()[location.block];
+
+                let kind = if let Some(&Statement {
+                    kind: StatementKind::FakeRead(FakeReadCause::ForLet, _),
+                    ..
+                }) = block.statements.get(location.statement_index) {
+                    LaterUseKind::FakeLetRead
+                } else if self.was_captured_by_trait_object(borrow) {
+                    LaterUseKind::TraitCapture
+                } else if location.statement_index == block.statements.len() {
+                    if let TerminatorKind::Call {
+                        ref func, from_hir_call: true, ..
+                    } = block.terminator().kind {
+                        // Just point to the function, to reduce the chance of overlapping spans.
+                        let function_span = match func {
+                            Operand::Constant(c) => c.span,
+                            Operand::Copy(Place::Local(l)) | Operand::Move(Place::Local(l)) => {
+                                let local_decl = &self.mir.local_decls[*l];
+                                if local_decl.name.is_none() {
+                                    local_decl.source_info.span
+                                } else {
+                                    span
+                                }
+                            },
+                            _ => span,
+                        };
+                        return (LaterUseKind::Call, function_span);
+                    } else {
+                        LaterUseKind::Other
                     }
                 } else {
-                    assert_eq!(location.statement_index, block.statements.len());
-                    match block.terminator().kind {
-                        TerminatorKind::Call { ref func, from_hir_call: true, .. } => {
-                            // Just point to the function, to reduce the chance
-                            // of overlapping spans.
-                            let function_span = match func {
-                                Operand::Constant(c) => c.span,
-                                Operand::Copy(Place::Local(l)) | Operand::Move(Place::Local(l)) => {
-                                    let local_decl = &self.mir.local_decls[*l];
-                                    if local_decl.name.is_none() {
-                                        local_decl.source_info.span
-                                    } else {
-                                        span
-                                    }
-                                },
-                                _ => span,
-                            };
-                            return (Call, function_span);
+                    LaterUseKind::Other
+                };
+
+                (kind, span)
+            }
+        }
+    }
+
+    /// Check if a borrowed value was captured by a trait object. We do this by
+    /// looking forward in the MIR from the reserve location and checking if we see
+    /// a unsized cast to a trait object on our data.
+    fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool {
+        // Start at the reserve location, find the place that we want to see cast to a trait object.
+        let location = borrow.reserve_location;
+        let block = &self.mir[location.block];
+        let stmt = block.statements.get(location.statement_index);
+        debug!("was_captured_by_trait_object: location={:?} stmt={:?}", location, stmt);
+
+        // We make a `queue` vector that has the locations we want to visit. As of writing, this
+        // will only ever have one item at any given time, but by using a vector, we can pop from
+        // it which simplifies the termination logic.
+        let mut queue = vec![location];
+        let mut target = if let Some(&Statement {
+            kind: StatementKind::Assign(Place::Local(local), _),
+            ..
+        }) = stmt {
+            local
+        } else {
+            return false;
+        };
+
+        debug!("was_captured_by_trait: target={:?} queue={:?}", target, queue);
+        while let Some(current_location) = queue.pop() {
+            debug!("was_captured_by_trait: target={:?}", target);
+            let block = &self.mir[current_location.block];
+            // We need to check the current location to find out if it is a terminator.
+            let is_terminator = current_location.statement_index == block.statements.len();
+            if !is_terminator {
+                let stmt = &block.statements[current_location.statement_index];
+                debug!("was_captured_by_trait_object: stmt={:?}", stmt);
+
+                // The only kind of statement that we care about is assignments...
+                if let StatementKind::Assign(
+                    place,
+                    box rvalue,
+                ) = &stmt.kind {
+                    let into = match place {
+                        Place::Local(into) => into,
+                        Place::Projection(box Projection {
+                            base: Place::Local(into),
+                            elem: ProjectionElem::Deref,
+                        }) => into,
+                        _ =>  {
+                            // Continue at the next location.
+                            queue.push(current_location.successor_within_block());
+                            continue;
                         },
-                        _ => Other,
+                    };
+
+                    match rvalue {
+                        // If we see a use, we should check whether it is our data, and if so
+                        // update the place that we're looking for to that new place.
+                        Rvalue::Use(operand) => match operand {
+                            Operand::Copy(Place::Local(from)) |
+                            Operand::Move(Place::Local(from)) if *from == target => {
+                                target = *into;
+                            },
+                            _ => {},
+                        },
+                        // If we see a unsized cast, then if it is our data we should check
+                        // whether it is being cast to a trait object.
+                        Rvalue::Cast(CastKind::Unsize, operand, ty) => match operand {
+                            Operand::Copy(Place::Local(from)) |
+                            Operand::Move(Place::Local(from)) if *from == target => {
+                                debug!("was_captured_by_trait_object: ty={:?}", ty);
+                                // Check the type for a trait object.
+                                match ty.sty {
+                                    // `&dyn Trait`
+                                    ty::TyKind::Ref(_, ty, _) if ty.is_trait() => return true,
+                                    // `Box<dyn Trait>`
+                                    _ if ty.is_box() && ty.boxed_ty().is_trait() =>
+                                        return true,
+                                    // `dyn Trait`
+                                    _ if ty.is_trait() => return true,
+                                    // Anything else.
+                                    _ => return false,
+                                }
+                            },
+                            _ => return false,
+                        },
+                        _ => {},
                     }
-                }, span)
+                }
+
+                // Continue at the next location.
+                queue.push(current_location.successor_within_block());
+            } else {
+                // The only thing we need to do for terminators is progress to the next block.
+                let terminator = block.terminator();
+                debug!("was_captured_by_trait_object: terminator={:?}", terminator);
+
+                match &terminator.kind {
+                    TerminatorKind::Call {
+                        destination: Some((Place::Local(dest), block)),
+                        args,
+                        ..
+                    } => {
+                        debug!(
+                            "was_captured_by_trait_object: target={:?} dest={:?} args={:?}",
+                            target, dest, args
+                        );
+                        // Check if one of the arguments to this function is the target place.
+                        let found_target = args.iter().any(|arg| {
+                            if let Operand::Move(Place::Local(potential)) = arg {
+                                *potential == target
+                            } else {
+                                false
+                            }
+                        });
+
+                        // If it is, follow this to the next block and update the target.
+                        if found_target {
+                            target = *dest;
+                            queue.push(block.start_location());
+                        }
+                    },
+                    _ => {},
+                }
             }
+
+            debug!("was_captured_by_trait: queue={:?}", queue);
         }
+
+        // We didn't find anything and ran out of locations to check.
+        false
     }
 }
index 039a92cee2ca2fcfba65f06617ece23d6de56141..c72a5894b6ac7f54f0b83bf1f9ed7bcf70e78479 100644 (file)
@@ -11,7 +11,6 @@
 //! Functions concerning immediate values and operands, and reading from operands.
 //! All high-level functions to read from memory work on operands as sources.
 
-use std::hash::{Hash, Hasher};
 use std::convert::TryInto;
 
 use rustc::{mir, ty};
@@ -290,7 +289,7 @@ pub fn to_immediate(self) -> Value<Tag>
     }
 }
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
 pub struct OpTy<'tcx, Tag=()> {
     crate op: Operand<Tag>, // ideally we'd make this private, but const_prop needs this
     pub layout: TyLayout<'tcx>,
@@ -324,26 +323,6 @@ fn from(val: ValTy<'tcx, Tag>) -> Self {
     }
 }
 
-// Validation needs to hash OpTy, but we cannot hash Layout -- so we just hash the type
-impl<'tcx, Tag> Hash for OpTy<'tcx, Tag>
-    where Tag: Hash
-{
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.op.hash(state);
-        self.layout.ty.hash(state);
-    }
-}
-impl<'tcx, Tag> PartialEq for OpTy<'tcx, Tag>
-    where Tag: PartialEq
-{
-    fn eq(&self, other: &Self) -> bool {
-        self.op == other.op && self.layout.ty == other.layout.ty
-    }
-}
-impl<'tcx, Tag> Eq for OpTy<'tcx, Tag>
-    where Tag: Eq
-{}
-
 impl<'tcx, Tag> OpTy<'tcx, Tag>
 {
     #[inline]
index 96eb69163220e7b33c57287bd9ac35596ab6b589..6b28fd091748f14114b21d7224e82620b5a65d55 100644 (file)
@@ -874,7 +874,7 @@ pub fn scalar<C: HasDataLayout>(cx: C, scalar: Scalar) -> Self {
 /// to those obtained from `layout_of(ty)`, as we need to produce
 /// layouts for which Rust types do not exist, such as enum variants
 /// or synthetic fields of enums (i.e. discriminants) and fat pointers.
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub struct TyLayout<'a, Ty> {
     pub ty: Ty,
     pub details: &'a LayoutDetails
index 3f1e8ee55286b6bfd682894aa3bbbc5e29c9cb13..9c0f945326d148006c8f9cd54e7412d4ea9d92eb 100644 (file)
@@ -576,6 +576,9 @@ pub struct TargetOptions {
     /// the functions in the executable are not randomized and can be used
     /// during an exploit of a vulnerability in any code.
     pub position_independent_executables: bool,
+    /// Determines if the target always requires using the PLT for indirect
+    /// library calls or not. This controls the default value of the `-Z plt` flag.
+    pub needs_plt: bool,
     /// Either partial, full, or off. Full RELRO makes the dynamic linker
     /// resolve all symbols at startup and marks the GOT read-only before
     /// starting the program, preventing overwriting the GOT.
@@ -720,6 +723,7 @@ fn default() -> TargetOptions {
             has_rpath: false,
             no_default_libraries: true,
             position_independent_executables: false,
+            needs_plt: false,
             relro_level: RelroLevel::None,
             pre_link_objects_exe: Vec::new(),
             pre_link_objects_exe_crt: Vec::new(),
@@ -1009,6 +1013,7 @@ macro_rules! key {
         key!(has_rpath, bool);
         key!(no_default_libraries, bool);
         key!(position_independent_executables, bool);
+        key!(needs_plt, bool);
         try!(key!(relro_level, RelroLevel));
         key!(archive_format);
         key!(allow_asm, bool);
@@ -1217,6 +1222,7 @@ macro_rules! target_option_val {
         target_option_val!(has_rpath);
         target_option_val!(no_default_libraries);
         target_option_val!(position_independent_executables);
+        target_option_val!(needs_plt);
         target_option_val!(relro_level);
         target_option_val!(archive_format);
         target_option_val!(allow_asm);
index 72b5bd27c7dfe3b35f1069e0fdb87362bd87eb3f..fd61067ba5168cdd575c6ef826d11ef3e34b8ad0 100644 (file)
@@ -17,6 +17,9 @@ pub fn target() -> TargetResult {
     base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string());
     base.stack_probes = true;
     base.has_elf_tls = false;
+    // BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI
+    // breaks code gen. See LLVM bug 36743
+    base.needs_plt = true;
 
     Ok(Target {
         llvm_target: "x86_64-unknown-linux-gnux32".to_string(),
index cd21ee601a7d2d47ffe0204b78cdfaac12bbb4a5..16f0f11757a1278661d0e67be407d28fd1eed9ca 100644 (file)
@@ -16,5 +16,5 @@ rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
-chalk-engine = { version = "0.7.0", default-features=false }
+chalk-engine = { version = "0.8.0", default-features=false }
 smallvec = { version = "0.6.5", features = ["union"] }
index 4c28df97bdf50a5024907237b2699463f6ca45b0..dea3aa4372a332f6252cd7be466fa29edbfea7ed 100644 (file)
@@ -19,6 +19,7 @@
     ExClauseFold,
     ExClauseLift,
     Goal,
+    GoalKind,
     ProgramClause,
     QuantifierKind
 };
@@ -92,7 +93,7 @@ impl context::Context for ChalkArenas<'tcx> {
 
     type DomainGoal = DomainGoal<'tcx>;
 
-    type BindersGoal = ty::Binder<&'tcx Goal<'tcx>>;
+    type BindersGoal = ty::Binder<Goal<'tcx>>;
 
     type Parameter = Kind<'tcx>;
 
@@ -102,14 +103,6 @@ impl context::Context for ChalkArenas<'tcx> {
 
     type UnificationResult = InferOk<'tcx, ()>;
 
-    fn into_goal(domain_goal: DomainGoal<'tcx>) -> Goal<'tcx> {
-        Goal::DomainGoal(domain_goal)
-    }
-
-    fn cannot_prove() -> Goal<'tcx> {
-        Goal::CannotProve
-    }
-
     fn goal_in_environment(
         env: &ty::ParamEnv<'tcx>,
         goal: Goal<'tcx>,
@@ -251,15 +244,23 @@ fn map_subst_from_canonical(
 impl context::InferenceTable<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
     for ChalkInferenceContext<'cx, 'gcx, 'tcx>
 {
+    fn into_goal(&self, domain_goal: DomainGoal<'tcx>) -> Goal<'tcx> {
+        self.infcx.tcx.mk_goal(GoalKind::DomainGoal(domain_goal))
+    }
+
+    fn cannot_prove(&self) -> Goal<'tcx> {
+        self.infcx.tcx.mk_goal(GoalKind::CannotProve)
+    }
+
     fn into_hh_goal(&mut self, goal: Goal<'tcx>) -> ChalkHhGoal<'tcx> {
-        match goal {
-            Goal::Implies(..) => panic!("FIXME rust-lang-nursery/chalk#94"),
-            Goal::And(left, right) => HhGoal::And(*left, *right),
-            Goal::Not(subgoal) => HhGoal::Not(*subgoal),
-            Goal::DomainGoal(d) => HhGoal::DomainGoal(d),
-            Goal::Quantified(QuantifierKind::Universal, binder) => HhGoal::ForAll(binder),
-            Goal::Quantified(QuantifierKind::Existential, binder) => HhGoal::Exists(binder),
-            Goal::CannotProve => HhGoal::CannotProve,
+        match *goal {
+            GoalKind::Implies(..) => panic!("FIXME rust-lang-nursery/chalk#94"),
+            GoalKind::And(left, right) => HhGoal::And(left, right),
+            GoalKind::Not(subgoal) => HhGoal::Not(subgoal),
+            GoalKind::DomainGoal(d) => HhGoal::DomainGoal(d),
+            GoalKind::Quantified(QuantifierKind::Universal, binder) => HhGoal::ForAll(binder),
+            GoalKind::Quantified(QuantifierKind::Existential, binder) => HhGoal::Exists(binder),
+            GoalKind::CannotProve => HhGoal::CannotProve,
         }
     }
 
@@ -363,21 +364,21 @@ fn program_clauses(
 
     fn instantiate_binders_universally(
         &mut self,
-        _arg: &ty::Binder<&'tcx Goal<'tcx>>,
+        _arg: &ty::Binder<Goal<'tcx>>,
     ) -> Goal<'tcx> {
         panic!("FIXME -- universal instantiation needs sgrif's branch")
     }
 
     fn instantiate_binders_existentially(
         &mut self,
-        arg: &ty::Binder<&'tcx Goal<'tcx>>,
+        arg: &ty::Binder<Goal<'tcx>>,
     ) -> Goal<'tcx> {
         let (value, _map) = self.infcx.replace_late_bound_regions_with_fresh_var(
             DUMMY_SP,
             LateBoundRegionConversionTime::HigherRankedType,
             arg,
         );
-        *value
+        value
     }
 
     fn debug_ex_clause(&mut self, value: &'v ChalkExClause<'tcx>) -> Box<dyn Debug + 'v> {
index ad724babe49fb69aa7e4e7f426876df7f21650a0..181106d3f84bf19f9b4f371ff65edd1476ae162d 100644 (file)
 use rustc::hir::map::definitions::DefPathData;
 use rustc::hir::{self, ImplPolarity};
 use rustc::traits::{
-    Clause, Clauses, DomainGoal, FromEnv, Goal, PolyDomainGoal, ProgramClause, WellFormed,
+    Clause,
+    Clauses,
+    DomainGoal,
+    FromEnv,
+    GoalKind,
+    PolyDomainGoal,
+    ProgramClause,
+    WellFormed,
     WhereClause,
 };
 use rustc::ty::query::Providers;
@@ -249,7 +256,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
     let impl_trait: DomainGoal = trait_pred.lower();
 
     // `FromEnv(Self: Trait<P1..Pn>)`
-    let from_env_goal = impl_trait.into_from_env_goal().into_goal();
+    let from_env_goal = tcx.mk_goal(impl_trait.into_from_env_goal().into_goal());
     let hypotheses = tcx.intern_goals(&[from_env_goal]);
 
     // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
@@ -308,7 +315,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
     let wf_clause = ProgramClause {
         goal: DomainGoal::WellFormed(WellFormed::Trait(trait_pred)),
         hypotheses: tcx.mk_goals(
-            wf_conditions.map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
+            wf_conditions.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
         ),
     };
     let wf_clause = iter::once(Clause::ForAll(ty::Binder::dummy(wf_clause)));
@@ -352,10 +359,10 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
         hypotheses: tcx.mk_goals(
             where_clauses
                 .into_iter()
-                .map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
+                .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
         ),
     };
-    tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))])
+    tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause))))
 }
 
 pub fn program_clauses_for_type_def<'a, 'tcx>(
@@ -388,7 +395,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
             where_clauses
                 .iter()
                 .cloned()
-                .map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
+                .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
         ),
     };
 
@@ -404,7 +411,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
     // ```
 
     // `FromEnv(Ty<...>)`
-    let from_env_goal = DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal();
+    let from_env_goal = tcx.mk_goal(DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal());
     let hypotheses = tcx.intern_goals(&[from_env_goal]);
 
     // For each where clause `WC`:
@@ -423,10 +430,86 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
 }
 
 pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
-    _tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    _item_id: DefId,
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    item_id: DefId,
 ) -> Clauses<'tcx> {
-    unimplemented!()
+    // Rule ProjectionEq-Skolemize
+    //
+    // ```
+    // trait Trait<P1..Pn> {
+    //     type AssocType<Pn+1..Pm>;
+    // }
+    // ```
+    //
+    // `ProjectionEq` can succeed by skolemizing, see "associated type"
+    // chapter for more:
+    // ```
+    // forall<Self, P1..Pn, Pn+1..Pm> {
+    //     ProjectionEq(
+    //         <Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> =
+    //         (Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>
+    //     )
+    // }
+    // ```
+
+    let item = tcx.associated_item(item_id);
+    debug_assert_eq!(item.kind, ty::AssociatedKind::Type);
+    let trait_id = match item.container {
+        ty::AssociatedItemContainer::TraitContainer(trait_id) => trait_id,
+        _ => bug!("not an trait container"),
+    };
+    let trait_ref = ty::TraitRef::identity(tcx, trait_id);
+
+    let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.ident);
+    let placeholder_ty = tcx.mk_ty(ty::UnnormalizedProjection(projection_ty));
+    let projection_eq = WhereClause::ProjectionEq(ty::ProjectionPredicate {
+        projection_ty,
+        ty: placeholder_ty,
+    });
+
+    let projection_eq_clause = ProgramClause {
+        goal: DomainGoal::Holds(projection_eq),
+        hypotheses: &ty::List::empty(),
+    };
+
+    // Rule WellFormed-AssocTy
+    // ```
+    // forall<Self, P1..Pn, Pn+1..Pm> {
+    //     WellFormed((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
+    //         :- Implemented(Self: Trait<P1..Pn>)
+    // }
+    // ```
+
+    let trait_predicate = ty::TraitPredicate { trait_ref };
+    let hypothesis = tcx.mk_goal(
+        DomainGoal::Holds(WhereClause::Implemented(trait_predicate)).into_goal()
+    );
+    let wf_clause = ProgramClause {
+        goal: DomainGoal::WellFormed(WellFormed::Ty(placeholder_ty)),
+        hypotheses: tcx.mk_goals(iter::once(hypothesis)),
+    };
+
+    // Rule Implied-Trait-From-AssocTy
+    // ```
+    // forall<Self, P1..Pn, Pn+1..Pm> {
+    //     FromEnv(Self: Trait<P1..Pn>)
+    //         :- FromEnv((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
+    // }
+    // ```
+
+    let hypothesis = tcx.mk_goal(
+        DomainGoal::FromEnv(FromEnv::Ty(placeholder_ty)).into_goal()
+    );
+    let from_env_clause = ProgramClause {
+        goal: DomainGoal::FromEnv(FromEnv::Trait(trait_predicate)),
+        hypotheses: tcx.mk_goals(iter::once(hypothesis)),
+    };
+
+    let clauses = iter::once(projection_eq_clause)
+        .chain(iter::once(wf_clause))
+        .chain(iter::once(from_env_clause));
+    let clauses = clauses.map(|clause| Clause::ForAll(ty::Binder::dummy(clause)));
+    tcx.mk_clauses(clauses)
 }
 
 pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
@@ -435,10 +518,11 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
 ) -> Clauses<'tcx> {
     // Rule Normalize-From-Impl (see rustc guide)
     //
-    // ```impl<P0..Pn> Trait<A1..An> for A0
-    // {
+    // ```
+    // impl<P0..Pn> Trait<A1..An> for A0 {
     //     type AssocType<Pn+1..Pm> = T;
-    // }```
+    // }
+    // ```
     //
     // FIXME: For the moment, we don't account for where clauses written on the associated
     // ty definition (i.e. in the trait def, as in `type AssocType<T> where T: Sized`).
@@ -482,10 +566,10 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
         hypotheses: tcx.mk_goals(
             hypotheses
                 .into_iter()
-                .map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
+                .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
         ),
     };
-    tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))])
+    tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause))))
 }
 
 pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
index 845bfad7807d32734be3695cd9af68e3221b66d6..8bac007b748ac20a6376f2ceb58f0e41f5d04922 100644 (file)
@@ -9,6 +9,6 @@ path = "lib.rs"
 
 [dependencies]
 pulldown-cmark = { version = "0.1.2", default-features = false }
-minifier = "0.0.19"
+minifier = "0.0.20"
 tempfile = "3"
 parking_lot = "0.6.4"
index 5df4862290e3c0d990e980320e3d85570a5c1495..87b4527a2a73946629e53bd4ecf5e6b1f81d702b 100644 (file)
@@ -44,9 +44,21 @@ pub fn render_with_highlighting(src: &str, class: Option<&str>,
     }
     write_header(class, &mut out).unwrap();
 
-    let mut classifier = Classifier::new(lexer::StringReader::new(&sess, fm, None),
-                                         sess.source_map());
+    let lexer = match lexer::StringReader::new_without_err(&sess, fm, None, "Output from rustc:") {
+        Ok(l) => l,
+        Err(_) => {
+            let first_line = src.lines().next().unwrap_or_else(|| "");
+            let mut err = sess.span_diagnostic
+                              .struct_warn(&format!("Invalid doc comment starting with: `{}`\n\
+                                                     (Ignoring this codeblock)",
+                                                    first_line));
+            err.emit();
+            return String::new();
+        }
+    };
+    let mut classifier = Classifier::new(lexer, sess.source_map());
     if classifier.write_source(&mut out).is_err() {
+        classifier.lexer.emit_fatal_errors();
         return format!("<pre>{}</pre>", src);
     }
 
@@ -162,11 +174,10 @@ fn try_next_token(&mut self) -> io::Result<TokenAndSpan> {
         match self.lexer.try_next_token() {
             Ok(tas) => Ok(tas),
             Err(_) => {
-                self.lexer.emit_fatal_errors();
-                self.lexer.sess.span_diagnostic
-                    .struct_warn("Backing out of syntax highlighting")
-                    .note("You probably did not intend to render this as a rust code-block")
-                    .emit();
+                let mut err = self.lexer.sess.span_diagnostic
+                                  .struct_warn("Backing out of syntax highlighting");
+                err.note("You probably did not intend to render this as a rust code-block");
+                err.emit();
                 Err(io::Error::new(io::ErrorKind::Other, ""))
             }
         }
index 1c61e73fae03cdd0f8346bee6244c05bfd517256..23f1e15de3c925c7c8acb3bebf9a68c2d840f875 100644 (file)
@@ -4098,12 +4098,13 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                         </div>",
                        version)?;
             }
+        }
 
+        write!(fmt, "<div class=\"sidebar-elems\">")?;
+        if it.is_crate() {
             write!(fmt, "<a id='all-types' href='all.html'><p>See all {}'s items</p></a>",
                    it.name.as_ref().expect("crates always have a name"))?;
         }
-
-        write!(fmt, "<div class=\"sidebar-elems\">")?;
         match it.inner {
             clean::StructItem(ref s) => sidebar_struct(fmt, it, s)?,
             clean::TraitItem(ref t) => sidebar_trait(fmt, it, t)?,
index 58ac46d22717bc7dd0af46b28d11b7335a5ce9f1..91ff03a327df4b1c78d4f866eaf4c228dfae99dc 100644 (file)
@@ -908,10 +908,9 @@ span.since {
                padding-top: 0px;
        }
 
-       .sidebar {
+       body > .sidebar {
                height: 45px;
                min-height: 40px;
-               width: calc(100% + 30px);
                margin: 0;
                margin-left: -15px;
                padding: 0 15px;
@@ -1013,6 +1012,10 @@ span.since {
        .anchor {
                display: none !important;
        }
+
+       h1.fqn {
+               overflow: initial;
+       }
 }
 
 @media print {
@@ -1112,6 +1115,18 @@ h4 > .important-traits {
        top: 2px;
 }
 
+#all-types {
+       text-align: center;
+       border: 1px solid;
+       margin: 0 10px;
+       margin-bottom: 10px;
+       display: block;
+       border-radius: 7px;
+}
+#all-types > p {
+       margin: 5px 0;
+}
+
 @media (max-width: 700px) {
        h4 > .important-traits {
                position: absolute;
@@ -1135,6 +1150,9 @@ h4 > .important-traits {
                background-color: rgba(0,0,0,0);
                height: 100%;
        }
+       .sidebar {
+               width: calc(100% + 30px);
+       }
 
        .show-it {
                display: block;
@@ -1180,6 +1198,10 @@ h4 > .important-traits {
        .impl > .collapse-toggle {
                left: -10px;
        }
+
+       #all-types {
+               margin: 10px;
+       }
 }
 
 
@@ -1383,17 +1405,6 @@ kbd {
 #main > ul > li {
        list-style: none;
 }
-#all-types {
-       text-align: center;
-       border: 1px solid;
-       margin: 0 10px;
-       margin-bottom: 10px;
-       display: block;
-       border-radius: 7px;
-}
-#all-types > p {
-       margin: 5px 0;
-}
 
 .non-exhaustive {
        margin-bottom: 1em;
index f14d55cb2d34f1ea8c443b8a197846307d3c0360..017949291bcf16e37f200141b9254d9fdbaad544 100644 (file)
@@ -726,7 +726,7 @@ pub fn write(&mut self, write: bool) -> &mut OpenOptions {
     /// If a file is opened with both read and append access, beware that after
     /// opening, and after every write, the position for reading may be set at the
     /// end of the file. So, before writing, save the current position (using
-    /// [`seek`]`(`[`SeekFrom`]`::`[`Current`]`(0))`, and restore it before the next read.
+    /// [`seek`]`(`[`SeekFrom`]`::`[`Current`]`(0))`), and restore it before the next read.
     ///
     /// ## Note
     ///
index 48a9b2f4a93de558e18ca361cd203d46333c1512..5c87035d8e929214e11ced115b76469307e2923a 100644 (file)
@@ -79,7 +79,7 @@
 ///
 /// Simply put, a type `T` implements `UnwindSafe` if it cannot easily allow
 /// witnessing a broken invariant through the use of `catch_unwind` (catching a
-/// panic). This trait is a marker trait, so it is automatically implemented for
+/// panic). This trait is an auto trait, so it is automatically implemented for
 /// many types, and it is also structurally composed (e.g. a struct is unwind
 /// safe if all of its components are unwind safe).
 ///
index 8d54728a75f42ff3e93918feeda1bf9c596e00c3..3b432d05132095adc8206d36e022275c51ebb321 100644 (file)
@@ -908,11 +908,36 @@ mod prim_usize { }
 /// `&mut T` references can be freely coerced into `&T` references with the same referent type, and
 /// references with longer lifetimes can be freely coerced into references with shorter ones.
 ///
+/// Reference equality by address, instead of comparing the values pointed to, is accomplished via
+/// implicit reference-pointer coercion and raw pointer equality via [`ptr::eq`], while
+/// [`PartialEq`] compares values.
+///
+/// [`ptr::eq`]: ptr/fn.eq.html
+/// [`PartialEq`]: cmp/trait.PartialEq.html
+///
+/// ```
+/// use std::ptr;
+///
+/// let five = 5;
+/// let other_five = 5;
+/// let five_ref = &five;
+/// let same_five_ref = &five;
+/// let other_five_ref = &other_five;
+///
+/// assert!(five_ref == same_five_ref);
+/// assert!(five_ref == other_five_ref);
+///
+/// assert!(ptr::eq(five_ref, same_five_ref));
+/// assert!(!ptr::eq(five_ref, other_five_ref));
+/// ```
+///
 /// For more information on how to use references, see [the book's section on "References and
 /// Borrowing"][book-refs].
 ///
 /// [book-refs]: ../book/second-edition/ch04-02-references-and-borrowing.html
 ///
+/// # Trait implementations
+///
 /// The following traits are implemented for all `&T`, regardless of the type of its referent:
 ///
 /// * [`Copy`]
index 17cb614ba11ff7ae12b573a4264bf3463c0936f5..98845e457b25c8a25dd1ee5b9554cafbfa5269a8 100644 (file)
@@ -329,7 +329,7 @@ pub fn call_once_force<F>(&self, f: F) where F: FnOnce(&OnceState) {
     /// assert!(handle.join().is_err());
     /// assert_eq!(INIT.is_completed(), false);
     /// ```
-    #[unstable(feature = "once_is_completed", issue = "42")]
+    #[unstable(feature = "once_is_completed", issue = "54890")]
     #[inline]
     pub fn is_completed(&self) -> bool {
         // An `Acquire` load is enough because that makes all the initialization
index a9ce23655777956dd32592f668dfb7e6307eccb8..e611eb86dc1b3214eb5637d5acb685f4a33881e2 100644 (file)
@@ -9,7 +9,14 @@
 // except according to those terms.
 
 use attr::HasAttrs;
-use feature_gate::{feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features, GateIssue};
+use feature_gate::{
+    feature_err,
+    EXPLAIN_STMT_ATTR_SYNTAX,
+    Features,
+    get_features,
+    GateIssue,
+    emit_feature_err,
+};
 use {fold, attr};
 use ast;
 use source_map::Spanned;
@@ -73,49 +80,103 @@ pub fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
         if self.in_cfg(node.attrs()) { Some(node) } else { None }
     }
 
+    /// Parse and expand all `cfg_attr` attributes into a list of attributes
+    /// that are within each `cfg_attr` that has a true configuration predicate.
+    ///
+    /// Gives compiler warnigns if any `cfg_attr` does not contain any
+    /// attributes and is in the original source code. Gives compiler errors if
+    /// the syntax of any `cfg_attr` is incorrect.
     pub fn process_cfg_attrs<T: HasAttrs>(&mut self, node: T) -> T {
         node.map_attrs(|attrs| {
-            attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect()
+            attrs.into_iter().flat_map(|attr| self.process_cfg_attr(attr)).collect()
         })
     }
 
-    fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
+    /// Parse and expand a single `cfg_attr` attribute into a list of attributes
+    /// when the configuration predicate is true, or otherwise expand into an
+    /// empty list of attributes.
+    ///
+    /// Gives a compiler warning when the `cfg_attr` contains no attribtes and
+    /// is in the original source file. Gives a compiler error if the syntax of
+    /// the attribute is incorrect
+    fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
         if !attr.check_name("cfg_attr") {
-            return Some(attr);
+            return vec![attr];
         }
 
-        let (cfg, path, tokens, span) = match attr.parse(self.sess, |parser| {
+        let gate_cfg_attr_multi = if let Some(ref features) = self.features {
+            !features.cfg_attr_multi
+        } else {
+            false
+        };
+        let cfg_attr_span = attr.span;
+
+        let (cfg_predicate, expanded_attrs) = match attr.parse(self.sess, |parser| {
             parser.expect(&token::OpenDelim(token::Paren))?;
-            let cfg = parser.parse_meta_item()?;
+
+            let cfg_predicate = parser.parse_meta_item()?;
             parser.expect(&token::Comma)?;
-            let lo = parser.span.lo();
-            let (path, tokens) = parser.parse_meta_item_unrestricted()?;
-            parser.eat(&token::Comma); // Optional trailing comma
+
+            // Presumably, the majority of the time there will only be one attr.
+            let mut expanded_attrs = Vec::with_capacity(1);
+
+            while !parser.check(&token::CloseDelim(token::Paren)) {
+                let lo = parser.span.lo();
+                let (path, tokens) = parser.parse_meta_item_unrestricted()?;
+                expanded_attrs.push((path, tokens, parser.prev_span.with_lo(lo)));
+                parser.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Paren)])?;
+            }
+
             parser.expect(&token::CloseDelim(token::Paren))?;
-            Ok((cfg, path, tokens, parser.prev_span.with_lo(lo)))
+            Ok((cfg_predicate, expanded_attrs))
         }) {
             Ok(result) => result,
             Err(mut e) => {
                 e.emit();
-                return None;
+                return Vec::new();
             }
         };
 
-        if attr::cfg_matches(&cfg, self.sess, self.features) {
-            self.process_cfg_attr(ast::Attribute {
+        // Check feature gate and lint on zero attributes in source. Even if the feature is gated,
+        // we still compute as if it wasn't, since the emitted error will stop compilation futher
+        // along the compilation.
+        match (expanded_attrs.len(), gate_cfg_attr_multi) {
+            (0, false) => {
+                // FIXME: Emit unused attribute lint here.
+            },
+            (1, _) => {},
+            (_, true) => {
+                emit_feature_err(
+                    self.sess,
+                    "cfg_attr_multi",
+                    cfg_attr_span,
+                    GateIssue::Language,
+                    "cfg_attr with zero or more than one attributes is experimental",
+                );
+            },
+            (_, false) => {}
+        }
+
+        if attr::cfg_matches(&cfg_predicate, self.sess, self.features) {
+            // We call `process_cfg_attr` recursively in case there's a
+            // `cfg_attr` inside of another `cfg_attr`. E.g.
+            //  `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
+            expanded_attrs.into_iter()
+            .flat_map(|(path, tokens, span)| self.process_cfg_attr(ast::Attribute {
                 id: attr::mk_attr_id(),
                 style: attr.style,
                 path,
                 tokens,
                 is_sugared_doc: false,
                 span,
-            })
+            }))
+            .collect()
         } else {
-            None
+            Vec::new()
         }
     }
 
-    // Determine if a node with the given attributes should be included in this configuration.
+    /// Determine if a node with the given attributes should be included in this configuration.
     pub fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
         attrs.iter().all(|attr| {
             if !is_cfg(attr) {
@@ -165,7 +226,7 @@ pub fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
         })
     }
 
-    // Visit attributes on expression and statements (but not attributes on items in blocks).
+    /// Visit attributes on expression and statements (but not attributes on items in blocks).
     fn visit_expr_attrs(&mut self, attrs: &[ast::Attribute]) {
         // flag the offending attributes
         for attr in attrs.iter() {
index 24ee24640558eddf2ff9702d40c9afd2f79fc605..b86b92fb29e60529d9a38f436d01d887c29c9832 100644 (file)
@@ -433,9 +433,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // #[doc(alias = "...")]
     (active, doc_alias, "1.27.0", Some(50146), None),
 
-    // Scoped lints
-    (active, tool_lints, "1.28.0", Some(44690), None),
-
     // Allows irrefutable patterns in if-let and while-let statements (RFC 2086)
     (active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
 
@@ -499,6 +496,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 
     // Allows `impl Trait` in bindings (`let`, `const`, `static`)
     (active, impl_trait_in_bindings, "1.30.0", Some(34511), None),
+
+    // #[cfg_attr(predicate, multiple, attributes, here)]
+    (active, cfg_attr_multi, "1.31.0", Some(54881), None),
 );
 
 declare_features! (
@@ -679,6 +679,8 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
     // Allows the definition of `const fn` functions.
     (accepted, min_const_fn, "1.31.0", Some(53555), None),
+    // Scoped lints
+    (accepted, tool_lints, "1.31.0", Some(44690), None),
 );
 
 // If you change this, please modify src/doc/unstable-book as well. You must
index aa47d5bf669bc0eb9f6015c78739094d9cb78951..a814c88ee78216babc4db391df90667d0efabcf7 100644 (file)
@@ -238,6 +238,19 @@ pub fn new(sess: &'a ParseSess,
         sr
     }
 
+    pub fn new_without_err(sess: &'a ParseSess,
+                           source_file: Lrc<syntax_pos::SourceFile>,
+                           override_span: Option<Span>,
+                           prepend_error_text: &str) -> Result<Self, ()> {
+        let mut sr = StringReader::new_raw(sess, source_file, override_span);
+        if sr.advance_token().is_err() {
+            eprintln!("{}", prepend_error_text);
+            sr.emit_fatal_errors();
+            return Err(());
+        }
+        Ok(sr)
+    }
+
     pub fn retokenize(sess: &'a ParseSess, mut span: Span) -> Self {
         let begin = sess.source_map().lookup_byte_offset(span.lo());
         let end = sess.source_map().lookup_byte_offset(span.hi());
index 08349084aa6d6babb3bb25fc4132799450c083e4..b5896f37c00b8b11eba35ac4798c7440e8bc5f2a 100644 (file)
@@ -678,7 +678,7 @@ pub fn expect(&mut self, t: &token::Token) -> PResult<'a,  ()> {
     /// Expect next token to be edible or inedible token.  If edible,
     /// then consume it; if inedible, then return without consuming
     /// anything.  Signal a fatal error if next token is unexpected.
-    fn expect_one_of(&mut self,
+    pub fn expect_one_of(&mut self,
                          edible: &[token::Token],
                          inedible: &[token::Token]) -> PResult<'a,  ()>{
         fn tokens_to_string(tokens: &[TokenType]) -> String {
@@ -1435,6 +1435,23 @@ fn parse_trait_item_(&mut self,
                     attrs.extend(inner_attrs.iter().cloned());
                     Some(body)
                 }
+                token::Interpolated(ref nt) => {
+                    match &nt.0 {
+                        token::NtBlock(..) => {
+                            *at_end = true;
+                            let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+                            attrs.extend(inner_attrs.iter().cloned());
+                            Some(body)
+                        }
+                        _ => {
+                            let token_str = self.this_token_to_string();
+                            let mut err = self.fatal(&format!("expected `;` or `{{`, found `{}`",
+                                                              token_str));
+                            err.span_label(self.span, "expected `;` or `{`");
+                            return Err(err);
+                        }
+                    }
+                }
                 _ => {
                     let token_str = self.this_token_to_string();
                     let mut err = self.fatal(&format!("expected `;` or `{{`, found `{}`",
@@ -3871,6 +3888,9 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<source_map::Spanned<ast::Fiel
             // check that a comma comes after every field
             if !ate_comma {
                 let err = self.struct_span_err(self.prev_span, "expected `,`");
+                if let Some(mut delayed) = delayed_err {
+                    delayed.emit();
+                }
                 return Err(err);
             }
             ate_comma = false;
index f1ab1d4ddfa476d8fb0006583f4a3b7521eac4e6..2b1bf1c0290812c228099457d3b57df54c6f8cda 100644 (file)
@@ -178,6 +178,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
     return Attribute::SanitizeAddress;
   case SanitizeMemory:
     return Attribute::SanitizeMemory;
+  case NonLazyBind:
+    return Attribute::NonLazyBind;
   }
   report_fatal_error("bad AttributeKind");
 }
index 1070068b99845f86c72e6cc839a4e0d90f2da995..b6fa9a2fa950809b5b52dd42bea14f10e1e112fa 100644 (file)
@@ -97,6 +97,7 @@ enum LLVMRustAttribute {
   SanitizeThread = 20,
   SanitizeAddress = 21,
   SanitizeMemory = 22,
+  NonLazyBind = 23,
 };
 
 typedef struct OpaqueRustString *RustStringRef;
index aab5f1bfb4f863825d67206ef1efd378688bbe0b..2cf8ce00bfb5d7d8366a67be1584d6f8f4c24c7a 100644 (file)
@@ -15,7 +15,7 @@
 #![crate_type = "lib"]
 #![feature(naked_functions)]
 
-// CHECK: Function Attrs: naked uwtable
+// CHECK: Function Attrs: naked
 // CHECK-NEXT: define void @naked_empty()
 #[no_mangle]
 #[naked]
@@ -24,7 +24,7 @@ pub fn naked_empty() {
     // CHECK-NEXT: ret void
 }
 
-// CHECK: Function Attrs: naked uwtable
+// CHECK: Function Attrs: naked
 #[no_mangle]
 #[naked]
 // CHECK-NEXT: define void @naked_with_args(i{{[0-9]+}})
@@ -35,7 +35,7 @@ pub fn naked_with_args(a: isize) {
     // CHECK: ret void
 }
 
-// CHECK: Function Attrs: naked uwtable
+// CHECK: Function Attrs: naked
 // CHECK-NEXT: define i{{[0-9]+}} @naked_with_return()
 #[no_mangle]
 #[naked]
@@ -45,7 +45,7 @@ pub fn naked_with_return() -> isize {
     0
 }
 
-// CHECK: Function Attrs: naked uwtable
+// CHECK: Function Attrs: naked
 // CHECK-NEXT: define i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}})
 #[no_mangle]
 #[naked]
@@ -57,7 +57,7 @@ pub fn naked_with_args_and_return(a: isize) -> isize {
     a
 }
 
-// CHECK: Function Attrs: naked uwtable
+// CHECK: Function Attrs: naked
 // CHECK-NEXT: define void @naked_recursive()
 #[no_mangle]
 #[naked]
diff --git a/src/test/codegen/no-plt.rs b/src/test/codegen/no-plt.rs
new file mode 100644 (file)
index 0000000..8f302e5
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -C relocation-model=pic -Z plt=no
+
+#![crate_type = "lib"]
+
+// We need a function which is normally called through the PLT.
+extern "C" {
+    // CHECK: Function Attrs: nounwind nonlazybind
+    fn getenv(name: *const u8) -> *mut u8;
+}
+
+// Ensure the function gets referenced.
+pub unsafe fn call_through_plt() -> *mut u8 {
+    getenv(b"\0".as_ptr())
+}
+
+// Ensure intrinsics also skip the PLT
+// CHECK: !"RtLibUseGOT"
diff --git a/src/test/run-pass/macros/macro-as-fn-body.rs b/src/test/run-pass/macros/macro-as-fn-body.rs
new file mode 100644 (file)
index 0000000..8c3c9fd
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// run-pass
+//
+// Description - ensure Interpolated blocks can act as valid function bodies
+// Covered cases: free functions, struct methods, and default trait functions
+
+macro_rules! def_fn {
+    ($body:block) => {
+        fn bar() $body
+    }
+}
+
+trait Foo {
+    def_fn!({ println!("foo"); });
+}
+
+struct Baz {}
+
+impl Foo for Baz {}
+
+struct Qux {}
+
+impl Qux {
+    def_fn!({ println!("qux"); });
+}
+
+def_fn!({ println!("quux"); });
+
+pub fn main() {
+    Baz::bar();
+    Qux::bar();
+    bar();
+}
index 24ec43b12f60e259f169bead63dab5c6214b219b..2705c03598a0d2c2bb84560dadc96478e7740b2e 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tool_lints)]
+
 #![deny(unknown_lints)]
 
 #[allow(clippy::almost_swapped)]
index 6cd57eaa195958d599ae1b32fa8df965eaaf212e..57df3e072a8dc988c56737177fd5e532223e10cd 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tool_lints)]
+
 #![feature(rust_2018_preview)]
 #![deny(unknown_lints)]
 
diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs
new file mode 100644 (file)
index 0000000..8c790d7
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+// compile-flags: --error-format=human
+
+/// ```
+/// \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+/// ```
+pub fn foo() {}
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
new file mode 100644 (file)
index 0000000..b566133
--- /dev/null
@@ -0,0 +1,10 @@
+Output from rustc:
+error: unknown start of token: /
+ --> <stdin>:1:1
+  |
+1 | /__________pkt->size___________/          /_result->size_/ /__pkt->size__/
+  | ^
+
+warning: Invalid doc comment starting with: `/__________pkt->size___________/          /_result->size_/ /__pkt->size__/`
+(Ignoring this codeblock)
+
index ebe10b3714f20fecf91988379b59d6d24e8f6710..11b70d1d7809cb20176513fe0e1c89982a46a228 100644 (file)
@@ -11,8 +11,8 @@
 // aux-build:lint_tool_test.rs
 // ignore-stage1
 // compile-flags: --cfg foo
+
 #![feature(plugin)]
-#![feature(tool_lints)]
 #![plugin(lint_tool_test)]
 #![allow(dead_code)]
 #![cfg_attr(foo, warn(test_lint))]
diff --git a/src/test/ui/auxiliary/namespaced_enums.rs b/src/test/ui/auxiliary/namespaced_enums.rs
deleted file mode 100644 (file)
index 3bf39b7..0000000
+++ /dev/null
@@ -1,20 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub enum Foo {
-    A,
-    B(isize),
-    C { a: isize },
-}
-
-impl Foo {
-    pub fn foo() {}
-    pub fn bar(&self) {}
-}
index f823a6f08d789485e47546b7e9fa34f4ec5f1f34..c3a2180b9f082e062f9afab0ede465a7511ac8f3 100644 (file)
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of dereference of raw pointer
   --> $DIR/borrowck-move-from-unsafe-ptr.rs:13:13
    |
 LL |     let y = *x; //~ ERROR cannot move out of dereference of raw pointer
    |             ^^
    |             |
-   |             cannot move out of borrowed content
+   |             cannot move out of dereference of raw pointer
    |             help: consider removing the `*`: `x`
 
 error: aborting due to previous error
diff --git a/src/test/ui/cfg-arg-invalid-1.rs b/src/test/ui/cfg-arg-invalid-1.rs
deleted file mode 100644 (file)
index 36dd78d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-// compile-flags: --cfg a(b=c)
-// error-pattern: invalid `--cfg` argument: `a(b=c)` (expected `key` or `key="value"`)
-fn main() {}
diff --git a/src/test/ui/cfg-arg-invalid-2.rs b/src/test/ui/cfg-arg-invalid-2.rs
deleted file mode 100644 (file)
index 48d656a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-// compile-flags: --cfg a{b}
-// error-pattern: invalid `--cfg` argument: `a{b}` (expected `key` or `key="value"`)
-fn main() {}
diff --git a/src/test/ui/cfg-arg-invalid-3.rs b/src/test/ui/cfg-arg-invalid-3.rs
deleted file mode 100644 (file)
index 96ac782..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-// compile-flags: --cfg a::b
-// error-pattern: invalid `--cfg` argument: `a::b` (argument key must be an identifier)
-fn main() {}
diff --git a/src/test/ui/cfg-arg-invalid-4.rs b/src/test/ui/cfg-arg-invalid-4.rs
deleted file mode 100644 (file)
index e7dfa17..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-// compile-flags: --cfg a(b)
-// error-pattern: invalid `--cfg` argument: `a(b)` (expected `key` or `key="value"`)
-fn main() {}
diff --git a/src/test/ui/cfg-arg-invalid-5.rs b/src/test/ui/cfg-arg-invalid-5.rs
deleted file mode 100644 (file)
index a939f45..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-// compile-flags: --cfg a=10
-// error-pattern: invalid `--cfg` argument: `a=10` (argument value must be a string)
-fn main() {}
diff --git a/src/test/ui/cfg-attr-cfg-2.rs b/src/test/ui/cfg-attr-cfg-2.rs
deleted file mode 100644 (file)
index 58a62d4..0000000
+++ /dev/null
@@ -1,18 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-//
-// error-pattern: `main` function not found
-// compile-flags: --cfg foo
-
-// main is conditionally compiled, but the conditional compilation
-// is conditional too!
-
-#[cfg_attr(foo, cfg(bar))]
-fn main() { }
diff --git a/src/test/ui/cfg-attr-cfg-2.stderr b/src/test/ui/cfg-attr-cfg-2.stderr
deleted file mode 100644 (file)
index db3c7ac..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-error[E0601]: `main` function not found in crate `cfg_attr_cfg_2`
-   |
-   = note: consider adding a `main` function to `$DIR/cfg-attr-cfg-2.rs`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/cfg-attr-crate-2.rs b/src/test/ui/cfg-attr-crate-2.rs
deleted file mode 100644 (file)
index a79c766..0000000
+++ /dev/null
@@ -1,17 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-//
-// compile-flags: --cfg broken
-
-// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044
-
-#![cfg_attr(broken, no_core)] //~ ERROR no_core is experimental
-
-fn main() { }
diff --git a/src/test/ui/cfg-attr-crate-2.stderr b/src/test/ui/cfg-attr-crate-2.stderr
deleted file mode 100644 (file)
index 7b66c8f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: no_core is experimental (see issue #29639)
-  --> $DIR/cfg-attr-crate-2.rs:15:21
-   |
-LL | #![cfg_attr(broken, no_core)] //~ ERROR no_core is experimental
-   |                     ^^^^^^^^
-   |
-   = help: add #![feature(no_core)] 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/cfg-attr-invalid-predicate.rs b/src/test/ui/cfg-attr-invalid-predicate.rs
deleted file mode 100644 (file)
index 09fe6ce..0000000
+++ /dev/null
@@ -1,12 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[cfg(foo(bar))] //~ ERROR invalid predicate `foo`
-fn main() {}
diff --git a/src/test/ui/cfg-attr-invalid-predicate.stderr b/src/test/ui/cfg-attr-invalid-predicate.stderr
deleted file mode 100644 (file)
index 5a89f97..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0537]: invalid predicate `foo`
-  --> $DIR/cfg-attr-invalid-predicate.rs:11:7
-   |
-LL | #[cfg(foo(bar))] //~ ERROR invalid predicate `foo`
-   |       ^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0537`.
diff --git a/src/test/ui/cfg-attr-syntax-validation.rs b/src/test/ui/cfg-attr-syntax-validation.rs
deleted file mode 100644 (file)
index 06a22ef..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#[cfg] //~ ERROR `cfg` is not followed by parentheses
-struct S1;
-
-#[cfg = 10] //~ ERROR `cfg` is not followed by parentheses
-struct S2;
-
-#[cfg()] //~ ERROR `cfg` predicate is not specified
-struct S3;
-
-#[cfg(a, b)] //~ ERROR multiple `cfg` predicates are specified
-struct S4;
-
-#[cfg("str")] //~ ERROR `cfg` predicate key cannot be a literal
-struct S5;
-
-#[cfg(a::b)] //~ ERROR `cfg` predicate key must be an identifier
-struct S6;
-
-#[cfg(a())] //~ ERROR invalid predicate `a`
-struct S7;
-
-#[cfg(a = 10)] //~ ERROR literal in `cfg` predicate value must be a string
-struct S8;
-
-macro_rules! generate_s9 {
-    ($expr: expr) => {
-        #[cfg(feature = $expr)] //~ ERROR `cfg` is not a well-formed meta-item
-        struct S9;
-    }
-}
-
-generate_s9!(concat!("nonexistent"));
diff --git a/src/test/ui/cfg-attr-syntax-validation.stderr b/src/test/ui/cfg-attr-syntax-validation.stderr
deleted file mode 100644 (file)
index 7773fdb..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-error: `cfg` is not followed by parentheses
-  --> $DIR/cfg-attr-syntax-validation.rs:1:1
-   |
-LL | #[cfg] //~ ERROR `cfg` is not followed by parentheses
-   | ^^^^^^ help: expected syntax is: `cfg(/* predicate */)`
-
-error: `cfg` is not followed by parentheses
-  --> $DIR/cfg-attr-syntax-validation.rs:4:1
-   |
-LL | #[cfg = 10] //~ ERROR `cfg` is not followed by parentheses
-   | ^^^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)`
-
-error: `cfg` predicate is not specified
-  --> $DIR/cfg-attr-syntax-validation.rs:7:1
-   |
-LL | #[cfg()] //~ ERROR `cfg` predicate is not specified
-   | ^^^^^^^^
-
-error: multiple `cfg` predicates are specified
-  --> $DIR/cfg-attr-syntax-validation.rs:10:10
-   |
-LL | #[cfg(a, b)] //~ ERROR multiple `cfg` predicates are specified
-   |          ^
-
-error: `cfg` predicate key cannot be a literal
-  --> $DIR/cfg-attr-syntax-validation.rs:13:7
-   |
-LL | #[cfg("str")] //~ ERROR `cfg` predicate key cannot be a literal
-   |       ^^^^^
-
-error: `cfg` predicate key must be an identifier
-  --> $DIR/cfg-attr-syntax-validation.rs:16:7
-   |
-LL | #[cfg(a::b)] //~ ERROR `cfg` predicate key must be an identifier
-   |       ^^^^
-
-error[E0537]: invalid predicate `a`
-  --> $DIR/cfg-attr-syntax-validation.rs:19:7
-   |
-LL | #[cfg(a())] //~ ERROR invalid predicate `a`
-   |       ^^^
-
-error: literal in `cfg` predicate value must be a string
-  --> $DIR/cfg-attr-syntax-validation.rs:22:11
-   |
-LL | #[cfg(a = 10)] //~ ERROR literal in `cfg` predicate value must be a string
-   |           ^^
-
-error: `cfg` is not a well-formed meta-item
-  --> $DIR/cfg-attr-syntax-validation.rs:27:9
-   |
-LL |         #[cfg(feature = $expr)] //~ ERROR `cfg` is not a well-formed meta-item
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: expected syntax is: `#[cfg(/* predicate */)]`
-...
-LL | generate_s9!(concat!("nonexistent"));
-   | ------------------------------------- in this macro invocation
-
-error: aborting due to 9 previous errors
-
-For more information about this error, try `rustc --explain E0537`.
diff --git a/src/test/ui/cfg-attr-trailing-comma.rs b/src/test/ui/cfg-attr-trailing-comma.rs
deleted file mode 100644 (file)
index 21e0054..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// compile-flags: --cfg TRUE
-
-#[cfg_attr(TRUE, inline,)] // OK
-fn f() {}
-
-#[cfg_attr(FALSE, inline,)] // OK
-fn g() {}
-
-#[cfg_attr(TRUE, inline,,)] //~ ERROR expected `)`, found `,`
-fn h() {}
-
-#[cfg_attr(FALSE, inline,,)] //~ ERROR expected `)`, found `,`
-fn i() {}
diff --git a/src/test/ui/cfg-attr-trailing-comma.stderr b/src/test/ui/cfg-attr-trailing-comma.stderr
deleted file mode 100644 (file)
index 76a4704..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error: expected `)`, found `,`
-  --> $DIR/cfg-attr-trailing-comma.rs:9:25
-   |
-LL | #[cfg_attr(TRUE, inline,,)] //~ ERROR expected `)`, found `,`
-   |                         ^ expected `)`
-
-error: expected `)`, found `,`
-  --> $DIR/cfg-attr-trailing-comma.rs:12:26
-   |
-LL | #[cfg_attr(FALSE, inline,,)] //~ ERROR expected `)`, found `,`
-   |                          ^ expected `)`
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/cfg-attr-unknown-attribute-macro-expansion.rs b/src/test/ui/cfg-attr-unknown-attribute-macro-expansion.rs
deleted file mode 100644 (file)
index afcb896..0000000
+++ /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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-macro_rules! foo {
-    () => {
-        #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
-        fn foo() {}
-    }
-}
-
-foo!();
-
-fn main() {}
diff --git a/src/test/ui/cfg-attr-unknown-attribute-macro-expansion.stderr b/src/test/ui/cfg-attr-unknown-attribute-macro-expansion.stderr
deleted file mode 100644 (file)
index 0f51c7d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
-  --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:13:27
-   |
-LL |         #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
-   |                           ^^^^^^^
-...
-LL | foo!();
-   | ------- in this macro invocation
-   |
-   = help: add #![feature(custom_attribute)] 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/cfg-empty-codemap.rs b/src/test/ui/cfg-empty-codemap.rs
deleted file mode 100644 (file)
index 5cf8135..0000000
+++ /dev/null
@@ -1,18 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Tests that empty source_maps don't ICE (#23301)
-
-// compile-flags: --cfg ""
-
-// error-pattern: invalid `--cfg` argument: `""` (expected `key` or `key="value"`)
-
-pub fn main() {
-}
diff --git a/src/test/ui/cfg-in-crate-1.rs b/src/test/ui/cfg-in-crate-1.rs
deleted file mode 100644 (file)
index bbccf2b..0000000
+++ /dev/null
@@ -1,13 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern: `main` function not found
-
-#![cfg(bar)]
diff --git a/src/test/ui/cfg-in-crate-1.stderr b/src/test/ui/cfg-in-crate-1.stderr
deleted file mode 100644 (file)
index c6d42c7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-error[E0601]: `main` function not found in crate `cfg_in_crate_1`
-   |
-   = note: consider adding a `main` function to `$DIR/cfg-in-crate-1.rs`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/cfg-non-opt-expr.rs b/src/test/ui/cfg-non-opt-expr.rs
deleted file mode 100644 (file)
index 55eca7f..0000000
+++ /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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(stmt_expr_attributes)]
-#![feature(custom_test_frameworks)]
-
-fn main() {
-    let _ = #[cfg(unset)] ();
-    //~^ ERROR removing an expression is not supported in this position
-    let _ = 1 + 2 + #[cfg(unset)] 3;
-    //~^ ERROR removing an expression is not supported in this position
-    let _ = [1, 2, 3][#[cfg(unset)] 1];
-    //~^ ERROR removing an expression is not supported in this position
-}
diff --git a/src/test/ui/cfg-non-opt-expr.stderr b/src/test/ui/cfg-non-opt-expr.stderr
deleted file mode 100644 (file)
index 1892cee..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error: removing an expression is not supported in this position
-  --> $DIR/cfg-non-opt-expr.rs:15:13
-   |
-LL |     let _ = #[cfg(unset)] ();
-   |             ^^^^^^^^^^^^^
-
-error: removing an expression is not supported in this position
-  --> $DIR/cfg-non-opt-expr.rs:17:21
-   |
-LL |     let _ = 1 + 2 + #[cfg(unset)] 3;
-   |                     ^^^^^^^^^^^^^
-
-error: removing an expression is not supported in this position
-  --> $DIR/cfg-non-opt-expr.rs:19:23
-   |
-LL |     let _ = [1, 2, 3][#[cfg(unset)] 1];
-   |                       ^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
diff --git a/src/test/ui/cfg_attr_path.rs b/src/test/ui/cfg_attr_path.rs
deleted file mode 100644 (file)
index 7d79985..0000000
+++ /dev/null
@@ -1,24 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(rustc_attrs)]
-#![allow(dead_code)]
-#![deny(unused_attributes)] // c.f #35584
-
-mod auxiliary {
-    #[cfg_attr(any(), path = "nonexistent_file.rs")] pub mod namespaced_enums;
-    #[cfg_attr(all(), path = "namespaced_enums.rs")] pub mod nonexistent_file;
-}
-
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
-    let _ = auxiliary::namespaced_enums::Foo::A;
-    let _ = auxiliary::nonexistent_file::Foo::A;
-}
diff --git a/src/test/ui/cfg_attr_path.stderr b/src/test/ui/cfg_attr_path.stderr
deleted file mode 100644 (file)
index 67e59d0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error: compilation successful
-  --> $DIR/cfg_attr_path.rs:21:1
-   |
-LL | / fn main() { //~ ERROR compilation successful
-LL | |     let _ = auxiliary::namespaced_enums::Foo::A;
-LL | |     let _ = auxiliary::nonexistent_file::Foo::A;
-LL | | }
-   | |_^
-
-error: aborting due to previous error
-
index c5ba5beeca7a57de53875488fcec1ad0f0e9fc7d..ba7d4ff0d9bf55ac0adc4573e195552b28810d93 100644 (file)
 
 #![feature(rustc_attrs)]
 
+trait Bar { }
+
 #[rustc_dump_program_clauses] //~ ERROR program clause dump
-trait Foo<S, T, U> {
-    fn s(_: S) -> S;
-    fn t(_: T) -> T;
-    fn u(_: U) -> U;
+trait Foo<S, T: ?Sized> {
+    #[rustc_dump_program_clauses] //~ ERROR program clause dump
+    type Assoc: Bar + ?Sized;
 }
 
 fn main() {
index c4e768415d60b5501ff5156f6c8a26b8bbab1b0d..dc2375277e7342d713049d371ae759707c5fdd1f 100644 (file)
@@ -1,14 +1,23 @@
 error: program clause dump
-  --> $DIR/lower_trait.rs:13:1
+  --> $DIR/lower_trait.rs:15:1
    |
 LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: FromEnv(S: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
-   = note: FromEnv(T: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
-   = note: FromEnv(U: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
-   = note: Implemented(Self: Foo<S, T, U>) :- FromEnv(Self: Foo<S, T, U>).
-   = note: WellFormed(Self: Foo<S, T, U>) :- Implemented(Self: Foo<S, T, U>), WellFormed(S: std::marker::Sized), WellFormed(T: std::marker::Sized), WellFormed(U: std::marker::Sized).
+   = note: FromEnv(<Self as Foo<S, T>>::Assoc: Bar) :- FromEnv(Self: Foo<S, T>).
+   = note: FromEnv(S: std::marker::Sized) :- FromEnv(Self: Foo<S, T>).
+   = note: Implemented(Self: Foo<S, T>) :- FromEnv(Self: Foo<S, T>).
+   = note: WellFormed(Self: Foo<S, T>) :- Implemented(Self: Foo<S, T>), WellFormed(S: std::marker::Sized), WellFormed(<Self as Foo<S, T>>::Assoc: Bar).
 
-error: aborting due to previous error
+error: program clause dump
+  --> $DIR/lower_trait.rs:17:5
+   |
+LL |     #[rustc_dump_program_clauses] //~ ERROR program clause dump
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: FromEnv(Self: Foo<S, T>) :- FromEnv(Unnormalized(<Self as Foo<S, T>>::Assoc)).
+   = note: ProjectionEq(<Self as Foo<S, T>>::Assoc == Unnormalized(<Self as Foo<S, T>>::Assoc)).
+   = note: WellFormed(Unnormalized(<Self as Foo<S, T>>::Assoc)) :- Implemented(Self: Foo<S, T>).
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/conditional-compilation/auxiliary/namespaced_enums.rs b/src/test/ui/conditional-compilation/auxiliary/namespaced_enums.rs
new file mode 100644 (file)
index 0000000..3bf39b7
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub enum Foo {
+    A,
+    B(isize),
+    C { a: isize },
+}
+
+impl Foo {
+    pub fn foo() {}
+    pub fn bar(&self) {}
+}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-1.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-1.rs
new file mode 100644 (file)
index 0000000..36dd78d
--- /dev/null
@@ -0,0 +1,3 @@
+// compile-flags: --cfg a(b=c)
+// error-pattern: invalid `--cfg` argument: `a(b=c)` (expected `key` or `key="value"`)
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-2.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-2.rs
new file mode 100644 (file)
index 0000000..48d656a
--- /dev/null
@@ -0,0 +1,3 @@
+// compile-flags: --cfg a{b}
+// error-pattern: invalid `--cfg` argument: `a{b}` (expected `key` or `key="value"`)
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-3.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-3.rs
new file mode 100644 (file)
index 0000000..96ac782
--- /dev/null
@@ -0,0 +1,3 @@
+// compile-flags: --cfg a::b
+// error-pattern: invalid `--cfg` argument: `a::b` (argument key must be an identifier)
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-4.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-4.rs
new file mode 100644 (file)
index 0000000..e7dfa17
--- /dev/null
@@ -0,0 +1,3 @@
+// compile-flags: --cfg a(b)
+// error-pattern: invalid `--cfg` argument: `a(b)` (expected `key` or `key="value"`)
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-5.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-5.rs
new file mode 100644 (file)
index 0000000..a939f45
--- /dev/null
@@ -0,0 +1,3 @@
+// compile-flags: --cfg a=10
+// error-pattern: invalid `--cfg` argument: `a=10` (argument value must be a string)
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-cfg-2.rs b/src/test/ui/conditional-compilation/cfg-attr-cfg-2.rs
new file mode 100644 (file)
index 0000000..58a62d4
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// error-pattern: `main` function not found
+// compile-flags: --cfg foo
+
+// main is conditionally compiled, but the conditional compilation
+// is conditional too!
+
+#[cfg_attr(foo, cfg(bar))]
+fn main() { }
diff --git a/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr
new file mode 100644 (file)
index 0000000..db3c7ac
--- /dev/null
@@ -0,0 +1,7 @@
+error[E0601]: `main` function not found in crate `cfg_attr_cfg_2`
+   |
+   = note: consider adding a `main` function to `$DIR/cfg-attr-cfg-2.rs`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs b/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs
new file mode 100644 (file)
index 0000000..a79c766
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// compile-flags: --cfg broken
+
+// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044
+
+#![cfg_attr(broken, no_core)] //~ ERROR no_core is experimental
+
+fn main() { }
diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr
new file mode 100644 (file)
index 0000000..a730473
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: no_core is experimental (see issue #29639)
+  --> $DIR/cfg-attr-crate-2.rs:15:21
+   |
+LL | #![cfg_attr(broken, no_core)] //~ ERROR no_core is experimental
+   |                     ^^^^^^^
+   |
+   = help: add #![feature(no_core)] 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/conditional-compilation/cfg-attr-invalid-predicate.rs b/src/test/ui/conditional-compilation/cfg-attr-invalid-predicate.rs
new file mode 100644 (file)
index 0000000..09fe6ce
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[cfg(foo(bar))] //~ ERROR invalid predicate `foo`
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-invalid-predicate.stderr b/src/test/ui/conditional-compilation/cfg-attr-invalid-predicate.stderr
new file mode 100644 (file)
index 0000000..5a89f97
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0537]: invalid predicate `foo`
+  --> $DIR/cfg-attr-invalid-predicate.rs:11:7
+   |
+LL | #[cfg(foo(bar))] //~ ERROR invalid predicate `foo`
+   |       ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0537`.
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs
new file mode 100644 (file)
index 0000000..84bd33f
--- /dev/null
@@ -0,0 +1,20 @@
+// Test that cfg_attr doesn't emit any attributes when the
+// configuation variable is false. This mirrors `cfg-attr-multi-true.rs`
+
+// compile-pass
+
+#![warn(unused_must_use)]
+#![feature(cfg_attr_multi)]
+
+#[cfg_attr(any(), deprecated, must_use)]
+struct Struct {}
+
+impl Struct {
+    fn new() -> Struct {
+        Struct {}
+    }
+}
+
+fn main() {
+    Struct::new();
+}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
new file mode 100644 (file)
index 0000000..d4c3186
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// compile-flags: --cfg broken
+
+#![feature(cfg_attr_multi)]
+#![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental
+
+fn main() { }
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
new file mode 100644 (file)
index 0000000..bf68d92
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: no_core is experimental (see issue #29639)
+  --> $DIR/cfg-attr-multi-invalid-1.rs:14:21
+   |
+LL | #![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental
+   |                     ^^^^^^^
+   |
+   = help: add #![feature(no_core)] 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/conditional-compilation/cfg-attr-multi-invalid-2.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
new file mode 100644 (file)
index 0000000..bee6b7d
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// compile-flags: --cfg broken
+
+#![feature(cfg_attr_multi)]
+#![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental
+
+fn main() { }
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
new file mode 100644 (file)
index 0000000..5c72a40
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: no_core is experimental (see issue #29639)
+  --> $DIR/cfg-attr-multi-invalid-2.rs:14:29
+   |
+LL | #![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental
+   |                             ^^^^^^^
+   |
+   = help: add #![feature(no_core)] 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/conditional-compilation/cfg-attr-multi-true.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs
new file mode 100644 (file)
index 0000000..a31dde0
--- /dev/null
@@ -0,0 +1,22 @@
+// Test that cfg_attr with multiple attributes actually emits both attributes.
+// This is done by emitting two attributes that cause new warnings, and then
+// triggering those warnings.
+
+// compile-pass
+
+#![warn(unused_must_use)]
+#![feature(cfg_attr_multi)]
+
+#[cfg_attr(all(), deprecated, must_use)]
+struct MustUseDeprecated {}
+
+impl MustUseDeprecated { //~ warning: use of deprecated item
+    fn new() -> MustUseDeprecated { //~ warning: use of deprecated item
+        MustUseDeprecated {} //~ warning: use of deprecated item
+    }
+}
+
+fn main() {
+    MustUseDeprecated::new(); //~ warning: use of deprecated item
+    //| warning: unused `MustUseDeprecated` which must be used
+}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
new file mode 100644 (file)
index 0000000..37cb3de
--- /dev/null
@@ -0,0 +1,38 @@
+warning: use of deprecated item 'MustUseDeprecated'
+  --> $DIR/cfg-attr-multi-true.rs:13:6
+   |
+LL | impl MustUseDeprecated { //~ warning: use of deprecated item
+   |      ^^^^^^^^^^^^^^^^^
+   |
+   = note: #[warn(deprecated)] on by default
+
+warning: use of deprecated item 'MustUseDeprecated'
+  --> $DIR/cfg-attr-multi-true.rs:20:5
+   |
+LL |     MustUseDeprecated::new(); //~ warning: use of deprecated item
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated item 'MustUseDeprecated'
+  --> $DIR/cfg-attr-multi-true.rs:14:17
+   |
+LL |     fn new() -> MustUseDeprecated { //~ warning: use of deprecated item
+   |                 ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated item 'MustUseDeprecated'
+  --> $DIR/cfg-attr-multi-true.rs:15:9
+   |
+LL |         MustUseDeprecated {} //~ warning: use of deprecated item
+   |         ^^^^^^^^^^^^^^^^^
+
+warning: unused `MustUseDeprecated` which must be used
+  --> $DIR/cfg-attr-multi-true.rs:20:5
+   |
+LL |     MustUseDeprecated::new(); //~ warning: use of deprecated item
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/cfg-attr-multi-true.rs:7:9
+   |
+LL | #![warn(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+
diff --git a/src/test/ui/conditional-compilation/cfg-attr-parse.rs b/src/test/ui/conditional-compilation/cfg-attr-parse.rs
new file mode 100644 (file)
index 0000000..eec0e8f
--- /dev/null
@@ -0,0 +1,45 @@
+// Parse `cfg_attr` with varying numbers of attributes and trailing commas
+
+#![feature(cfg_attr_multi)]
+
+// Completely empty `cfg_attr` input
+#[cfg_attr()] //~ error: expected identifier, found `)`
+struct NoConfigurationPredicate;
+
+// Zero attributes, zero trailing comma (comma manatory here)
+#[cfg_attr(all())] //~ error: expected `,`, found `)`
+struct A0C0;
+
+// Zero attributes, one trailing comma
+#[cfg_attr(all(),)] // Ok
+struct A0C1;
+
+// Zero attributes, two trailing commas
+#[cfg_attr(all(),,)] //~ ERROR expected identifier
+struct A0C2;
+
+// One attribute, no trailing comma
+#[cfg_attr(all(), must_use)] // Ok
+struct A1C0;
+
+// One attribute, one trailing comma
+#[cfg_attr(all(), must_use,)] // Ok
+struct A1C1;
+
+// One attribute, two trailing commas
+#[cfg_attr(all(), must_use,,)] //~ ERROR expected identifier
+struct A1C2;
+
+// Two attributes, no trailing comma
+#[cfg_attr(all(), must_use, deprecated)] // Ok
+struct A2C0;
+
+// Two attributes, one trailing comma
+#[cfg_attr(all(), must_use, deprecated,)] // Ok
+struct A2C1;
+
+// Two attributes, two trailing commas
+#[cfg_attr(all(), must_use, deprecated,,)] //~ ERROR expected identifier
+struct A2C2;
+
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-parse.stderr b/src/test/ui/conditional-compilation/cfg-attr-parse.stderr
new file mode 100644 (file)
index 0000000..553406b
--- /dev/null
@@ -0,0 +1,32 @@
+error: expected identifier, found `)`
+  --> $DIR/cfg-attr-parse.rs:6:12
+   |
+LL | #[cfg_attr()] //~ error: expected identifier, found `)`
+   |            ^ expected identifier
+
+error: expected `,`, found `)`
+  --> $DIR/cfg-attr-parse.rs:10:17
+   |
+LL | #[cfg_attr(all())] //~ error: expected `,`, found `)`
+   |                 ^ expected `,`
+
+error: expected identifier, found `,`
+  --> $DIR/cfg-attr-parse.rs:18:18
+   |
+LL | #[cfg_attr(all(),,)] //~ ERROR expected identifier
+   |                  ^ expected identifier
+
+error: expected identifier, found `,`
+  --> $DIR/cfg-attr-parse.rs:30:28
+   |
+LL | #[cfg_attr(all(), must_use,,)] //~ ERROR expected identifier
+   |                            ^ expected identifier
+
+error: expected identifier, found `,`
+  --> $DIR/cfg-attr-parse.rs:42:40
+   |
+LL | #[cfg_attr(all(), must_use, deprecated,,)] //~ ERROR expected identifier
+   |                                        ^ expected identifier
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.rs b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.rs
new file mode 100644 (file)
index 0000000..06a22ef
--- /dev/null
@@ -0,0 +1,32 @@
+#[cfg] //~ ERROR `cfg` is not followed by parentheses
+struct S1;
+
+#[cfg = 10] //~ ERROR `cfg` is not followed by parentheses
+struct S2;
+
+#[cfg()] //~ ERROR `cfg` predicate is not specified
+struct S3;
+
+#[cfg(a, b)] //~ ERROR multiple `cfg` predicates are specified
+struct S4;
+
+#[cfg("str")] //~ ERROR `cfg` predicate key cannot be a literal
+struct S5;
+
+#[cfg(a::b)] //~ ERROR `cfg` predicate key must be an identifier
+struct S6;
+
+#[cfg(a())] //~ ERROR invalid predicate `a`
+struct S7;
+
+#[cfg(a = 10)] //~ ERROR literal in `cfg` predicate value must be a string
+struct S8;
+
+macro_rules! generate_s9 {
+    ($expr: expr) => {
+        #[cfg(feature = $expr)] //~ ERROR `cfg` is not a well-formed meta-item
+        struct S9;
+    }
+}
+
+generate_s9!(concat!("nonexistent"));
diff --git a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr
new file mode 100644 (file)
index 0000000..7773fdb
--- /dev/null
@@ -0,0 +1,60 @@
+error: `cfg` is not followed by parentheses
+  --> $DIR/cfg-attr-syntax-validation.rs:1:1
+   |
+LL | #[cfg] //~ ERROR `cfg` is not followed by parentheses
+   | ^^^^^^ help: expected syntax is: `cfg(/* predicate */)`
+
+error: `cfg` is not followed by parentheses
+  --> $DIR/cfg-attr-syntax-validation.rs:4:1
+   |
+LL | #[cfg = 10] //~ ERROR `cfg` is not followed by parentheses
+   | ^^^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)`
+
+error: `cfg` predicate is not specified
+  --> $DIR/cfg-attr-syntax-validation.rs:7:1
+   |
+LL | #[cfg()] //~ ERROR `cfg` predicate is not specified
+   | ^^^^^^^^
+
+error: multiple `cfg` predicates are specified
+  --> $DIR/cfg-attr-syntax-validation.rs:10:10
+   |
+LL | #[cfg(a, b)] //~ ERROR multiple `cfg` predicates are specified
+   |          ^
+
+error: `cfg` predicate key cannot be a literal
+  --> $DIR/cfg-attr-syntax-validation.rs:13:7
+   |
+LL | #[cfg("str")] //~ ERROR `cfg` predicate key cannot be a literal
+   |       ^^^^^
+
+error: `cfg` predicate key must be an identifier
+  --> $DIR/cfg-attr-syntax-validation.rs:16:7
+   |
+LL | #[cfg(a::b)] //~ ERROR `cfg` predicate key must be an identifier
+   |       ^^^^
+
+error[E0537]: invalid predicate `a`
+  --> $DIR/cfg-attr-syntax-validation.rs:19:7
+   |
+LL | #[cfg(a())] //~ ERROR invalid predicate `a`
+   |       ^^^
+
+error: literal in `cfg` predicate value must be a string
+  --> $DIR/cfg-attr-syntax-validation.rs:22:11
+   |
+LL | #[cfg(a = 10)] //~ ERROR literal in `cfg` predicate value must be a string
+   |           ^^
+
+error: `cfg` is not a well-formed meta-item
+  --> $DIR/cfg-attr-syntax-validation.rs:27:9
+   |
+LL |         #[cfg(feature = $expr)] //~ ERROR `cfg` is not a well-formed meta-item
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: expected syntax is: `#[cfg(/* predicate */)]`
+...
+LL | generate_s9!(concat!("nonexistent"));
+   | ------------------------------------- in this macro invocation
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0537`.
diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs
new file mode 100644 (file)
index 0000000..afcb896
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! foo {
+    () => {
+        #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
+        fn foo() {}
+    }
+}
+
+foo!();
+
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr
new file mode 100644 (file)
index 0000000..0f51c7d
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+  --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:13:27
+   |
+LL |         #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
+   |                           ^^^^^^^
+...
+LL | foo!();
+   | ------- in this macro invocation
+   |
+   = help: add #![feature(custom_attribute)] 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/conditional-compilation/cfg-empty-codemap.rs b/src/test/ui/conditional-compilation/cfg-empty-codemap.rs
new file mode 100644 (file)
index 0000000..5cf8135
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests that empty source_maps don't ICE (#23301)
+
+// compile-flags: --cfg ""
+
+// error-pattern: invalid `--cfg` argument: `""` (expected `key` or `key="value"`)
+
+pub fn main() {
+}
diff --git a/src/test/ui/conditional-compilation/cfg-in-crate-1.rs b/src/test/ui/conditional-compilation/cfg-in-crate-1.rs
new file mode 100644 (file)
index 0000000..bbccf2b
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern: `main` function not found
+
+#![cfg(bar)]
diff --git a/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr b/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr
new file mode 100644 (file)
index 0000000..c6d42c7
--- /dev/null
@@ -0,0 +1,7 @@
+error[E0601]: `main` function not found in crate `cfg_in_crate_1`
+   |
+   = note: consider adding a `main` function to `$DIR/cfg-in-crate-1.rs`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/conditional-compilation/cfg-non-opt-expr.rs b/src/test/ui/conditional-compilation/cfg-non-opt-expr.rs
new file mode 100644 (file)
index 0000000..55eca7f
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(stmt_expr_attributes)]
+#![feature(custom_test_frameworks)]
+
+fn main() {
+    let _ = #[cfg(unset)] ();
+    //~^ ERROR removing an expression is not supported in this position
+    let _ = 1 + 2 + #[cfg(unset)] 3;
+    //~^ ERROR removing an expression is not supported in this position
+    let _ = [1, 2, 3][#[cfg(unset)] 1];
+    //~^ ERROR removing an expression is not supported in this position
+}
diff --git a/src/test/ui/conditional-compilation/cfg-non-opt-expr.stderr b/src/test/ui/conditional-compilation/cfg-non-opt-expr.stderr
new file mode 100644 (file)
index 0000000..1892cee
--- /dev/null
@@ -0,0 +1,20 @@
+error: removing an expression is not supported in this position
+  --> $DIR/cfg-non-opt-expr.rs:15:13
+   |
+LL |     let _ = #[cfg(unset)] ();
+   |             ^^^^^^^^^^^^^
+
+error: removing an expression is not supported in this position
+  --> $DIR/cfg-non-opt-expr.rs:17:21
+   |
+LL |     let _ = 1 + 2 + #[cfg(unset)] 3;
+   |                     ^^^^^^^^^^^^^
+
+error: removing an expression is not supported in this position
+  --> $DIR/cfg-non-opt-expr.rs:19:23
+   |
+LL |     let _ = [1, 2, 3][#[cfg(unset)] 1];
+   |                       ^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/conditional-compilation/cfg_attr_path.rs b/src/test/ui/conditional-compilation/cfg_attr_path.rs
new file mode 100644 (file)
index 0000000..7d79985
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+#![deny(unused_attributes)] // c.f #35584
+
+mod auxiliary {
+    #[cfg_attr(any(), path = "nonexistent_file.rs")] pub mod namespaced_enums;
+    #[cfg_attr(all(), path = "namespaced_enums.rs")] pub mod nonexistent_file;
+}
+
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
+    let _ = auxiliary::namespaced_enums::Foo::A;
+    let _ = auxiliary::nonexistent_file::Foo::A;
+}
diff --git a/src/test/ui/conditional-compilation/cfg_attr_path.stderr b/src/test/ui/conditional-compilation/cfg_attr_path.stderr
new file mode 100644 (file)
index 0000000..67e59d0
--- /dev/null
@@ -0,0 +1,11 @@
+error: compilation successful
+  --> $DIR/cfg_attr_path.rs:21:1
+   |
+LL | / fn main() { //~ ERROR compilation successful
+LL | |     let _ = auxiliary::namespaced_enums::Foo::A;
+LL | |     let _ = auxiliary::nonexistent_file::Foo::A;
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs
new file mode 100644 (file)
index 0000000..9515380
--- /dev/null
@@ -0,0 +1,5 @@
+// gate-test-cfg_attr_multi
+
+#![cfg_attr(all(), warn(nonstandard_style), allow(unused_attributes))]
+//~^ ERROR cfg_attr with zero or more than one attributes is experimental
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr
new file mode 100644 (file)
index 0000000..088e6df
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: cfg_attr with zero or more than one attributes is experimental (see issue #54881)
+  --> $DIR/feature-gate-cfg-attr-multi-1.rs:3:1
+   |
+LL | #![cfg_attr(all(), warn(nonstandard_style), allow(unused_attributes))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(cfg_attr_multi)] 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-gates/feature-gate-cfg-attr-multi-2.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.rs
new file mode 100644 (file)
index 0000000..cf02432
--- /dev/null
@@ -0,0 +1,3 @@
+#![cfg_attr(all(),)]
+//~^ ERROR cfg_attr with zero or more than one attributes is experimental
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr
new file mode 100644 (file)
index 0000000..a018761
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: cfg_attr with zero or more than one attributes is experimental (see issue #54881)
+  --> $DIR/feature-gate-cfg-attr-multi-2.rs:1:1
+   |
+LL | #![cfg_attr(all(),)]
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(cfg_attr_multi)] 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-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs
new file mode 100644 (file)
index 0000000..e473792
--- /dev/null
@@ -0,0 +1,7 @@
+// Test that settingt the featute gate while using its functionality doesn't error.
+
+// compile-pass
+
+#![cfg_attr(all(), feature(cfg_attr_multi), crate_type="bin")]
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs
new file mode 100644 (file)
index 0000000..df74054
--- /dev/null
@@ -0,0 +1,9 @@
+// Test that settingt the featute gate while using its functionality doesn't error.
+// Specifically, if there's a cfg-attr *before* the feature gate.
+
+// compile-pass
+
+#![cfg_attr(all(),)]
+#![cfg_attr(all(), feature(cfg_attr_multi), crate_type="bin")]
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-tool_lints-fail.rs b/src/test/ui/feature-gates/feature-gate-tool_lints-fail.rs
deleted file mode 100644 (file)
index c311eb7..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[warn(clippy::assign_ops)] //~ ERROR scoped lint `clippy::assign_ops` is experimental
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-tool_lints-fail.stderr b/src/test/ui/feature-gates/feature-gate-tool_lints-fail.stderr
deleted file mode 100644 (file)
index 33ee79c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: scoped lint `clippy::assign_ops` is experimental (see issue #44690)
-  --> $DIR/feature-gate-tool_lints-fail.rs:11:8
-   |
-LL | #[warn(clippy::assign_ops)] //~ ERROR scoped lint `clippy::assign_ops` is experimental
-   |        ^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(tool_lints)] 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-gates/feature-gate-tool_lints.rs b/src/test/ui/feature-gates/feature-gate-tool_lints.rs
deleted file mode 100644 (file)
index 3ef6798..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[warn(clippy::decimal_literal_representation)]
-//~^ ERROR scoped lint `clippy::decimal_literal_representation` is experimental
-fn main() {
-    let a = 65_535;
-}
diff --git a/src/test/ui/feature-gates/feature-gate-tool_lints.stderr b/src/test/ui/feature-gates/feature-gate-tool_lints.stderr
deleted file mode 100644 (file)
index 8019b1e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: scoped lint `clippy::decimal_literal_representation` is experimental (see issue #44690)
-  --> $DIR/feature-gate-tool_lints.rs:11:8
-   |
-LL | #[warn(clippy::decimal_literal_representation)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(tool_lints)] 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/inline-asm-bad-operand.rs b/src/test/ui/inline-asm-bad-operand.rs
new file mode 100644 (file)
index 0000000..37021f3
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the compiler will catch passing invalid values to inline assembly
+// operands.
+
+#![feature(asm)]
+
+#[repr(C)]
+struct MyPtr(usize);
+
+fn main() {
+    issue_37433();
+    issue_37437();
+    issue_40187();
+    issue_54067();
+}
+
+fn issue_37433() {
+    unsafe {
+        asm!("" :: "r"("")); //~ ERROR E0669
+    }
+
+    unsafe {
+        let target = MyPtr(0);
+        asm!("ret" : : "{rdi}"(target)); //~ ERROR E0669
+    }
+}
+
+fn issue_37437() {
+    let hello: &str = "hello";
+    // this should fail...
+    unsafe { asm!("" :: "i"(hello)) }; //~ ERROR E0669
+    // but this should succeed.
+    unsafe { asm!("" :: "r"(hello.as_ptr())) };
+}
+
+fn issue_40187() {
+    let arr: [u8; 1] = [0; 1];
+    unsafe {
+        asm!("movups $1, %xmm0"::"m"(arr)); //~ ERROR E0669
+    }
+}
+
+fn issue_54067() {
+    let addr: Option<u32> = Some(123);
+    unsafe {
+        asm!("mov sp, $0"::"r"(addr)); //~ ERROR E0669
+    }
+}
diff --git a/src/test/ui/inline-asm-bad-operand.stderr b/src/test/ui/inline-asm-bad-operand.stderr
new file mode 100644 (file)
index 0000000..6971215
--- /dev/null
@@ -0,0 +1,33 @@
+error[E0669]: invalid value for constraint in inline assembly
+  --> $DIR/inline-asm-bad-operand.rs:28:9
+   |
+LL |         asm!("" :: "r"("")); //~ ERROR E0669
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error[E0669]: invalid value for constraint in inline assembly
+  --> $DIR/inline-asm-bad-operand.rs:33:9
+   |
+LL |         asm!("ret" : : "{rdi}"(target)); //~ ERROR E0669
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0669]: invalid value for constraint in inline assembly
+  --> $DIR/inline-asm-bad-operand.rs:40:14
+   |
+LL |     unsafe { asm!("" :: "i"(hello)) }; //~ ERROR E0669
+   |              ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0669]: invalid value for constraint in inline assembly
+  --> $DIR/inline-asm-bad-operand.rs:48:9
+   |
+LL |         asm!("movups $1, %xmm0"::"m"(arr)); //~ ERROR E0669
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0669]: invalid value for constraint in inline assembly
+  --> $DIR/inline-asm-bad-operand.rs:55:9
+   |
+LL |         asm!("mov sp, $0"::"r"(addr)); //~ ERROR E0669
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0669`.
index 3a6784eed67dd35d3adaaadb90b1bcd59d38ebc7..362778b26c861911d2624046c87cd15c65d575ea 100644 (file)
@@ -16,22 +16,22 @@ LL |     let b = unsafe { *imm_ref() };
    |                      cannot move out of borrowed content
    |                      help: consider removing the `*`: `imm_ref()`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of dereference of raw pointer
   --> $DIR/issue-20801.rs:42:22
    |
 LL |     let c = unsafe { *mut_ptr() };
    |                      ^^^^^^^^^^
    |                      |
-   |                      cannot move out of borrowed content
+   |                      cannot move out of dereference of raw pointer
    |                      help: consider removing the `*`: `mut_ptr()`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of dereference of raw pointer
   --> $DIR/issue-20801.rs:45:22
    |
 LL |     let d = unsafe { *const_ptr() };
    |                      ^^^^^^^^^^^^
    |                      |
-   |                      cannot move out of borrowed content
+   |                      cannot move out of dereference of raw pointer
    |                      help: consider removing the `*`: `const_ptr()`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/lint/must_use-unit.rs b/src/test/ui/lint/must_use-unit.rs
new file mode 100644 (file)
index 0000000..9256825
--- /dev/null
@@ -0,0 +1,17 @@
+#![feature(never_type)]
+
+#![deny(unused_must_use)]
+
+#[must_use]
+fn foo() {}
+
+#[must_use]
+fn bar() -> ! {
+    unimplemented!()
+}
+
+fn main() {
+    foo(); //~ unused return value of `foo`
+
+    bar(); //~ unused return value of `bar`
+}
diff --git a/src/test/ui/lint/must_use-unit.stderr b/src/test/ui/lint/must_use-unit.stderr
new file mode 100644 (file)
index 0000000..0a956f7
--- /dev/null
@@ -0,0 +1,20 @@
+error: unused return value of `foo` which must be used
+  --> $DIR/must_use-unit.rs:14:5
+   |
+LL |     foo(); //~ unused return value of `foo`
+   |     ^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/must_use-unit.rs:3:9
+   |
+LL | #![deny(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+
+error: unused return value of `bar` which must be used
+  --> $DIR/must_use-unit.rs:16:5
+   |
+LL |     bar(); //~ unused return value of `bar`
+   |     ^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/nll/issue-52663-trait-object.rs b/src/test/ui/nll/issue-52663-trait-object.rs
new file mode 100644 (file)
index 0000000..65d73ee
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(box_syntax)]
+#![feature(nll)]
+
+trait Foo { fn get(&self); }
+
+impl<A> Foo for A {
+    fn get(&self) { }
+}
+
+fn main() {
+    let _ = {
+        let tmp0 = 3;
+        let tmp1 = &tmp0;
+        box tmp1 as Box<Foo + '_>
+    };
+    //~^^^ ERROR `tmp0` does not live long enough
+}
diff --git a/src/test/ui/nll/issue-52663-trait-object.stderr b/src/test/ui/nll/issue-52663-trait-object.stderr
new file mode 100644 (file)
index 0000000..035422f
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0597]: `tmp0` does not live long enough
+  --> $DIR/issue-52663-trait-object.rs:23:20
+   |
+LL |         let tmp1 = &tmp0;
+   |                    ^^^^^ borrowed value does not live long enough
+LL |         box tmp1 as Box<Foo + '_>
+   |         ------------------------- borrow later captured here by trait object
+LL |     };
+   |     - `tmp0` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/resolve/issue-54379.rs b/src/test/ui/resolve/issue-54379.rs
new file mode 100644 (file)
index 0000000..24aa758
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+struct MyStruct {
+    pub s1: Option<String>,
+}
+
+fn main() {
+    let thing = MyStruct { s1: None };
+
+    match thing {
+        MyStruct { .., Some(_) } => {},
+        _ => {}
+    }
+}
diff --git a/src/test/ui/resolve/issue-54379.stderr b/src/test/ui/resolve/issue-54379.stderr
new file mode 100644 (file)
index 0000000..d1d693a
--- /dev/null
@@ -0,0 +1,24 @@
+error: expected `}`, found `,`
+  --> $DIR/issue-54379.rs:18:22
+   |
+LL |         MyStruct { .., Some(_) } => {},
+   |                    --^
+   |                    | |
+   |                    | expected `}`
+   |                    `..` must be at the end and cannot have a trailing comma
+
+error: expected `,`
+  --> $DIR/issue-54379.rs:18:24
+   |
+LL |         MyStruct { .., Some(_) } => {},
+   |                        ^^^^
+
+error[E0027]: pattern does not mention field `s1`
+  --> $DIR/issue-54379.rs:18:9
+   |
+LL |         MyStruct { .., Some(_) } => {},
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ missing field `s1`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0027`.
index f8e5e3914eb3cc2fcb64216e89a2be526ce97eae..11fa447b5489a0e7739e0271bde49cd3a9ff647c 100644 (file)
@@ -4,7 +4,7 @@ error[E0597]: `tmp0` does not live long enough
 LL |         let tmp1 = &tmp0;
    |                    ^^^^^ borrowed value does not live long enough
 LL |         repeater3(tmp1)
-   |         --------------- borrow later used here
+   |         --------------- borrow later captured here by trait object
 LL |     };
    |     - `tmp0` dropped here while still borrowed
 
index ea1efab4cb6f87d8a4ec360f5aad74dd7ebdb386..4134fca1ce6caa31be3d148495cd73e50bef8388 100644 (file)
@@ -10,7 +10,7 @@
 
 // Don't allow tool_lints, which aren't scoped
 
-#![feature(tool_lints)]
+
 #![deny(unknown_lints)]
 
 #![deny(clippy)] //~ ERROR: unknown lint: `clippy`
index 71f90b17c18fcefd792a8d6a36ccbab0779db93d..001f2f11e5cb358c17d94222d0ba3fa9214fb956 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tool_lints)]
+
 
 #[warn(foo::bar)]
 //~^ ERROR an unknown tool name found in scoped lint: `foo::bar`
index 78b736edcebe6e0699beae6d7deb7c789518718a..a1d6c27e518e514268c2221e2e611ea450161d77 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tool_lints)]
+
 
 #![deny(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`