]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #60627 - matklad:test, r=estebank
authorMazdak Farrokhzad <twingoow@gmail.com>
Wed, 8 May 2019 22:58:28 +0000 (00:58 +0200)
committerGitHub <noreply@github.com>
Wed, 8 May 2019 22:58:28 +0000 (00:58 +0200)
test for #50518

It was fixed somewhere between 1.28.0 and 1.31.1

closes #50518

r? @estebank

Where's the best place to add this test? I *think* we want "compile-pass" for this test (no need to run a binary, and not running saves us a millisecond of process creation) , but there's no compile-pass anymore.

Should this be UI test with empty stdout, stderr and zero return code?

121 files changed:
Cargo.lock
appveyor.yml
src/liballoc/lib.rs
src/libcore/mem.rs
src/libcore/num/mod.rs
src/libprofiler_builtins/build.rs
src/librustc/dep_graph/graph.rs
src/librustc/error_codes.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/collector.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/ich/impls_syntax.rs
src/librustc/infer/at.rs
src/librustc/infer/canonical/query_response.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/mod.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/select.rs
src/librustc/traits/util.rs
src/librustc/ty/context.rs
src/librustc/ty/mod.rs
src/librustc/ty/relate.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/ty/subst.rs
src/librustc_codegen_ssa/back/link.rs
src/librustc_codegen_ssa/back/linker.rs
src/librustc_driver/pretty.rs
src/librustc_errors/emitter.rs
src/librustc_errors/lib.rs
src/librustc_interface/passes.rs
src/librustc_lint/builtin.rs
src/librustc_metadata/creader.rs
src/librustc_mir/hair/pattern/check_match.rs
src/librustc_mir/monomorphize/item.rs
src/librustc_target/spec/apple_base.rs
src/librustc_target/spec/i686_apple_darwin.rs
src/librustc_target/spec/x86_64_apple_darwin.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/constrained_generic_params.rs
src/librustc_typeck/variance/constraints.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/static/rustdoc.css
src/libserialize/serialize.rs
src/libstd/Cargo.toml
src/libsyntax/ast.rs
src/libsyntax/feature_gate.rs
src/libsyntax/json.rs
src/libsyntax/mut_visit.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/parser.rs
src/libsyntax/visit.rs
src/libsyntax_pos/hygiene.rs
src/libsyntax_pos/symbol.rs
src/test/codegen/i686-macosx-deployment-target.rs [new file with mode: 0644]
src/test/codegen/i686-no-macosx-deployment-target.rs [new file with mode: 0644]
src/test/codegen/x86_64-macosx-deployment-target.rs [new file with mode: 0644]
src/test/codegen/x86_64-no-macosx-deployment-target.rs [new file with mode: 0644]
src/test/run-make/wasm-export-all-symbols/Makefile
src/test/run-make/wasm-export-all-symbols/main.rs [new file with mode: 0644]
src/test/run-make/wasm-export-all-symbols/verify.js
src/test/run-pass/async-await.rs
src/test/run-pass/await-macro.rs [new file with mode: 0644]
src/test/run-pass/generator/issue-59972.rs [new file with mode: 0644]
src/test/run-pass/issue-55809.rs
src/test/ui/async-await/argument-patterns.rs [new file with mode: 0644]
src/test/ui/async-await/drop-order-for-async-fn-parameters-by-ref-binding.rs [new file with mode: 0644]
src/test/ui/async-await/drop-order-locals-are-hidden.rs
src/test/ui/async-await/drop-order-locals-are-hidden.stderr
src/test/ui/async-await/mutable-arguments.rs [deleted file]
src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.rs [new file with mode: 0644]
src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.stderr [new file with mode: 0644]
src/test/ui/await-keyword/2015-edition-no-warnings-with-feature-gate.rs [deleted file]
src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs [new file with mode: 0644]
src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr [new file with mode: 0644]
src/test/ui/await-keyword/2018-edition-error.rs
src/test/ui/await-keyword/2018-edition-error.stderr
src/test/ui/await-keyword/2018-edition-no-error-with-feature-gate.rs [deleted file]
src/test/ui/await-keyword/post_expansion_error.rs
src/test/ui/await-keyword/post_expansion_error.stderr
src/test/ui/const-generics/concrete-const-as-fn-arg.rs [new file with mode: 0644]
src/test/ui/const-generics/concrete-const-as-fn-arg.stderr [new file with mode: 0644]
src/test/ui/const-generics/concrete-const-impl-method.rs [new file with mode: 0644]
src/test/ui/const-generics/concrete-const-impl-method.stderr [new file with mode: 0644]
src/test/ui/const-generics/const-expression-parameter.rs
src/test/ui/const-generics/const-expression-parameter.stderr
src/test/ui/const-generics/issue-60263.rs [new file with mode: 0644]
src/test/ui/const-generics/issue-60263.stderr [new file with mode: 0644]
src/test/ui/consts/const-eval/unused-broken-const.stderr
src/test/ui/emit-artifact-notifications.nll.stderr [new file with mode: 0644]
src/test/ui/emit-artifact-notifications.rs [new file with mode: 0644]
src/test/ui/emit-artifact-notifications.stderr [new file with mode: 0644]
src/test/ui/emit-directives.rs [deleted file]
src/test/ui/emit-directives.stderr [deleted file]
src/test/ui/feature-gate/await-macro.rs [new file with mode: 0644]
src/test/ui/feature-gate/await-macro.stderr [new file with mode: 0644]
src/test/ui/generator-yielding-or-returning-itself.rs
src/test/ui/generator-yielding-or-returning-itself.stderr
src/test/ui/generator/type-mismatch-signature-deduction.rs [new file with mode: 0644]
src/test/ui/generator/type-mismatch-signature-deduction.stderr [new file with mode: 0644]
src/test/ui/generator/unresolved_type_param.rs
src/test/ui/generator/unresolved_type_param.stderr
src/test/ui/issues/issue-51719.rs [new file with mode: 0644]
src/test/ui/issues/issue-51719.stderr [new file with mode: 0644]
src/test/ui/issues/issue-51751.rs [new file with mode: 0644]
src/test/ui/issues/issue-51751.stderr [new file with mode: 0644]
src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs
src/tools/cargo
src/tools/clippy
src/tools/compiletest/src/header.rs
src/tools/compiletest/src/json.rs
src/tools/compiletest/src/runtest.rs
src/tools/tidy/src/features.rs

index c930b628f4b37cb50b49e6ffaa318c266703bf54..0154b96751d361658b83f5708c57bc85fe504cf8 100644 (file)
@@ -17,7 +17,7 @@ dependencies = [
 name = "alloc"
 version = "0.0.0"
 dependencies = [
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -115,7 +115,7 @@ version = "0.1.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
@@ -271,9 +271,10 @@ dependencies = [
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "opener 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proptest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -449,7 +450,7 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.10"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -735,7 +736,7 @@ name = "dlmalloc"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
@@ -901,7 +902,7 @@ name = "fortanix-sgx-abi"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -1062,7 +1063,7 @@ name = "hashbrown"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-alloc 1.0.0",
  "rustc-std-workspace-core 1.0.0",
 ]
@@ -1688,11 +1689,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "opener"
-version = "0.3.2"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1765,7 +1764,7 @@ dependencies = [
 name = "panic_abort"
 version = "0.0.0"
 dependencies = [
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1775,7 +1774,7 @@ name = "panic_unwind"
 version = "0.0.0"
 dependencies = [
  "alloc 0.0.0",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "unwind 0.0.0",
@@ -1960,7 +1959,7 @@ name = "profiler_builtins"
 version = "0.0.0"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2485,7 +2484,7 @@ name = "rustc-demangle"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -2613,7 +2612,7 @@ dependencies = [
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2843,7 +2842,7 @@ dependencies = [
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2905,7 +2904,7 @@ dependencies = [
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -3022,7 +3021,7 @@ dependencies = [
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -3291,7 +3290,7 @@ dependencies = [
  "alloc 0.0.0",
  "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3883,7 +3882,7 @@ name = "unwind"
 version = "0.0.0"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -4079,7 +4078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
 "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007"
 "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2"
-"checksum compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4ada53ac629568219809178f988ca2aac9889e9a847379588c097d30ce185145"
+"checksum compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6549720ae78db799196d4af8f719facb4c7946710b4b64148482553e54b56d15"
 "checksum compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6"
 "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
 "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
@@ -4202,7 +4201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
 "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113"
-"checksum opener 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "04b1d6b086d9b3009550f9b6f81b10ad9428cf14f404b8e1a3a06f6f012c8ec9"
+"checksum opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "998c59e83d9474c01127a96e023b7a04bb061dd286bf8bb939d31dc8d31a7448"
 "checksum openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9"
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 "checksum openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)" = "26bb632127731bf4ac49bf86a5dde12d2ca0918c2234fc39d79d4da2ccbc6da7"
index be960dc13af57ae5eed3ae4ade16f800b3212af9..dffd79c56e48a70ac26addf789d553601069eed2 100644 (file)
@@ -158,9 +158,9 @@ install:
   # Note that the LLVM installer is an NSIS installer
   #
   # Original downloaded here came from
-  # http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.exe
-  - if NOT defined MINGW_URL appveyor-retry appveyor DownloadFile https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/LLVM-7.0.0-win64.exe
-  - if NOT defined MINGW_URL .\LLVM-7.0.0-win64.exe /S /NCRC /D=C:\clang-rust
+  # http://releases.llvm.org/8.0.0/LLVM-8.0.0-win64.exe
+  - if NOT defined MINGW_URL appveyor-retry appveyor DownloadFile https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/LLVM-8.0.0-win64.exe
+  - if NOT defined MINGW_URL .\LLVM-8.0.0-win64.exe /S /NCRC /D=C:\clang-rust
   - if NOT defined MINGW_URL set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --set llvm.clang-cl=C:\clang-rust\bin\clang-cl.exe
 
   # Here we do a pretty heinous thing which is to mangle the MinGW installation
index eb673488170b64a15d6acc145ddf6465a513d09f..2edd946ff11cfa91ce2c397ec2edd85df0a81582 100644 (file)
@@ -87,7 +87,6 @@
 #![feature(fundamental)]
 #![feature(lang_items)]
 #![feature(libc)]
-#![feature(needs_allocator)]
 #![feature(nll)]
 #![feature(optin_builtin_traits)]
 #![feature(pattern)]
index 5bd442bc0664f12acd7c308ddf374115840d1a2f..9fb071d29524bee5abfc0694c77f155da4a1b405 100644 (file)
@@ -665,8 +665,8 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
 /// let mut v: Vec<i32> = vec![1, 2];
 ///
 /// let old_v = mem::replace(&mut v, vec![3, 4, 5]);
-/// assert_eq!(2, old_v.len());
-/// assert_eq!(3, v.len());
+/// assert_eq!(vec![1, 2], old_v);
+/// assert_eq!(vec![3, 4, 5], v);
 /// ```
 ///
 /// `replace` allows consumption of a struct field by replacing it with another value.
index c1887a93490f85ad3a2fe04d033294492c899914..562a7a4b3c7196d1ef392299b7e68e7de66b3163 100644 (file)
@@ -214,11 +214,31 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 mod wrapping;
 
+macro_rules! usize_isize_to_xe_bytes_doc {
+    () => {"
+
+**Note**: This function returns an array of length 2, 4 or 8 bytes
+depending on the target pointer size.
+
+"}
+}
+
+
+macro_rules! usize_isize_from_xe_bytes_doc {
+    () => {"
+
+**Note**: This function takes an array of length 2, 4 or 8 bytes
+depending on the target pointer size.
+
+"}
+}
+
 // `Int` + `SignedInt` implemented for signed integers
 macro_rules! int_impl {
     ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr, $Feature:expr,
      $EndFeature:expr, $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
-     $reversed:expr, $le_bytes:expr, $be_bytes:expr) => {
+     $reversed:expr, $le_bytes:expr, $be_bytes:expr,
+     $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
         doc_comment! {
             concat!("Returns the smallest value that can be represented by this integer type.
 
@@ -2023,7 +2043,9 @@ pub const fn is_negative(self) -> bool { self < 0 }
         doc_comment! {
             concat!("Return the memory representation of this integer as a byte array in
 big-endian (network) byte order.
-
+",
+$to_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -2041,7 +2063,9 @@ pub const fn is_negative(self) -> bool { self < 0 }
 doc_comment! {
             concat!("Return the memory representation of this integer as a byte array in
 little-endian byte order.
-
+",
+$to_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -2064,7 +2088,9 @@ pub const fn is_negative(self) -> bool { self < 0 }
 As the target platform's native endianness is used, portable code
 should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate,
 instead.
-
+",
+$to_xe_bytes_doc,
+"
 [`to_be_bytes`]: #method.to_be_bytes
 [`to_le_bytes`]: #method.to_le_bytes
 
@@ -2089,7 +2115,9 @@ pub const fn is_negative(self) -> bool { self < 0 }
 doc_comment! {
             concat!("Create an integer value from its representation as a byte array in
 big endian.
-
+",
+$from_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -2120,7 +2148,9 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
             concat!("
 Create an integer value from its representation as a byte array in
 little endian.
-
+",
+$from_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -2157,7 +2187,9 @@ fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 
 [`from_be_bytes`]: #method.from_be_bytes
 [`from_le_bytes`]: #method.from_le_bytes
-
+",
+$from_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -2193,20 +2225,20 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 #[lang = "i8"]
 impl i8 {
     int_impl! { i8, i8, u8, 8, -128, 127, "", "", 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
-        "[0x12]", "[0x12]" }
+        "[0x12]", "[0x12]", "", "" }
 }
 
 #[lang = "i16"]
 impl i16 {
     int_impl! { i16, i16, u16, 16, -32768, 32767, "", "", 4, "-0x5ffd", "0x3a", "0x1234", "0x3412",
-        "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]" }
+        "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
 }
 
 #[lang = "i32"]
 impl i32 {
     int_impl! { i32, i32, u32, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301",
         "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
-        "[0x12, 0x34, 0x56, 0x78]" }
+        "[0x12, 0x34, 0x56, 0x78]", "", "" }
 }
 
 #[lang = "i64"]
@@ -2214,7 +2246,7 @@ impl i64 {
     int_impl! { i64, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "", 12,
          "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412",
          "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-         "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" }
+         "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "" }
 }
 
 #[lang = "i128"]
@@ -2226,14 +2258,15 @@ impl i128 {
         "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
           0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
         "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
-          0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]" }
+          0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "" }
 }
 
 #[cfg(target_pointer_width = "16")]
 #[lang = "isize"]
 impl isize {
     int_impl! { isize, i16, u16, 16, -32768, 32767, "", "", 4, "-0x5ffd", "0x3a", "0x1234",
-        "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]" }
+        "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]",
+        usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
 }
 
 #[cfg(target_pointer_width = "32")]
@@ -2241,7 +2274,8 @@ impl isize {
 impl isize {
     int_impl! { isize, i32, u32, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301",
         "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
-        "[0x12, 0x34, 0x56, 0x78]" }
+        "[0x12, 0x34, 0x56, 0x78]",
+        usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
 }
 
 #[cfg(target_pointer_width = "64")]
@@ -2250,14 +2284,16 @@ impl isize {
     int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "",
         12, "0xaa00000000006e1", "0x6e10aa",  "0x1234567890123456", "0x5634129078563412",
          "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-         "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" }
+         "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+         usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
 }
 
 // `Int` + `UnsignedInt` implemented for unsigned integers
 macro_rules! uint_impl {
     ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr,
         $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
-        $reversed:expr, $le_bytes:expr, $be_bytes:expr) => {
+        $reversed:expr, $le_bytes:expr, $be_bytes:expr,
+        $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
         doc_comment! {
             concat!("Returns the smallest value that can be represented by this integer type.
 
@@ -3817,7 +3853,9 @@ pub fn wrapping_next_power_of_two(self) -> Self {
         doc_comment! {
             concat!("Return the memory representation of this integer as a byte array in
 big-endian (network) byte order.
-
+",
+$to_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -3835,7 +3873,9 @@ pub fn wrapping_next_power_of_two(self) -> Self {
         doc_comment! {
             concat!("Return the memory representation of this integer as a byte array in
 little-endian byte order.
-
+",
+$to_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -3858,7 +3898,9 @@ pub fn wrapping_next_power_of_two(self) -> Self {
 As the target platform's native endianness is used, portable code
 should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate,
 instead.
-
+",
+$to_xe_bytes_doc,
+"
 [`to_be_bytes`]: #method.to_be_bytes
 [`to_le_bytes`]: #method.to_le_bytes
 
@@ -3883,7 +3925,9 @@ pub fn wrapping_next_power_of_two(self) -> Self {
         doc_comment! {
             concat!("Create an integer value from its representation as a byte array in
 big endian.
-
+",
+$from_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -3914,7 +3958,9 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
             concat!("
 Create an integer value from its representation as a byte array in
 little endian.
-
+",
+$from_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -3951,7 +3997,9 @@ fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 
 [`from_be_bytes`]: #method.from_be_bytes
 [`from_le_bytes`]: #method.from_le_bytes
-
+",
+$from_xe_bytes_doc,
+"
 # Examples
 
 ```
@@ -3987,7 +4035,7 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 #[lang = "u8"]
 impl u8 {
     uint_impl! { u8, u8, 8, 255, "", "", 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
-        "[0x12]" }
+        "[0x12]", "", "" }
 
 
     /// Checks if the value is within the ASCII range.
@@ -4506,13 +4554,13 @@ pub fn is_ascii_control(&self) -> bool {
 #[lang = "u16"]
 impl u16 {
     uint_impl! { u16, u16, 16, 65535, "", "", 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
-        "[0x34, 0x12]", "[0x12, 0x34]" }
+        "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
 }
 
 #[lang = "u32"]
 impl u32 {
     uint_impl! { u32, u32, 32, 4294967295, "", "", 8, "0x10000b3", "0xb301", "0x12345678",
-        "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]" }
+        "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" }
 }
 
 #[lang = "u64"]
@@ -4520,7 +4568,8 @@ impl u64 {
     uint_impl! { u64, u64, 64, 18446744073709551615, "", "", 12, "0xaa00000000006e1", "0x6e10aa",
         "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
         "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-        "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" }
+        "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+        "", ""}
 }
 
 #[lang = "u128"]
@@ -4531,20 +4580,23 @@ impl u128 {
         "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
           0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
         "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
-          0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]" }
+          0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
+         "", ""}
 }
 
 #[cfg(target_pointer_width = "16")]
 #[lang = "usize"]
 impl usize {
     uint_impl! { usize, u16, 16, 65535, "", "", 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
-        "[0x34, 0x12]", "[0x12, 0x34]" }
+        "[0x34, 0x12]", "[0x12, 0x34]",
+        usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
 }
 #[cfg(target_pointer_width = "32")]
 #[lang = "usize"]
 impl usize {
     uint_impl! { usize, u32, 32, 4294967295, "", "", 8, "0x10000b3", "0xb301", "0x12345678",
-        "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]" }
+        "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
+        usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
 }
 
 #[cfg(target_pointer_width = "64")]
@@ -4553,7 +4605,8 @@ impl usize {
     uint_impl! { usize, u64, 64, 18446744073709551615, "", "", 12, "0xaa00000000006e1", "0x6e10aa",
         "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
         "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-         "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" }
+         "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+        usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
 }
 
 /// A classification of floating point numbers.
index ff52a03d9dd9725fc0fed1c280be447e1ff7dec9..331edb73d6df96d810393f5c904d5667dd157cc3 100644 (file)
@@ -44,6 +44,19 @@ fn main() {
         cfg.define("COMPILER_RT_HAS_UNAME", Some("1"));
     }
 
+    // Assume that the Unixes we are building this for have fnctl() available
+    if env::var_os("CARGO_CFG_UNIX").is_some() {
+        cfg.define("COMPILER_RT_HAS_FCNTL_LCK", Some("1"));
+    }
+
+    // This should be a pretty good heuristic for when to set
+    // COMPILER_RT_HAS_ATOMICS
+    if env::var_os("CARGO_CFG_TARGET_HAS_ATOMIC").map(|features| {
+        features.to_string_lossy().to_lowercase().contains("cas")
+    }).unwrap_or(false) {
+        cfg.define("COMPILER_RT_HAS_ATOMICS", Some("1"));
+    }
+
     // The source for `compiler-rt` comes from the `compiler-builtins` crate, so
     // load our env var set by cargo to find the source code.
     let root = env::var_os("DEP_COMPILER_RT_COMPILER_RT").unwrap();
index 1ecc580d8c5c436d063b80281fea3b6482c698ca..a87c98a04a4abc64dacb0420b626f8500856df29 100644 (file)
@@ -1021,25 +1021,22 @@ fn complete_task(
     fn complete_anon_task(&mut self, kind: DepKind, task_deps: TaskDeps) -> DepNodeIndex {
         debug_assert!(!kind.is_eval_always());
 
-        let mut fingerprint = self.anon_id_seed;
         let mut hasher = StableHasher::new();
 
-        for &read in task_deps.reads.iter() {
-            let read_dep_node = self.data[read].node;
+        // The dep node indices are hashed here instead of hashing the dep nodes of the
+        // dependencies. These indices may refer to different nodes per session, but this isn't
+        // a problem here because we that ensure the final dep node hash is per session only by
+        // combining it with the per session random number `anon_id_seed`. This hash only need
+        // to map the dependencies to a single value on a per session basis.
+        task_deps.reads.hash(&mut hasher);
 
-            ::std::mem::discriminant(&read_dep_node.kind).hash(&mut hasher);
+        let target_dep_node = DepNode {
+            kind,
 
             // Fingerprint::combine() is faster than sending Fingerprint
             // through the StableHasher (at least as long as StableHasher
             // is so slow).
-            fingerprint = fingerprint.combine(read_dep_node.hash);
-        }
-
-        fingerprint = fingerprint.combine(hasher.finish());
-
-        let target_dep_node = DepNode {
-            kind,
-            hash: fingerprint,
+            hash: self.anon_id_seed.combine(hasher.finish()),
         };
 
         self.intern_node(target_dep_node, task_deps.reads, Fingerprint::ZERO).0
index fd089fc688e32d5db01a66650e90a1dfe0a6bbce..a1bfd417566ad7473f93f8c2696af3674503aa6f 100644 (file)
@@ -2205,4 +2205,6 @@ trait Foo { }
     E0711, // a feature has been declared with conflicting stability attributes
 //  E0702, // replaced with a generic attribute input check
     E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
+    E0727, // `async` generators are not yet supported
+    E0728, // `await` must be in an `async` function or block
 }
index 36e4195c989c0d0eb3a42c62e2ea95b110f4ad06..20e016b8b5b1ea59fe1bca158c679d84d0dcfe3e 100644 (file)
@@ -95,6 +95,7 @@ pub struct LoweringContext<'a> {
     modules: BTreeMap<NodeId, hir::ModuleItems>,
 
     is_generator: bool,
+    is_async_body: bool,
 
     catch_scopes: Vec<NodeId>,
     loop_scopes: Vec<NodeId>,
@@ -248,6 +249,7 @@ pub fn lower_crate(
         item_local_id_counters: Default::default(),
         node_id_to_hir_id: IndexVec::new(),
         is_generator: false,
+        is_async_body: false,
         is_in_trait_impl: false,
         lifetimes_to_define: Vec::new(),
         is_collecting_in_band_lifetimes: false,
@@ -801,8 +803,17 @@ fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> hi
     }
 
     fn record_body(&mut self, value: hir::Expr, arguments: HirVec<hir::Arg>) -> hir::BodyId {
+        if self.is_generator && self.is_async_body {
+            span_err!(
+                self.sess,
+                value.span,
+                E0727,
+                "`async` generators are not yet supported",
+            );
+            self.sess.abort_if_errors();
+        }
         let body = hir::Body {
-            is_generator: self.is_generator,
+            is_generator: self.is_generator || self.is_async_body,
             arguments,
             value,
         };
@@ -1124,7 +1135,8 @@ fn make_async_expr(
         span: Span,
         body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
     ) -> hir::ExprKind {
-        let prev_is_generator = mem::replace(&mut self.is_generator, true);
+        let prev_is_generator = mem::replace(&mut self.is_generator, false);
+        let prev_is_async_body = mem::replace(&mut self.is_async_body, true);
         let output = match ret_ty {
             Some(ty) => FunctionRetTy::Ty(P(ty.clone())),
             None => FunctionRetTy::Default(span),
@@ -1140,6 +1152,7 @@ fn make_async_expr(
         let body_expr = body(self);
         let body_id = self.record_body(body_expr, arguments);
         self.is_generator = prev_is_generator;
+        self.is_async_body = prev_is_async_body;
 
         let capture_clause = self.lower_capture_clause(capture_clause);
         let decl = self.lower_fn_decl(&decl, None, /* impl trait allowed */ false, None);
@@ -1167,11 +1180,13 @@ fn lower_body<F>(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId
     where
         F: FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
     {
-        let prev = mem::replace(&mut self.is_generator, false);
+        let prev_generator = mem::replace(&mut self.is_generator, false);
+        let prev_async = mem::replace(&mut self.is_async_body, false);
         let arguments = self.lower_args(decl);
         let result = f(self);
         let r = self.record_body(result, arguments);
-        self.is_generator = prev;
+        self.is_generator = prev_generator;
+        self.is_async_body = prev_async;
         return r;
     }
 
@@ -4205,6 +4220,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     })
                 })
             }
+            ExprKind::Await(_origin, ref expr) => self.lower_await(e.span, expr),
             ExprKind::Closure(
                 capture_clause, ref asyncness, movability, ref decl, ref body, fn_decl_span
             ) => {
@@ -4326,12 +4342,13 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let id = self.next_id();
                 let e1 = self.lower_expr(e1);
                 let e2 = self.lower_expr(e2);
-                let ty_path = P(self.std_path(e.span, &["ops", "RangeInclusive"], None, false));
-                let ty = P(self.ty_path(id, e.span, hir::QPath::Resolved(None, ty_path)));
-                let new_seg = P(hir::PathSegment::from_ident(Ident::from_str("new")));
-                let new_path = hir::QPath::TypeRelative(ty, new_seg);
-                let new = P(self.expr(e.span, hir::ExprKind::Path(new_path), ThinVec::new()));
-                hir::ExprKind::Call(new, hir_vec![e1, e2])
+                self.expr_call_std_assoc_fn(
+                    id,
+                    e.span,
+                    &["ops", "RangeInclusive"],
+                    "new",
+                    hir_vec![e1, e2],
+                )
             }
             ExprKind::Range(ref e1, ref e2, lims) => {
                 use syntax::ast::RangeLimits::*;
@@ -4468,9 +4485,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let expr = opt_expr
                     .as_ref()
                     .map(|x| self.lower_expr(x))
-                    .unwrap_or_else(||
-                    self.expr(e.span, hir::ExprKind::Tup(hir_vec![]), ThinVec::new())
-                );
+                    .unwrap_or_else(|| self.expr_unit(e.span));
                 hir::ExprKind::Yield(P(expr))
             }
 
@@ -4503,7 +4518,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let body = if let Some(else_expr) = wildcard_arm {
                         P(self.lower_expr(else_expr))
                     } else {
-                        self.expr_tuple(e.span, hir_vec![])
+                        P(self.expr_tuple(e.span, hir_vec![]))
                     };
                     arms.push(self.arm(hir_vec![wildcard_pattern], body));
                 }
@@ -4651,8 +4666,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
                     let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
                     let next_path = &["iter", "Iterator", "next"];
-                    let next_path = P(self.expr_std_path(head_sp, next_path, None, ThinVec::new()));
-                    let next_expr = P(self.expr_call(head_sp, next_path, hir_vec![ref_mut_iter]));
+                    let next_expr = P(self.expr_call_std_path(
+                        head_sp,
+                        next_path,
+                        hir_vec![ref_mut_iter],
+                    ));
                     let arms = hir_vec![pat_arm, break_arm];
 
                     P(self.expr(
@@ -4723,9 +4741,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
                 let into_iter_expr = {
                     let into_iter_path = &["iter", "IntoIterator", "into_iter"];
-                    let into_iter = P(self.expr_std_path(
-                            head_sp, into_iter_path, None, ThinVec::new()));
-                    P(self.expr_call(head_sp, into_iter, hir_vec![head]))
+                    P(self.expr_call_std_path(
+                        head_sp,
+                        into_iter_path,
+                        hir_vec![head],
+                    ))
                 };
 
                 let match_expr = P(self.expr_match(
@@ -4778,9 +4798,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let sub_expr = self.lower_expr(sub_expr);
 
                     let path = &["ops", "Try", "into_result"];
-                    let path = P(self.expr_std_path(
-                            unstable_span, path, None, ThinVec::new()));
-                    P(self.expr_call(e.span, path, hir_vec![sub_expr]))
+                    P(self.expr_call_std_path(
+                        unstable_span,
+                        path,
+                        hir_vec![sub_expr],
+                    ))
                 };
 
                 // `#[allow(unreachable_code)]`
@@ -4817,12 +4839,9 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let err_ident = self.str_to_ident("err");
                     let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
                     let from_expr = {
-                        let path = &["convert", "From", "from"];
-                        let from = P(self.expr_std_path(
-                                try_span, path, None, ThinVec::new()));
+                        let from_path = &["convert", "From", "from"];
                         let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
-
-                        self.expr_call(try_span, from, hir_vec![err_expr])
+                        self.expr_call_std_path(try_span, from_path, hir_vec![err_expr])
                     };
                     let from_err_expr =
                         self.wrap_in_try_constructor("from_error", from_expr, unstable_span);
@@ -5056,6 +5075,42 @@ fn expr_call(
         self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new())
     }
 
+    // Note: associated functions must use `expr_call_std_path`.
+    fn expr_call_std_path(
+        &mut self,
+        span: Span,
+        path_components: &[&str],
+        args: hir::HirVec<hir::Expr>,
+    ) -> hir::Expr {
+        let path = P(self.expr_std_path(span, path_components, None, ThinVec::new()));
+        self.expr_call(span, path, args)
+    }
+
+    // Create an expression calling an associated function of an std type.
+    //
+    // Associated functions cannot be resolved through the normal `std_path` function,
+    // as they are resolved differently and so cannot use `expr_call_std_path`.
+    //
+    // This function accepts the path component (`ty_path_components`) separately from
+    // the name of the associated function (`assoc_fn_name`) in order to facilitate
+    // separate resolution of the type and creation of a path referring to its associated
+    // function.
+    fn expr_call_std_assoc_fn(
+        &mut self,
+        ty_path_id: hir::HirId,
+        span: Span,
+        ty_path_components: &[&str],
+        assoc_fn_name: &str,
+        args: hir::HirVec<hir::Expr>,
+    ) -> hir::ExprKind {
+        let ty_path = P(self.std_path(span, ty_path_components, None, false));
+        let ty = P(self.ty_path(ty_path_id, span, hir::QPath::Resolved(None, ty_path)));
+        let fn_seg = P(hir::PathSegment::from_ident(Ident::from_str(assoc_fn_name)));
+        let fn_path = hir::QPath::TypeRelative(ty, fn_seg);
+        let fn_expr = P(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
+        hir::ExprKind::Call(fn_expr, args)
+    }
+
     fn expr_ident(&mut self, span: Span, ident: Ident, binding: hir::HirId) -> hir::Expr {
         self.expr_ident_with_attrs(span, ident, binding, ThinVec::new())
     }
@@ -5127,8 +5182,12 @@ fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> hir::Ex
         self.expr(b.span, hir::ExprKind::Block(b, None), attrs)
     }
 
-    fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> P<hir::Expr> {
-        P(self.expr(sp, hir::ExprKind::Tup(exprs), ThinVec::new()))
+    fn expr_unit(&mut self, sp: Span) -> hir::Expr {
+        self.expr_tuple(sp, hir_vec![])
+    }
+
+    fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> hir::Expr {
+        self.expr(sp, hir::ExprKind::Tup(exprs), ThinVec::new())
     }
 
     fn expr(&mut self, span: Span, node: hir::ExprKind, attrs: ThinVec<Attribute>) -> hir::Expr {
@@ -5184,6 +5243,23 @@ fn block_all(
         }
     }
 
+    fn expr_unsafe(&mut self, expr: P<hir::Expr>) -> hir::Expr {
+        let hir_id = self.next_id();
+        let span = expr.span;
+        self.expr(
+            span,
+            hir::ExprKind::Block(P(hir::Block {
+                stmts: hir_vec![],
+                expr: Some(expr),
+                hir_id,
+                rules: hir::UnsafeBlock(hir::CompilerGenerated),
+                span,
+                targeted_by_break: false,
+            }), None),
+            ThinVec::new(),
+        )
+    }
+
     fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
         self.pat_std_enum(span, &["result", "Result", "Ok"], hir_vec![pat])
     }
@@ -5258,13 +5334,12 @@ fn std_path(
         span: Span,
         components: &[&str],
         params: Option<P<hir::GenericArgs>>,
-        is_value: bool
+        is_value: bool,
     ) -> hir::Path {
         let mut path = self.resolver
             .resolve_str_path(span, self.crate_root, components, is_value);
         path.segments.last_mut().unwrap().args = params;
 
-
         for seg in path.segments.iter_mut() {
             if seg.hir_id.is_some() {
                 seg.hir_id = Some(self.next_id());
@@ -5465,6 +5540,175 @@ fn wrap_in_try_constructor(
                                             ThinVec::new()));
         P(self.expr_call(e.span, from_err, hir_vec![e]))
     }
+
+    fn lower_await(
+        &mut self,
+        await_span: Span,
+        expr: &ast::Expr,
+    ) -> hir::ExprKind {
+        // to:
+        //
+        // {
+        //     let mut pinned = <expr>;
+        //     loop {
+        //         match ::std::future::poll_with_tls_context(unsafe {
+        //             ::std::pin::Pin::new_unchecked(&mut pinned)
+        //         }) {
+        //             ::std::task::Poll::Ready(x) => break x,
+        //             ::std::task::Poll::Pending => {},
+        //         }
+        //         yield ();
+        //     }
+        // }
+        if !self.is_async_body {
+            span_err!(
+                self.sess,
+                await_span,
+                E0728,
+                "`await` is only allowed inside `async` functions and blocks"
+            );
+            self.sess.abort_if_errors();
+        }
+        let span = self.mark_span_with_reason(
+            CompilerDesugaringKind::Await,
+            await_span,
+            None,
+        );
+        let gen_future_span = self.mark_span_with_reason(
+            CompilerDesugaringKind::Await,
+            await_span,
+            Some(vec![Symbol::intern("gen_future")].into()),
+        );
+
+        // let mut pinned = <expr>;
+        let expr = P(self.lower_expr(expr));
+        let pinned_ident = self.str_to_ident("pinned");
+        let (pinned_pat, pinned_pat_hid) = self.pat_ident_binding_mode(
+            span,
+            pinned_ident,
+            hir::BindingAnnotation::Mutable,
+        );
+        let pinned_let = self.stmt_let_pat(
+            span,
+            Some(expr),
+            pinned_pat,
+            hir::LocalSource::AwaitDesugar,
+        );
+
+        // ::std::future::poll_with_tls_context(unsafe {
+        //     ::std::pin::Pin::new_unchecked(&mut pinned)
+        // })`
+        let poll_expr = {
+            let pinned = P(self.expr_ident(span, pinned_ident, pinned_pat_hid));
+            let ref_mut_pinned = self.expr_mut_addr_of(span, pinned);
+            let pin_ty_id = self.next_id();
+            let new_unchecked_expr_kind = self.expr_call_std_assoc_fn(
+                pin_ty_id,
+                span,
+                &["pin", "Pin"],
+                "new_unchecked",
+                hir_vec![ref_mut_pinned],
+            );
+            let new_unchecked = P(self.expr(span, new_unchecked_expr_kind, ThinVec::new()));
+            let unsafe_expr = self.expr_unsafe(new_unchecked);
+            P(self.expr_call_std_path(
+                gen_future_span,
+                &["future", "poll_with_tls_context"],
+                hir_vec![unsafe_expr],
+            ))
+        };
+
+        // `::std::task::Poll::Ready(x) => break x`
+        let loop_node_id = self.sess.next_node_id();
+        let loop_hir_id = self.lower_node_id(loop_node_id);
+        let ready_arm = {
+            let x_ident = self.str_to_ident("x");
+            let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
+            let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid));
+            let ready_pat = self.pat_std_enum(
+                span,
+                &["task", "Poll", "Ready"],
+                hir_vec![x_pat],
+            );
+            let break_x = self.with_loop_scope(loop_node_id, |this| {
+                let expr_break = hir::ExprKind::Break(
+                    this.lower_loop_destination(None),
+                    Some(x_expr),
+                );
+                P(this.expr(await_span, expr_break, ThinVec::new()))
+            });
+            self.arm(hir_vec![ready_pat], break_x)
+        };
+
+        // `::std::task::Poll::Pending => {}`
+        let pending_arm = {
+            let pending_pat = self.pat_std_enum(
+                span,
+                &["task", "Poll", "Pending"],
+                hir_vec![],
+            );
+            let empty_block = P(hir::Block {
+                stmts: hir_vec![],
+                expr: None,
+                hir_id: self.next_id(),
+                rules: hir::DefaultBlock,
+                span,
+                targeted_by_break: false,
+            });
+            let empty_block = P(self.expr_block(empty_block, ThinVec::new()));
+            self.arm(hir_vec![pending_pat], empty_block)
+        };
+
+        let match_stmt = {
+            let match_expr = P(self.expr_match(
+                span,
+                poll_expr,
+                hir_vec![ready_arm, pending_arm],
+                hir::MatchSource::AwaitDesugar,
+            ));
+            hir::Stmt {
+                hir_id: self.next_id(),
+                node: hir::StmtKind::Expr(match_expr),
+                span,
+            }
+        };
+
+        let yield_stmt = {
+            let unit = self.expr_unit(span);
+            let yield_expr = P(self.expr(
+                span,
+                hir::ExprKind::Yield(P(unit)),
+                ThinVec::new(),
+            ));
+            hir::Stmt {
+                hir_id: self.next_id(),
+                node: hir::StmtKind::Expr(yield_expr),
+                span,
+            }
+        };
+
+        let loop_block = P(self.block_all(
+            span,
+            hir_vec![match_stmt, yield_stmt],
+            None,
+        ));
+
+        let loop_expr = P(hir::Expr {
+            hir_id: loop_hir_id,
+            node: hir::ExprKind::Loop(
+                loop_block,
+                None,
+                hir::LoopSource::Loop,
+            ),
+            span,
+            attrs: ThinVec::new(),
+        });
+
+        hir::ExprKind::Block(
+            P(self.block_all(span, hir_vec![pinned_let], Some(loop_expr))),
+            None,
+        )
+    }
 }
 
 fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
index 50bd89a1589645d688d15ff719d2366d51afeb14..136d683e76b483abc2af87c4d7a7fa02d957ebb9 100644 (file)
@@ -1,9 +1,11 @@
 use super::*;
 use crate::dep_graph::{DepGraph, DepKind, DepNodeIndex};
 use crate::hir;
+use crate::hir::map::HirEntryMap;
 use crate::hir::def_id::{LOCAL_CRATE, CrateNum};
 use crate::hir::intravisit::{Visitor, NestedVisitorMap};
 use rustc_data_structures::svh::Svh;
+use rustc_data_structures::indexed_vec::IndexVec;
 use crate::ich::Fingerprint;
 use crate::middle::cstore::CrateStore;
 use crate::session::CrateDisambiguator;
@@ -12,6 +14,7 @@
 use syntax::ast::NodeId;
 use syntax::source_map::SourceMap;
 use syntax_pos::Span;
+use std::iter::repeat;
 
 use crate::ich::StableHashingContext;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
@@ -25,7 +28,7 @@ pub(super) struct NodeCollector<'a, 'hir> {
     source_map: &'a SourceMap,
 
     /// The node map
-    map: FxHashMap<HirId, Entry<'hir>>,
+    map: HirEntryMap<'hir>,
     /// The parent of this node
     parent_node: hir::HirId,
 
@@ -142,11 +145,15 @@ pub(super) fn root(sess: &'a Session,
             );
         }
 
+        let (lo, hi) = definitions.def_index_counts_lo_hi();
+
         let mut collector = NodeCollector {
             krate,
             source_map: sess.source_map(),
-            map: FxHashMap::with_capacity_and_hasher(sess.current_node_id_count(),
-                Default::default()),
+            map: [
+                repeat(None).take(lo).collect(),
+                repeat(None).take(hi).collect(),
+            ],
             parent_node: hir::CRATE_HIR_ID,
             current_signature_dep_index: root_mod_sig_dep_index,
             current_full_dep_index: root_mod_full_dep_index,
@@ -171,7 +178,7 @@ pub(super) fn finalize_and_compute_crate_hash(mut self,
                                                   crate_disambiguator: CrateDisambiguator,
                                                   cstore: &dyn CrateStore,
                                                   commandline_args_hash: u64)
-                                                  -> (FxHashMap<HirId, Entry<'hir>>, Svh)
+                                                  -> (HirEntryMap<'hir>, Svh)
     {
         self.hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
 
@@ -224,7 +231,17 @@ pub(super) fn finalize_and_compute_crate_hash(mut self,
 
     fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>) {
         debug!("hir_map: {:?} => {:?}", id, entry);
-        self.map.insert(id, entry);
+        let local_map = &mut self.map[id.owner.address_space().index()][id.owner.as_array_index()];
+        let i = id.local_id.as_u32() as usize;
+        if local_map.is_none() {
+            *local_map = Some(IndexVec::with_capacity(i + 1));
+        }
+        let local_map = local_map.as_mut().unwrap();
+        let len = local_map.len();
+        if i >= len {
+            local_map.extend(repeat(None).take(i - len + 1));
+        }
+        local_map[id.local_id] = Some(entry);
     }
 
     fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
index a59170e96669c3d1e7ec790576c4b246c2934e8e..c2b513a39a8b7b520bc0f8e325dcde04eca3f6e6 100644 (file)
@@ -11,6 +11,7 @@
 
 use rustc_target::spec::abi::Abi;
 use rustc_data_structures::svh::Svh;
+use rustc_data_structures::indexed_vec::IndexVec;
 use syntax::ast::{self, Name, NodeId};
 use syntax::source_map::Spanned;
 use syntax::ext::base::MacroKind;
@@ -161,6 +162,13 @@ pub fn untracked_krate<'hir>(&'hir self) -> &'hir Crate {
     }
 }
 
+/// This type is effectively a `HashMap<HirId, Entry<'hir>>`,
+/// but is implemented by 3 layers of arrays.
+/// - the outer layer is `[A; 2]` and correspond to the 2 address spaces `DefIndex`es can be in
+/// - then we have `A = Vec<Option<B>>` mapping a `DefIndex`'s index to a inner value
+/// - which is `B = IndexVec<ItemLocalId, Option<Entry<'hir>>` which finally gives you the `Entry`.
+pub(super) type HirEntryMap<'hir> = [Vec<Option<IndexVec<ItemLocalId, Option<Entry<'hir>>>>>; 2];
+
 /// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s.
 #[derive(Clone)]
 pub struct Map<'hir> {
@@ -174,7 +182,7 @@ pub struct Map<'hir> {
     /// The SVH of the local crate.
     pub crate_hash: Svh,
 
-    map: FxHashMap<HirId, Entry<'hir>>,
+    map: HirEntryMap<'hir>,
 
     definitions: &'hir Definitions,
 
@@ -183,6 +191,12 @@ pub struct Map<'hir> {
 }
 
 impl<'hir> Map<'hir> {
+    #[inline]
+    fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> {
+        let local_map = self.map[id.owner.address_space().index()].get(id.owner.as_array_index())?;
+        local_map.as_ref()?.get(id.local_id)?.as_ref()
+    }
+
     /// Registers a read in the dependency graph of the AST node with
     /// the given `id`. This needs to be called each time a public
     /// function returns the HIR for a node -- in other words, when it
@@ -191,7 +205,7 @@ impl<'hir> Map<'hir> {
     /// read recorded). If the function just returns a DefId or
     /// NodeId, no actual content was returned, so no read is needed.
     pub fn read(&self, hir_id: HirId) {
-        if let Some(entry) = self.map.get(&hir_id) {
+        if let Some(entry) = self.lookup(hir_id) {
             self.dep_graph.read_index(entry.dep_node);
         } else {
             bug!("called `HirMap::read()` with invalid `HirId`: {:?}", hir_id)
@@ -378,12 +392,8 @@ fn def_kind(&self, node_id: NodeId) -> Option<DefKind> {
         })
     }
 
-    fn entry_count(&self) -> usize {
-        self.map.len()
-    }
-
     fn find_entry(&self, id: HirId) -> Option<Entry<'hir>> {
-        self.map.get(&id).cloned()
+        self.lookup(id).cloned()
     }
 
     pub fn krate(&self) -> &'hir Crate {
@@ -433,7 +443,7 @@ pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<FnDecl> {
     /// item (possibly associated), a closure, or a `hir::AnonConst`.
     pub fn body_owner(&self, BodyId { hir_id }: BodyId) -> NodeId {
         let parent = self.get_parent_node_by_hir_id(hir_id);
-        assert!(self.map.get(&parent).map_or(false, |e| e.is_body_owner(hir_id)));
+        assert!(self.lookup(parent).map_or(false, |e| e.is_body_owner(hir_id)));
         self.hir_to_node_id(parent)
     }
 
@@ -1004,6 +1014,34 @@ pub fn attrs_by_hir_id(&self, id: HirId) -> &'hir [ast::Attribute] {
         attrs.unwrap_or(&[])
     }
 
+    /// Returns an iterator that yields all the hir ids in the map.
+    fn all_ids<'a>(&'a self) -> impl Iterator<Item = HirId> + 'a {
+        // This code is a bit awkward because the map is implemented as 3 levels of arrays,
+        // see the comment on `HirEntryMap`.
+        let map = &self.map;
+
+        // Look at both the def index address spaces
+        let spaces = [DefIndexAddressSpace::Low, DefIndexAddressSpace::High].iter().cloned();
+        spaces.flat_map(move |space| {
+            // Iterate over all the indices in the address space and return a reference to
+            // local maps and their index given that they exist.
+            let local_maps = map[space.index()].iter().enumerate().filter_map(|(i, local_map)| {
+                local_map.as_ref().map(|m| (i, m))
+            });
+
+            local_maps.flat_map(move |(array_index, local_map)| {
+                // Iterate over each valid entry in the local map
+                local_map.iter_enumerated().filter_map(move |(i, entry)| entry.map(move |_| {
+                    // Reconstruct the HirId based on the 3 indices we used to find it
+                    HirId {
+                        owner: DefIndex::from_array_index(array_index, space),
+                        local_id: i,
+                    }
+                }))
+            })
+        })
+    }
+
     /// Returns an iterator that yields the node id's with paths that
     /// match `parts`.  (Requires `parts` is non-empty.)
     ///
@@ -1012,13 +1050,16 @@ pub fn attrs_by_hir_id(&self, id: HirId) -> &'hir [ast::Attribute] {
     /// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and
     /// any other such items it can find in the map.
     pub fn nodes_matching_suffix<'a>(&'a self, parts: &'a [String])
-                                 -> NodesMatchingSuffix<'a, 'hir> {
-        NodesMatchingSuffix {
+                                 -> impl Iterator<Item = NodeId> + 'a {
+        let nodes = NodesMatchingSuffix {
             map: self,
             item_name: parts.last().unwrap(),
             in_which: &parts[..parts.len() - 1],
-            idx: ast::CRATE_NODE_ID,
-        }
+        };
+
+        self.all_ids().filter(move |hir| nodes.matces_suffix(*hir)).map(move |hir| {
+            self.hir_to_node_id(hir)
+        })
     }
 
     pub fn span(&self, id: NodeId) -> Span {
@@ -1097,21 +1138,20 @@ pub fn hir_to_pretty_string(&self, id: HirId) -> String {
     }
 }
 
-pub struct NodesMatchingSuffix<'a, 'hir:'a> {
-    map: &'a Map<'hir>,
+pub struct NodesMatchingSuffix<'a> {
+    map: &'a Map<'a>,
     item_name: &'a String,
     in_which: &'a [String],
-    idx: NodeId,
 }
 
-impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> {
+impl<'a> NodesMatchingSuffix<'a> {
     /// Returns `true` only if some suffix of the module path for parent
     /// matches `self.in_which`.
     ///
     /// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`;
     /// returns true if parent's path ends with the suffix
     /// `x_0::x_1::...::x_k`.
-    fn suffix_matches(&self, parent: NodeId) -> bool {
+    fn suffix_matches(&self, parent: HirId) -> bool {
         let mut cursor = parent;
         for part in self.in_which.iter().rev() {
             let (mod_id, mod_name) = match find_first_mod_parent(self.map, cursor) {
@@ -1121,7 +1161,7 @@ fn suffix_matches(&self, parent: NodeId) -> bool {
             if mod_name != &**part {
                 return false;
             }
-            cursor = self.map.get_parent(mod_id);
+            cursor = self.map.get_parent_item(mod_id);
         }
         return true;
 
@@ -1131,14 +1171,14 @@ fn suffix_matches(&self, parent: NodeId) -> bool {
         // If `id` itself is a mod named `m` with parent `p`, then
         // returns `Some(id, m, p)`.  If `id` has no mod in its parent
         // chain, then returns `None`.
-        fn find_first_mod_parent<'a>(map: &'a Map<'_>, mut id: NodeId) -> Option<(NodeId, Name)> {
+        fn find_first_mod_parent<'a>(map: &'a Map<'_>, mut id: HirId) -> Option<(HirId, Name)> {
             loop {
-                if let Node::Item(item) = map.find(id)? {
+                if let Node::Item(item) = map.find_by_hir_id(id)? {
                     if item_is_mod(&item) {
                         return Some((id, item.ident.name))
                     }
                 }
-                let parent = map.get_parent(id);
+                let parent = map.get_parent_item(id);
                 if parent == id { return None }
                 id = parent;
             }
@@ -1154,35 +1194,21 @@ fn item_is_mod(item: &Item) -> bool {
 
     // We are looking at some node `n` with a given name and parent
     // id; do their names match what I am seeking?
-    fn matches_names(&self, parent_of_n: NodeId, name: Name) -> bool {
+    fn matches_names(&self, parent_of_n: HirId, name: Name) -> bool {
         name == &**self.item_name && self.suffix_matches(parent_of_n)
     }
-}
 
-impl<'a, 'hir> Iterator for NodesMatchingSuffix<'a, 'hir> {
-    type Item = NodeId;
-
-    fn next(&mut self) -> Option<NodeId> {
-        loop {
-            let idx = self.idx;
-            if idx.as_usize() >= self.map.entry_count() {
-                return None;
-            }
-            self.idx = NodeId::from_u32(self.idx.as_u32() + 1);
-            let hir_idx = self.map.node_to_hir_id(idx);
-            let name = match self.map.find_entry(hir_idx).map(|entry| entry.node) {
-                Some(Node::Item(n)) => n.name(),
-                Some(Node::ForeignItem(n)) => n.name(),
-                Some(Node::TraitItem(n)) => n.name(),
-                Some(Node::ImplItem(n)) => n.name(),
-                Some(Node::Variant(n)) => n.name(),
-                Some(Node::Field(n)) => n.name(),
-                _ => continue,
-            };
-            if self.matches_names(self.map.get_parent(idx), name) {
-                return Some(idx)
-            }
-        }
+    fn matces_suffix(&self, hir: HirId) -> bool {
+        let name = match self.map.find_entry(hir).map(|entry| entry.node) {
+            Some(Node::Item(n)) => n.name(),
+            Some(Node::ForeignItem(n)) => n.name(),
+            Some(Node::TraitItem(n)) => n.name(),
+            Some(Node::ImplItem(n)) => n.name(),
+            Some(Node::Variant(n)) => n.name(),
+            Some(Node::Field(n)) => n.name(),
+            _ => return false,
+        };
+        self.matches_names(self.map.get_parent_item(hir), name)
     }
 }
 
index 1e357e1341710578392e22fab8e635db9cca9be9..01de7917e6e238224a7526acd53c46531be7f9bb 100644 (file)
@@ -1606,6 +1606,8 @@ pub enum LocalSource {
     /// }
     /// ```
     AsyncFn,
+    /// A desugared `<expr>.await`.
+    AwaitDesugar,
 }
 
 /// Hints at the original code for a `match _ { .. }`.
@@ -1624,6 +1626,8 @@ pub enum MatchSource {
     ForLoopDesugar,
     /// A desugared `?` operator.
     TryDesugar,
+    /// A desugared `<expr>.await`.
+    AwaitDesugar,
 }
 
 /// The loop type that yielded an `ExprKind::Loop`.
index 40cce8e77c0e049028d51d44bc9f8879ef43d226..90dd5099cbfd69d0f0faf21d11ffe19b2eca6d09 100644 (file)
@@ -396,6 +396,7 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
 
 impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind {
     Async,
+    Await,
     QuestionMark,
     ExistentialReturnType,
     ForLoop,
index 34cd3ae5427e0ff849f6456615533a396bb3f5a6..577211088929025ba2c06ac70fba2b231630dab9 100644 (file)
@@ -27,6 +27,7 @@
 
 use super::*;
 
+use crate::ty::Const;
 use crate::ty::relate::{Relate, TypeRelation};
 
 pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
@@ -308,6 +309,20 @@ fn to_trace(cause: &ObligationCause<'tcx>,
     }
 }
 
+impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>,
+                a_is_expected: bool,
+                a: Self,
+                b: Self)
+                -> TypeTrace<'tcx>
+    {
+        TypeTrace {
+            cause: cause.clone(),
+            values: Consts(ExpectedFound::new(a_is_expected, a, b))
+        }
+    }
+}
+
 impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>,
                 a_is_expected: bool,
index 8225ed70c5827b283f06748bf8ff21a71f1b03bd..413c1428ff954e13f09275edaec37d364fc03f0b 100644 (file)
@@ -318,8 +318,9 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
                     obligations.extend(ok.into_obligations());
                 }
 
-                (UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
-                    unimplemented!() // FIXME(const_generics)
+                (UnpackedKind::Const(v1), UnpackedKind::Const(v2)) => {
+                    let ok = self.at(cause, param_env).eq(v1, v2)?;
+                    obligations.extend(ok.into_obligations());
                 }
 
                 _ => {
@@ -626,8 +627,9 @@ fn unify_canonical_vars(
                         obligations
                             .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
                     }
-                    (UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
-                        unimplemented!() // FIXME(const_generics)
+                    (UnpackedKind::Const(v1), UnpackedKind::Const(v2)) => {
+                        let ok = self.at(cause, param_env).eq(v1, v2)?;
+                        obligations.extend(ok.into_obligations());
                     }
                     _ => {
                         bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
index 95b566d4a1b6933736e3c4fc12756e5f7bd7974f..4b6e7da333081891add336eb6ac22a3fd79f80b0 100644 (file)
@@ -1260,6 +1260,7 @@ fn values_str(
         match *values {
             infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found),
             infer::Regions(ref exp_found) => self.expected_found_str(exp_found),
+            infer::Consts(ref exp_found) => self.expected_found_str(exp_found),
             infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found),
             infer::PolyTraitRefs(ref exp_found) => self.expected_found_str(exp_found),
         }
index 5846e604cfc09b046d1f0c75a791f199572cac0d..b5a9184079aa66b42713b6c5101c8e4f41133c2c 100644 (file)
@@ -232,6 +232,7 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
 pub enum ValuePairs<'tcx> {
     Types(ExpectedFound<Ty<'tcx>>),
     Regions(ExpectedFound<ty::Region<'tcx>>),
+    Consts(ExpectedFound<&'tcx ty::Const<'tcx>>),
     TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
     PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
 }
@@ -1730,6 +1731,7 @@ pub fn span(&self) -> Span {
     impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
         (ValuePairs::Types)(a),
         (ValuePairs::Regions)(a),
+        (ValuePairs::Consts)(a),
         (ValuePairs::TraitRefs)(a),
         (ValuePairs::PolyTraitRefs)(a),
     }
index 084a5429f26fa89945b8f7596983cacd7dd1fdc5..12427daa38381d2baea1549380f2458bd9589754 100644 (file)
@@ -1462,8 +1462,8 @@ fn parse_merge_functions(slot: &mut Option<MergeFunctions>, v: Option<&str>) ->
          the same values as the target option of the same name"),
     allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
         "only allow the listed language features to be enabled in code (space separated)"),
-    emit_directives: bool = (false, parse_bool, [UNTRACKED],
-        "emit build directives if producing JSON output"),
+    emit_artifact_notifications: bool = (false, parse_bool, [UNTRACKED],
+        "emit notifications after each artifact has been output (only in the JSON format)"),
 }
 
 pub fn default_lib_output() -> CrateType {
index ad8825bc5de5a2ebc01a089c2c169a76d1850b7f..e8c7965ab4f45835c196bdff7909b22b7d3ee480 100644 (file)
@@ -408,9 +408,6 @@ pub fn reserve_node_ids(&self, count: usize) -> ast::NodeId {
     pub fn next_node_id(&self) -> NodeId {
         self.reserve_node_ids(1)
     }
-    pub(crate) fn current_node_id_count(&self) -> usize {
-        self.next_node_id.get().as_u32() as usize
-    }
     pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
         &self.parse_sess.span_diagnostic
     }
index 007ff32f32776a1229a2c34e94d815173441df95..d9ccbba69d5c09e61c11c63d7b996f6bb1a76e1d 100644 (file)
@@ -1453,7 +1453,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ParamToVarFolder<'a, 'gcx, 'tcx>
             fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.infcx.tcx }
 
             fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-                if let ty::Param(ty::ParamTy {name, ..}) = ty.sty {
+                if let ty::Param(ty::ParamTy {name, .. }) = ty.sty {
                     let infcx = self.infcx;
                     self.var_map.entry(ty).or_insert_with(||
                         infcx.next_ty_var(
index f0c402789c4cd192428a241e4493672c4ce08715..d68e2be9ea0860ef2439c4d6b5c9ee7873f6ebd7 100644 (file)
@@ -3424,7 +3424,7 @@ fn confirm_builtin_unsize_candidate(
                 let mut found = false;
                 for ty in field.walk() {
                     if let ty::Param(p) = ty.sty {
-                        ty_params.insert(p.idx as usize);
+                        ty_params.insert(p.index as usize);
                         found = true;
                     }
                 }
index 90f62a4d132c7c1731a9c93d751090cda5ff70f7..be29ea5701b2f70371fd80936639fc9e78ae5bbe 100644 (file)
@@ -204,7 +204,7 @@ fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
                            },
 
                            Component::Param(p) => {
-                               let ty = tcx.mk_ty_param(p.idx, p.name);
+                               let ty = tcx.mk_ty_param(p.index, p.name);
                                Some(ty::Predicate::TypeOutlives(
                                    ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min))))
                            },
index 19440d0bc64ea3456a4d5c8efeab23154034efb0..15524ca6e930ce322cd74cd3ad9050688e7bea76 100644 (file)
@@ -2715,10 +2715,8 @@ pub fn mk_const_infer(
     }
 
     #[inline]
-    pub fn mk_ty_param(self,
-                       index: u32,
-                       name: InternedString) -> Ty<'tcx> {
-        self.mk_ty(Param(ParamTy { idx: index, name: name }))
+    pub fn mk_ty_param(self, index: u32, name: InternedString) -> Ty<'tcx> {
+        self.mk_ty(Param(ParamTy { index, name: name }))
     }
 
     #[inline]
index cb92e4b7470a58640d2625c44fd61325ea5148e7..7b749957c3ff5e8f4ad728bcda0addc6f3a5cc85 100644 (file)
@@ -979,7 +979,7 @@ pub fn type_param(&'tcx self,
                       param: &ParamTy,
                       tcx: TyCtxt<'a, 'gcx, 'tcx>)
                       -> &'tcx GenericParamDef {
-        if let Some(index) = param.idx.checked_sub(self.parent_count as u32) {
+        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
             let param = &self.params[index as usize];
             match param.kind {
                 GenericParamDefKind::Type { .. } => param,
index d7b19070741955075e205afe50b5f4ae1e47e477..2049341327495bc822005f99a131df03f1ef1542 100644 (file)
@@ -390,7 +390,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
         }
 
         (&ty::Param(ref a_p), &ty::Param(ref b_p))
-            if a_p.idx == b_p.idx =>
+            if a_p.index == b_p.index =>
         {
             Ok(a)
         }
index bab9527dd07f6695793a6b641252bef5c8e7c288..cf04d6eac3ae0b608db0fd0168be15138edd7a83 100644 (file)
@@ -6,7 +6,7 @@
 use crate::hir::def::Namespace;
 use crate::mir::ProjectionKind;
 use crate::mir::interpret::ConstValue;
-use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid};
+use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use crate::ty::print::{FmtPrinter, Printer};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -240,7 +240,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 impl fmt::Debug for ty::ParamTy {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}/#{}", self.name, self.idx)
+        write!(f, "{}/#{}", self.name, self.index)
     }
 }
 
@@ -1352,8 +1352,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         match *self {
             ConstValue::ByRef(ptr, alloc) => ConstValue::ByRef(ptr, alloc),
-            // FIXME(const_generics): implement TypeFoldable for InferConst
-            ConstValue::Infer(ic) => ConstValue::Infer(ic),
+            ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)),
             ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)),
             ConstValue::Placeholder(p) => ConstValue::Placeholder(p),
             ConstValue::Scalar(a) => ConstValue::Scalar(a),
@@ -1366,8 +1365,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
         match *self {
             ConstValue::ByRef(..) => false,
-            // FIXME(const_generics): implement TypeFoldable for InferConst
-            ConstValue::Infer(_) => false,
+            ConstValue::Infer(ic) => ic.visit_with(visitor),
             ConstValue::Param(p) => p.visit_with(visitor),
             ConstValue::Placeholder(_) => false,
             ConstValue::Scalar(_) => false,
@@ -1376,3 +1374,13 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
         }
     }
 }
+
+impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
+    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
+        *self
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
+        false
+    }
+}
index cca40c379fc110e99f8d54a5a36b780644adf33d..760f3d60d0571c3a6c8a375fc203a65269d0c901 100644 (file)
@@ -1111,13 +1111,13 @@ pub fn abi(&self) -> abi::Abi {
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
          Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ParamTy {
-    pub idx: u32,
+    pub index: u32,
     pub name: InternedString,
 }
 
 impl<'a, 'gcx, 'tcx> ParamTy {
     pub fn new(index: u32, name: InternedString) -> ParamTy {
-        ParamTy { idx: index, name: name }
+        ParamTy { index, name: name }
     }
 
     pub fn for_self() -> ParamTy {
@@ -1129,14 +1129,14 @@ pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
     }
 
     pub fn to_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
-        tcx.mk_ty_param(self.idx, self.name)
+        tcx.mk_ty_param(self.index, self.name)
     }
 
     pub fn is_self(&self) -> bool {
-        // FIXME(#50125): Ignoring `Self` with `idx != 0` might lead to weird behavior elsewhere,
+        // FIXME(#50125): Ignoring `Self` with `index != 0` might lead to weird behavior elsewhere,
         // but this should only be possible when using `-Z continue-parse-after-error` like
         // `compile-fail/issue-36638.rs`.
-        self.name == keywords::SelfUpper.name().as_str() && self.idx == 0
+        self.name == keywords::SelfUpper.name().as_str() && self.index == 0
     }
 }
 
@@ -1763,7 +1763,7 @@ pub fn is_bool(&self) -> bool { self.sty == Bool }
 
     pub fn is_param(&self, index: u32) -> bool {
         match self.sty {
-            ty::Param(ref data) => data.idx == index,
+            ty::Param(ref data) => data.index == index,
             _ => false,
         }
     }
index 8d51fbc174a045cba9e5678189a026dfcd30ef4e..72dfe581ba73586082b7848f030c4c190158448a 100644 (file)
@@ -547,7 +547,7 @@ fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
 impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
     fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
         // Look up the type in the substitutions. It really should be in there.
-        let opt_ty = self.substs.get(p.idx as usize).map(|k| k.unpack());
+        let opt_ty = self.substs.get(p.index as usize).map(|k| k.unpack());
         let ty = match opt_ty {
             Some(UnpackedKind::Type(ty)) => ty,
             Some(kind) => {
@@ -558,7 +558,7 @@ fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
                      when substituting (root type={:?}) substs={:?}",
                     p,
                     source_ty,
-                    p.idx,
+                    p.index,
                     kind,
                     self.root_ty,
                     self.substs,
@@ -572,7 +572,7 @@ fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
                      when substituting (root type={:?}) substs={:?}",
                     p,
                     source_ty,
-                    p.idx,
+                    p.index,
                     self.root_ty,
                     self.substs,
                 );
@@ -618,8 +618,7 @@ fn const_for_param(
             }
         };
 
-        // FIXME(const_generics): shift const through binders
-        ct
+        self.shift_vars_through_binders(ct)
     }
 
     /// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs
@@ -664,15 +663,15 @@ fn const_for_param(
     /// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
     /// first case we do not increase the De Bruijn index and in the second case we do. The reason
     /// is that only in the second case have we passed through a fn binder.
-    fn shift_vars_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        debug!("shift_vars(ty={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
-               ty, self.binders_passed, ty.has_escaping_bound_vars());
+    fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T {
+        debug!("shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
+               val, self.binders_passed, val.has_escaping_bound_vars());
 
-        if self.binders_passed == 0 || !ty.has_escaping_bound_vars() {
-            return ty;
+        if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
+            return val;
         }
 
-        let result = ty::fold::shift_vars(self.tcx(), &ty, self.binders_passed);
+        let result = ty::fold::shift_vars(self.tcx(), &val, self.binders_passed);
         debug!("shift_vars: shifted result = {:?}", result);
 
         result
index f25891d77ce5353b6b4564ee96beb44537e46ca2..d5a56f6a09e02c8c5f6db44636b19b6deeeaa84e 100644 (file)
@@ -95,6 +95,9 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
                     );
                 }
             }
+            if sess.opts.debugging_opts.emit_artifact_notifications {
+                sess.parse_sess.span_diagnostic.emit_artifact_notification(&out_filename);
+            }
         }
 
         if sess.opts.cg.save_temps {
@@ -1017,12 +1020,10 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
         }
     }
 
-    // If we're building a dynamic library then some platforms need to make sure
-    // that all symbols are exported correctly from the dynamic library.
-    if crate_type != config::CrateType::Executable ||
-       sess.target.target.options.is_like_emscripten {
-        cmd.export_symbols(tmpdir, crate_type);
-    }
+    // If we're building something like a dynamic library then some platforms
+    // need to make sure that all symbols are exported correctly from the
+    // dynamic library.
+    cmd.export_symbols(tmpdir, crate_type);
 
     // When linking a dynamic library, we put the metadata into a section of the
     // executable. This metadata is in a separate object file from the main
index c99fc17dd89a18b80553b27720d8150aa6d776e1..926f4febe7bae7ca61b68a75feb7bd1f15c1f669 100644 (file)
@@ -372,6 +372,11 @@ fn build_dylib(&mut self, out_filename: &Path) {
     }
 
     fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
+        // Symbol visibility in object files typically takes care of this.
+        if crate_type == CrateType::Executable {
+            return;
+        }
+
         // If we're compiling a dylib, then we let symbol visibility in object
         // files to take care of whether they're exported or not.
         //
@@ -645,6 +650,11 @@ fn debuginfo(&mut self) {
     fn export_symbols(&mut self,
                       tmpdir: &Path,
                       crate_type: CrateType) {
+        // Symbol visibility takes care of this typically
+        if crate_type == CrateType::Executable {
+            return;
+        }
+
         let path = tmpdir.join("lib.def");
         let res: io::Result<()> = try {
             let mut f = BufWriter::new(File::create(&path)?);
index 4fdcdafcab86c7b9059a158e7fe5995bca1c1f4f..a339ec30a74f8b262a1ca9b402bfa060967937ad 100644 (file)
@@ -543,12 +543,12 @@ fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
     }
 }
 
-enum NodesMatchingUII<'a, 'hir: 'a> {
+enum NodesMatchingUII<'a> {
     NodesMatchingDirect(option::IntoIter<ast::NodeId>),
-    NodesMatchingSuffix(hir_map::NodesMatchingSuffix<'a, 'hir>),
+    NodesMatchingSuffix(Box<dyn Iterator<Item = ast::NodeId> + 'a>),
 }
 
-impl<'a, 'hir> Iterator for NodesMatchingUII<'a, 'hir> {
+impl<'a> Iterator for NodesMatchingUII<'a> {
     type Item = ast::NodeId;
 
     fn next(&mut self) -> Option<ast::NodeId> {
@@ -576,10 +576,12 @@ fn reconstructed_input(&self) -> String {
 
     fn all_matching_node_ids<'a, 'hir>(&'a self,
                                        map: &'a hir_map::Map<'hir>)
-                                       -> NodesMatchingUII<'a, 'hir> {
+                                       -> NodesMatchingUII<'a> {
         match *self {
             ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()),
-            ItemViaPath(ref parts) => NodesMatchingSuffix(map.nodes_matching_suffix(&parts)),
+            ItemViaPath(ref parts) => {
+                NodesMatchingSuffix(Box::new(map.nodes_matching_suffix(&parts)))
+            }
         }
     }
 
index bfc9113c2d41ed8d56e6c5bfc44da512a9a4c8e8..59cbd65f05c68a4a936192e58d49da99ecd4f09a 100644 (file)
@@ -16,6 +16,7 @@
 use std::io::prelude::*;
 use std::io;
 use std::cmp::{min, Reverse};
+use std::path::Path;
 use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter, Ansi};
 use termcolor::{WriteColor, Color, Buffer};
 
@@ -52,9 +53,10 @@ pub trait Emitter {
     /// Emit a structured diagnostic.
     fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>);
 
-    /// Emit a JSON directive. The default is to do nothing; this should only
-    /// be emitted with --error-format=json.
-    fn maybe_emit_json_directive(&mut self, _directive: String) {}
+    /// Emit a notification that an artifact has been output.
+    /// This is currently only supported for the JSON format,
+    /// other formats can, and will, simply ignore it.
+    fn emit_artifact_notification(&mut self, _path: &Path) {}
 
     /// Checks if should show explanations about "rustc --explain"
     fn should_show_explain(&self) -> bool {
index e173e1060cc1097988a89a93ed98593078c565fd..3aa87fad0717416fcf9993cdb80ab0561e86b19a 100644 (file)
@@ -26,6 +26,7 @@
 use std::cell::Cell;
 use std::{error, fmt};
 use std::panic;
+use std::path::Path;
 
 use termcolor::{ColorSpec, Color};
 
@@ -294,16 +295,9 @@ fn description(&self) -> &str {
 pub use diagnostic::{Diagnostic, SubDiagnostic, DiagnosticStyledString, DiagnosticId};
 pub use diagnostic_builder::DiagnosticBuilder;
 
-/// A handler deals with two kinds of compiler output.
-/// - Errors: certain errors (fatal, bug, unimpl) may cause immediate exit,
-///   others log errors for later reporting.
-/// - Directives: with --error-format=json, the compiler produces directives
-///   that indicate when certain actions have completed, which are useful for
-///   Cargo. They may change at any time and should not be considered a public
-///   API.
-///
-/// This crate's name (rustc_errors) doesn't encompass the directives, because
-/// directives were added much later.
+/// A handler deals with errors and other compiler output.
+/// Certain errors (fatal, bug, unimpl) may cause immediate exit,
+/// others log errors for later reporting.
 pub struct Handler {
     pub flags: HandlerFlags,
 
@@ -775,8 +769,8 @@ fn emit_db(&self, db: &DiagnosticBuilder<'_>) {
         }
     }
 
-    pub fn maybe_emit_json_directive(&self, directive: String) {
-        self.emitter.borrow_mut().maybe_emit_json_directive(directive);
+    pub fn emit_artifact_notification(&self, path: &Path) {
+        self.emitter.borrow_mut().emit_artifact_notification(path);
     }
 }
 
index 8543cca1dd54502f9131521f67bf0c81d80c40c8..54b3e7342056041c98664df29de120d0fc6b1dff 100644 (file)
@@ -1048,14 +1048,11 @@ enum MetadataKind {
                 tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err))
             });
         let metadata_filename = emit_metadata(tcx.sess, &metadata, &metadata_tmpdir);
-        match std::fs::rename(&metadata_filename, &out_filename) {
-            Ok(_) => {
-                if tcx.sess.opts.debugging_opts.emit_directives {
-                    tcx.sess.parse_sess.span_diagnostic.maybe_emit_json_directive(
-                        format!("metadata file written: {}", out_filename.display()));
-                }
-            }
-            Err(e) => tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)),
+        if let Err(e) = fs::rename(&metadata_filename, &out_filename) {
+            tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
+        }
+        if tcx.sess.opts.debugging_opts.emit_artifact_notifications {
+            tcx.sess.parse_sess.span_diagnostic.emit_artifact_notification(&out_filename);
         }
     }
 
index f70429c22b68c24607543d3440f1dc1634e8181e..f7a89271ec55f41659f8dbc197b8aafa25ff0d43 100644 (file)
@@ -46,7 +46,6 @@
 use syntax::errors::{Applicability, DiagnosticBuilder};
 use syntax::print::pprust::expr_to_string;
 use syntax::visit::FnKind;
-use syntax::struct_span_err;
 
 use rustc::hir::{self, GenericParamKind, PatKind};
 
@@ -1438,15 +1437,10 @@ fn check_ident_token(&mut self,
                          UnderMacro(under_macro): UnderMacro,
                          ident: ast::Ident)
     {
-        let ident_str = &ident.as_str()[..];
-        let cur_edition = cx.sess.edition();
-        let is_raw_ident = |ident: ast::Ident| {
-            cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span)
-        };
-        let next_edition = match cur_edition {
+        let next_edition = match cx.sess.edition() {
             Edition::Edition2015 => {
-                match ident_str {
-                    "async" | "try" => Edition::Edition2018,
+                match &ident.as_str()[..] {
+                    "async" | "await" | "try" => Edition::Edition2018,
 
                     // rust-lang/rust#56327: Conservatively do not
                     // attempt to report occurrences of `dyn` within
@@ -1462,43 +1456,16 @@ fn check_ident_token(&mut self,
                     // an identifier.
                     "dyn" if !under_macro => Edition::Edition2018,
 
-                    // Only issue warnings for `await` if the `async_await`
-                    // feature isn't being used. Otherwise, users need
-                    // to keep using `await` for the macro exposed by std.
-                    "await" if !cx.sess.features_untracked().async_await => Edition::Edition2018,
                     _ => return,
                 }
             }
 
             // There are no new keywords yet for the 2018 edition and beyond.
-            // However, `await` is a "false" keyword in the 2018 edition,
-            // and can only be used if the `async_await` feature is enabled.
-            // Otherwise, we emit an error.
-            _ => {
-                if "await" == ident_str
-                    && !cx.sess.features_untracked().async_await
-                    && !is_raw_ident(ident)
-                {
-                    let mut err = struct_span_err!(
-                        cx.sess,
-                        ident.span,
-                        E0721,
-                        "`await` is a keyword in the {} edition", cur_edition,
-                    );
-                    err.span_suggestion(
-                        ident.span,
-                        "you can use a raw identifier to stay compatible",
-                        "r#await".to_string(),
-                        Applicability::MachineApplicable,
-                    );
-                    err.emit();
-                }
-                return
-            },
+            _ => return,
         };
 
         // don't lint `r#foo`
-        if is_raw_ident(ident) {
+        if cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span) {
             return;
         }
 
index 160d4c30c0bad24f513cd53b57636e0e17a3c77e..c47d7d85a3769cd7cfb61ff20c9c55b51fa086d2 100644 (file)
@@ -783,7 +783,7 @@ fn inject_sanitizer_runtime(&mut self) {
                 Sanitizer::Leak => LSAN_SUPPORTED_TARGETS,
                 Sanitizer::Memory => MSAN_SUPPORTED_TARGETS,
             };
-            if !supported_targets.contains(&&*self.sess.target.target.llvm_target) {
+            if !supported_targets.contains(&&*self.sess.opts.target_triple.triple()) {
                 self.sess.err(&format!("{:?}Sanitizer only works with the `{}` target",
                     sanitizer,
                     supported_targets.join("` or `")
@@ -794,7 +794,7 @@ fn inject_sanitizer_runtime(&mut self) {
             // firstyear 2017 - during testing I was unable to access an OSX machine
             // to make this work on different crate types. As a result, today I have
             // only been able to test and support linux as a target.
-            if self.sess.target.target.llvm_target == "x86_64-unknown-linux-gnu" {
+            if self.sess.opts.target_triple.triple() == "x86_64-unknown-linux-gnu" {
                 if !self.sess.crate_types.borrow().iter().all(|ct| {
                     match *ct {
                         // Link the runtime
index ed183acc93b74f75e9f5adafb28c90c8fef37406..1a7266859ad9f1a343a4ad1c1099cc4532e08068 100644 (file)
@@ -77,6 +77,7 @@ fn visit_local(&mut self, loc: &'tcx hir::Local) {
             hir::LocalSource::Normal => "local binding",
             hir::LocalSource::ForLoopDesugar => "`for` loop binding",
             hir::LocalSource::AsyncFn => "async fn binding",
+            hir::LocalSource::AwaitDesugar => "`await` future binding",
         });
 
         // Check legality of move bindings and `@` patterns.
@@ -412,8 +413,9 @@ fn check_arms<'a, 'tcx>(
                             err.emit();
                         }
 
-                        // Unreachable patterns in try expressions occur when one of the arms
-                        // are an uninhabited type. Which is OK.
+                        // Unreachable patterns in try and await expressions occur when one of
+                        // the arms are an uninhabited type. Which is OK.
+                        hir::MatchSource::AwaitDesugar |
                         hir::MatchSource::TryDesugar => {}
                     }
                 }
index b001a09529e5b44867d8a52c50f28d5fa82d58db..999e7402afd93a57f64787feee4416534a6a2d33 100644 (file)
@@ -3,7 +3,7 @@
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::mir::interpret::ConstValue;
 use rustc::session::config::OptLevel;
-use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, ParamConst};
+use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts};
 use rustc::ty::subst::{SubstsRef, InternalSubsts};
 use syntax::ast;
 use syntax::attr::InlineAttr;
@@ -240,11 +240,11 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
     // Pushes the type name of the specified type to the provided string.
-    // If 'debug' is true, printing normally unprintable types is allowed
-    // (e.g. ty::GeneratorWitness). This parameter should only be set when
-    // this method is being used for logging purposes (e.g. with debug! or info!)
-    // When being used for codegen purposes, 'debug' should be set to 'false'
-    // in order to catch unexpected types that should never end up in a type name
+    // If `debug` is true, printing normally unprintable types is allowed
+    // (e.g. `ty::GeneratorWitness`). This parameter should only be set when
+    // this method is being used for logging purposes (e.g. with `debug!` or `info!`)
+    // When being used for codegen purposes, `debug` should be set to `false`
+    // in order to catch unexpected types that should never end up in a type name.
     pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
         match t.sty {
             ty::Bool              => output.push_str("bool"),
@@ -387,22 +387,34 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
                 if debug {
                     output.push_str(&format!("`{:?}`", t));
                 } else {
-                    bug!("DefPathBasedNames: Trying to create type name for \
-                                         unexpected type: {:?}", t);
+                    bug!(
+                        "DefPathBasedNames: trying to create type name for unexpected type: {:?}",
+                        t,
+                    );
                 }
             }
         }
     }
 
-    // FIXME(const_generics): handle debug printing.
+    // Pushes the the name of the specified const to the provided string.
+    // If `debug` is true, usually-unprintable consts (such as `Infer`) will be printed,
+    // as well as the unprintable types of constants (see `push_type_name` for more details).
     pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) {
         match c.val {
-            ConstValue::Infer(..) | ConstValue::Placeholder(_) => output.push_str("_"),
-            ConstValue::Param(ParamConst { name, .. }) => {
-                write!(output, "{}", name).unwrap();
+            ConstValue::Scalar(..) | ConstValue::Slice(..) | ConstValue::ByRef(..) => {
+                // FIXME(const_generics): we could probably do a better job here.
+                write!(output, "{:?}", c).unwrap()
+            }
+            _ => {
+                if debug {
+                    write!(output, "{:?}", c).unwrap()
+                } else {
+                    bug!(
+                        "DefPathBasedNames: trying to create const name for unexpected const: {:?}",
+                        c,
+                    );
+                }
             }
-            ConstValue::Unevaluated(..) => output.push_str("_: _"),
-            _ => write!(output, "{:?}", c).unwrap(),
         }
         output.push_str(": ");
         self.push_type_name(c.ty, output, debug);
index c21f7f38ca5a3767572b87961a4d8b64b9d2abad..9dd343b6c8de8ee1ee964858f63dfb6cb7a9b7e4 100644 (file)
@@ -14,13 +14,7 @@ pub fn opts() -> TargetOptions {
     //
     // Here we detect what version is being requested, defaulting to 10.7. ELF
     // TLS is flagged as enabled if it looks to be supported.
-    let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
-    let version = deployment_target.as_ref().and_then(|s| {
-        let mut i = s.splitn(2, '.');
-        i.next().and_then(|a| i.next().map(|b| (a, b)))
-    }).and_then(|(a, b)| {
-        a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()
-    }).unwrap_or((10, 7));
+    let version = macos_deployment_target().unwrap_or((10, 7));
 
     TargetOptions {
         // macOS has -dead_strip, which doesn't rely on function_sections
@@ -40,3 +34,27 @@ pub fn opts() -> TargetOptions {
         .. Default::default()
     }
 }
+
+fn macos_deployment_target() -> Option<(u32, u32)> {
+    let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
+    let version = deployment_target.as_ref().and_then(|s| {
+        let mut i = s.splitn(2, '.');
+        i.next().and_then(|a| i.next().map(|b| (a, b)))
+    }).and_then(|(a, b)| {
+        a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()
+    });
+
+    version
+}
+
+pub fn macos_llvm_target(arch: &str) -> String {
+    let version = macos_deployment_target();
+    let llvm_target = match version {
+        Some((major, minor)) => {
+            format!("{}-apple-macosx{}.{}.0", arch, major, minor)
+        },
+        None => format!("{}-apple-darwin", arch)
+    };
+
+    llvm_target
+}
index 58c59cc8728464dc362e26d428e2d3bedd3f9502..7d804ea53fb31aa7521ee5926397594ede17ff5f 100644 (file)
@@ -8,8 +8,14 @@ pub fn target() -> TargetResult {
     base.stack_probes = true;
     base.eliminate_frame_pointer = false;
 
+    // Clang automatically chooses a more specific target based on
+    // MACOSX_DEPLOYMENT_TARGET.  To enable cross-language LTO to work
+    // correctly, we do too.
+    let arch = "i686";
+    let llvm_target = super::apple_base::macos_llvm_target(&arch);
+
     Ok(Target {
-        llvm_target: "i686-apple-darwin".to_string(),
+        llvm_target: llvm_target,
         target_endian: "little".to_string(),
         target_pointer_width: "32".to_string(),
         target_c_int_width: "32".to_string(),
index c54181741b3cca5f1955ccb949f023ef565d399a..182103440f035e9a0d47109131ad2ba7e3f96718 100644 (file)
@@ -8,13 +8,19 @@ pub fn target() -> TargetResult {
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
     base.stack_probes = true;
 
+    // Clang automatically chooses a more specific target based on
+    // MACOSX_DEPLOYMENT_TARGET.  To enable cross-language LTO to work
+    // correctly, we do too.
+    let arch = "x86_64";
+    let llvm_target = super::apple_base::macos_llvm_target(&arch);
+
     Ok(Target {
-        llvm_target: "x86_64-apple-darwin".to_string(),
+        llvm_target: llvm_target,
         target_endian: "little".to_string(),
         target_pointer_width: "64".to_string(),
         target_c_int_width: "32".to_string(),
         data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(),
-        arch: "x86_64".to_string(),
+        arch: arch.to_string(),
         target_os: "macos".to_string(),
         target_env: String::new(),
         target_vendor: "apple".to_string(),
index 838874cc2bf074b25f1224162615f3a63c5398c4..3fa192f16f32e2c431740c5735f747089f0d5773 100644 (file)
@@ -246,7 +246,7 @@ fn deduce_expectations_from_obligations(
     }
 
     /// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
-    /// everything we need to know about a closure.
+    /// everything we need to know about a closure or generator.
     ///
     /// The `cause_span` should be the span that caused us to
     /// have this expected signature, or `None` if we can't readily
@@ -262,37 +262,50 @@ fn deduce_sig_from_projection(
 
         let trait_ref = projection.to_poly_trait_ref(tcx);
 
-        if tcx.lang_items().fn_trait_kind(trait_ref.def_id()).is_none() {
+        let is_fn = tcx.lang_items().fn_trait_kind(trait_ref.def_id()).is_some();
+        let gen_trait = tcx.lang_items().gen_trait().unwrap();
+        let is_gen = gen_trait == trait_ref.def_id();
+        if !is_fn && !is_gen {
+            debug!("deduce_sig_from_projection: not fn or generator");
             return None;
         }
 
-        let arg_param_ty = trait_ref.skip_binder().substs.type_at(1);
-        let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
-        debug!(
-            "deduce_sig_from_projection: arg_param_ty {:?}",
-            arg_param_ty
-        );
+        if is_gen {
+            // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return`
+            // associated item and not yield.
+            let return_assoc_item = self.tcx.associated_items(gen_trait).nth(1).unwrap().def_id;
+            if return_assoc_item != projection.projection_def_id() {
+                debug!("deduce_sig_from_projection: not return assoc item of generator");
+                return None;
+            }
+        }
+
+        let input_tys = if is_fn {
+            let arg_param_ty = trait_ref.skip_binder().substs.type_at(1);
+            let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
+            debug!("deduce_sig_from_projection: arg_param_ty={:?}", arg_param_ty);
 
-        let input_tys = match arg_param_ty.sty {
-            ty::Tuple(tys) => tys.into_iter().map(|k| k.expect_ty()),
-            _ => return None,
+            match arg_param_ty.sty {
+                ty::Tuple(tys) => tys.into_iter().map(|k| k.expect_ty()).collect::<Vec<_>>(),
+                _ => return None,
+            }
+        } else {
+            // Generators cannot have explicit arguments.
+            vec![]
         };
 
         let ret_param_ty = projection.skip_binder().ty;
         let ret_param_ty = self.resolve_type_vars_if_possible(&ret_param_ty);
-        debug!(
-            "deduce_sig_from_projection: ret_param_ty {:?}",
-            ret_param_ty
-        );
+        debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty);
 
         let sig = self.tcx.mk_fn_sig(
-            input_tys,
-            ret_param_ty,
+            input_tys.iter(),
+            &ret_param_ty,
             false,
             hir::Unsafety::Normal,
             Abi::Rust,
         );
-        debug!("deduce_sig_from_projection: sig {:?}", sig);
+        debug!("deduce_sig_from_projection: sig={:?}", sig);
 
         Some(ExpectedSig { cause_span, sig })
     }
index 314f7e97cd28d921d2e633fe5d0b27f4f499ae8e..251400e65f3839f74eecf1e1234e2fa5421df04f 100644 (file)
@@ -757,8 +757,7 @@ fn assemble_inherent_candidates_from_object(&mut self,
         });
     }
 
-    fn assemble_inherent_candidates_from_param(&mut self,
-                                               param_ty: ty::ParamTy) {
+    fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
         // FIXME -- Do we want to commit to this behavior for param bounds?
 
         let bounds = self.param_env
index e404a8e6972c8c70a3ac48f1294606854339c77c..64c8ff8ff8630319c8fff4e1baf9ba582fb6ef87 100644 (file)
@@ -5785,8 +5785,6 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         ty
     );
 
-    // FIXME(const_generics): we probably want to check the bounds for const parameters too.
-
     if own_counts.types == 0 {
         return;
     }
@@ -5795,9 +5793,9 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut types_used = vec![false; own_counts.types];
 
     for leaf_ty in ty.walk() {
-        if let ty::Param(ty::ParamTy { idx, .. }) = leaf_ty.sty {
-            debug!("Found use of ty param num {}", idx);
-            types_used[idx as usize - own_counts.lifetimes] = true;
+        if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.sty {
+            debug!("Found use of ty param num {}", index);
+            types_used[index as usize - own_counts.lifetimes] = true;
         } else if let ty::Error = leaf_ty.sty {
             // If there is already another error, do not emit
             // an error for not using a type Parameter.
index 1420c66c73ea3ca6849d0f172601d39caab897e3..fd7d6fe694ccd747ca08de924ecab3e8a37b928a 100644 (file)
@@ -494,7 +494,7 @@ struct CountParams { params: FxHashSet<u32> }
         impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
             fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
                 if let ty::Param(param) = t.sty {
-                    self.params.insert(param.idx);
+                    self.params.insert(param.index);
                 }
                 t.super_visit_with(self)
             }
index 18bf66ceb3501fc0d0ff14dbf49380f5a75d5535..49910e39fed200727d43a13f07010b9e0eb85801 100644 (file)
@@ -8,7 +8,7 @@
 pub struct Parameter(pub u32);
 
 impl From<ty::ParamTy> for Parameter {
-    fn from(param: ty::ParamTy) -> Self { Parameter(param.idx) }
+    fn from(param: ty::ParamTy) -> Self { Parameter(param.index) }
 }
 
 impl From<ty::EarlyBoundRegion> for Parameter {
index 5079a3bb55f899a97a27eb4c7e3c1c357534171c..4f82978f01a5d5f9cbdf4ce388ae3f21c271ea5d 100644 (file)
@@ -324,7 +324,7 @@ fn add_constraints_from_ty(&mut self,
             }
 
             ty::Param(ref data) => {
-                self.add_constraint(current, data.idx, variance);
+                self.add_constraint(current, data.index, variance);
             }
 
             ty::FnPtr(sig) => {
index de74a6a540055c9c79d4e4ef942ad6eeafb3a52c..3a260db806520a69261a447c7681225b0a001b9f 100644 (file)
@@ -1706,9 +1706,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Generics {
                 }
                 Some(param.clean(cx))
             }
-            ty::GenericParamDefKind::Const { .. } => {
-                unimplemented!() // FIXME(const_generics)
-            }
+            ty::GenericParamDefKind::Const { .. } => None,
         }).collect::<Vec<GenericParamDef>>();
 
         let mut where_predicates = preds.predicates.iter()
index 4204d20498d701a5f74a76ded3bdb18c50ac2809..880b824335517a63f76f98104c66836d1b62a110 100644 (file)
@@ -1052,6 +1052,10 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
                height: 45px;
        }
 
+       .rustdoc.source > .sidebar > .sidebar-menu {
+               display: none;
+       }
+
        .sidebar-elems {
                position: fixed;
                z-index: 1;
index 8ef8c2b4c0a22b92f62691b1d2864627c6fed4f1..36a1628014ddb6b47bb1cf116e52c8529cb09eac 100644 (file)
@@ -764,12 +764,18 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
 
 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
 
-impl Encodable for path::PathBuf {
+impl Encodable for path::Path {
     fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
         self.to_str().unwrap().encode(e)
     }
 }
 
+impl Encodable for path::PathBuf {
+    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
+        path::Path::encode(self, e)
+    }
+}
+
 impl Decodable for path::PathBuf {
     fn decode<D: Decoder>(d: &mut D) -> Result<path::PathBuf, D::Error> {
         let bytes: String = Decodable::decode(d)?;
index ac1aff845d8c9d2fb9f04e6934c381ae358d986d..ad5d62f667ac97648ca07e2dc2ac0041b682f3f0 100644 (file)
@@ -19,7 +19,7 @@ panic_unwind = { path = "../libpanic_unwind", optional = true }
 panic_abort = { path = "../libpanic_abort" }
 core = { path = "../libcore" }
 libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] }
-compiler_builtins = { version = "0.1.9" }
+compiler_builtins = { version = "0.1.12" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.3.0", features = ['rustc-dep-of-std'] }
index 33b8c76bb531a2a6fc9219eb373bec20d0fad763..af2302d24f5214724715608ca6f26d59ca482112 100644 (file)
@@ -1065,6 +1065,7 @@ pub fn precedence(&self) -> ExprPrecedence {
             ExprKind::Block(..) => ExprPrecedence::Block,
             ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
             ExprKind::Async(..) => ExprPrecedence::Async,
+            ExprKind::Await(..) => ExprPrecedence::Await,
             ExprKind::Assign(..) => ExprPrecedence::Assign,
             ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
             ExprKind::Field(..) => ExprPrecedence::Field,
@@ -1186,6 +1187,9 @@ pub enum ExprKind {
     /// created during lowering cannot be made the parent of any other
     /// preexisting defs.
     Async(CaptureBy, NodeId, P<Block>),
+    /// An await expression (`my_future.await`).
+    Await(AwaitOrigin, P<Expr>),
+
     /// A try block (`try { ... }`).
     TryBlock(P<Block>),
 
@@ -1287,6 +1291,15 @@ pub enum Movability {
     Movable,
 }
 
+/// Whether an `await` comes from `await!` or `.await` syntax.
+/// FIXME: this should be removed when support for legacy `await!` is removed.
+/// https://github.com/rust-lang/rust/issues/60610
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+pub enum AwaitOrigin {
+    FieldLike,
+    MacroLike,
+}
+
 pub type Mac = Spanned<Mac_>;
 
 /// Represents a macro invocation. The `Path` indicates which macro
index 2a1f3c48014069191ac6461a8277b230f2c978cd..c3bad3aba184b06bfb16ab58ccdf5be865866c6c 100644 (file)
@@ -108,8 +108,8 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 // was set. This is most important for knowing when a particular feature became
 // stable (active).
 //
-// Note that the features should be grouped into internal/user-facing
-// and then sorted by version inside those groups. This is inforced with tidy.
+// Note that the features are grouped into internal/user-facing and then
+// sorted by version inside those groups. This is inforced with tidy.
 //
 // N.B., `tools/tidy/src/features.rs` parses this information directly out of the
 // source, so take care when modifying it.
@@ -119,7 +119,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // feature-group-start: internal feature gates
     // -------------------------------------------------------------------------
 
-    // no tracking issue START
+    // no-tracking-issue-start
 
     // Allows using the `rust-intrinsic`'s "ABI".
     (active, intrinsics, "1.0.0", None, None),
@@ -152,7 +152,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // lets a function to be `const` when opted into with `#![feature(foo)]`.
     (active, rustc_const_unstable, "1.0.0", None, None),
 
-    // no tracking issue END
+    // no-tracking-issue-end
 
     // Allows using `#[link_name="llvm.*"]`.
     (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
@@ -187,20 +187,17 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows using `box` in patterns (RFC 469).
     (active, box_patterns, "1.0.0", Some(29641), None),
 
-    // no tracking issue START
+    // no-tracking-issue-start
 
     // Allows using `#[prelude_import]` on glob `use` items.
     (active, prelude_import, "1.2.0", None, None),
 
-    // no tracking issue END
+    // no-tracking-issue-end
 
     // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
     (active, dropck_parametricity, "1.3.0", Some(28498), None),
 
-    // FIXME(Centril): Investigate whether this gate actually has any effect.
-    (active, needs_allocator, "1.4.0", Some(27389), None),
-
-    // no tracking issue START
+    // no-tracking-issue-start
 
     // Allows using `#[omit_gdb_pretty_printer_section]`.
     (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
@@ -208,7 +205,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows using the `vectorcall` ABI.
     (active, abi_vectorcall, "1.7.0", None, None),
 
-    // no tracking issue END
+    // no-tracking-issue-end
 
     // Allows using `#[structural_match]` which indicates that a type is structurally matchable.
     (active, structural_match, "1.8.0", Some(31434), None),
@@ -222,7 +219,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
     (active, needs_panic_runtime, "1.10.0", Some(32837), None),
 
-    // no tracking issue START
+    // no-tracking-issue-start
 
     // Allows identifying the `compiler_builtins` crate.
     (active, compiler_builtins, "1.13.0", None, None),
@@ -245,7 +242,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows using the `format_args_nl` macro.
     (active, format_args_nl, "1.29.0", None, None),
 
-    // no tracking issue END
+    // no-tracking-issue-end
 
     // Added for testing E0705; perma-unstable.
     (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
@@ -485,6 +482,10 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows async and await syntax.
     (active, async_await, "1.28.0", Some(50547), None),
 
+    // Allows await! macro-like syntax.
+    // This will likely be removed prior to stabilization of async/await.
+    (active, await_macro, "1.28.0", Some(50547), None),
+
     // Allows reinterpretation of the bits of a value of one type as another type during const eval.
     (active, const_transmute, "1.29.0", Some(53605), None),
 
@@ -567,6 +568,10 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 ];
 
 declare_features! (
+    // -------------------------------------------------------------------------
+    // feature-group-start: removed features
+    // -------------------------------------------------------------------------
+
     (removed, import_shadowing, "1.0.0", None, None, None),
     (removed, managed_boxes, "1.0.0", None, None, None),
     // Allows use of unary negate on unsigned integers, e.g., -e for e: u8
@@ -581,7 +586,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
     // Allows using items which are missing stability attributes
     (removed, unmarked_api, "1.0.0", None, None, None),
-    (removed, pushpop_unsafe, "1.2.0", None, None, None),
     (removed, allocator, "1.0.0", None, None, None),
     (removed, simd, "1.0.0", Some(27731), None,
      Some("removed in favor of `#[repr(simd)]`")),
@@ -589,6 +593,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
      Some("merged into `#![feature(slice_patterns)]`")),
     (removed, macro_reexport, "1.0.0", Some(29638), None,
      Some("subsumed by `pub use`")),
+    (removed, pushpop_unsafe, "1.2.0", None, None, None),
+    (removed, needs_allocator, "1.4.0", Some(27389), None,
+     Some("subsumed by `#![feature(allocator_internals)]`")),
     (removed, proc_macro_mod, "1.27.0", Some(54727), None,
      Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
     (removed, proc_macro_expr, "1.27.0", Some(54727), None,
@@ -600,12 +607,16 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (removed, panic_implementation, "1.28.0", Some(44489), None,
      Some("subsumed by `#[panic_handler]`")),
     // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
-    (removed, custom_derive, "1.0.0", Some(29644), None,
+    (removed, custom_derive, "1.32.0", Some(29644), None,
      Some("subsumed by `#[proc_macro_derive]`")),
     // Paths of the form: `extern::foo::bar`
     (removed, extern_in_paths, "1.33.0", Some(55600), None,
      Some("subsumed by `::foo::bar` paths")),
-    (removed, quote, "1.0.0", Some(29601), None, None),
+    (removed, quote, "1.33.0", Some(29601), None, None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: removed features
+    // -------------------------------------------------------------------------
 );
 
 declare_features! (
@@ -613,6 +624,10 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 );
 
 declare_features! (
+    // -------------------------------------------------------------------------
+    // feature-group-start: for testing purposes
+    // -------------------------------------------------------------------------
+
     // A temporary feature gate used to enable parser extensions needed
     // to bootstrap fix for #5723.
     (accepted, issue_5723_bootstrap, "1.0.0", None, None),
@@ -620,6 +635,14 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // they don't actually mean anything.
     (accepted, test_accepted_feature, "1.0.0", None, None),
 
+    // -------------------------------------------------------------------------
+    // feature-group-end: for testing purposes
+    // -------------------------------------------------------------------------
+
+    // -------------------------------------------------------------------------
+    // feature-group-start: accepted features
+    // -------------------------------------------------------------------------
+
     // Allows using associated `type`s in `trait`s.
     (accepted, associated_types, "1.0.0", None, None),
     // Allows using assigning a default type to type parameters in algebraic data type definitions.
@@ -809,6 +832,10 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (accepted, extern_crate_self, "1.34.0", Some(56409), None),
     // Allows arbitrary delimited token streams in non-macro attributes.
     (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: accepted features
+    // -------------------------------------------------------------------------
 );
 
 // If you change this, please modify `src/doc/unstable-book` as well. You must
@@ -2104,6 +2131,20 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
             ast::ExprKind::Async(..) => {
                 gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
             }
+            ast::ExprKind::Await(origin, _) => {
+                match origin {
+                    ast::AwaitOrigin::FieldLike =>
+                        gate_feature_post!(&self, async_await, e.span, "async/await is unstable"),
+                    ast::AwaitOrigin::MacroLike =>
+                        gate_feature_post!(
+                            &self,
+                            await_macro,
+                            e.span,
+                            "`await!(<expr>)` macro syntax is unstable, and will soon be removed \
+                            in favor of `<expr>.await` syntax."
+                        ),
+                }
+            }
             _ => {}
         }
         visit::walk_expr(self, e);
index 65f8d0e77d7be430318685fb353fa1944244f521..2dd2ecb749300ec19853d138e18710a9f919663c 100644 (file)
@@ -19,6 +19,7 @@
 use syntax_pos::{MacroBacktrace, Span, SpanLabel, MultiSpan};
 use rustc_data_structures::sync::{self, Lrc};
 use std::io::{self, Write};
+use std::path::Path;
 use std::vec;
 use std::sync::{Arc, Mutex};
 
@@ -91,15 +92,15 @@ fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
         }
     }
 
-    fn maybe_emit_json_directive(&mut self, directive: String) {
-        let data = Directive { directive };
+    fn emit_artifact_notification(&mut self, path: &Path) {
+        let data = ArtifactNotification { artifact: path };
         let result = if self.pretty {
             writeln!(&mut self.dst, "{}", as_pretty_json(&data))
         } else {
             writeln!(&mut self.dst, "{}", as_json(&data))
         };
         if let Err(e) = result {
-            panic!("failed to print message: {:?}", e);
+            panic!("failed to print notification: {:?}", e);
         }
     }
 }
@@ -181,9 +182,9 @@ struct DiagnosticCode {
 }
 
 #[derive(RustcEncodable)]
-struct Directive {
-    /// The directive itself.
-    directive: String,
+struct ArtifactNotification<'a> {
+    /// The path of the artifact.
+    artifact: &'a Path,
 }
 
 impl Diagnostic {
index 2e09235ca77b0a72bbcb1463778789e73e747164..6eb8b1b5004c96468958756878d0dbcf8a7b7b28 100644 (file)
@@ -1185,6 +1185,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
             vis.visit_id(node_id);
             vis.visit_block(body);
         }
+        ExprKind::Await(_origin, expr) => vis.visit_expr(expr),
         ExprKind::Assign(el, er) => {
             vis.visit_expr(el);
             vis.visit_expr(er);
index d46feeab33599773fd3713303e45f53f2beba422..f3eac71ee7761a5574b06f6c5526b203c7fbc426 100644 (file)
@@ -1576,7 +1576,7 @@ fn parse_trait_item_(&mut self,
             let ident = self.parse_ident()?;
             let mut generics = self.parse_generics()?;
 
-            let d = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
+            let mut decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
                 // This is somewhat dubious; We don't want to allow
                 // argument names to be left off if there is a
                 // definition...
@@ -1585,7 +1585,7 @@ fn parse_trait_item_(&mut self,
                 p.parse_arg_general(p.span.rust_2018(), true, false)
             })?;
             generics.where_clause = self.parse_where_clause()?;
-            self.construct_async_arguments(&mut asyncness, &d);
+            self.construct_async_arguments(&mut asyncness, &mut decl);
 
             let sig = ast::MethodSig {
                 header: FnHeader {
@@ -1594,7 +1594,7 @@ fn parse_trait_item_(&mut self,
                     abi,
                     asyncness,
                 },
-                decl: d,
+                decl,
             };
 
             let body = match self.token {
@@ -2319,7 +2319,8 @@ fn parse_path_segment(&mut self, style: PathStyle) -> PResult<'a, PathSegment> {
         let ident = self.parse_path_segment_ident()?;
 
         let is_args_start = |token: &token::Token| match *token {
-            token::Lt | token::BinOp(token::Shl) | token::OpenDelim(token::Paren) => true,
+            token::Lt | token::BinOp(token::Shl) | token::OpenDelim(token::Paren)
+            | token::LArrow => true,
             _ => false,
         };
         let check_args_start = |this: &mut Self| {
@@ -2751,6 +2752,14 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
                     db.span_label(self.span, "expected expression");
                     db.note("variable declaration using `let` is a statement");
                     return Err(db);
+                } else if self.span.rust_2018() && self.eat_keyword(keywords::Await) {
+                    // FIXME: remove this branch when `await!` is no longer supported
+                    // https://github.com/rust-lang/rust/issues/60610
+                    self.expect(&token::Not)?;
+                    self.expect(&token::OpenDelim(token::Paren))?;
+                    let expr = self.parse_expr()?;
+                    self.expect(&token::CloseDelim(token::Paren))?;
+                    ex = ExprKind::Await(ast::AwaitOrigin::MacroLike, expr);
                 } else if self.token.is_path_start() {
                     let path = self.parse_path(PathStyle::Expr)?;
 
@@ -3014,6 +3023,15 @@ fn parse_dot_or_call_expr_with(&mut self,
 
     // Assuming we have just parsed `.`, continue parsing into an expression.
     fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
+        if self.span.rust_2018() && self.eat_keyword(keywords::Await) {
+            let span = lo.to(self.prev_span);
+            let await_expr = self.mk_expr(
+                span,
+                ExprKind::Await(ast::AwaitOrigin::FieldLike, self_arg),
+                ThinVec::new(),
+            );
+            return Ok(await_expr);
+        }
         let segment = self.parse_path_segment(PathStyle::Expr)?;
         self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren));
 
@@ -6045,10 +6063,6 @@ fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<TypeBindin
                 });
                 assoc_ty_bindings.push(span);
             } else if self.check_const_arg() {
-                // FIXME(const_generics): to distinguish between idents for types and consts,
-                // we should introduce a GenericArg::Ident in the AST and distinguish when
-                // lowering to the HIR. For now, idents for const args are not permitted.
-
                 // Parse const argument.
                 let expr = if let token::OpenDelim(token::Brace) = self.token {
                     self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())?
@@ -6060,8 +6074,6 @@ fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<TypeBindin
                         self.fatal("identifiers may currently not be used for const generics")
                     );
                 } else {
-                    // FIXME(const_generics): this currently conflicts with emplacement syntax
-                    // with negative integer literals.
                     self.parse_literal_maybe_minus()?
                 };
                 let value = AnonConst {
@@ -6479,10 +6491,10 @@ fn parse_item_fn(&mut self,
                      -> PResult<'a, ItemInfo> {
         let (ident, mut generics) = self.parse_fn_header()?;
         let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe;
-        let decl = self.parse_fn_decl(allow_c_variadic)?;
+        let mut decl = self.parse_fn_decl(allow_c_variadic)?;
         generics.where_clause = self.parse_where_clause()?;
         let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-        self.construct_async_arguments(&mut asyncness, &decl);
+        self.construct_async_arguments(&mut asyncness, &mut decl);
         let header = FnHeader { unsafety, asyncness, constness, abi };
         Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
     }
@@ -6666,9 +6678,9 @@ fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
             let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?;
             let ident = self.parse_ident()?;
             let mut generics = self.parse_generics()?;
-            let decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
+            let mut decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
             generics.where_clause = self.parse_where_clause()?;
-            self.construct_async_arguments(&mut asyncness, &decl);
+            self.construct_async_arguments(&mut asyncness, &mut decl);
             *at_end = true;
             let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
             let header = ast::FnHeader { abi, unsafety, constness, asyncness };
@@ -8714,9 +8726,9 @@ fn eat_bad_pub(&mut self) {
     ///
     /// The arguments of the function are replaced in HIR lowering with the arguments created by
     /// this function and the statements created here are inserted at the top of the closure body.
-    fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl: &FnDecl) {
+    fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl: &mut FnDecl) {
         if let IsAsync::Async { ref mut arguments, .. } = asyncness.node {
-            for (index, input) in decl.inputs.iter().enumerate() {
+            for (index, input) in decl.inputs.iter_mut().enumerate() {
                 let id = ast::DUMMY_NODE_ID;
                 let span = input.pat.span;
 
@@ -8728,8 +8740,10 @@ fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl:
                 // `let <pat> = __argN;` statement, instead just adding a `let <pat> = <pat>;`
                 // statement.
                 let (binding_mode, ident, is_simple_pattern) = match input.pat.node {
-                    PatKind::Ident(binding_mode, ident, _) => (binding_mode, ident, true),
-                    _ => (BindingMode::ByValue(Mutability::Immutable), ident, false),
+                    PatKind::Ident(binding_mode @ BindingMode::ByValue(_), ident, _) => {
+                        (binding_mode, ident, true)
+                    }
+                    _ => (BindingMode::ByValue(Mutability::Mutable), ident, false),
                 };
 
                 // Construct an argument representing `__argN: <ty>` to replace the argument of the
@@ -8796,6 +8810,15 @@ fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl:
                     })
                 };
 
+                // Remove mutability from arguments. If this is not a simple pattern,
+                // those arguments are replaced by `__argN`, so there is no need to do this.
+                if let PatKind::Ident(BindingMode::ByValue(mutability @ Mutability::Mutable), ..) =
+                    &mut input.pat.node
+                {
+                    assert!(is_simple_pattern);
+                    *mutability = Mutability::Immutable;
+                }
+
                 let move_stmt = Stmt { id, node: StmtKind::Local(P(move_local)), span };
                 arguments.push(AsyncArgument { ident, arg, pat_stmt, move_stmt });
             }
index 2fa4f5263fbc581b951d2aeddf3b49e638846860..fd7a39c576daa79407a4650264f284bdd7490fa5 100644 (file)
@@ -99,6 +99,11 @@ pub(crate) fn ident_can_begin_expr(ident: ast::Ident, is_raw: bool) -> bool {
     ident_token.is_path_segment_keyword() ||
     [
         keywords::Async.name(),
+
+        // FIXME: remove when `await!(..)` syntax is removed
+        // https://github.com/rust-lang/rust/issues/60610
+        keywords::Await.name(),
+
         keywords::Do.name(),
         keywords::Box.name(),
         keywords::Break.name(),
index 6c0fdfaa776f956bc8f9ca590d9a53b2a40385ad..682621d40ab6583dfd2f2439c8d2d890b0eadc35 100644 (file)
@@ -2250,6 +2250,18 @@ fn print_expr_outer_attr_style(&mut self,
                 self.ibox(0)?;
                 self.print_block_with_attrs(blk, attrs)?;
             }
+            ast::ExprKind::Await(origin, ref expr) => {
+                match origin {
+                    ast::AwaitOrigin::MacroLike => {
+                        self.s.word("await!")?;
+                        self.print_expr_maybe_paren(expr, parser::PREC_FORCE_PAREN)?;
+                    }
+                    ast::AwaitOrigin::FieldLike => {
+                        self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
+                        self.s.word(".await")?;
+                    }
+                }
+            }
             ast::ExprKind::Assign(ref lhs, ref rhs) => {
                 let prec = AssocOp::Assign.precedence() as i8;
                 self.print_expr_maybe_paren(lhs, prec + 1)?;
index 5f15ede7b0b6afac704a1097622415c061fda3ca..80dabffaba9f422414e76dcbdaf1544e121c8f89 100644 (file)
@@ -267,6 +267,7 @@ pub enum ExprPrecedence {
     TryBlock,
     Struct,
     Async,
+    Await,
     Err,
 }
 
@@ -301,6 +302,7 @@ pub fn order(self) -> i8 {
             ExprPrecedence::Unary => PREC_PREFIX,
 
             // Unary, postfix
+            ExprPrecedence::Await |
             ExprPrecedence::Call |
             ExprPrecedence::MethodCall |
             ExprPrecedence::Field |
@@ -346,6 +348,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
             // X { y: 1 } + X { y: 2 }
             contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
         }
+        ast::ExprKind::Await(_, ref x) |
         ast::ExprKind::Unary(_, ref x) |
         ast::ExprKind::Cast(ref x, _) |
         ast::ExprKind::Type(ref x, _) |
index fc99d10b0b6c613cb76f4ec67b8f9522a2dc8ead..0503e5644dbc58112bd6547e974c1c2865b9f6df 100644 (file)
@@ -768,6 +768,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::Async(_, _, ref body) => {
             visitor.visit_block(body);
         }
+        ExprKind::Await(_, ref expr) => visitor.visit_expr(expr),
         ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => {
             visitor.visit_expr(left_hand_expression);
             visitor.visit_expr(right_hand_expression);
index c806020039d267cd4462cc9f5baa6be84d6caf2b..a901afdff43e63ff84e705a0870775907e1c21cf 100644 (file)
@@ -598,6 +598,7 @@ pub enum CompilerDesugaringKind {
     /// `impl Trait` with `Foo`.
     ExistentialReturnType,
     Async,
+    Await,
     ForLoop,
 }
 
@@ -605,6 +606,7 @@ impl CompilerDesugaringKind {
     pub fn name(self) -> Symbol {
         Symbol::intern(match self {
             CompilerDesugaringKind::Async => "async",
+            CompilerDesugaringKind::Await => "await",
             CompilerDesugaringKind::QuestionMark => "?",
             CompilerDesugaringKind::TryBlock => "try block",
             CompilerDesugaringKind::ExistentialReturnType => "existential type",
index cdbfabae7ce1f01cd2c7303da7635bd201bdf971..20759217b54a0962f72fdf16511f6b3a8dfa35f0 100644 (file)
@@ -84,6 +84,7 @@
 
         // Edition-specific keywords that are used in unstable Rust or reserved for future use.
         Async:              "async", // >= 2018 Edition only
+        Await:              "await", // >= 2018 Edition only
         Try:                "try", // >= 2018 Edition only
 
         // Special lifetime names
diff --git a/src/test/codegen/i686-macosx-deployment-target.rs b/src/test/codegen/i686-macosx-deployment-target.rs
new file mode 100644 (file)
index 0000000..dad376d
--- /dev/null
@@ -0,0 +1,26 @@
+//
+// Checks that we correctly modify the target when MACOSX_DEPLOYMENT_TARGET is set.
+// See issue #60235.
+
+// compile-flags: -O --target=i686-apple-darwin --crate-type=rlib
+// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
+#[lang="freeze"]
+trait Freeze { }
+#[lang="copy"]
+trait Copy { }
+
+#[repr(C)]
+pub struct Bool {
+    b: bool,
+}
+
+// CHECK: target triple = "i686-apple-macosx10.9.0"
+#[no_mangle]
+pub extern "C" fn structbool() -> Bool {
+    Bool { b: true }
+}
diff --git a/src/test/codegen/i686-no-macosx-deployment-target.rs b/src/test/codegen/i686-no-macosx-deployment-target.rs
new file mode 100644 (file)
index 0000000..eb82659
--- /dev/null
@@ -0,0 +1,26 @@
+//
+// Checks that we leave the target alone MACOSX_DEPLOYMENT_TARGET is unset.
+// See issue #60235.
+
+// compile-flags: -O --target=i686-apple-darwin --crate-type=rlib
+// unset-rustc-env:MACOSX_DEPLOYMENT_TARGET
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
+#[lang="freeze"]
+trait Freeze { }
+#[lang="copy"]
+trait Copy { }
+
+#[repr(C)]
+pub struct Bool {
+    b: bool,
+}
+
+// CHECK: target triple = "i686-apple-darwin"
+#[no_mangle]
+pub extern "C" fn structbool() -> Bool {
+    Bool { b: true }
+}
diff --git a/src/test/codegen/x86_64-macosx-deployment-target.rs b/src/test/codegen/x86_64-macosx-deployment-target.rs
new file mode 100644 (file)
index 0000000..8e291b7
--- /dev/null
@@ -0,0 +1,26 @@
+//
+// Checks that we correctly modify the target when MACOSX_DEPLOYMENT_TARGET is set.
+// See issue #60235.
+
+// compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib
+// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
+#[lang="freeze"]
+trait Freeze { }
+#[lang="copy"]
+trait Copy { }
+
+#[repr(C)]
+pub struct Bool {
+    b: bool,
+}
+
+// CHECK: target triple = "x86_64-apple-macosx10.9.0"
+#[no_mangle]
+pub extern "C" fn structbool() -> Bool {
+    Bool { b: true }
+}
diff --git a/src/test/codegen/x86_64-no-macosx-deployment-target.rs b/src/test/codegen/x86_64-no-macosx-deployment-target.rs
new file mode 100644 (file)
index 0000000..58a11d1
--- /dev/null
@@ -0,0 +1,26 @@
+//
+// Checks that we leave the target alone when MACOSX_DEPLOYMENT_TARGET is unset.
+// See issue #60235.
+
+// compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib
+// unset-rustc-env:MACOSX_DEPLOYMENT_TARGET
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
+#[lang="freeze"]
+trait Freeze { }
+#[lang="copy"]
+trait Copy { }
+
+#[repr(C)]
+pub struct Bool {
+    b: bool,
+}
+
+// CHECK: target triple = "x86_64-apple-darwin"
+#[no_mangle]
+pub extern "C" fn structbool() -> Bool {
+    Bool { b: true }
+}
index 039481215f0a6033ee44975173d1cce9cc492017..15403d8d4109d88ba8b4088ab691493304f0ad81 100644 (file)
@@ -6,8 +6,14 @@ all:
        $(RUSTC) bar.rs --target wasm32-unknown-unknown
        $(RUSTC) foo.rs --target wasm32-unknown-unknown
        $(NODE) verify.js $(TMPDIR)/foo.wasm
+       $(RUSTC) main.rs --target wasm32-unknown-unknown
+       $(NODE) verify.js $(TMPDIR)/main.wasm
        $(RUSTC) bar.rs --target wasm32-unknown-unknown -O
        $(RUSTC) foo.rs --target wasm32-unknown-unknown -O
        $(NODE) verify.js $(TMPDIR)/foo.wasm
+       $(RUSTC) main.rs --target wasm32-unknown-unknown -O
+       $(NODE) verify.js $(TMPDIR)/main.wasm
        $(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto
        $(NODE) verify.js $(TMPDIR)/foo.wasm
+       $(RUSTC) main.rs --target wasm32-unknown-unknown -C lto
+       $(NODE) verify.js $(TMPDIR)/main.wasm
diff --git a/src/test/run-make/wasm-export-all-symbols/main.rs b/src/test/run-make/wasm-export-all-symbols/main.rs
new file mode 100644 (file)
index 0000000..0edda7d
--- /dev/null
@@ -0,0 +1,3 @@
+extern crate bar;
+
+fn main() {}
index 0f56fa45c223d876a7d008b8e7f3e78805b5e48f..7b6fc7a45682b2b96bee0f99af97c2662506fb14 100644 (file)
@@ -16,7 +16,13 @@ for (const entry of list) {
   nexports += 1;
 }
 
-if (nexports != 1)
-  throw new Error("should only have one function export");
 if (my_exports.foo === undefined)
   throw new Error("`foo` wasn't defined");
+
+if (my_exports.main === undefined) {
+  if (nexports != 1)
+    throw new Error("should only have one function export");
+} else {
+  if (nexports != 2)
+    throw new Error("should only have two function exports");
+}
index e1b4328debd9a8918e7bea0c3e4aa16326bc31a9..49fd8b8b1ce27031f8111564473cb7b12bb13d92 100644 (file)
@@ -1,7 +1,7 @@
 // edition:2018
 // aux-build:arc_wake.rs
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 extern crate arc_wake;
 
@@ -46,14 +46,14 @@ fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
 
 fn async_block(x: u8) -> impl Future<Output = u8> {
     async move {
-        await!(wake_and_yield_once());
+        wake_and_yield_once().await;
         x
     }
 }
 
 fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
     async move {
-        await!(wake_and_yield_once());
+        wake_and_yield_once().await;
         *x
     }
 }
@@ -61,43 +61,43 @@ fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output =
 fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
     async move {
         let future = async {
-            await!(wake_and_yield_once());
+            wake_and_yield_once().await;
             x
         };
-        await!(future)
+        future.await
     }
 }
 
 fn async_closure(x: u8) -> impl Future<Output = u8> {
     (async move |x: u8| -> u8 {
-        await!(wake_and_yield_once());
+        wake_and_yield_once().await;
         x
     })(x)
 }
 
 async fn async_fn(x: u8) -> u8 {
-    await!(wake_and_yield_once());
+    wake_and_yield_once().await;
     x
 }
 
 async fn generic_async_fn<T>(x: T) -> T {
-    await!(wake_and_yield_once());
+    wake_and_yield_once().await;
     x
 }
 
 async fn async_fn_with_borrow(x: &u8) -> u8 {
-    await!(wake_and_yield_once());
+    wake_and_yield_once().await;
     *x
 }
 
 async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 {
-    await!(wake_and_yield_once());
+    wake_and_yield_once().await;
     *x
 }
 
 fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
     async move {
-        await!(wake_and_yield_once());
+        wake_and_yield_once().await;
         *x
     }
 }
@@ -110,18 +110,18 @@ async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
 */
 
 async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 {
-    await!(wake_and_yield_once());
+    wake_and_yield_once().await;
     *x
 }
 
 fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
     async move {
-        await!(async_fn_with_borrow_named_lifetime(&y))
+        async_fn_with_borrow_named_lifetime(&y).await
     }
 }
 
 unsafe async fn unsafe_async_fn(x: u8) -> u8 {
-    await!(wake_and_yield_once());
+    wake_and_yield_once().await;
     x
 }
 
@@ -134,7 +134,7 @@ fn foo() {}
 impl Foo {
     async fn async_method(x: u8) -> u8 {
         unsafe {
-            await!(unsafe_async_fn(x))
+            unsafe_async_fn(x).await
         }
     }
 }
@@ -165,7 +165,7 @@ macro_rules! test_with_borrow {
         ($($fn_name:expr,)*) => { $(
             test_future_yields_once_then_returns(|x| {
                 async move {
-                    await!($fn_name(&x))
+                    $fn_name(&x).await
                 }
             });
         )* }
@@ -181,7 +181,7 @@ macro_rules! test_with_borrow {
         Foo::async_method,
         |x| {
             async move {
-                unsafe { await!(unsafe_async_fn(x)) }
+                unsafe { unsafe_async_fn(x).await }
             }
         },
     }
@@ -192,7 +192,7 @@ macro_rules! test_with_borrow {
         async_fn_with_impl_future_named_lifetime,
         |x| {
             async move {
-                await!(async_fn_multiple_args_named_lifetime(x, x))
+                async_fn_multiple_args_named_lifetime(x, x).await
             }
         },
     }
diff --git a/src/test/run-pass/await-macro.rs b/src/test/run-pass/await-macro.rs
new file mode 100644 (file)
index 0000000..e1b4328
--- /dev/null
@@ -0,0 +1,199 @@
+// edition:2018
+// aux-build:arc_wake.rs
+
+#![feature(async_await, await_macro)]
+
+extern crate arc_wake;
+
+use std::pin::Pin;
+use std::future::Future;
+use std::sync::{
+    Arc,
+    atomic::{self, AtomicUsize},
+};
+use std::task::{Context, Poll};
+use arc_wake::ArcWake;
+
+struct Counter {
+    wakes: AtomicUsize,
+}
+
+impl ArcWake for Counter {
+    fn wake(self: Arc<Self>) {
+        Self::wake_by_ref(&self)
+    }
+    fn wake_by_ref(arc_self: &Arc<Self>) {
+        arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+}
+
+struct WakeOnceThenComplete(bool);
+
+fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
+
+impl Future for WakeOnceThenComplete {
+    type Output = ();
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+        if self.0 {
+            Poll::Ready(())
+        } else {
+            cx.waker().wake_by_ref();
+            self.0 = true;
+            Poll::Pending
+        }
+    }
+}
+
+fn async_block(x: u8) -> impl Future<Output = u8> {
+    async move {
+        await!(wake_and_yield_once());
+        x
+    }
+}
+
+fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
+    async move {
+        await!(wake_and_yield_once());
+        *x
+    }
+}
+
+fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
+    async move {
+        let future = async {
+            await!(wake_and_yield_once());
+            x
+        };
+        await!(future)
+    }
+}
+
+fn async_closure(x: u8) -> impl Future<Output = u8> {
+    (async move |x: u8| -> u8 {
+        await!(wake_and_yield_once());
+        x
+    })(x)
+}
+
+async fn async_fn(x: u8) -> u8 {
+    await!(wake_and_yield_once());
+    x
+}
+
+async fn generic_async_fn<T>(x: T) -> T {
+    await!(wake_and_yield_once());
+    x
+}
+
+async fn async_fn_with_borrow(x: &u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+
+async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+
+fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
+    async move {
+        await!(wake_and_yield_once());
+        *x
+    }
+}
+
+/* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works
+async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+*/
+
+async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+
+fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
+    async move {
+        await!(async_fn_with_borrow_named_lifetime(&y))
+    }
+}
+
+unsafe async fn unsafe_async_fn(x: u8) -> u8 {
+    await!(wake_and_yield_once());
+    x
+}
+
+struct Foo;
+
+trait Bar {
+    fn foo() {}
+}
+
+impl Foo {
+    async fn async_method(x: u8) -> u8 {
+        unsafe {
+            await!(unsafe_async_fn(x))
+        }
+    }
+}
+
+fn test_future_yields_once_then_returns<F, Fut>(f: F)
+where
+    F: FnOnce(u8) -> Fut,
+    Fut: Future<Output = u8>,
+{
+    let mut fut = Box::pin(f(9));
+    let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
+    let waker = ArcWake::into_waker(counter.clone());
+    let mut cx = Context::from_waker(&waker);
+    assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx));
+    assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx));
+}
+
+fn main() {
+    macro_rules! test {
+        ($($fn_name:expr,)*) => { $(
+            test_future_yields_once_then_returns($fn_name);
+        )* }
+    }
+
+    macro_rules! test_with_borrow {
+        ($($fn_name:expr,)*) => { $(
+            test_future_yields_once_then_returns(|x| {
+                async move {
+                    await!($fn_name(&x))
+                }
+            });
+        )* }
+    }
+
+    test! {
+        async_block,
+        async_nonmove_block,
+        async_closure,
+        async_fn,
+        generic_async_fn,
+        async_fn_with_internal_borrow,
+        Foo::async_method,
+        |x| {
+            async move {
+                unsafe { await!(unsafe_async_fn(x)) }
+            }
+        },
+    }
+    test_with_borrow! {
+        async_block_with_borrow_named_lifetime,
+        async_fn_with_borrow,
+        async_fn_with_borrow_named_lifetime,
+        async_fn_with_impl_future_named_lifetime,
+        |x| {
+            async move {
+                await!(async_fn_multiple_args_named_lifetime(x, x))
+            }
+        },
+    }
+}
diff --git a/src/test/run-pass/generator/issue-59972.rs b/src/test/run-pass/generator/issue-59972.rs
new file mode 100644 (file)
index 0000000..995da4f
--- /dev/null
@@ -0,0 +1,23 @@
+// compile-flags: --edition=2018
+
+#![feature(async_await, await_macro)]
+
+pub enum Uninhabited { }
+
+fn uninhabited_async() -> Uninhabited {
+    unreachable!()
+}
+
+async fn noop() { }
+
+#[allow(unused)]
+async fn contains_never() {
+    let error = uninhabited_async();
+    await!(noop());
+    let error2 = error;
+}
+
+#[allow(unused_must_use)]
+fn main() {
+    contains_never();
+}
index 12be6582a21e8e5df40d5dd24b7396ebcd3eae03..b7e60b773b416be29340e2330ab565894996a8c7 100644 (file)
@@ -1,7 +1,7 @@
 // edition:2018
 // run-pass
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 trait Foo { }
 
@@ -14,15 +14,15 @@ async fn foo_async<T>(_v: T) -> u8 where T: Foo {
 }
 
 async fn bad<T>(v: T) -> u8 where T: Foo {
-    await!(foo_async(v))
+    foo_async(v).await
 }
 
 async fn async_main() {
     let mut v = ();
 
-    let _ = await!(bad(&mut v));
-    let _ = await!(foo_async(&mut v));
-    let _ = await!(bad(v));
+    let _ = bad(&mut v).await;
+    let _ = foo_async(&mut v).await;
+    let _ = bad(v).await;
 }
 
 fn main() {
diff --git a/src/test/ui/async-await/argument-patterns.rs b/src/test/ui/async-await/argument-patterns.rs
new file mode 100644 (file)
index 0000000..3750c2b
--- /dev/null
@@ -0,0 +1,30 @@
+// edition:2018
+// run-pass
+
+#![allow(unused_variables)]
+#![deny(unused_mut)]
+#![feature(async_await)]
+
+type A = Vec<u32>;
+
+async fn a(n: u32, mut vec: A) {
+    vec.push(n);
+}
+
+async fn b(n: u32, ref mut vec: A) {
+    vec.push(n);
+}
+
+async fn c(ref vec: A) {
+    vec.contains(&0);
+}
+
+async fn d((a, mut b): (A, A)) {
+    b.push(1);
+}
+
+async fn f((ref mut a, ref b): (A, A)) {}
+
+async fn g(((ref a, ref mut b), (ref mut c, ref d)): ((A, A), (A, A))) {}
+
+fn main() {}
diff --git a/src/test/ui/async-await/drop-order-for-async-fn-parameters-by-ref-binding.rs b/src/test/ui/async-await/drop-order-for-async-fn-parameters-by-ref-binding.rs
new file mode 100644 (file)
index 0000000..c2b59ee
--- /dev/null
@@ -0,0 +1,271 @@
+// aux-build:arc_wake.rs
+// edition:2018
+// run-pass
+
+#![allow(unused_variables)]
+#![feature(async_await, await_macro)]
+
+// Test that the drop order for parameters in a fn and async fn matches up. Also test that
+// parameters (used or unused) are not dropped until the async fn completes execution.
+// See also #54716.
+
+extern crate arc_wake;
+
+use arc_wake::ArcWake;
+use std::cell::RefCell;
+use std::future::Future;
+use std::marker::PhantomData;
+use std::sync::Arc;
+use std::rc::Rc;
+use std::task::Context;
+
+struct EmptyWaker;
+
+impl ArcWake for EmptyWaker {
+    fn wake(self: Arc<Self>) {}
+}
+
+#[derive(Debug, Eq, PartialEq)]
+enum DropOrder {
+    Function,
+    Val(&'static str),
+}
+
+type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
+
+struct D(&'static str, DropOrderListPtr);
+
+impl Drop for D {
+    fn drop(&mut self) {
+        self.1.borrow_mut().push(DropOrder::Val(self.0));
+    }
+}
+
+/// Check that unused bindings are dropped after the function is polled.
+async fn foo_async(ref mut x: D, ref mut _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn foo_sync(ref mut x: D, ref mut _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore patterns are dropped after the function is polled.
+async fn bar_async(ref mut x: D, _: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn bar_sync(ref mut x: D, _: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore patterns within more complex patterns are dropped after the function
+/// is polled.
+async fn baz_async((ref mut x, _): (D, D)) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn baz_sync((ref mut x, _): (D, D)) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore and unused bindings within and outwith more complex patterns are dropped
+/// after the function is polled.
+async fn foobar_async(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn foobar_sync(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+struct Foo;
+
+impl Foo {
+    /// Check that unused bindings are dropped after the method is polled.
+    async fn foo_async(ref mut x: D, ref mut _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foo_sync(ref mut x: D, ref mut _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns are dropped after the method is polled.
+    async fn bar_async(ref mut x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn bar_sync(ref mut x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns within more complex patterns are dropped after the method
+    /// is polled.
+    async fn baz_async((ref mut x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn baz_sync((ref mut x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore and unused bindings within and outwith more complex patterns are
+    /// dropped after the method is polled.
+    async fn foobar_async(
+        ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
+    ) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foobar_sync(
+        ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
+    ) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+}
+
+struct Bar<'a>(PhantomData<&'a ()>);
+
+impl<'a> Bar<'a> {
+    /// Check that unused bindings are dropped after the method with self is polled.
+    async fn foo_async(&'a self, ref mut x: D, ref mut _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foo_sync(&'a self, ref mut x: D, ref mut _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns are dropped after the method with self is polled.
+    async fn bar_async(&'a self, ref mut x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn bar_sync(&'a self, ref mut x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns within more complex patterns are dropped after the method
+    /// with self is polled.
+    async fn baz_async(&'a self, (ref mut x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn baz_sync(&'a self, (ref mut x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore and unused bindings within and outwith more complex patterns are
+    /// dropped after the method with self is polled.
+    async fn foobar_async(
+        &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
+    ) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foobar_sync(
+        &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
+    ) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+}
+
+fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
+    f: impl FnOnce(DropOrderListPtr) -> Fut,
+    g: impl FnOnce(DropOrderListPtr),
+) {
+    let empty = Arc::new(EmptyWaker);
+    let waker = ArcWake::into_waker(empty);
+    let mut cx = Context::from_waker(&waker);
+
+    let actual_order = Rc::new(RefCell::new(Vec::new()));
+    let mut fut = Box::pin(f(actual_order.clone()));
+    let _ = fut.as_mut().poll(&mut cx);
+
+    let expected_order = Rc::new(RefCell::new(Vec::new()));
+    g(expected_order.clone());
+
+    assert_eq!(*actual_order.borrow(), *expected_order.borrow());
+}
+
+fn main() {
+    // Free functions (see doc comment on function for what it tests).
+    assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+
+    // Methods w/out self (see doc comment on function for what it tests).
+    assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            Foo::foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            Foo::foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+
+    // Methods (see doc comment on function for what it tests).
+    let b = Bar(Default::default());
+    assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            b.foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            b.foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+}
index 10dc5e27f6f9f26763d31fd723d64cc16a20a4fe..bcdb8878eb5d225333dfc6f15c6da9d61f4be331 100644 (file)
@@ -8,4 +8,9 @@ async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) {
     assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` in this scope [E0425]
 }
 
+async fn baz_async(ref mut x: u32, ref y: u32) {
+    assert_eq!(__arg0, 1); //~ ERROR cannot find value `__arg0` in this scope [E0425]
+    assert_eq!(__arg1, 2); //~ ERROR cannot find value `__arg1` in this scope [E0425]
+}
+
 fn main() {}
index ca0da6b7c962add94c48989232011b95477ca0b0..484e1f4f4269ede5589f301a640046ca957eed2d 100644 (file)
@@ -10,6 +10,18 @@ error[E0425]: cannot find value `__arg2` in this scope
 LL |     assert_eq!(__arg2, 4);
    |                ^^^^^^ not found in this scope
 
-error: aborting due to 2 previous errors
+error[E0425]: cannot find value `__arg0` in this scope
+  --> $DIR/drop-order-locals-are-hidden.rs:12:16
+   |
+LL |     assert_eq!(__arg0, 1);
+   |                ^^^^^^ not found in this scope
+
+error[E0425]: cannot find value `__arg1` in this scope
+  --> $DIR/drop-order-locals-are-hidden.rs:13:16
+   |
+LL |     assert_eq!(__arg1, 2);
+   |                ^^^^^^ not found in this scope
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/async-await/mutable-arguments.rs b/src/test/ui/async-await/mutable-arguments.rs
deleted file mode 100644 (file)
index 4d6dba7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// edition:2018
-// run-pass
-
-#![feature(async_await)]
-
-async fn foo(n: u32, mut vec: Vec<u32>) {
-    vec.push(n);
-}
-
-fn main() {}
diff --git a/src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.rs b/src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.rs
new file mode 100644 (file)
index 0000000..c4f3f3e
--- /dev/null
@@ -0,0 +1,36 @@
+#![feature(async_await, await_macro)]
+#![allow(non_camel_case_types)]
+#![deny(keyword_idents)]
+
+mod outer_mod {
+    pub mod await { //~ ERROR `await` is a keyword in the 2018 edition
+    //~^ WARN this was previously accepted by the compiler
+        pub struct await; //~ ERROR `await` is a keyword in the 2018 edition
+        //~^ WARN this was previously accepted by the compiler
+    }
+}
+use outer_mod::await::await; //~ ERROR `await` is a keyword in the 2018 edition
+//~^ ERROR `await` is a keyword in the 2018 edition
+//~^^ WARN this was previously accepted by the compiler
+//~^^^ WARN this was previously accepted by the compiler
+
+struct Foo { await: () }
+//~^ ERROR `await` is a keyword in the 2018 edition
+//~^^ WARN this was previously accepted by the compiler
+
+impl Foo { fn await() {} }
+//~^ ERROR `await` is a keyword in the 2018 edition
+//~^^ WARN this was previously accepted by the compiler
+
+macro_rules! await {
+//~^ ERROR `await` is a keyword in the 2018 edition
+//~^^ WARN this was previously accepted by the compiler
+    () => {}
+}
+
+fn main() {
+    match await { await => {} } //~ ERROR `await` is a keyword in the 2018 edition
+    //~^ ERROR `await` is a keyword in the 2018 edition
+    //~^^ WARN this was previously accepted by the compiler
+    //~^^^ WARN this was previously accepted by the compiler
+}
diff --git a/src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.stderr b/src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.stderr
new file mode 100644 (file)
index 0000000..067ecd6
--- /dev/null
@@ -0,0 +1,88 @@
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:6:13
+   |
+LL |     pub mod await {
+   |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+note: lint level defined here
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:3:9
+   |
+LL | #![deny(keyword_idents)]
+   |         ^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:8:20
+   |
+LL |         pub struct await;
+   |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:12:16
+   |
+LL | use outer_mod::await::await;
+   |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:12:23
+   |
+LL | use outer_mod::await::await;
+   |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:17:14
+   |
+LL | struct Foo { await: () }
+   |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:21:15
+   |
+LL | impl Foo { fn await() {} }
+   |               ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:25:14
+   |
+LL | macro_rules! await {
+   |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:32:11
+   |
+LL |     match await { await => {} }
+   |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:32:19
+   |
+LL |     match await { await => {} }
+   |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/await-keyword/2015-edition-no-warnings-with-feature-gate.rs b/src/test/ui/await-keyword/2015-edition-no-warnings-with-feature-gate.rs
deleted file mode 100644 (file)
index 92c60e7..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// compile-pass
-
-#![feature(async_await)]
-#![allow(non_camel_case_types)]
-#![deny(keyword_idents)]
-
-mod outer_mod {
-    pub mod await {
-        pub struct await;
-    }
-}
-use outer_mod::await::await;
-
-fn main() {
-    match await { await => {} }
-}
diff --git a/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs
new file mode 100644 (file)
index 0000000..b2e8e4b
--- /dev/null
@@ -0,0 +1,27 @@
+// edition:2018
+
+#![allow(non_camel_case_types)]
+#![feature(async_await, await_macro)]
+
+mod outer_mod {
+    pub mod await { //~ ERROR expected identifier, found reserved keyword `await`
+        pub struct await; //~ ERROR expected identifier, found reserved keyword `await`
+    }
+}
+use self::outer_mod::await::await; //~ ERROR expected identifier, found reserved keyword `await`
+//~^ ERROR expected identifier, found reserved keyword `await`
+
+struct Foo { await: () }
+//~^ ERROR expected identifier, found reserved keyword `await`
+
+impl Foo { fn await() {} }
+//~^ ERROR expected identifier, found reserved keyword `await`
+
+macro_rules! await {
+//~^ ERROR expected identifier, found reserved keyword `await`
+    () => {}
+}
+
+fn main() {
+    match await { await => () } //~ ERROR expected `!`, found `{`
+}
diff --git a/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr b/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr
new file mode 100644 (file)
index 0000000..076a31b
--- /dev/null
@@ -0,0 +1,80 @@
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:7:13
+   |
+LL |     pub mod await {
+   |             ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     pub mod r#await {
+   |             ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:8:20
+   |
+LL |         pub struct await;
+   |                    ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |         pub struct r#await;
+   |                    ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:11:22
+   |
+LL | use self::outer_mod::await::await;
+   |                      ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | use self::outer_mod::r#await::await;
+   |                      ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:11:29
+   |
+LL | use self::outer_mod::await::await;
+   |                             ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | use self::outer_mod::await::r#await;
+   |                             ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:14:14
+   |
+LL | struct Foo { await: () }
+   |              ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | struct Foo { r#await: () }
+   |              ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:17:15
+   |
+LL | impl Foo { fn await() {} }
+   |               ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | impl Foo { fn r#await() {} }
+   |               ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:20:14
+   |
+LL | macro_rules! await {
+   |              ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | macro_rules! r#await {
+   |              ^^^^^^^
+
+error: expected `!`, found `{`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:26:17
+   |
+LL |     match await { await => () }
+   |     -----       ^ expected `!`
+   |     |
+   |     while parsing this match expression
+
+error: aborting due to 8 previous errors
+
index 7ba3382ddf1298229797b850a8840d180d8fe03b..e0b2962ce9791975acab3dc4bb0d8f7c6c0fd71d 100644 (file)
@@ -2,14 +2,13 @@
 #![allow(non_camel_case_types)]
 
 mod outer_mod {
-    pub mod await { //~ ERROR `await` is a keyword
-        pub struct await; //~ ERROR `await` is a keyword
+    pub mod await { //~ ERROR expected identifier
+        pub struct await; //~ ERROR expected identifier
     }
 }
-use self::outer_mod::await::await; //~ ERROR `await` is a keyword
-    //~^ ERROR `await` is a keyword
+use self::outer_mod::await::await; //~ ERROR expected identifier
+    //~^ ERROR expected identifier, found reserved keyword `await`
 
 fn main() {
-    match await { await => () } //~ ERROR `await` is a keyword
-    //~^ ERROR `await` is a keyword
+    match await { await => () } //~ ERROR expected `!`, found `{`
 }
index 67ff6c5675abfd7a0361fd57e852dff571e375ec..c8bf9b42ca5459f1b28e86c23135ef44d39659c9 100644 (file)
@@ -1,38 +1,50 @@
-error[E0721]: `await` is a keyword in the 2018 edition
+error: expected identifier, found reserved keyword `await`
   --> $DIR/2018-edition-error.rs:5:13
    |
 LL |     pub mod await {
-   |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |             ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     pub mod r#await {
+   |             ^^^^^^^
 
-error[E0721]: `await` is a keyword in the 2018 edition
+error: expected identifier, found reserved keyword `await`
   --> $DIR/2018-edition-error.rs:6:20
    |
 LL |         pub struct await;
-   |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |                    ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |         pub struct r#await;
+   |                    ^^^^^^^
 
-error[E0721]: `await` is a keyword in the 2018 edition
+error: expected identifier, found reserved keyword `await`
   --> $DIR/2018-edition-error.rs:9:22
    |
 LL | use self::outer_mod::await::await;
-   |                      ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |                      ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | use self::outer_mod::r#await::await;
+   |                      ^^^^^^^
 
-error[E0721]: `await` is a keyword in the 2018 edition
+error: expected identifier, found reserved keyword `await`
   --> $DIR/2018-edition-error.rs:9:29
    |
 LL | use self::outer_mod::await::await;
-   |                             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-
-error[E0721]: `await` is a keyword in the 2018 edition
-  --> $DIR/2018-edition-error.rs:13:11
+   |                             ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
    |
-LL |     match await { await => () }
-   |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+LL | use self::outer_mod::await::r#await;
+   |                             ^^^^^^^
 
-error[E0721]: `await` is a keyword in the 2018 edition
-  --> $DIR/2018-edition-error.rs:13:19
+error: expected `!`, found `{`
+  --> $DIR/2018-edition-error.rs:13:17
    |
 LL |     match await { await => () }
-   |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |     -----       ^ expected `!`
+   |     |
+   |     while parsing this match expression
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/await-keyword/2018-edition-no-error-with-feature-gate.rs b/src/test/ui/await-keyword/2018-edition-no-error-with-feature-gate.rs
deleted file mode 100644 (file)
index 52d32c8..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![allow(non_camel_case_types)]
-#![feature(async_await)]
-
-mod outer_mod {
-    pub mod await {
-        pub struct await;
-    }
-}
-use self::outer_mod::await::await;
-
-fn main() {
-    match await { await => () }
-}
index 96dd48052def876cc7a3951334cf12bc8de07065..b4c899b0d0295b6b77b0fd45a5b0640dd51ad754 100644 (file)
@@ -6,5 +6,5 @@ macro_rules! r#await {
 
 fn main() {
     await!()
-    //~^ ERROR `await` is a keyword
+    //~^ ERROR expected expression, found `)`
 }
index 9483f77422759215a3287594fda81e3904e8c561..0996c38b3b6c61f18efcbefa970c498b3457bf8b 100644 (file)
@@ -1,8 +1,8 @@
-error[E0721]: `await` is a keyword in the 2018 edition
-  --> $DIR/post_expansion_error.rs:8:5
+error: expected expression, found `)`
+  --> $DIR/post_expansion_error.rs:8:12
    |
 LL |     await!()
-   |     ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |            ^ expected expression
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/concrete-const-as-fn-arg.rs b/src/test/ui/const-generics/concrete-const-as-fn-arg.rs
new file mode 100644 (file)
index 0000000..54981b7
--- /dev/null
@@ -0,0 +1,14 @@
+// Test that a concrete const type i.e. A<2>, can be used as an argument type in a function
+// run-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+struct A<const N: usize>; // ok
+
+fn with_concrete_const_arg(_: A<2>) -> u32 { 17 }
+
+fn main() {
+    let val: A<2> = A;
+    assert_eq!(with_concrete_const_arg(val), 17);
+}
diff --git a/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr b/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr
new file mode 100644 (file)
index 0000000..955b319
--- /dev/null
@@ -0,0 +1,6 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/concrete-const-as-fn-arg.rs:4:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+
diff --git a/src/test/ui/const-generics/concrete-const-impl-method.rs b/src/test/ui/const-generics/concrete-const-impl-method.rs
new file mode 100644 (file)
index 0000000..226ea41
--- /dev/null
@@ -0,0 +1,24 @@
+// Test that a method/associated non-method within an impl block of a concrete const type i.e. A<2>,
+// is callable.
+// run-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+pub struct A<const N: u32>;
+
+impl A<2> {
+    fn impl_method(&self) -> u32 {
+        17
+    }
+
+    fn associated_non_method() -> u32 {
+        17
+    }
+}
+
+fn main() {
+    let val: A<2> = A;
+    assert_eq!(val.impl_method(), 17);
+    assert_eq!(A::<2>::associated_non_method(), 17);
+}
diff --git a/src/test/ui/const-generics/concrete-const-impl-method.stderr b/src/test/ui/const-generics/concrete-const-impl-method.stderr
new file mode 100644 (file)
index 0000000..3ce488c
--- /dev/null
@@ -0,0 +1,6 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/concrete-const-impl-method.rs:5:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+
index 662c7b767bae06e550891842d1deac0e556947dc..22c6c351622817fd29a28338b59add36ffe24858 100644 (file)
@@ -6,7 +6,7 @@ fn i32_identity<const X: i32>() -> i32 {
 }
 
 fn foo_a() {
-    i32_identity::<-1>(); //~ ERROR expected identifier, found `<-`
+    i32_identity::<-1>(); // ok
 }
 
 fn foo_b() {
index 2f7a80f0c8fde5ef68441a7c3194cec9fa2b1c8f..c255127c28079a436c170b36b02dd120ebbbeca1 100644 (file)
@@ -1,9 +1,3 @@
-error: expected identifier, found `<-`
-  --> $DIR/const-expression-parameter.rs:9:19
-   |
-LL |     i32_identity::<-1>();
-   |                   ^^ expected identifier
-
 error: expected one of `,` or `>`, found `+`
   --> $DIR/const-expression-parameter.rs:13:22
    |
@@ -16,5 +10,5 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t
 LL | #![feature(const_generics)]
    |            ^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/issue-60263.rs b/src/test/ui/const-generics/issue-60263.rs
new file mode 100644 (file)
index 0000000..70cbc24
--- /dev/null
@@ -0,0 +1,9 @@
+struct B<const I: u8>; //~ ERROR const generics are unstable
+
+impl B<0> {
+    fn bug() -> Self {
+        panic!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issue-60263.stderr b/src/test/ui/const-generics/issue-60263.stderr
new file mode 100644 (file)
index 0000000..ab1b9e4
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: const generics are unstable
+  --> $DIR/issue-60263.rs:1:16
+   |
+LL | struct B<const I: u8>;
+   |                ^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/44580
+   = help: add #![feature(const_generics)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
index 603efe449f143160fe88f5f52c2cd391c2589dd2..e45ce65d8bb3522222212dd41a3587bb337de1a1 100644 (file)
@@ -1,5 +1,3 @@
-warning: due to multiple output types requested, the explicitly specified output file name will be adapted for each output type
-
 error: any use of this value will cause an error
   --> $DIR/unused-broken-const.rs:5:18
    |
diff --git a/src/test/ui/emit-artifact-notifications.nll.stderr b/src/test/ui/emit-artifact-notifications.nll.stderr
new file mode 100644 (file)
index 0000000..347d9ae
--- /dev/null
@@ -0,0 +1 @@
+{"artifact":"$TEST_BUILD_DIR/emit-artifact-notifications.nll/libemit_artifact_notifications.rmeta"}
diff --git a/src/test/ui/emit-artifact-notifications.rs b/src/test/ui/emit-artifact-notifications.rs
new file mode 100644 (file)
index 0000000..c2c930c
--- /dev/null
@@ -0,0 +1,6 @@
+// compile-flags:--emit=metadata --error-format=json -Z emit-artifact-notifications
+// compile-pass
+
+// A very basic test for the emission of artifact notifications in JSON output.
+
+fn main() {}
diff --git a/src/test/ui/emit-artifact-notifications.stderr b/src/test/ui/emit-artifact-notifications.stderr
new file mode 100644 (file)
index 0000000..56c9771
--- /dev/null
@@ -0,0 +1 @@
+{"artifact":"$TEST_BUILD_DIR/emit-artifact-notifications/libemit_artifact_notifications.rmeta"}
diff --git a/src/test/ui/emit-directives.rs b/src/test/ui/emit-directives.rs
deleted file mode 100644 (file)
index 088280e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// ignore-tidy-linelength
-// compile-flags:--emit=metadata --error-format=json -Z emit-directives
-// compile-pass
-//
-// Normalization is required to eliminated minor path and filename differences
-// across platforms.
-// normalize-stderr-test: "metadata file written: .*/emit-directives" -> "metadata file written: .../emit-directives"
-// normalize-stderr-test: "emit-directives(\.\w*)?/a(\.\w*)?" -> "emit-directives/a"
-
-// A very basic test for the emission of build directives in JSON output.
-
-fn main() {}
diff --git a/src/test/ui/emit-directives.stderr b/src/test/ui/emit-directives.stderr
deleted file mode 100644 (file)
index b8a4b96..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"directive":"metadata file written: .../emit-directives/a"}
diff --git a/src/test/ui/feature-gate/await-macro.rs b/src/test/ui/feature-gate/await-macro.rs
new file mode 100644 (file)
index 0000000..291db9b
--- /dev/null
@@ -0,0 +1,12 @@
+// gate-test-await_macro
+// edition:2018
+
+#![feature(async_await)]
+
+async fn bar() {}
+
+async fn foo() {
+    await!(bar()); //~ ERROR `await!(<expr>)` macro syntax is unstable, and will soon be removed
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gate/await-macro.stderr b/src/test/ui/feature-gate/await-macro.stderr
new file mode 100644 (file)
index 0000000..b683365
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: `await!(<expr>)` macro syntax is unstable, and will soon be removed in favor of `<expr>.await` syntax.
+  --> $DIR/await-macro.rs:9:5
+   |
+LL |     await!(bar());
+   |     ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
+   = help: add #![feature(await_macro)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
index 30788e3c1864bb1935c4ae4a1ee029b74c6e56a6..fd5266798187307a66f77fd2d58b8f68bf875566 100644 (file)
@@ -13,7 +13,7 @@ pub fn want_cyclic_generator_return<T>(_: T)
 
 fn supply_cyclic_generator_return() {
     want_cyclic_generator_return(|| {
-        //~^ ERROR type mismatch
+        //~^ ERROR closure/generator type that references itself
         if false { yield None.unwrap(); }
         None.unwrap()
     })
index 5834aed2450b1a184fa2a50f233205d9de65f05e..42591683fe4e327abea54e92bc9a61ed00aba4b9 100644 (file)
@@ -1,20 +1,17 @@
-error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 19:6 _] as std::ops::Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 19:6 _]`
-  --> $DIR/generator-yielding-or-returning-itself.rs:15:5
+error[E0644]: closure/generator type that references itself
+  --> $DIR/generator-yielding-or-returning-itself.rs:15:34
    |
-LL |     want_cyclic_generator_return(|| {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+LL |       want_cyclic_generator_return(|| {
+   |  __________________________________^
+LL | |
+LL | |         if false { yield None.unwrap(); }
+LL | |         None.unwrap()
+LL | |     })
+   | |_____^ cyclic type of infinite size
    |
    = note: closures cannot capture themselves or take themselves as argument;
            this error may be the result of a recent compiler bug-fix,
            see https://github.com/rust-lang/rust/issues/46062 for more details
-note: required by `want_cyclic_generator_return`
-  --> $DIR/generator-yielding-or-returning-itself.rs:9:1
-   |
-LL | / pub fn want_cyclic_generator_return<T>(_: T)
-LL | |     where T: Generator<Yield = (), Return = T>
-LL | | {
-LL | | }
-   | |_^
 
 error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6 _] as std::ops::Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6 _]`
   --> $DIR/generator-yielding-or-returning-itself.rs:28:5
@@ -36,4 +33,5 @@ LL | | }
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0271, E0644.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.rs b/src/test/ui/generator/type-mismatch-signature-deduction.rs
new file mode 100644 (file)
index 0000000..b9c6bc5
--- /dev/null
@@ -0,0 +1,17 @@
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+
+fn foo() -> impl Generator<Return = i32> {
+    || {
+        if false {
+            return Ok(6); //~ ERROR mismatched types [E0308]
+        }
+
+        yield ();
+
+        5
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr
new file mode 100644 (file)
index 0000000..35d3f95
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch-signature-deduction.rs:8:20
+   |
+LL |             return Ok(6);
+   |                    ^^^^^ expected i32, found enum `std::result::Result`
+   |
+   = note: expected type `i32`
+              found type `std::result::Result<{integer}, _>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
index f49369b125f6fa5dcd72bea3f8a099c54b2ff465..77174b03217829661093ca8b391bd0f7210489be 100644 (file)
@@ -2,13 +2,14 @@
 // Error message should pinpoint the type parameter T as needing to be bound
 // (rather than give a general error message)
 // edition:2018
-#![feature(futures_api, async_await, await_macro)]
+#![feature(async_await)]
 async fn bar<T>() -> () {}
 
 async fn foo() {
-        await!(bar());
-        //~^ ERROR type inside generator must be known in this context
-        //~| NOTE cannot infer type for `T`
-        //~| NOTE the type is part of the generator because of this `yield`
+    bar().await;
+    //~^ ERROR type inside generator must be known in this context
+    //~| NOTE cannot infer type for `T`
+    //~| NOTE the type is part of the generator because of this `yield`
+    //~| NOTE in this expansion of desugaring of `await`
 }
 fn main() {}
index 57ccdda3f43a19b07718ea56c31ec07c3642d8df..afb9adf4c77cc019005117079f9577d23f90192e 100644 (file)
@@ -1,15 +1,14 @@
 error[E0698]: type inside generator must be known in this context
-  --> $DIR/unresolved_type_param.rs:9:16
+  --> $DIR/unresolved_type_param.rs:9:5
    |
-LL |         await!(bar());
-   |                ^^^ cannot infer type for `T`
+LL |     bar().await;
+   |     ^^^ cannot infer type for `T`
    |
 note: the type is part of the generator because of this `yield`
-  --> $DIR/unresolved_type_param.rs:9:9
+  --> $DIR/unresolved_type_param.rs:9:5
    |
-LL |         await!(bar());
-   |         ^^^^^^^^^^^^^^
-   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+LL |     bar().await;
+   |     ^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-51719.rs b/src/test/ui/issues/issue-51719.rs
new file mode 100644 (file)
index 0000000..2c02ac0
--- /dev/null
@@ -0,0 +1,11 @@
+// edition:2018
+//
+// Tests that the .await syntax can't be used to make a generator
+
+#![feature(async_await)]
+
+async fn foo() {}
+
+fn make_generator() {
+    let _gen = || foo.await; //~ ERROR `await` is only allowed inside `async` functions and blocks
+}
diff --git a/src/test/ui/issues/issue-51719.stderr b/src/test/ui/issues/issue-51719.stderr
new file mode 100644 (file)
index 0000000..768909b
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-51719.rs:10:19
+   |
+LL |     let _gen = || foo.await;
+   |                   ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-51751.rs b/src/test/ui/issues/issue-51751.rs
new file mode 100644 (file)
index 0000000..7afd7ec
--- /dev/null
@@ -0,0 +1,13 @@
+// edition:2018
+
+#![feature(async_await)]
+
+async fn inc(limit: i64) -> i64 {
+    limit + 1
+}
+
+fn main() {
+    let result = inc(10000);
+    let finished = result.await;
+    //~^ ERROR `await` is only allowed inside `async` functions and blocks
+}
diff --git a/src/test/ui/issues/issue-51751.stderr b/src/test/ui/issues/issue-51751.stderr
new file mode 100644 (file)
index 0000000..0c4cb03
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-51751.rs:11:20
+   |
+LL |     let finished = result.await;
+   |                    ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
index 46c083f93059116ce2f0a0ed763ff8ed23435e49..3e9f612a2afee3af146ae55bf3b239d65390b53f 100644 (file)
@@ -1,5 +1,8 @@
 // compile-pass
 
+// FIXME(eddyb) shorten the name so windows doesn't choke on it.
+#![crate_name = "trait_test"]
+
 // Regression test related to #56288. Check that a supertrait projection (of
 // `Output`) that references `Self` is ok if there is another occurence of
 // the same supertrait that specifies the projection explicitly, even if
index beb8fcb5248dc2e6aa488af9613216d5ccb31c6a..759b6161a328db1d4863139e90875308ecd25a75 160000 (submodule)
@@ -1 +1 @@
-Subproject commit beb8fcb5248dc2e6aa488af9613216d5ccb31c6a
+Subproject commit 759b6161a328db1d4863139e90875308ecd25a75
index fc96aa036884183ddc68d2659f4633e6f138b4e0..341c96afd331195beeb001436535c1feb479ff9d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit fc96aa036884183ddc68d2659f4633e6f138b4e0
+Subproject commit 341c96afd331195beeb001436535c1feb479ff9d
index fb6ada89171abadb3ab66a0eb07bef55d63dfa0b..54e9b76a21ee07920fff3862cb9b5166f38528cb 100644 (file)
@@ -305,6 +305,9 @@ pub struct TestProps {
     pub extern_private: Vec<String>,
     // Environment settings to use for compiling
     pub rustc_env: Vec<(String, String)>,
+    // Environment variables to unset prior to compiling.
+    // Variables are unset before applying 'rustc_env'.
+    pub unset_rustc_env: Vec<String>,
     // Environment settings to use during execution
     pub exec_env: Vec<(String, String)>,
     // Lines to check if they appear in the expected debugger output
@@ -373,6 +376,7 @@ pub fn new() -> Self {
             extern_private: vec![],
             revisions: vec![],
             rustc_env: vec![],
+            unset_rustc_env: vec![],
             exec_env: vec![],
             check_lines: vec![],
             build_aux_docs: false,
@@ -499,6 +503,10 @@ fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
                 self.rustc_env.push(ee);
             }
 
+            if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") {
+                self.unset_rustc_env.push(ev);
+            }
+
             if let Some(cl) = config.parse_check_line(ln) {
                 self.check_lines.push(cl);
             }
index 26a3c4dee40aa478f3ec112f56187d167b59c34b..d651b9a92b64992e3d7be575c4b20450c68be4d6 100644 (file)
@@ -4,7 +4,7 @@
 use crate::errors::{Error, ErrorKind};
 use crate::runtest::ProcRes;
 use serde_json;
-use std::path::Path;
+use std::path::{Path, PathBuf};
 use std::str::FromStr;
 
 #[derive(Deserialize)]
@@ -18,9 +18,9 @@ struct Diagnostic {
 }
 
 #[derive(Deserialize)]
-struct Directive {
+struct ArtifactNotification {
     #[allow(dead_code)]
-    directive: String,
+    artifact: PathBuf,
 }
 
 #[derive(Deserialize, Clone)]
@@ -75,8 +75,8 @@ pub fn extract_rendered(output: &str) -> String {
             if line.starts_with('{') {
                 if let Ok(diagnostic) = serde_json::from_str::<Diagnostic>(line) {
                     diagnostic.rendered
-                } else if let Ok(_directive) = serde_json::from_str::<Directive>(line) {
-                    // Swallow the directive.
+                } else if let Ok(_) = serde_json::from_str::<ArtifactNotification>(line) {
+                    // Ignore the notification.
                     None
                 } else {
                     print!(
index 42f9cdb7886fd5eeee66e4b5cb8d993b2bc63566..a11a4f17eb5040315c2843913d65fb290bdbf088 100644 (file)
@@ -1422,10 +1422,21 @@ fn is_unexpected_compiler_message(
     }
 
     fn compile_test(&self) -> ProcRes {
-        let mut rustc = self.make_compile_args(
-            &self.testpaths.file,
-            TargetLocation::ThisFile(self.make_exe_name()),
-        );
+        // Only use `make_exe_name` when the test ends up being executed.
+        let will_execute = match self.config.mode {
+            RunPass | Ui => self.should_run_successfully(),
+            Incremental => self.revision.unwrap().starts_with("r"),
+            RunFail | RunPassValgrind | MirOpt |
+            DebugInfoBoth | DebugInfoGdb | DebugInfoLldb => true,
+            _ => false,
+        };
+        let output_file = if will_execute {
+            TargetLocation::ThisFile(self.make_exe_name())
+        } else {
+            TargetLocation::ThisDirectory(self.output_base_dir())
+        };
+
+        let mut rustc = self.make_compile_args(&self.testpaths.file, output_file);
 
         rustc.arg("-L").arg(&self.aux_output_dir_name());
 
@@ -1692,6 +1703,9 @@ fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) ->
             add_extern_priv(&private_lib, true);
         }
 
+        self.props.unset_rustc_env.clone()
+            .iter()
+            .fold(&mut rustc, |rustc, v| rustc.env_remove(v));
         rustc.envs(self.props.rustc_env.clone());
         self.compose_and_run(
             rustc,
@@ -1882,7 +1896,12 @@ fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> C
                 rustc.arg("-o").arg(path);
             }
             TargetLocation::ThisDirectory(path) => {
-                rustc.arg("--out-dir").arg(path);
+                if is_rustdoc {
+                    // `rustdoc` uses `-o` for the output directory.
+                    rustc.arg("-o").arg(path);
+                } else {
+                    rustc.arg("--out-dir").arg(path);
+                }
             }
         }
 
@@ -3138,42 +3157,40 @@ fn get_mir_dump_dir(&self) -> PathBuf {
     }
 
     fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> String {
-        let parent_dir = self.testpaths.file.parent().unwrap();
         let cflags = self.props.compile_flags.join(" ");
         let json = cflags.contains("--error-format json")
             || cflags.contains("--error-format pretty-json")
             || cflags.contains("--error-format=json")
             || cflags.contains("--error-format=pretty-json");
-        let parent_dir_str = if json {
-            parent_dir.display().to_string().replace("\\", "\\\\")
-        } else {
-            parent_dir.display().to_string()
+
+        let mut normalized = output.to_string();
+
+        let mut normalize_path = |from: &Path, to: &str| {
+            let mut from = from.display().to_string();
+            if json {
+                from = from.replace("\\", "\\\\");
+            }
+            normalized = normalized.replace(&from, to);
         };
 
-        let mut normalized = output.replace(&parent_dir_str, "$DIR");
+        let parent_dir = self.testpaths.file.parent().unwrap();
+        normalize_path(parent_dir, "$DIR");
 
         // Paths into the libstd/libcore
         let src_dir = self.config.src_base.parent().unwrap().parent().unwrap();
-        let src_dir_str = if json {
-            src_dir.display().to_string().replace("\\", "\\\\")
-        } else {
-            src_dir.display().to_string()
-        };
-        normalized = normalized.replace(&src_dir_str, "$SRC_DIR");
+        normalize_path(src_dir, "$SRC_DIR");
 
         // Paths into the build directory
         let test_build_dir = &self.config.build_base;
         let parent_build_dir = test_build_dir.parent().unwrap().parent().unwrap().parent().unwrap();
 
         // eg. /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui
-        normalized = normalized.replace(test_build_dir.to_str().unwrap(), "$TEST_BUILD_DIR");
+        normalize_path(test_build_dir, "$TEST_BUILD_DIR");
         // eg. /home/user/rust/build
-        normalized = normalized.replace(&parent_build_dir.to_str().unwrap(), "$BUILD_DIR");
+        normalize_path(parent_build_dir, "$BUILD_DIR");
 
         // Paths into lib directory.
-        let mut lib_dir = parent_build_dir.parent().unwrap().to_path_buf();
-        lib_dir.push("lib");
-        normalized = normalized.replace(&lib_dir.to_str().unwrap(), "$LIB_DIR");
+        normalize_path(&parent_build_dir.parent().unwrap().join("lib"), "$LIB_DIR");
 
         if json {
             // escaped newlines in json strings should be readable
index f9f3623679e175db2a641a4ef1037a1857bf706a..637f10c5ae745a14ef39f5f52e48451c14d1d045 100644 (file)
@@ -191,7 +191,7 @@ pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
 
     // We allow rustc-internal features to omit a tracking issue.
     // To make tidy accept omitting a tracking issue, group the list of features
-    // without one inside `// no tracking issue START` and `// no tracking issue END`.
+    // without one inside `// no-tracking-issue` and `// no-tracking-issue-end`.
     let mut next_feature_omits_tracking_issue = false;
 
     let mut in_feature_group = false;
@@ -201,13 +201,13 @@ pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
         .filter_map(|(line, line_number)| {
             let line = line.trim();
 
-            // Within START and END, the tracking issue can be omitted.
+            // Within -start and -end, the tracking issue can be omitted.
             match line {
-                "// no tracking issue START" => {
+                "// no-tracking-issue-start" => {
                     next_feature_omits_tracking_issue = true;
                     return None;
                 }
-                "// no tracking issue END" => {
+                "// no-tracking-issue-end" => {
                     next_feature_omits_tracking_issue = false;
                     return None;
                 }