]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #47251 - rkruppe:rm-simd-attr, r=eddyb
authorbors <bors@rust-lang.org>
Sat, 13 Jan 2018 15:29:31 +0000 (15:29 +0000)
committerbors <bors@rust-lang.org>
Sat, 13 Jan 2018 15:29:31 +0000 (15:29 +0000)
Remove deprecated unstable attribute #[simd]

The `#[simd]` attribute has been deprecated since c8b6d5b23cc8b2d43ece9f06252c7e98280fb8e5 back in 2015. Any nightly crates using it have had ample time to switch to `#[repr(simd)]`, and if they didn't they're likely broken by now anyway.

r? @eddyb

248 files changed:
.travis.yml
src/Cargo.lock
src/bootstrap/bin/rustdoc.rs
src/bootstrap/builder.rs
src/bootstrap/check.rs
src/bootstrap/compile.rs
src/bootstrap/config.rs
src/bootstrap/configure.py
src/bootstrap/doc.rs
src/bootstrap/native.rs
src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile [new file with mode: 0644]
src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile [deleted file]
src/ci/docker/dist-i586-gnu-i686-musl/build-musl.sh [deleted file]
src/ci/docker/dist-i586-gnu-i686-musl/musl-libunwind-patch.patch [deleted file]
src/ci/docker/dist-various-1/Dockerfile
src/ci/docker/dist-various-1/build-arm-musl.sh [deleted file]
src/ci/docker/dist-x86_64-musl/Dockerfile
src/ci/docker/dist-x86_64-musl/build-musl.sh [deleted file]
src/ci/docker/scripts/musl.sh [new file with mode: 0644]
src/doc/rust.css
src/doc/unstable-book/src/language-features/crate_in_paths.md [new file with mode: 0644]
src/doc/unstable-book/src/language-features/extern_absolute_paths.md [new file with mode: 0644]
src/doc/unstable-book/src/language-features/extern_in_paths.md [new file with mode: 0644]
src/liballoc/benches/slice.rs
src/liballoc/slice.rs
src/liballoc/string.rs
src/liballoc/tests/slice.rs
src/libarena/lib.rs
src/libcore/fmt/mod.rs
src/libcore/iter/range.rs
src/libcore/slice/mod.rs
src/libcore/str/pattern.rs
src/libcore/tests/iter.rs
src/libcore/tests/num/mod.rs
src/libcore/tests/pattern.rs
src/libcore/tests/slice.rs
src/liblibc
src/libproc_macro/lib.rs
src/librustc/Cargo.toml
src/librustc/dep_graph/dep_node.rs
src/librustc/dep_graph/graph.rs
src/librustc/hir/def_id.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/map/hir_id_validator.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/ich/fingerprint.rs
src/librustc/infer/lexical_region_resolve/graphviz.rs
src/librustc/lib.rs
src/librustc/lint/context.rs
src/librustc/middle/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/mem_categorization.rs
src/librustc/mir/mono.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/traits/mod.rs
src/librustc/ty/layout.rs
src/librustc/ty/maps/config.rs
src/librustc/ty/maps/mod.rs
src/librustc/ty/maps/on_disk_cache.rs
src/librustc/ty/maps/plumbing.rs
src/librustc/ty/mod.rs
src/librustc/ty/sty.rs
src/librustc/ty/util.rs
src/librustc/util/common.rs
src/librustc_back/Cargo.toml
src/librustc_back/lib.rs
src/librustc_back/target/i586_unknown_linux_musl.rs [new file with mode: 0644]
src/librustc_back/target/mod.rs
src/librustc_borrowck/Cargo.toml
src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
src/librustc_borrowck/borrowck/move_data.rs
src/librustc_const_eval/Cargo.toml
src/librustc_const_eval/pattern.rs
src/librustc_data_structures/Cargo.toml
src/librustc_data_structures/base_n.rs
src/librustc_driver/Cargo.toml
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_errors/lib.rs
src/librustc_incremental/Cargo.toml
src/librustc_incremental/assert_dep_graph.rs
src/librustc_incremental/lib.rs
src/librustc_incremental/persist/dirty_clean.rs
src/librustc_incremental/persist/file_format.rs
src/librustc_incremental/persist/fs.rs
src/librustc_incremental/persist/save.rs
src/librustc_incremental/persist/work_product.rs
src/librustc_lint/Cargo.toml
src/librustc_lint/bad_style.rs
src/librustc_lint/builtin.rs
src/librustc_lint/types.rs
src/librustc_llvm/ffi.rs
src/librustc_llvm/lib.rs
src/librustc_metadata/Cargo.toml
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/index.rs
src/librustc_metadata/index_builder.rs
src/librustc_metadata/lib.rs
src/librustc_metadata/locator.rs
src/librustc_metadata/schema.rs
src/librustc_mir/Cargo.toml
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_mir/dataflow/graphviz.rs
src/librustc_mir/interpret/const_eval.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/place.rs
src/librustc_mir/lib.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/monomorphize/item.rs
src/librustc_mir/monomorphize/partitioning.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_passes/Cargo.toml
src/librustc_resolve/Cargo.toml
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_save_analysis/Cargo.toml
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_trans/Cargo.toml
src/librustc_trans/assert_module_sources.rs
src/librustc_trans/back/bytecode.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/write.rs
src/librustc_trans/context.rs
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/lib.rs
src/librustc_trans/llvm_util.rs
src/librustc_trans/symbol_names_test.rs
src/librustc_trans_utils/Cargo.toml
src/librustc_typeck/Cargo.toml
src/librustc_typeck/check/autoderef.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/builtin.rs
src/librustc_typeck/diagnostics.rs
src/librustdoc/clean/inline.rs
src/librustdoc/externalfiles.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/librustdoc/visit_ast.rs
src/libserialize/opaque.rs
src/libstd/collections/hash/map.rs
src/libstd/ffi/mod.rs
src/libstd/ffi/os_str.rs
src/libstd/fs.rs
src/libstd/io/cursor.rs
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/panicking.rs
src/libstd/path.rs
src/libstd/sync/rwlock.rs
src/libstd/sys/wasm/mod.rs
src/libstd/sys/windows/c.rs
src/libstd/time/duration.rs
src/libsyntax/Cargo.toml
src/libsyntax/attr.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/tokenstream.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_pos/hygiene.rs
src/libtest/lib.rs
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.h
src/test/compile-fail/directory_ownership/backcompat-warnings.rs [deleted file]
src/test/compile-fail/issue-28433.rs
src/test/compile-fail/issue-39687.rs [new file with mode: 0644]
src/test/compile-fail/issue-43105.rs [new file with mode: 0644]
src/test/compile-fail/keyword-extern-as-identifier.rs [new file with mode: 0644]
src/test/compile-fail/rfc-2126-extern-in-paths/auxiliary/xcrate.rs [new file with mode: 0644]
src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-1.rs [new file with mode: 0644]
src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-2.rs [new file with mode: 0644]
src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-3.rs [new file with mode: 0644]
src/test/compile-fail/rfc-2126-extern-in-paths/single-segment.rs [new file with mode: 0644]
src/test/compile-fail/static-drop-scope.rs
src/test/parse-fail/issue-32501.rs
src/test/parse-fail/keyword-extern-as-identifier.rs [deleted file]
src/test/run-make/linker-output-non-utf8/Makefile
src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs [new file with mode: 0644]
src/test/run-pass/hygiene/auxiliary/my_crate.rs [new file with mode: 0644]
src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs [new file with mode: 0644]
src/test/run-pass/hygiene/legacy_interaction.rs [new file with mode: 0644]
src/test/run-pass/hygiene/wrap_unhygienic_example.rs [new file with mode: 0644]
src/test/run-pass/impl-trait/example-calendar.rs
src/test/run-pass/issue-33903.rs [new file with mode: 0644]
src/test/run-pass/issue-36792.rs [new file with mode: 0644]
src/test/run-pass/issue-38091.rs [new file with mode: 0644]
src/test/run-pass/issue-42148.rs [new file with mode: 0644]
src/test/run-pass/issue-42956.rs [new file with mode: 0644]
src/test/run-pass/issue-46095.rs [new file with mode: 0644]
src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs [deleted file]
src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs [deleted file]
src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs [new file with mode: 0644]
src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs [new file with mode: 0644]
src/test/run-pass/rfc-2126-extern-absolute-paths/extern.rs [new file with mode: 0644]
src/test/rustdoc/issue-43893.rs
src/test/rustdoc/issue-47038.rs [new file with mode: 0644]
src/test/rustdoc/issue-47197-blank-line-in-doc-block.rs [new file with mode: 0644]
src/test/ui/deref-suggestion.stderr
src/test/ui/did_you_mean/multiple-pattern-typo.rs [new file with mode: 0644]
src/test/ui/did_you_mean/multiple-pattern-typo.stderr [new file with mode: 0644]
src/test/ui/did_you_mean/recursion_limit_deref.stderr
src/test/ui/feature-gate-extern_in_paths.rs [new file with mode: 0644]
src/test/ui/feature-gate-extern_in_paths.stderr [new file with mode: 0644]
src/test/ui/issue-41652/issue_41652.rs
src/test/ui/issue-41652/issue_41652.stderr
src/test/ui/issue-44406.stderr
src/test/ui/macros/macro-backtrace-invalid-internals.rs
src/test/ui/macros/macro-backtrace-invalid-internals.stderr
src/test/ui/non_modrs_mods/non_modrs_mods.stderr
src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs [deleted file]
src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs [deleted file]
src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs [new file with mode: 0644]
src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs [new file with mode: 0644]
src/test/ui/pub/pub-restricted-error.stderr
src/test/ui/pub/pub-restricted-non-path.stderr
src/test/ui/span/coerce-suggestions.stderr
src/test/ui/span/issue-34264.stderr
src/test/ui/suggestions/conversion-methods.rs [new file with mode: 0644]
src/test/ui/suggestions/conversion-methods.stderr [new file with mode: 0644]
src/test/ui/suggestions/issue-45562.rs [new file with mode: 0644]
src/test/ui/suggestions/issue-45562.stderr [new file with mode: 0644]
src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs [new file with mode: 0644]
src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr [new file with mode: 0644]
src/test/ui/token/issue-15980.rs [new file with mode: 0644]
src/test/ui/token/issue-15980.stderr [new file with mode: 0644]
src/tools/build-manifest/src/main.rs
src/tools/compiletest/Cargo.toml
src/tools/compiletest/src/runtest.rs
src/tools/error_index_generator/main.rs
src/tools/linkchecker/main.rs

index d955c3ac3c3976aebc1e69c2adaa9ae545296432..6e242b74894c5dd66715f904683287ba94338b69 100644 (file)
@@ -126,7 +126,7 @@ matrix:
       if: branch = auto
     - env: IMAGE=dist-armv7-linux DEPLOY=1
       if: branch = auto
-    - env: IMAGE=dist-i586-gnu-i686-musl DEPLOY=1
+    - env: IMAGE=dist-i586-gnu-i586-i686-musl DEPLOY=1
       if: branch = auto
     - env: IMAGE=dist-i686-freebsd DEPLOY=1
       if: branch = auto
index 52bfa2ab1090ee432ffecfae6cc42d593e531894..8fbf3535264fcd8868478dfd718af213f86cf7b5 100644 (file)
@@ -74,7 +74,7 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -88,7 +88,7 @@ dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -99,7 +99,7 @@ version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -131,7 +131,7 @@ dependencies = [
  "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -194,9 +194,9 @@ dependencies = [
  "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -353,7 +353,7 @@ name = "commoncrypto-sys"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -372,8 +372,8 @@ dependencies = [
  "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -388,7 +388,7 @@ dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -410,7 +410,7 @@ version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -418,7 +418,7 @@ name = "core-foundation-sys"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -485,7 +485,7 @@ version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "curl-sys 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -498,7 +498,7 @@ version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -665,7 +665,7 @@ version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -682,7 +682,7 @@ name = "flate2"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -714,7 +714,7 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -757,7 +757,7 @@ version = "0.6.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -928,10 +928,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "jobserver"
-version = "0.1.8"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1009,7 +1009,7 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.34"
+version = "0.2.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1020,7 +1020,7 @@ dependencies = [
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl-sys 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1033,7 +1033,7 @@ version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1045,7 +1045,7 @@ version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1085,7 +1085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1138,7 +1138,7 @@ name = "memchr"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1146,7 +1146,7 @@ name = "memchr"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1154,7 +1154,7 @@ name = "memchr"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1163,7 +1163,7 @@ version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1199,7 +1199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1216,7 +1216,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1291,7 +1291,7 @@ name = "num_cpus"
 version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1307,7 +1307,7 @@ dependencies = [
  "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1322,7 +1322,7 @@ version = "0.9.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1378,7 +1378,7 @@ version = "0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1531,7 +1531,7 @@ version = "0.3.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1550,7 +1550,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1711,8 +1711,8 @@ dependencies = [
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fmt_macros 0.0.0",
  "graphviz 0.0.0",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_apfloat 0.0.0",
  "rustc_back 0.0.0",
  "rustc_const_math 0.0.0",
@@ -1774,7 +1774,7 @@ dependencies = [
 name = "rustc_back"
 version = "0.0.0"
 dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
  "syntax 0.0.0",
@@ -1786,7 +1786,7 @@ version = "0.0.0"
 dependencies = [
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1794,7 +1794,7 @@ name = "rustc_borrowck"
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_mir 0.0.0",
@@ -1807,7 +1807,7 @@ name = "rustc_const_eval"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -1837,7 +1837,7 @@ name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
@@ -1852,7 +1852,7 @@ dependencies = [
  "arena 0.0.0",
  "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_allocator 0.0.0",
  "rustc_back 0.0.0",
@@ -1893,7 +1893,7 @@ name = "rustc_incremental"
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -1906,7 +1906,7 @@ dependencies = [
 name = "rustc_lint"
 version = "0.0.0"
 dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_const_eval 0.0.0",
  "syntax 0.0.0",
@@ -1939,7 +1939,7 @@ name = "rustc_metadata"
 version = "0.0.0"
 dependencies = [
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
@@ -1958,7 +1958,7 @@ dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_apfloat 0.0.0",
@@ -1988,7 +1988,7 @@ dependencies = [
 name = "rustc_passes"
 version = "0.0.0"
 dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_const_eval 0.0.0",
  "rustc_const_math 0.0.0",
@@ -2027,7 +2027,7 @@ name = "rustc_resolve"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2039,7 +2039,7 @@ dependencies = [
 name = "rustc_save_analysis"
 version = "0.0.0"
 dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -2057,8 +2057,8 @@ dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2086,7 +2086,7 @@ version = "0.0.0"
 dependencies = [
  "ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2111,7 +2111,7 @@ version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
  "fmt_macros 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2149,7 +2149,7 @@ dependencies = [
  "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2275,7 +2275,7 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2306,7 +2306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2413,7 +2413,7 @@ name = "syntax"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2446,7 +2446,7 @@ name = "syntex_errors"
 version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2468,7 +2468,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2483,7 +2483,7 @@ version = "0.4.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2532,7 +2532,7 @@ name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2559,7 +2559,7 @@ version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2771,7 +2771,7 @@ name = "xattr"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2862,7 +2862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fcaf2365eb14b28ec7603c98c06cc531f19de9eb283d89a3dff8417c8c99f5"
 "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21"
 "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
-"checksum jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "931b04e5e57d88cc909528f0d701db36a870b72a052648ded8baf80f9f445e0f"
+"checksum jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "565f6106bd87b394398f813bea4e5ecad6d6b0f6aa077592d088f882a506481d"
 "checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483"
 "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
@@ -2871,7 +2871,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
 "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
 "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b"
-"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
+"checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb"
 "checksum libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "82fc20bd8beefe7c9f98aae2d3cff78e57f544cdd83d58fe181ec37a5fbe0c77"
 "checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75"
 "checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
index 62037590853c7dd72a09fa317a283b234c568413..389b504c64cdcdb5a4718424cdff3deeddd51ea5 100644 (file)
 fn main() {
     let args = env::args_os().skip(1).collect::<Vec<_>>();
     let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set");
-    let libdir = env::var_os("RUSTC_LIBDIR").expect("RUSTC_LIBDIR was not set");
+    let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set");
     let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
     let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
 
+    use std::str::FromStr;
+
+    let verbose = match env::var("RUSTC_VERBOSE") {
+        Ok(s) => usize::from_str(&s).expect("RUSTC_VERBOSE should be an integer"),
+        Err(_) => 0,
+    };
+
     let mut dylib_path = bootstrap::util::dylib_path();
     dylib_path.insert(0, PathBuf::from(libdir));
 
@@ -63,6 +70,10 @@ fn main() {
         cmd.arg("--deny-render-differences");
     }
 
+    if verbose > 1 {
+        eprintln!("rustdoc command: {:?}", cmd);
+    }
+
     std::process::exit(match cmd.status() {
         Ok(s) => s.code().unwrap_or(1),
         Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e),
index ce30d1f4cec42a050b21e567cc7f88ce98225c62..a660b5cf852aa991af8d51139da1dfa5cac6da99 100644 (file)
@@ -357,8 +357,8 @@ fn should_run(run: ShouldRun) -> ShouldRun {
 
             fn run(self, builder: &Builder) -> Interned<PathBuf> {
                 let compiler = self.compiler;
-                let lib = if compiler.stage >= 2 && builder.build.config.libdir_relative.is_some() {
-                    builder.build.config.libdir_relative.clone().unwrap()
+                let lib = if compiler.stage >= 1 && builder.build.config.libdir.is_some() {
+                    builder.build.config.libdir.clone().unwrap()
                 } else {
                     PathBuf::from("lib")
                 };
@@ -416,7 +416,7 @@ pub fn rustdoc_cmd(&self, host: Interned<String>) -> Command {
         let compiler = self.compiler(self.top_stage, host);
         cmd.env("RUSTC_STAGE", compiler.stage.to_string())
            .env("RUSTC_SYSROOT", self.sysroot(compiler))
-           .env("RUSTC_LIBDIR", self.sysroot_libdir(compiler, self.build.build))
+           .env("RUSTDOC_LIBDIR", self.sysroot_libdir(compiler, self.build.build))
            .env("CFG_RELEASE_CHANNEL", &self.build.config.channel)
            .env("RUSTDOC_REAL", self.rustdoc(host))
            .env("RUSTDOC_CRATE_VERSION", self.build.rust_version())
@@ -496,6 +496,9 @@ pub fn cargo(&self,
         if let Some(target_linker) = self.build.linker(target) {
             cargo.env("RUSTC_TARGET_LINKER", target_linker);
         }
+        if cmd != "build" {
+            cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(self.compiler(2, self.build.build)));
+        }
 
         if mode != Mode::Tool {
             // Tools don't get debuginfo right now, e.g. cargo and rls don't
index cc9be3cec34762fd073e998cbcd7b20c85e441e4..ed110762cb3c0f74a12aa581ec8139ab3f2563d3 100644 (file)
@@ -1166,7 +1166,7 @@ fn run(self, builder: &Builder) {
             }
             Mode::Librustc => {
                 builder.ensure(compile::Rustc { compiler, target });
-                compile::rustc_cargo(build, &compiler, target, &mut cargo);
+                compile::rustc_cargo(build, target, &mut cargo);
                 ("librustc", "rustc-main")
             }
             _ => panic!("can only test libraries"),
index c8e500a4f68c0615bb07061c5a6c1b80dd7dd320..c6adfc7ffae47598b6c930e14dee3f5e842418c1 100644 (file)
@@ -485,7 +485,7 @@ fn run(self, builder: &Builder) {
         build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
 
         let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
-        rustc_cargo(build, &compiler, target, &mut cargo);
+        rustc_cargo(build, target, &mut cargo);
         run_cargo(build,
                   &mut cargo,
                   &librustc_stamp(build, compiler, target));
@@ -500,7 +500,6 @@ fn run(self, builder: &Builder) {
 
 /// Same as `std_cargo`, but for libtest
 pub fn rustc_cargo(build: &Build,
-                   compiler: &Compiler,
                    target: Interned<String>,
                    cargo: &mut Command) {
     cargo.arg("--features").arg(build.rustc_features())
@@ -514,13 +513,9 @@ pub fn rustc_cargo(build: &Build,
          .env("CFG_VERSION", build.rust_version())
          .env("CFG_PREFIX", build.config.prefix.clone().unwrap_or_default());
 
-    if compiler.stage == 0 {
-        cargo.env("CFG_LIBDIR_RELATIVE", "lib");
-    } else {
-        let libdir_relative =
-            build.config.libdir_relative.clone().unwrap_or(PathBuf::from("lib"));
-        cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
-    }
+    let libdir_relative =
+        build.config.libdir.clone().unwrap_or(PathBuf::from("lib"));
+    cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
 
     // If we're not building a compiler with debugging information then remove
     // these two env vars which would be set otherwise.
index f3ffe9a276111efc2e6beac1e5a18175e81f148c..72e75fddc1942cbbfcc3bd399d110c5f910845a6 100644 (file)
@@ -121,7 +121,6 @@ pub struct Config {
     pub docdir: Option<PathBuf>,
     pub bindir: Option<PathBuf>,
     pub libdir: Option<PathBuf>,
-    pub libdir_relative: Option<PathBuf>,
     pub mandir: Option<PathBuf>,
     pub codegen_tests: bool,
     pub nodejs: Option<PathBuf>,
index 48ca2838e4febd9001244ef7231174420043bb9b..aa9fe459e88c996abd961515514529ac19a1e7ad 100755 (executable)
@@ -108,6 +108,8 @@ v("musl-root", "target.x86_64-unknown-linux-musl.musl-root",
   "MUSL root installation directory (deprecated)")
 v("musl-root-x86_64", "target.x86_64-unknown-linux-musl.musl-root",
   "x86_64-unknown-linux-musl install directory")
+v("musl-root-i586", "target.i586-unknown-linux-musl.musl-root",
+  "i586-unknown-linux-musl install directory")
 v("musl-root-i686", "target.i686-unknown-linux-musl.musl-root",
   "i686-unknown-linux-musl install directory")
 v("musl-root-arm", "target.arm-unknown-linux-musleabi.musl-root",
index 832da24c994db784d0d7f4015523c0b98dcd0fdc..178d60dd7df73a07bffdddb76f6e8174d8c17132 100644 (file)
@@ -616,7 +616,7 @@ fn run(self, builder: &Builder) {
         t!(symlink_dir_force(&my_out, &out_dir));
 
         let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
-        compile::rustc_cargo(build, &compiler, target, &mut cargo);
+        compile::rustc_cargo(build, target, &mut cargo);
 
         if build.config.compiler_docs {
             // src/rustc/Cargo.toml contains a bin crate called rustc which
index a5408ee381bbbb23c2338ce0cdd5eb04316856c5..ba8cf3a8e2eb597844e202e5563937646c758f80 100644 (file)
@@ -429,6 +429,8 @@ fn run(self, builder: &Builder) {
             "arm-unknown-linux-gnueabihf" => "linux-armv4",
             "armv7-linux-androideabi" => "android-armv7",
             "armv7-unknown-linux-gnueabihf" => "linux-armv4",
+            "i586-unknown-linux-gnu" => "linux-elf",
+            "i586-unknown-linux-musl" => "linux-elf",
             "i686-apple-darwin" => "darwin-i386-cc",
             "i686-linux-android" => "android-x86",
             "i686-unknown-freebsd" => "BSD-x86-elf",
diff --git a/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile
new file mode 100644 (file)
index 0000000..4c9d4b3
--- /dev/null
@@ -0,0 +1,54 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+  g++-multilib \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python2.7 \
+  git \
+  cmake \
+  xz-utils \
+  sudo \
+  gdb \
+  patch \
+  libssl-dev \
+  pkg-config
+
+WORKDIR /build/
+COPY scripts/musl.sh /build/
+RUN CC=gcc CFLAGS="-m32 -fPIC -Wa,-mrelax-relocations=no" \
+    CXX=g++ CXXFLAGS="-m32 -Wa,-mrelax-relocations=no" \
+    bash musl.sh i686 --target=i686 && \
+    CC=gcc CFLAGS="-march=pentium -m32 -fPIC -Wa,-mrelax-relocations=no" \
+    CXX=g++ CXXFLAGS="-march=pentium -m32 -Wa,-mrelax-relocations=no" \
+    bash musl.sh i586 --target=i586 && \
+    rm -rf /build
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV RUST_CONFIGURE_ARGS \
+      --target=i686-unknown-linux-musl,i586-unknown-linux-gnu \
+      --musl-root-i586=/musl-i586 \
+      --musl-root-i686=/musl-i686 \
+      --enable-extended
+
+# Newer binutils broke things on some vms/distros (i.e., linking against
+# unknown relocs disabled by the following flag), so we need to go out of our
+# way to produce "super compatible" binaries.
+#
+# See: https://github.com/rust-lang/rust/issues/34978
+ENV CFLAGS_i686_unknown_linux_musl=-Wa,-mrelax-relocations=no
+ENV CFLAGS_i586_unknown_linux_gnu=-Wa,-mrelax-relocations=no
+# FIXME remove -Wl,-melf_i386 after cc is updated to include
+#       https://github.com/alexcrichton/cc-rs/pull/281
+ENV CFLAGS_i586_unknown_linux_musl="-Wa,-mrelax-relocations=no -Wl,-melf_i386"
+
+ENV TARGETS=i586-unknown-linux-gnu
+ENV TARGETS=$TARGETS,i686-unknown-linux-musl
+
+ENV SCRIPT \
+      python2.7 ../x.py test --target $TARGETS && \
+      python2.7 ../x.py dist --target $TARGETS,i586-unknown-linux-musl
diff --git a/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile b/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile
deleted file mode 100644 (file)
index 2fb1219..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-FROM ubuntu:16.04
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
-  g++-multilib \
-  make \
-  file \
-  curl \
-  ca-certificates \
-  python2.7 \
-  git \
-  cmake \
-  xz-utils \
-  sudo \
-  gdb \
-  patch \
-  libssl-dev \
-  pkg-config
-
-WORKDIR /build/
-COPY dist-i586-gnu-i686-musl/musl-libunwind-patch.patch dist-i586-gnu-i686-musl/build-musl.sh /build/
-RUN sh /build/build-musl.sh && rm -rf /build
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-ENV RUST_CONFIGURE_ARGS \
-      --target=i686-unknown-linux-musl,i586-unknown-linux-gnu \
-      --musl-root-i686=/musl-i686 \
-      --enable-extended
-
-# Newer binutils broke things on some vms/distros (i.e., linking against
-# unknown relocs disabled by the following flag), so we need to go out of our
-# way to produce "super compatible" binaries.
-#
-# See: https://github.com/rust-lang/rust/issues/34978
-ENV CFLAGS_i686_unknown_linux_musl=-Wa,-mrelax-relocations=no
-ENV CFLAGS_i586_unknown_linux_gnu=-Wa,-mrelax-relocations=no
-
-ENV SCRIPT \
-      python2.7 ../x.py test \
-          --target i686-unknown-linux-musl \
-          --target i586-unknown-linux-gnu \
-          && \
-      python2.7 ../x.py dist \
-          --target i686-unknown-linux-musl \
-          --target i586-unknown-linux-gnu
diff --git a/src/ci/docker/dist-i586-gnu-i686-musl/build-musl.sh b/src/ci/docker/dist-i586-gnu-i686-musl/build-musl.sh
deleted file mode 100644 (file)
index 883859d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-set -ex
-
-# We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
-export CFLAGS="-fPIC -Wa,-mrelax-relocations=no"
-export CXXFLAGS="-Wa,-mrelax-relocations=no"
-
-MUSL=musl-1.1.17
-curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
-cd $MUSL
-CC=gcc \
-  CFLAGS="$CFLAGS -m32" \
-  ./configure --prefix=/musl-i686 --disable-shared \
-    --target=i686
-make AR=ar RANLIB=ranlib -j10
-make install
-cd ..
-
-# To build MUSL we're going to need a libunwind lying around, so acquire that
-# here and build it.
-curl -L https://github.com/llvm-mirror/llvm/archive/release_37.tar.gz | tar xzf -
-curl -L https://github.com/llvm-mirror/libunwind/archive/release_37.tar.gz | tar xzf -
-
-# Whoa what's this mysterious patch we're applying to libunwind! Why are we
-# swapping the values of ESP/EBP in libunwind?!
-#
-# Discovered in #35599 it turns out that the vanilla build of libunwind is not
-# suitable for unwinding 32-bit musl. After some investigation it ended up
-# looking like the register values for ESP/EBP were indeed incorrect (swapped)
-# in the source. Similar commits in libunwind (r280099 and r282589) have noticed
-# this for other platforms, and we just need to realize it for musl linux as
-# well.
-#
-# More technical info can be found at #35599
-cd libunwind-release_37
-patch -Np1 < /build/musl-libunwind-patch.patch
-cd ..
-
-mkdir libunwind-build
-cd libunwind-build
-CFLAGS="$CFLAGS -m32" CXXFLAGS="$CXXFLAGS -m32" cmake ../libunwind-release_37 \
-          -DLLVM_PATH=/build/llvm-release_37 \
-          -DLIBUNWIND_ENABLE_SHARED=0
-make -j10
-cp lib/libunwind.a /musl-i686/lib
diff --git a/src/ci/docker/dist-i586-gnu-i686-musl/musl-libunwind-patch.patch b/src/ci/docker/dist-i586-gnu-i686-musl/musl-libunwind-patch.patch
deleted file mode 100644 (file)
index 99cd685..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/include/libunwind.h b/include/libunwind.h
-index c5b9633..1360eb2 100644
---- a/include/libunwind.h
-+++ b/include/libunwind.h
-@@ -151,8 +151,8 @@ enum {
-   UNW_X86_ECX = 1,
-   UNW_X86_EDX = 2,
-   UNW_X86_EBX = 3,
--  UNW_X86_EBP = 4,
--  UNW_X86_ESP = 5,
-+  UNW_X86_ESP = 4,
-+  UNW_X86_EBP = 5,
-   UNW_X86_ESI = 6,
-   UNW_X86_EDI = 7
- };
index b58ee7a719c4cc4138804e0d7f69393a94f16a34..0f08bcddd388fe28c0785ed1f4d01f432d91674e 100644 (file)
@@ -22,23 +22,39 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   libssl-dev \
   pkg-config
 
-WORKDIR /tmp
+WORKDIR /build
 
-COPY dist-various-1/build-rumprun.sh /tmp/
+COPY dist-various-1/build-rumprun.sh /build
 RUN ./build-rumprun.sh
 
-COPY dist-various-1/build-arm-musl.sh /tmp/
-RUN ./build-arm-musl.sh
+COPY dist-various-1/install-x86_64-redox.sh /build
+RUN ./install-x86_64-redox.sh
+
+COPY scripts/musl.sh /build
+RUN env \
+    CC=arm-linux-gnueabi-gcc CFLAGS="-march=armv6 -marm" \
+    CXX=arm-linux-gnueabi-g++ CXXFLAGS="-march=armv6 -marm" \
+    bash musl.sh arm && \
+    env \
+    CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm" \
+    CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm" \
+    bash musl.sh armhf && \
+    env \
+    CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \
+    CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv7-a" \
+    bash musl.sh armv7 && \
+    env \
+    CC=aarch64-linux-gnu-gcc \
+    CXX=aarch64-linux-gnu-g++ \
+    bash musl.sh aarch64 && \
+    rm -rf /build/*
 
-COPY dist-various-1/install-mips-musl.sh /tmp/
+COPY dist-various-1/install-mips-musl.sh /build
 RUN ./install-mips-musl.sh
 
-COPY dist-various-1/install-mipsel-musl.sh /tmp/
+COPY dist-various-1/install-mipsel-musl.sh /build
 RUN ./install-mipsel-musl.sh
 
-COPY dist-various-1/install-x86_64-redox.sh /tmp/
-RUN ./install-x86_64-redox.sh
-
 ENV TARGETS=asmjs-unknown-emscripten
 ENV TARGETS=$TARGETS,wasm32-unknown-emscripten
 ENV TARGETS=$TARGETS,x86_64-rumprun-netbsd
@@ -67,10 +83,10 @@ ENV STAGING_DIR=/tmp
 ENV RUST_CONFIGURE_ARGS \
       --enable-extended \
       --target=$TARGETS \
-      --musl-root-arm=/usr/local/arm-linux-musleabi \
-      --musl-root-armhf=/usr/local/arm-linux-musleabihf \
-      --musl-root-armv7=/usr/local/armv7-linux-musleabihf \
-      --musl-root-aarch64=/usr/local/aarch64-linux-musl
+      --musl-root-arm=/musl-arm \
+      --musl-root-armhf=/musl-armhf \
+      --musl-root-armv7=/musl-armv7 \
+      --musl-root-aarch64=/musl-aarch64
 ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
 
 # sccache
diff --git a/src/ci/docker/dist-various-1/build-arm-musl.sh b/src/ci/docker/dist-various-1/build-arm-musl.sh
deleted file mode 100755 (executable)
index f9444a3..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-set -ex
-
-MUSL=1.1.17
-
-hide_output() {
-  set +x
-  on_err="
-echo ERROR: An error was encountered with the build.
-cat /tmp/build.log
-exit 1
-"
-  trap "$on_err" ERR
-  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
-  PING_LOOP_PID=$!
-  $@ &> /tmp/build.log
-  trap - ERR
-  kill $PING_LOOP_PID
-  rm /tmp/build.log
-  set -x
-}
-
-curl -O https://www.musl-libc.org/releases/musl-$MUSL.tar.gz
-tar xf musl-$MUSL.tar.gz
-cd musl-$MUSL
-CC=arm-linux-gnueabi-gcc \
-CFLAGS="-march=armv6 -marm" \
-    hide_output ./configure \
-        --prefix=/usr/local/arm-linux-musleabi \
-        --enable-wrapper=gcc
-hide_output make -j$(nproc)
-hide_output make install
-cd ..
-rm -rf musl-$MUSL
-
-tar xf musl-$MUSL.tar.gz
-cd musl-$MUSL
-CC=arm-linux-gnueabihf-gcc \
-CFLAGS="-march=armv6 -marm" \
-    hide_output ./configure \
-        --prefix=/usr/local/arm-linux-musleabihf \
-        --enable-wrapper=gcc
-hide_output make -j$(nproc)
-hide_output make install
-cd ..
-rm -rf musl-$MUSL
-
-tar xf musl-$MUSL.tar.gz
-cd musl-$MUSL
-CC=arm-linux-gnueabihf-gcc \
-CFLAGS="-march=armv7-a" \
-    hide_output ./configure \
-        --prefix=/usr/local/armv7-linux-musleabihf \
-        --enable-wrapper=gcc
-hide_output make -j$(nproc)
-hide_output make install
-cd ..
-rm -rf musl-$MUSL
-
-tar xf musl-$MUSL.tar.gz
-cd musl-$MUSL
-CC=aarch64-linux-gnu-gcc \
-CFLAGS="" \
-    hide_output ./configure \
-        --prefix=/usr/local/aarch64-linux-musl \
-        --enable-wrapper=gcc
-hide_output make -j$(nproc)
-hide_output make install
-cd ..
-rm -rf musl-$MUSL*
-
-ln -nsf ../arm-linux-musleabi/bin/musl-gcc /usr/local/bin/arm-linux-musleabi-gcc
-ln -nsf ../arm-linux-musleabihf/bin/musl-gcc /usr/local/bin/arm-linux-musleabihf-gcc
-ln -nsf ../armv7-linux-musleabihf/bin/musl-gcc /usr/local/bin/armv7-linux-musleabihf-gcc
-ln -nsf ../aarch64-linux-musl/bin/musl-gcc /usr/local/bin/aarch64-unknown-linux-musl-gcc
-
-curl -L https://github.com/llvm-mirror/llvm/archive/release_39.tar.gz | tar xzf -
-curl -L https://github.com/llvm-mirror/libunwind/archive/release_39.tar.gz | tar xzf -
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_39 \
-          -DLLVM_PATH=/tmp/llvm-release_39 \
-          -DLIBUNWIND_ENABLE_SHARED=0 \
-          -DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc \
-          -DCMAKE_CXX_COMPILER=arm-linux-gnueabi-g++ \
-          -DCMAKE_C_FLAGS="-march=armv6 -marm" \
-          -DCMAKE_CXX_FLAGS="-march=armv6 -marm"
-make -j$(nproc)
-cp lib/libunwind.a /usr/local/arm-linux-musleabi/lib
-cd ..
-rm -rf libunwind-build
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_39 \
-          -DLLVM_PATH=/tmp/llvm-release_39 \
-          -DLIBUNWIND_ENABLE_SHARED=0 \
-          -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
-          -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
-          -DCMAKE_C_FLAGS="-march=armv6 -marm" \
-          -DCMAKE_CXX_FLAGS="-march=armv6 -marm"
-make -j$(nproc)
-cp lib/libunwind.a /usr/local/arm-linux-musleabihf/lib
-cd ..
-rm -rf libunwind-build
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_39 \
-          -DLLVM_PATH=/tmp/llvm-release_39 \
-          -DLIBUNWIND_ENABLE_SHARED=0 \
-          -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
-          -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
-          -DCMAKE_C_FLAGS="-march=armv7-a" \
-          -DCMAKE_CXX_FLAGS="-march=armv7-a"
-make -j$(nproc)
-cp lib/libunwind.a /usr/local/armv7-linux-musleabihf/lib
-cd ..
-rm -rf libunwind-build
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_39 \
-          -DLLVM_PATH=/tmp/llvm-release_39 \
-          -DLIBUNWIND_ENABLE_SHARED=0 \
-          -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
-          -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \
-          -DCMAKE_C_FLAGS="" \
-          -DCMAKE_CXX_FLAGS=""
-make -j$(nproc)
-cp lib/libunwind.a /usr/local/aarch64-linux-musl/lib
-cd ..
-rm -rf libunwind-build
-
-rm -rf libunwind-release_39
-rm -rf llvm-release_39
index 91ed6bfe1f63d3300392fde5bdec6e187c5d4217..77a55b33e41b25963c1af3ba11bc84b7d7dde672 100644 (file)
@@ -17,8 +17,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 WORKDIR /build/
-COPY dist-x86_64-musl/build-musl.sh /build/
-RUN sh /build/build-musl.sh && rm -rf /build
+
+COPY scripts/musl.sh /build/
+# We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
+RUN CC=gcc \
+    CFLAGS="-fPIC -Wa,-mrelax-relocations=no" \
+    CXX=g++ \
+    CXXFLAGS="-Wa,-mrelax-relocations=no" \
+    bash musl.sh x86_64 && rm -rf /build
 
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/dist-x86_64-musl/build-musl.sh b/src/ci/docker/dist-x86_64-musl/build-musl.sh
deleted file mode 100644 (file)
index 9be8d00..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-set -ex
-
-# We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
-export CFLAGS="-fPIC -Wa,-mrelax-relocations=no"
-export CXXFLAGS="-Wa,-mrelax-relocations=no"
-
-MUSL=musl-1.1.17
-curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
-cd $MUSL
-./configure --prefix=/musl-x86_64 --disable-shared
-make -j10
-make install
-
-cd ..
-rm -rf $MUSL
-
-# To build MUSL we're going to need a libunwind lying around, so acquire that
-# here and build it.
-curl -L https://github.com/llvm-mirror/llvm/archive/release_37.tar.gz | tar xzf -
-curl -L https://github.com/llvm-mirror/libunwind/archive/release_37.tar.gz | tar xzf -
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_37 -DLLVM_PATH=/build/llvm-release_37 \
-          -DLIBUNWIND_ENABLE_SHARED=0
-make -j10
-cp lib/libunwind.a /musl-x86_64/lib
diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh
new file mode 100644 (file)
index 0000000..7a72332
--- /dev/null
@@ -0,0 +1,102 @@
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+set -ex
+
+hide_output() {
+  set +x
+  on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+  trap "$on_err" ERR
+  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+  PING_LOOP_PID=$!
+  $@ &> /tmp/build.log
+  trap - ERR
+  kill $PING_LOOP_PID
+  rm /tmp/build.log
+  set -x
+}
+
+TAG=$1
+shift
+
+MUSL=musl-1.1.18
+
+# may have been downloaded in a previous run
+if [ ! -d $MUSL ]; then
+  curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
+fi
+
+cd $MUSL
+./configure --disable-shared --prefix=/musl-$TAG $@
+if [ "$TAG" = "i586" -o "$TAG" = "i686" ]; then
+  hide_output make -j$(nproc) AR=ar RANLIB=ranlib
+else
+  hide_output make -j$(nproc)
+fi
+hide_output make install
+hide_output make clean
+
+cd ..
+
+LLVM=39
+# may have been downloaded in a previous run
+if [ ! -d libunwind-release_$LLVM ]; then
+  curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf -
+  curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf -
+  # Whoa what's this mysterious patch we're applying to libunwind! Why are we
+  # swapping the values of ESP/EBP in libunwind?!
+  #
+  # Discovered in #35599 it turns out that the vanilla build of libunwind is not
+  # suitable for unwinding i686 musl. After some investigation it ended up
+  # looking like the register values for ESP/EBP were indeed incorrect (swapped)
+  # in the source. Similar commits in libunwind (r280099 and r282589) have noticed
+  # this for other platforms, and we just need to realize it for musl linux as
+  # well.
+  #
+  # More technical info can be found at #35599
+  cd libunwind-release_$LLVM
+  patch -Np1 << EOF
+diff --git a/include/libunwind.h b/include/libunwind.h
+index c5b9633..1360eb2 100644
+--- a/include/libunwind.h
++++ b/include/libunwind.h
+@@ -151,8 +151,8 @@ enum {
+   UNW_X86_ECX = 1,
+   UNW_X86_EDX = 2,
+   UNW_X86_EBX = 3,
+-  UNW_X86_EBP = 4,
+-  UNW_X86_ESP = 5,
++  UNW_X86_ESP = 4,
++  UNW_X86_EBP = 5,
+   UNW_X86_ESI = 6,
+   UNW_X86_EDI = 7
+ };
+fi
+EOF
+  cd ..
+fi
+
+mkdir libunwind-build
+cd libunwind-build
+cmake ../libunwind-release_$LLVM \
+          -DLLVM_PATH=/build/llvm-release_$LLVM \
+          -DLIBUNWIND_ENABLE_SHARED=0 \
+          -DCMAKE_C_COMPILER=$CC \
+          -DCMAKE_CXX_COMPILER=$CXX \
+          -DCMAKE_C_FLAGS="$CFLAGS" \
+          -DCMAKE_CXX_FLAGS="$CXXFLAGS"
+
+hide_output make -j$(nproc)
+cp lib/libunwind.a /musl-$TAG/lib
+cd ../ && rm -rf libunwind-build
index 664bc0fdab0025c0e5111f448cb7f0c8ba7aa2ac..5f216169efe2ce8a81df17f66eaaaf1383cf484f 100644 (file)
  * except according to those terms.
  */
 @font-face {
-    font-family: 'Fira Sans';
-    font-style: normal;
-    font-weight: 400;
-    src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff');
+       font-family: 'Fira Sans';
+       font-style: normal;
+       font-weight: 400;
+       src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff');
 }
 @font-face {
-    font-family: 'Fira Sans';
-    font-style: normal;
-    font-weight: 500;
-    src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
+       font-family: 'Fira Sans';
+       font-style: normal;
+       font-weight: 500;
+       src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
 }
 @font-face {
-    font-family: 'Source Serif Pro';
-    font-style: normal;
-    font-weight: 400;
-    src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
+       font-family: 'Source Serif Pro';
+       font-style: normal;
+       font-weight: 400;
+       src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
 }
 @font-face {
-    font-family: 'Source Serif Pro';
-    font-style: italic;
-    font-weight: 400;
-    src: url("Heuristica-Italic.woff") format('woff');
+       font-family: 'Source Serif Pro';
+       font-style: italic;
+       font-weight: 400;
+       src: url("Heuristica-Italic.woff") format('woff');
 }
 @font-face {
-    font-family: 'Source Serif Pro';
-    font-style: normal;
-    font-weight: 700;
-    src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
+       font-family: 'Source Serif Pro';
+       font-style: normal;
+       font-weight: 700;
+       src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
 }
 @font-face {
-    font-family: 'Source Code Pro';
-    font-style: normal;
-    font-weight: 400;
-    /* Avoid using locally installed font because bad versions are in circulation:
-     * see https://github.com/rust-lang/rust/issues/24355 */
-    src: url("SourceCodePro-Regular.woff") format('woff');
+       font-family: 'Source Code Pro';
+       font-style: normal;
+       font-weight: 400;
+       /* Avoid using locally installed font because bad versions are in circulation:
+        * see https://github.com/rust-lang/rust/issues/24355 */
+       src: url("SourceCodePro-Regular.woff") format('woff');
 }
 
 *:not(body) {
   -webkit-box-sizing: border-box;
-     -moz-box-sizing: border-box;
-          box-sizing: border-box;
+        -moz-box-sizing: border-box;
+                 box-sizing: border-box;
 }
 
 /* General structure */
 
 body {
-    background-color: white;
-    margin: 0 auto;
-    padding: 0 15px;
-    font-family: "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
-    font-size: 18px;
-    color: #333;
-    line-height: 1.428571429;
-
-    -webkit-font-feature-settings: "kern", "liga";
-    -moz-font-feature-settings: "kern", "liga";
-    font-feature-settings: "kern", "liga";
+       background-color: white;
+       margin: 0 auto;
+       padding: 0 15px;
+       font-family: "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
+       font-size: 18px;
+       color: #333;
+       line-height: 1.428571429;
+
+       -webkit-font-feature-settings: "kern", "liga";
+       -moz-font-feature-settings: "kern", "liga";
+       font-feature-settings: "kern", "liga";
 }
 @media (min-width: 768px) {
-    body {
-        max-width: 750px;
-    }
+       body {
+               max-width: 750px;
+       }
 }
 
 h1, h2, h3, h4, h5, h6, nav, #versioninfo {
-    font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+       font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
 }
 h1, h2, h3, h4, h5, h6 {
-    color: black;
-    font-weight: 400;
-    line-height: 1.1;
+       color: black;
+       font-weight: 400;
+       line-height: 1.1;
 }
 h1, h2, h3 {
-    margin-top: 20px;
-    margin-bottom: 15px;
+       margin-top: 20px;
+       margin-bottom: 15px;
 }
 h1 {
-    margin-bottom: 20px;
+       margin-bottom: 20px;
 }
 h4, h5, h6 {
-    margin-top: 12px;
-    margin-bottom: 10px;
-    padding: 5px 10px;
+       margin-top: 12px;
+       margin-bottom: 10px;
+       padding: 5px 10px;
 }
 h5, h6 {
-    text-decoration: underline;
+       text-decoration: underline;
 }
 
 h1 {
-    font-size: 28px;
-    font-weight: 500;
-    padding: .1em .4em;
-    border-bottom: 2px solid #ddd;
+       font-size: 28px;
+       font-weight: 500;
+       padding: .1em .4em;
+       border-bottom: 2px solid #ddd;
 }
 h1.title {
-    line-height: 1.5em;
+       line-height: 1.5em;
 }
 h2 {
-    font-size: 26px;
-    padding: .2em .5em;
-    border-bottom: 1px solid #ddd;
+       font-size: 26px;
+       padding: .2em .5em;
+       border-bottom: 1px solid #ddd;
 }
 h3 {
-    font-size: 24px;
-    padding: .2em .7em;
-    border-bottom: 1px solid #DDE8FC;
+       font-size: 24px;
+       padding: .2em .7em;
+       border-bottom: 1px solid #DDE8FC;
 }
 h4 {
-    font-size: 22px;
+       font-size: 22px;
 }
 h5 {
-    font-size: 20px;
+       font-size: 20px;
 }
 h6 {
-    font-size: 18px;
+       font-size: 18px;
 }
 @media (min-width: 992px) {
-    h1 {
-        font-size: 36px;
-    }
-    h2 {
-        font-size: 30px;
-    }
-    h3 {
-        font-size: 26px;
-    }
+       h1 {
+               font-size: 36px;
+       }
+       h2 {
+               font-size: 30px;
+       }
+       h3 {
+               font-size: 26px;
+       }
 }
 
 nav {
-    column-count: 2;
-    -moz-column-count: 2;
-    -webkit-column-count: 2;
-    font-size: 15px;
-    margin: 0 0 1em 0;
+       column-count: 2;
+       -moz-column-count: 2;
+       -webkit-column-count: 2;
+       font-size: 15px;
+       margin: 0 0 1em 0;
 }
 p {
-    margin: 0 0 1em 0;
+       margin: 0 0 1em 0;
 }
 
 strong {
-    font-weight: bold;
+       font-weight: bold;
 }
 
 em {
-    font-style: italic;
+       font-style: italic;
 }
 
 footer {
-    border-top: 1px solid #ddd;
-    font-size: 14px;
-    font-style: italic;
-    padding-top: 5px;
-    margin-top: 3em;
-    margin-bottom: 1em;
+       border-top: 1px solid #ddd;
+       font-size: 14px;
+       font-style: italic;
+       padding-top: 5px;
+       margin-top: 3em;
+       margin-bottom: 1em;
 }
 
 /* Links layout */
 
 a {
-    text-decoration: none;
-    color: #428BCA;
-    background: transparent;
+       text-decoration: none;
+       color: #428BCA;
+       background: transparent;
 }
 a:hover, a:focus {
-    color: #2A6496;
-    text-decoration: underline;
+       color: #2A6496;
+       text-decoration: underline;
 }
 a:focus {
-    outline: thin dotted #333;
-    outline: 5px auto -webkit-focus-ring-color;
-    outline-offset: -2px;
+       outline: thin dotted #333;
+       outline: 5px auto -webkit-focus-ring-color;
+       outline-offset: -2px;
 }
 a:hover, a:active {
-    outline: 0;
+       outline: 0;
 }
 
 h1 a:link, h1 a:visited, h2 a:link, h2 a:visited,
@@ -197,34 +197,34 @@ h5 a:hover {text-decoration: none;}
 /* Code */
 
 pre, code {
-    font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", monospace;
-    word-wrap: break-word;
+       font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", monospace;
+       word-wrap: break-word;
 }
 pre {
-    border-left: 2px solid #eee;
-    white-space: pre-wrap;
-    padding: 14px;
-    padding-right: 0;
-    margin: 20px 0;
-    font-size: 13px;
-    word-break: break-all;
+       border-left: 2px solid #eee;
+       white-space: pre-wrap;
+       padding: 14px;
+       padding-right: 0;
+       margin: 20px 0;
+       font-size: 15px;
+       word-break: break-all;
 }
 code {
-    padding: 0 2px;
-    color: #8D1A38;
+       padding: 0 2px;
+       color: #8D1A38;
 }
 pre code {
-    padding: 0;
-    font-size: inherit;
-    color: inherit;
+       padding: 0;
+       font-size: inherit;
+       color: inherit;
 }
 
 a > code {
-    color: #428BCA;
+       color: #428BCA;
 }
 
 .section-header > a > code {
-    color: #8D1A38;
+       color: #8D1A38;
 }
 
 /* Code highlighting */
@@ -241,178 +241,221 @@ pre.rust .lifetime { color: #B76514; }
 /* The rest */
 
 #versioninfo {
-    text-align: center;
-    margin: 0.5em;
-    font-size: 1.1em;
+       text-align: center;
+       margin: 0.5em;
+       font-size: 1.1em;
 }
 @media (min-width: 992px) {
-    #versioninfo {
-        font-size: 0.8em;
-        position: fixed;
-        bottom: 0px;
-        right: 0px;
-    }
-    .white-sticker {
-        background-color: #fff;
-        margin: 2px;
-        padding: 0 2px;
-        border-radius: .2em;
-    }
+       #versioninfo {
+               font-size: 0.8em;
+               position: fixed;
+               bottom: 0px;
+               right: 0px;
+       }
+       .white-sticker {
+               background-color: #fff;
+               margin: 2px;
+               padding: 0 2px;
+               border-radius: .2em;
+       }
 }
 #versioninfo a.hash {
-    color: gray;
-    font-size: 80%;
+       color: gray;
+       font-size: 80%;
 }
 
 blockquote {
-    color: #000;
-    margin: 20px 0;
-    padding: 15px 20px;
-    background-color: #f2f7f9;
-    border-top: .1em solid #e5eef2;
-    border-bottom: .1em solid #e5eef2;
+       color: #000;
+       margin: 20px 0;
+       padding: 15px 20px;
+       background-color: #f2f7f9;
+       border-top: .1em solid #e5eef2;
+       border-bottom: .1em solid #e5eef2;
 }
 blockquote p {
-    font-size: 17px;
-    font-weight: 300;
-    line-height: 1.4;
+       font-size: 17px;
+       font-weight: 300;
+       line-height: 1.4;
 }
 blockquote p:last-child {
-    margin-bottom: 0;
+       margin-bottom: 0;
 }
 
 ul, ol {
-    padding-left: 25px;
+       padding-left: 25px;
 }
 ul ul, ol ul, ul ol, ol ol {
-    margin-bottom: 0;
+       margin-bottom: 0;
 }
 dl {
-    margin-bottom: 20px;
+       margin-bottom: 20px;
 }
 dd {
-    margin-left: 0;
+       margin-left: 0;
 }
 
 nav ul {
-    list-style-type: none;
-    margin: 0;
-    padding-left: 0px;
+       list-style-type: none;
+       margin: 0;
+       padding-left: 0px;
 }
 
 /* Only display one level of hierarchy in the TOC */
 nav ul ul {
-    display: none;
+       display: none;
 }
 
 sub,
 sup {
-    font-size: 75%;
-    line-height: 0;
-    position: relative;
+       font-size: 75%;
+       line-height: 0;
+       position: relative;
 }
 
 hr {
-    margin-top: 20px;
-    margin-bottom: 20px;
-    border: 0;
-    border-top: 1px solid #eeeeee;
+       margin-top: 20px;
+       margin-bottom: 20px;
+       border: 0;
+       border-top: 1px solid #eeeeee;
 }
 
 table {
-    border-collapse: collapse;
-    border-spacing: 0;
-    overflow-x: auto;
-    display: block;
+       border-collapse: collapse;
+       border-spacing: 0;
+       overflow-x: auto;
+       display: block;
 }
 
 table tr.odd {
-    background: #eee;
+       background: #eee;
 }
 
 table td,
 table th {
-    border: 1px solid #ddd;
-    padding: 5px;
+       border: 1px solid #ddd;
+       padding: 5px;
 }
 
 /* Code snippets */
 
 pre.rust { position: relative; }
 a.test-arrow {
-    background-color: rgba(78, 139, 202, 0.2);
-    display: inline-block;
-    position: absolute;
-    color: #f5f5f5;
-    padding: 5px 10px 5px 10px;
-    border-radius: 5px;
-    font-size: 130%;
-    top: 5px;
-    right: 5px;
+       background-color: rgba(78, 139, 202, 0.2);
+       display: inline-block;
+       position: absolute;
+       color: #f5f5f5;
+       padding: 5px 10px 5px 10px;
+       border-radius: 5px;
+       font-size: 130%;
+       top: 5px;
+       right: 5px;
 }
 a.test-arrow:hover{
-    background-color: #4e8bca;
-    text-decoration: none;
+       background-color: #4e8bca;
+       text-decoration: none;
 }
 
 .unstable-feature {
-    border: 2px solid red;
-    padding: 5px;
+       border: 2px solid red;
+       padding: 5px;
 }
 
 @media (min-width: 1170px) {
-    pre {
-        font-size: 15px;
-    }
+       pre {
+               font-size: 15px;
+       }
 }
 
 @media print {
-    * {
-        text-shadow: none !important;
-        color: #000 !important;
-        background: transparent !important;
-        box-shadow: none !important;
-    }
-    a, a:visited {
-        text-decoration: underline;
-    }
-    p a[href]:after {
-        content: " (" attr(href) ")";
-    }
-    footer a[href]:after {
-        content: "";
-    }
-    a[href^="javascript:"]:after, a[href^="#"]:after {
-        content: "";
-    }
-    pre, blockquote {
-        border: 1px solid #999;
-        page-break-inside: avoid;
-    }
-    @page {
-        margin: 2cm .5cm;
-    }
-    h1:not(.title), h2, h3 {
-        border-bottom: 0px none;
-    }
-    p, h2, h3 {
-        orphans: 3;
-        widows: 3;
-    }
-    h2, h3 {
-        page-break-after: avoid;
-    }
-    table {
-        border-collapse: collapse !important;
-    }
-    table td, table th {
-        background-color: #fff !important;
-    }
+       * {
+               text-shadow: none !important;
+               color: #000 !important;
+               background: transparent !important;
+               box-shadow: none !important;
+       }
+       a, a:visited {
+               text-decoration: underline;
+       }
+       p a[href]:after {
+               content: " (" attr(href) ")";
+       }
+       footer a[href]:after {
+               content: "";
+       }
+       a[href^="javascript:"]:after, a[href^="#"]:after {
+               content: "";
+       }
+       pre, blockquote {
+               border: 1px solid #999;
+               page-break-inside: avoid;
+       }
+       @page {
+               margin: 2cm .5cm;
+       }
+       h1:not(.title), h2, h3 {
+               border-bottom: 0px none;
+       }
+       p, h2, h3 {
+               orphans: 3;
+               widows: 3;
+       }
+       h2, h3 {
+               page-break-after: avoid;
+       }
+       table {
+               border-collapse: collapse !important;
+       }
+       table td, table th {
+               background-color: #fff !important;
+       }
 }
 
 #keyword-table-marker + table thead { display: none; }
 #keyword-table-marker + table td { border: none; }
 #keyword-table-marker + table {
-    margin-left: 2em;
-    margin-bottom: 1em;
+       margin-left: 2em;
+       margin-bottom: 1em;
+}
+
+.error-described {
+       position: relative;
+}
+
+.information {
+       position: absolute;
+       left: -25px;
+       margin-top: 7px;
+       z-index: 1;
+}
+
+.tooltip {
+       position: relative;
+       display: inline-block;
+       cursor: pointer;
+}
+
+.tooltip .tooltiptext {
+       width: 120px;
+       display: none;
+       text-align: center;
+       padding: 5px 3px;
+       border-radius: 6px;
+       margin-left: 5px;
+       top: -5px;
+       left: 105%;
+       z-index: 1;
+}
+
+.tooltip:hover .tooltiptext {
+       display: inline;
+}
+
+.tooltip .tooltiptext::after {
+       content: " ";
+       position: absolute;
+       top: 50%;
+       left: 13px;
+       margin-top: -5px;
+       border-width: 5px;
+       border-style: solid;
 }
diff --git a/src/doc/unstable-book/src/language-features/crate_in_paths.md b/src/doc/unstable-book/src/language-features/crate_in_paths.md
new file mode 100644 (file)
index 0000000..f165699
--- /dev/null
@@ -0,0 +1,54 @@
+# `crate_in_paths`
+
+The tracking issue for this feature is: [#44660]
+
+[#44660]: https://github.com/rust-lang/rust/issues/44660
+
+------------------------
+
+The `crate_in_paths` feature allows to explicitly refer to the crate root in absolute paths
+using keyword `crate`.
+
+`crate` can be used *only* in absolute paths, i.e. either in `::crate::a::b::c` form or in `use`
+items where the starting `::` is added implicitly.  
+Paths like `crate::a::b::c` are not accepted currently.
+
+This feature is required in `feature(extern_absolute_paths)` mode to refer to any absolute path
+in the local crate (absolute paths refer to extern crates by default in that mode), but can be
+used without `feature(extern_absolute_paths)` as well.
+
+```rust
+#![feature(crate_in_paths)]
+
+// Imports, `::` is added implicitly
+use crate::m::f;
+use crate as root;
+
+mod m {
+    pub fn f() -> u8 { 1 }
+    pub fn g() -> u8 { 2 }
+    pub fn h() -> u8 { 3 }
+
+    // OK, visibilities implicitly add starting `::` as well, like imports
+    pub(in crate::m) struct S;
+}
+
+mod n
+{
+    use crate::m::f;
+    use crate as root;
+    pub fn check() {
+        assert_eq!(f(), 1);
+        // `::` is required in non-import paths
+        assert_eq!(::crate::m::g(), 2);
+        assert_eq!(root::m::h(), 3);
+    }
+}
+
+fn main() {
+    assert_eq!(f(), 1);
+    assert_eq!(::crate::m::g(), 2);
+    assert_eq!(root::m::h(), 3);
+    n::check();
+}
+```
diff --git a/src/doc/unstable-book/src/language-features/extern_absolute_paths.md b/src/doc/unstable-book/src/language-features/extern_absolute_paths.md
new file mode 100644 (file)
index 0000000..f45c505
--- /dev/null
@@ -0,0 +1,43 @@
+# `extern_absolute_paths`
+
+The tracking issue for this feature is: [#44660]
+
+[#44660]: https://github.com/rust-lang/rust/issues/44660
+
+------------------------
+
+The `extern_absolute_paths` feature enables mode allowing to refer to names from other crates
+"inline", without introducing `extern crate` items, using absolute paths like `::my_crate::a::b`.
+
+`::my_crate::a::b` will resolve to path `a::b` in crate `my_crate`.
+
+`feature(crate_in_paths)` can be used in `feature(extern_absolute_paths)` mode for referring
+to absolute paths in the local crate (`::crate::a::b`).
+
+`feature(extern_in_paths)` provides the same effect by using keyword `extern` to refer to
+paths from other crates (`extern::my_crate::a::b`).
+
+```rust,ignore
+#![feature(extern_absolute_paths)]
+
+// Suppose we have a dependency crate `xcrate` available through `Cargo.toml`, or `--extern`
+// options, or standard Rust distribution, or some other means.
+
+use xcrate::Z;
+
+fn f() {
+    use xcrate;
+    use xcrate as ycrate;
+    let s = xcrate::S;
+    assert_eq!(format!("{:?}", s), "S");
+    let z = ycrate::Z;
+    assert_eq!(format!("{:?}", z), "Z");
+}
+
+fn main() {
+    let s = ::xcrate::S;
+    assert_eq!(format!("{:?}", s), "S");
+    let z = Z;
+    assert_eq!(format!("{:?}", z), "Z");
+}
+```
diff --git a/src/doc/unstable-book/src/language-features/extern_in_paths.md b/src/doc/unstable-book/src/language-features/extern_in_paths.md
new file mode 100644 (file)
index 0000000..3ae6cc2
--- /dev/null
@@ -0,0 +1,40 @@
+# `extern_in_paths`
+
+The tracking issue for this feature is: [#44660]
+
+[#44660]: https://github.com/rust-lang/rust/issues/44660
+
+------------------------
+
+The `extern_in_paths` feature allows to refer to names from other crates "inline", without
+introducing `extern crate` items, using keyword `extern`.
+
+For example, `extern::my_crat::a::b` will resolve to path `a::b` in crate `my_crate`.
+
+`feature(extern_absolute_paths)` mode provides the same effect by resolving absolute paths like
+`::my_crate::a::b` to paths from extern crates by default.
+
+```rust,ignore
+#![feature(extern_in_paths)]
+
+// Suppose we have a dependency crate `xcrate` available through `Cargo.toml`, or `--extern`
+// options, or standard Rust distribution, or some other means.
+
+use extern::xcrate::Z;
+
+fn f() {
+    use extern::xcrate;
+    use extern::xcrate as ycrate;
+    let s = xcrate::S;
+    assert_eq!(format!("{:?}", s), "S");
+    let z = ycrate::Z;
+    assert_eq!(format!("{:?}", z), "Z");
+}
+
+fn main() {
+    let s = extern::xcrate::S;
+    assert_eq!(format!("{:?}", s), "S");
+    let z = Z;
+    assert_eq!(format!("{:?}", z), "Z");
+}
+```
index 17538d885f8f4753f327b3a2b3bdcb812bf29338..ee5182a1d46637cf59306139c4de621820f04281 100644 (file)
@@ -343,7 +343,7 @@ macro_rules! rotate {
         fn $name(b: &mut Bencher) {
             let size = mem::size_of_val(&$gen(1)[0]);
             let mut v = $gen($len * 8 / size);
-            b.iter(|| black_box(&mut v).rotate(($mid*8+size-1)/size));
+            b.iter(|| black_box(&mut v).rotate_left(($mid*8+size-1)/size));
             b.bytes = (v.len() * size) as u64;
         }
     }
index fa73197885be79bf34aa3cc2396bcace33cd6117..2c7bdc427ea7c70dbe594ca55d82c215fe62606d 100644 (file)
@@ -1360,24 +1360,61 @@ pub fn sort_unstable_by_key<B, F>(&mut self, f: F)
         core_slice::SliceExt::sort_unstable_by_key(self, f);
     }
 
-    /// Permutes the slice in-place such that `self[mid..]` moves to the
-    /// beginning of the slice while `self[..mid]` moves to the end of the
-    /// slice.  Equivalently, rotates the slice `mid` places to the left
-    /// or `k = self.len() - mid` places to the right.
+    /// Rotates the slice in-place such that the first `mid` elements of the
+    /// slice move to the end while the last `self.len() - mid` elements move to
+    /// the front. After calling `rotate_left`, the element previously at index
+    /// `mid` will become the first element in the slice.
     ///
-    /// This is a "k-rotation", a permutation in which item `i` moves to
-    /// position `i + k`, modulo the length of the slice.  See _Elements
-    /// of Programming_ [§10.4][eop].
+    /// # Panics
+    ///
+    /// This function will panic if `mid` is greater than the length of the
+    /// slice. Note that `mid == self.len()` does _not_ panic and is a no-op
+    /// rotation.
+    ///
+    /// # Complexity
+    ///
+    /// Takes linear (in `self.len()`) time.
+    ///
+    /// # Examples
     ///
-    /// Rotation by `mid` and rotation by `k` are inverse operations.
+    /// ```
+    /// #![feature(slice_rotate)]
     ///
-    /// [eop]: https://books.google.com/books?id=CO9ULZGINlsC&pg=PA178&q=k-rotation
+    /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+    /// a.rotate_left(2);
+    /// assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+    /// ```
+    ///
+    /// Rotating a subslice:
+    ///
+    /// ```
+    /// #![feature(slice_rotate)]
+    ///
+    /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+    /// a[1..5].rotate_left(1);
+    /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+    /// ```
+    #[unstable(feature = "slice_rotate", issue = "41891")]
+    pub fn rotate_left(&mut self, mid: usize) {
+        core_slice::SliceExt::rotate_left(self, mid);
+    }
+
+    #[unstable(feature = "slice_rotate", issue = "41891")]
+    #[rustc_deprecated(since = "", reason = "renamed to `rotate_left`")]
+    pub fn rotate(&mut self, mid: usize) {
+        core_slice::SliceExt::rotate_left(self, mid);
+    }
+
+    /// Rotates the slice in-place such that the first `self.len() - k`
+    /// elements of the slice move to the end while the last `k` elements move
+    /// to the front. After calling `rotate_right`, the element previously at
+    /// index `self.len() - k` will become the first element in the slice.
     ///
     /// # Panics
     ///
-    /// This function will panic if `mid` is greater than the length of the
-    /// slice.  (Note that `mid == self.len()` does _not_ panic; it's a nop
-    /// rotation with `k == 0`, the inverse of a rotation with `mid == 0`.)
+    /// This function will panic if `k` is greater than the length of the
+    /// slice. Note that `k == self.len()` does _not_ panic and is a no-op
+    /// rotation.
     ///
     /// # Complexity
     ///
@@ -1388,31 +1425,23 @@ pub fn sort_unstable_by_key<B, F>(&mut self, f: F)
     /// ```
     /// #![feature(slice_rotate)]
     ///
-    /// let mut a = [1, 2, 3, 4, 5, 6, 7];
-    /// let mid = 2;
-    /// a.rotate(mid);
-    /// assert_eq!(&a, &[3, 4, 5, 6, 7, 1, 2]);
-    /// let k = a.len() - mid;
-    /// a.rotate(k);
-    /// assert_eq!(&a, &[1, 2, 3, 4, 5, 6, 7]);
-    ///
-    /// use std::ops::Range;
-    /// fn slide<T>(slice: &mut [T], range: Range<usize>, to: usize) {
-    ///     if to < range.start {
-    ///         slice[to..range.end].rotate(range.start-to);
-    ///     } else if to > range.end {
-    ///         slice[range.start..to].rotate(range.end-range.start);
-    ///     }
-    /// }
-    /// let mut v: Vec<_> = (0..10).collect();
-    /// slide(&mut v, 1..4, 7);
-    /// assert_eq!(&v, &[0, 4, 5, 6, 1, 2, 3, 7, 8, 9]);
-    /// slide(&mut v, 6..8, 1);
-    /// assert_eq!(&v, &[0, 3, 7, 4, 5, 6, 1, 2, 8, 9]);
+    /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+    /// a.rotate_right(2);
+    /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+    /// ```
+    ///
+    /// Rotate a subslice:
+    ///
+    /// ```
+    /// #![feature(slice_rotate)]
+    ///
+    /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+    /// a[1..5].rotate_right(1);
+    /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
     /// ```
     #[unstable(feature = "slice_rotate", issue = "41891")]
-    pub fn rotate(&mut self, mid: usize) {
-        core_slice::SliceExt::rotate(self, mid);
+    pub fn rotate_right(&mut self, k: usize) {
+        core_slice::SliceExt::rotate_right(self, k);
     }
 
     /// Copies the elements from `src` into `self`.
@@ -1595,6 +1624,7 @@ pub fn swap_with_slice(&mut self, other: &mut [T]) {
     /// let x = s.to_vec();
     /// // Here, `s` and `x` can be modified independently.
     /// ```
+    #[rustc_conversion_suggestion]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_vec(&self) -> Vec<T>
index ca493ab27e3ad67003d5655416eee41da0711aa6..8d99d0bc8f4dc330f14ac5b06e7bb23503173738 100644 (file)
@@ -2034,6 +2034,7 @@ pub trait ToString {
     ///
     /// assert_eq!(five, i.to_string());
     /// ```
+    #[rustc_conversion_suggestion]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_string(&self) -> String;
 }
index 85d5ce304b88de2c27556a8414d61e93bb681173..49bdc9e1b90de5c252ac2321e9d0e85da3643899 100644 (file)
@@ -494,37 +494,72 @@ fn test_sort_stability() {
 }
 
 #[test]
-fn test_rotate() {
+fn test_rotate_left() {
     let expected: Vec<_> = (0..13).collect();
     let mut v = Vec::new();
 
     // no-ops
     v.clone_from(&expected);
-    v.rotate(0);
+    v.rotate_left(0);
     assert_eq!(v, expected);
-    v.rotate(expected.len());
+    v.rotate_left(expected.len());
     assert_eq!(v, expected);
     let mut zst_array = [(), (), ()];
-    zst_array.rotate(2);
+    zst_array.rotate_left(2);
 
     // happy path
     v = (5..13).chain(0..5).collect();
-    v.rotate(8);
+    v.rotate_left(8);
     assert_eq!(v, expected);
 
     let expected: Vec<_> = (0..1000).collect();
 
     // small rotations in large slice, uses ptr::copy
     v = (2..1000).chain(0..2).collect();
-    v.rotate(998);
+    v.rotate_left(998);
     assert_eq!(v, expected);
     v = (998..1000).chain(0..998).collect();
-    v.rotate(2);
+    v.rotate_left(2);
     assert_eq!(v, expected);
 
     // non-small prime rotation, has a few rounds of swapping
     v = (389..1000).chain(0..389).collect();
-    v.rotate(1000-389);
+    v.rotate_left(1000-389);
+    assert_eq!(v, expected);
+}
+
+#[test]
+fn test_rotate_right() {
+    let expected: Vec<_> = (0..13).collect();
+    let mut v = Vec::new();
+
+    // no-ops
+    v.clone_from(&expected);
+    v.rotate_right(0);
+    assert_eq!(v, expected);
+    v.rotate_right(expected.len());
+    assert_eq!(v, expected);
+    let mut zst_array = [(), (), ()];
+    zst_array.rotate_right(2);
+
+    // happy path
+    v = (5..13).chain(0..5).collect();
+    v.rotate_right(5);
+    assert_eq!(v, expected);
+
+    let expected: Vec<_> = (0..1000).collect();
+
+    // small rotations in large slice, uses ptr::copy
+    v = (2..1000).chain(0..2).collect();
+    v.rotate_right(2);
+    assert_eq!(v, expected);
+    v = (998..1000).chain(0..998).collect();
+    v.rotate_right(998);
+    assert_eq!(v, expected);
+
+    // non-small prime rotation, has a few rounds of swapping
+    v = (389..1000).chain(0..389).collect();
+    v.rotate_right(389);
     assert_eq!(v, expected);
 }
 
index e635df5204007e7496256236695ad80f154370f8..72fa3148fe54aba3563439947fb212864f3d7e3f 100644 (file)
@@ -69,7 +69,9 @@ struct TypedArenaChunk<T> {
 impl<T> TypedArenaChunk<T> {
     #[inline]
     unsafe fn new(capacity: usize) -> TypedArenaChunk<T> {
-        TypedArenaChunk { storage: RawVec::with_capacity(capacity) }
+        TypedArenaChunk {
+            storage: RawVec::with_capacity(capacity),
+        }
     }
 
     /// Destroys this arena chunk.
@@ -132,7 +134,9 @@ pub fn alloc(&self, object: T) -> &mut T {
 
         unsafe {
             if mem::size_of::<T>() == 0 {
-                self.ptr.set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) as *mut T);
+                self.ptr
+                    .set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1)
+                        as *mut T);
                 let ptr = mem::align_of::<T>() as *mut T;
                 // Don't drop the object. This `write` is equivalent to `forget`.
                 ptr::write(ptr, object);
@@ -157,7 +161,9 @@ pub fn alloc(&self, object: T) -> &mut T {
     ///  - Zero-length slices
     #[inline]
     pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
-        where T: Copy {
+    where
+        T: Copy,
+    {
         assert!(mem::size_of::<T>() != 0);
         assert!(slice.len() != 0);
 
@@ -321,7 +327,10 @@ fn grow<T>(&self, n: usize) {
             let (chunk, mut new_capacity);
             if let Some(last_chunk) = chunks.last_mut() {
                 let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
-                if last_chunk.storage.reserve_in_place(used_bytes, needed_bytes) {
+                if last_chunk
+                    .storage
+                    .reserve_in_place(used_bytes, needed_bytes)
+                {
                     self.end.set(last_chunk.end());
                     return;
                 } else {
@@ -357,9 +366,9 @@ pub fn alloc<T>(&self, object: T) -> &mut T {
 
             let ptr = self.ptr.get();
             // Set the pointer past ourselves
-            self.ptr.set(intrinsics::arith_offset(
-                    self.ptr.get(), mem::size_of::<T>() as isize
-            ) as *mut u8);
+            self.ptr.set(
+                intrinsics::arith_offset(self.ptr.get(), mem::size_of::<T>() as isize) as *mut u8,
+            );
             // Write into uninitialized memory.
             ptr::write(ptr as *mut T, object);
             &mut *(ptr as *mut T)
@@ -375,7 +384,9 @@ pub fn alloc<T>(&self, object: T) -> &mut T {
     ///  - Zero-length slices
     #[inline]
     pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
-        where T: Copy {
+    where
+        T: Copy,
+    {
         assert!(!mem::needs_drop::<T>());
         assert!(mem::size_of::<T>() != 0);
         assert!(slice.len() != 0);
@@ -391,7 +402,8 @@ pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
         unsafe {
             let arena_slice = slice::from_raw_parts_mut(self.ptr.get() as *mut T, slice.len());
             self.ptr.set(intrinsics::arith_offset(
-                    self.ptr.get(), (slice.len() * mem::size_of::<T>()) as isize
+                self.ptr.get(),
+                (slice.len() * mem::size_of::<T>()) as isize,
             ) as *mut u8);
             arena_slice.copy_from_slice(slice);
             arena_slice
@@ -456,8 +468,9 @@ fn alloc_outer<F: Fn() -> Outer<'a>>(&self, f: F) -> &Outer {
 
         let arena = Wrap(TypedArena::new());
 
-        let result =
-            arena.alloc_outer(|| Outer { inner: arena.alloc_inner(|| Inner { value: 10 }) });
+        let result = arena.alloc_outer(|| Outer {
+            inner: arena.alloc_inner(|| Inner { value: 10 }),
+        });
 
         assert_eq!(result.inner.value, 10);
     }
index 0f541a4b53789930d992090a034ed83c8020f7ee..65aacb23bd76813511c1381d85f73b17b1a1a344 100644 (file)
@@ -83,9 +83,12 @@ pub mod rt {
 /// some other means.
 ///
 /// An important thing to remember is that the type `fmt::Error` should not be
-/// confused with `std::io::Error` or `std::error::Error`, which you may also
+/// confused with [`std::io::Error`] or [`std::error::Error`], which you may also
 /// have in scope.
 ///
+/// [`std::io::Error`]: ../../std/io/struct.Error.html
+/// [`std::error::Error`]: ../../std/error/trait.Error.html
+///
 /// # Examples
 ///
 /// ```rust
index e9aee4a4676de47fda7282106908e79d3d80b430..66a76a24df45afc983395776ad5c69f83c651d38 100644 (file)
@@ -251,6 +251,21 @@ fn nth(&mut self, n: usize) -> Option<A> {
         self.start = self.end.clone();
         None
     }
+
+    #[inline]
+    fn last(mut self) -> Option<A> {
+        self.next_back()
+    }
+
+    #[inline]
+    fn min(mut self) -> Option<A> {
+        self.next()
+    }
+
+    #[inline]
+    fn max(mut self) -> Option<A> {
+        self.next_back()
+    }
 }
 
 // These macros generate `ExactSizeIterator` impls for various range types.
@@ -367,6 +382,21 @@ fn nth(&mut self, n: usize) -> Option<A> {
         self.end.replace_zero();
         None
     }
+
+    #[inline]
+    fn last(mut self) -> Option<A> {
+        self.next_back()
+    }
+
+    #[inline]
+    fn min(mut self) -> Option<A> {
+        self.next()
+    }
+
+    #[inline]
+    fn max(mut self) -> Option<A> {
+        self.next_back()
+    }
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
index 72036d6d3a248e0cff831c3d5d6e1cd1e3c6f007..e6b79314aa96d47a2dd19800b1ce5731be430282 100644 (file)
@@ -206,7 +206,10 @@ unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
     fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
 
     #[unstable(feature = "slice_rotate", issue = "41891")]
-    fn rotate(&mut self, mid: usize);
+    fn rotate_left(&mut self, mid: usize);
+
+    #[unstable(feature = "slice_rotate", issue = "41891")]
+    fn rotate_right(&mut self, k: usize);
 
     #[stable(feature = "clone_from_slice", since = "1.7.0")]
     fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
@@ -645,7 +648,7 @@ fn binary_search(&self, x: &T) -> Result<usize, usize>
         self.binary_search_by(|p| p.cmp(x))
     }
 
-    fn rotate(&mut self, mid: usize) {
+    fn rotate_left(&mut self, mid: usize) {
         assert!(mid <= self.len());
         let k = self.len() - mid;
 
@@ -655,6 +658,16 @@ fn rotate(&mut self, mid: usize) {
         }
     }
 
+    fn rotate_right(&mut self, k: usize) {
+        assert!(k <= self.len());
+        let mid = self.len() - k;
+
+        unsafe {
+            let p = self.as_mut_ptr();
+            rotate::ptr_rotate(mid, p.offset(mid as isize), k);
+        }
+    }
+
     #[inline]
     fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
         assert!(self.len() == src.len(),
index 677c0ecc33d7f5baa8ee63da15d3e2905117de9f..089d691773a1bcf94a6b1ab31407006cb022e9ee 100644 (file)
@@ -284,7 +284,7 @@ fn haystack(&self) -> &'a str {
     #[inline]
     fn next(&mut self) -> SearchStep {
         let old_finger = self.finger;
-        let slice = unsafe { self.haystack.get_unchecked(old_finger..self.haystack.len()) };
+        let slice = unsafe { self.haystack.get_unchecked(old_finger..self.finger_back) };
         let mut iter = slice.chars();
         let old_len = iter.iter.len();
         if let Some(ch) = iter.next() {
@@ -304,7 +304,8 @@ fn next(&mut self) -> SearchStep {
     fn next_match(&mut self) -> Option<(usize, usize)> {
         loop {
             // get the haystack after the last character found
-            let bytes = if let Some(slice) = self.haystack.as_bytes().get(self.finger..) {
+            let bytes = if let Some(slice) = self.haystack.as_bytes()
+                                                 .get(self.finger..self.finger_back) {
                 slice
             } else {
                 return None;
@@ -340,7 +341,7 @@ fn next_match(&mut self) -> Option<(usize, usize)> {
                 }
             } else {
                 // found nothing, exit
-                self.finger = self.haystack.len();
+                self.finger = self.finger_back;
                 return None;
             }
         }
@@ -353,7 +354,7 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> {
     #[inline]
     fn next_back(&mut self) -> SearchStep {
         let old_finger = self.finger_back;
-        let slice = unsafe { self.haystack.slice_unchecked(0, old_finger) };
+        let slice = unsafe { self.haystack.slice_unchecked(self.finger, old_finger) };
         let mut iter = slice.chars();
         let old_len = iter.iter.len();
         if let Some(ch) = iter.next_back() {
@@ -374,7 +375,7 @@ fn next_match_back(&mut self) -> Option<(usize, usize)> {
         let haystack = self.haystack.as_bytes();
         loop {
             // get the haystack up to but not including the last character searched
-            let bytes = if let Some(slice) = haystack.get(..self.finger_back) {
+            let bytes = if let Some(slice) = haystack.get(self.finger..self.finger_back) {
                 slice
             } else {
                 return None;
@@ -382,6 +383,9 @@ fn next_match_back(&mut self) -> Option<(usize, usize)> {
             // the last byte of the utf8 encoded needle
             let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size - 1) };
             if let Some(index) = memchr::memrchr(last_byte, bytes) {
+                // we searched a slice that was offset by self.finger,
+                // add self.finger to recoup the original index
+                let index = self.finger + index;
                 // memrchr will return the index of the byte we wish to
                 // find. In case of an ASCII character, this is indeed
                 // were we wish our new finger to be ("after" the found
@@ -412,7 +416,7 @@ fn next_match_back(&mut self) -> Option<(usize, usize)> {
                 // found the last byte when searching in reverse.
                 self.finger_back = index;
             } else {
-                self.finger_back = 0;
+                self.finger_back = self.finger;
                 // found nothing, exit
                 return None;
             }
index 5cac5b26d88bd238f3eb722885d744a3f2e16f3f..8997cf9c6bff9d1e50af8d14e7efeb6582b6012a 100644 (file)
@@ -1352,6 +1352,51 @@ fn test_range_step() {
     assert_eq!((isize::MIN..isize::MAX).step_by(1).size_hint(), (usize::MAX, Some(usize::MAX)));
 }
 
+#[test]
+fn test_range_last_max() {
+    assert_eq!((0..20).last(), Some(19));
+    assert_eq!((-20..0).last(), Some(-1));
+    assert_eq!((5..5).last(), None);
+
+    assert_eq!((0..20).max(), Some(19));
+    assert_eq!((-20..0).max(), Some(-1));
+    assert_eq!((5..5).max(), None);
+}
+
+#[test]
+fn test_range_inclusive_last_max() {
+    assert_eq!((0..=20).last(), Some(20));
+    assert_eq!((-20..=0).last(), Some(0));
+    assert_eq!((5..=5).last(), Some(5));
+    let mut r = 10..=10;
+    r.next();
+    assert_eq!(r.last(), None);
+
+    assert_eq!((0..=20).max(), Some(20));
+    assert_eq!((-20..=0).max(), Some(0));
+    assert_eq!((5..=5).max(), Some(5));
+    let mut r = 10..=10;
+    r.next();
+    assert_eq!(r.max(), None);
+}
+
+#[test]
+fn test_range_min() {
+    assert_eq!((0..20).min(), Some(0));
+    assert_eq!((-20..0).min(), Some(-20));
+    assert_eq!((5..5).min(), None);
+}
+
+#[test]
+fn test_range_inclusive_min() {
+    assert_eq!((0..=20).min(), Some(0));
+    assert_eq!((-20..=0).min(), Some(-20));
+    assert_eq!((5..=5).min(), Some(5));
+    let mut r = 10..=10;
+    r.next();
+    assert_eq!(r.min(), None);
+}
+
 #[test]
 fn test_repeat() {
     let mut it = repeat(42);
index 7eb5ff988577766058c656e5d681f40319792448..587dcbe6d6784556796881e87b351d8538e50757 100644 (file)
@@ -197,7 +197,6 @@ fn $fn_name() {
 test_impl_from! { test_u32f64, u32, f64 }
 
 // Float -> Float
-#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
 #[test]
 fn test_f32f64() {
     use core::f32;
index d0fd15263b219644b17bf07829b521f222572773..cfa3b7ee6640fadb930c62be5f1a07b62f615dcd 100644 (file)
@@ -262,3 +262,41 @@ fn test_reverse_search_shared_bytes() {
         [InRange(37, 40), Rejects(34, 37), InRange(10, 13), Rejects(8, 10), Done]
     );
 }
+
+#[test]
+fn double_ended_regression_test() {
+    // https://github.com/rust-lang/rust/issues/47175
+    // Ensures that double ended searching comes to a convergence
+    search_asserts!("abcdeabcdeabcde", 'a', "alternating double ended search",
+        [next_match,    next_match_back,    next_match,      next_match_back],
+        [InRange(0, 1), InRange(10, 11), InRange(5, 6), Done]
+    );
+    search_asserts!("abcdeabcdeabcde", 'a', "triple double ended search for a",
+        [next_match,    next_match_back,    next_match_back,      next_match_back],
+        [InRange(0, 1), InRange(10, 11), InRange(5, 6), Done]
+    );
+    search_asserts!("abcdeabcdeabcde", 'd', "triple double ended search for d",
+        [next_match,    next_match_back,    next_match_back,      next_match_back],
+        [InRange(3, 4), InRange(13, 14), InRange(8, 9), Done]
+    );
+    search_asserts!(STRESS, 'Á', "Double ended search for two-byte Latin character",
+        [next_match,    next_match_back,     next_match,      next_match_back],
+        [InRange(0, 2), InRange(32, 34), InRange(8, 10), Done]
+    );
+    search_asserts!(STRESS, '각', "Reverse double ended search for three-byte Hangul character",
+        [next_match_back, next_back,       next_match,      next,            next_match_back, next_match],
+        [InRange(34, 37), Rejects(32, 34), InRange(19, 22), Rejects(22, 25), InRange(28, 31), Done]
+    );
+    search_asserts!(STRESS, 'ก', "Double ended search for three-byte Thai character",
+        [next_match,      next_back,       next,            next_match_back, next_match],
+        [InRange(22, 25), Rejects(47, 48), Rejects(25, 28), InRange(40, 43), Done]
+    );
+    search_asserts!(STRESS, '😁', "Double ended search for four-byte emoji",
+        [next_match_back, next,          next_match,      next_back,       next_match],
+        [InRange(43, 47), Rejects(0, 2), InRange(15, 19), Rejects(40, 43), Done]
+    );
+    search_asserts!(STRESS, 'ꁁ', "Double ended search for three-byte Yi character with repeated bytes",
+        [next_match,      next,            next_match_back, next_back,       next_match],
+        [InRange(10, 13), Rejects(13, 14), InRange(37, 40), Rejects(34, 37), Done]
+    );
+}
index d6230e93f998d052b2f9aa55d3b6fbec186fedf7..40e5fe5758ac987e629444ee0a612d15c3f183d7 100644 (file)
@@ -329,17 +329,32 @@ fn test_iter_folds() {
 }
 
 #[test]
-fn test_rotate() {
+fn test_rotate_left() {
     const N: usize = 600;
     let a: &mut [_] = &mut [0; N];
     for i in 0..N {
         a[i] = i;
     }
 
-    a.rotate(42);
+    a.rotate_left(42);
     let k = N - 42;
 
     for i in 0..N {
-        assert_eq!(a[(i+k)%N], i);
+        assert_eq!(a[(i + k) % N], i);
+    }
+}
+
+#[test]
+fn test_rotate_right() {
+    const N: usize = 600;
+    let a: &mut [_] = &mut [0; N];
+    for i in 0..N {
+        a[i] = i;
+    }
+
+    a.rotate_right(42);
+
+    for i in 0..N {
+        assert_eq!(a[(i + 42) % N], i);
     }
 }
index ef9eefb6df3f3a2cb989e8050519661faa7d7118..2b4cd1016bdba92becb4f982a4dcb18fe6653bc4 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ef9eefb6df3f3a2cb989e8050519661faa7d7118
+Subproject commit 2b4cd1016bdba92becb4f982a4dcb18fe6653bc4
index 50e70e3bce70b1e8c7cc8b37ada63a9fdb24afef..b9e816baac0dc0f50f8e340eff4908b3e58ba57d 100644 (file)
@@ -95,7 +95,7 @@ fn from_str(src: &str) -> Result<TokenStream, LexError> {
             // notify the expansion info that it is unhygienic
             let mark = Mark::fresh(mark);
             mark.set_expn_info(expn_info);
-            let span = call_site.with_ctxt(call_site.ctxt().apply_mark(mark));
+            let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark));
             let stream = parse::parse_stream_from_source_str(name, src, sess, Some(span));
             Ok(__internal::token_stream_wrap(stream))
         })
index 9dad3c2031d40c9d6b2451f1dc2dc446cb32120b..f95dbcf411cba5eee54b9437a0e3e14e821ff348 100644 (file)
@@ -14,7 +14,7 @@ bitflags = "1.0"
 fmt_macros = { path = "../libfmt_macros" }
 graphviz = { path = "../libgraphviz" }
 jobserver = "0.1"
-log = "0.3"
+log = "0.4"
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_back = { path = "../librustc_back" }
 rustc_const_math = { path = "../librustc_const_math" }
index 29839bb565bb459dc2ac97dc06adbcb27e6c9361..ec52c6cf57bf76ca4ff2230de54da685f8ca5342 100644 (file)
@@ -633,6 +633,8 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
     [anon] NormalizeTy,
     // We use this for most things when incr. comp. is turned off.
     [] Null,
+
+    [] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
 );
 
 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
index 3816bbc1a3378f06b69017e33fa6acefd22be80b..55ec8adb5fbf3131ad02837a5da7cdf0b92ed1d0 100644 (file)
@@ -141,14 +141,22 @@ pub fn query(&self) -> DepGraphQuery {
         DepGraphQuery::new(&nodes[..], &edges[..])
     }
 
-    pub fn in_ignore<'graph>(&'graph self) -> Option<raii::IgnoreTask<'graph>> {
-        self.data.as_ref().map(|data| raii::IgnoreTask::new(&data.current))
+    pub fn assert_ignored(&self)
+    {
+        if let Some(ref data) = self.data {
+            match data.current.borrow().task_stack.last() {
+                Some(&OpenTask::Ignore) | None => {
+                    // ignored
+                }
+                _ => panic!("expected an ignore context")
+            }
+        }
     }
 
     pub fn with_ignore<OP,R>(&self, op: OP) -> R
         where OP: FnOnce() -> R
     {
-        let _task = self.in_ignore();
+        let _task = self.data.as_ref().map(|data| raii::IgnoreTask::new(&data.current));
         op()
     }
 
index 8858023ec1d7ba6eaececfc866d1920a904aeed0..637b156ceef5d998ddedb5969a52b4bb4e2988ac 100644 (file)
@@ -71,27 +71,23 @@ impl serialize::UseSpecializedDecodable for CrateNum {}
 /// particular definition. It should really be considered an interned
 /// shorthand for a particular DefPath.
 ///
-/// At the moment we are allocating the numerical values of DefIndexes into two
-/// ranges: the "low" range (starting at zero) and the "high" range (starting at
-/// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
-/// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
+/// At the moment we are allocating the numerical values of DefIndexes from two
+/// address spaces: DefIndexAddressSpace::Low and DefIndexAddressSpace::High.
+/// This allows us to allocate the DefIndexes of all item-likes
+/// (Items, TraitItems, and ImplItems) into one of these spaces and
 /// consequently use a simple array for lookup tables keyed by DefIndex and
 /// known to be densely populated. This is especially important for the HIR map.
 ///
 /// Since the DefIndex is mostly treated as an opaque ID, you probably
-/// don't have to care about these ranges.
-newtype_index!(DefIndex
-    {
-        ENCODABLE = custom
-        DEBUG_FORMAT = custom,
+/// don't have to care about these address spaces.
 
-        /// The start of the "high" range of DefIndexes.
-        const DEF_INDEX_HI_START = 1 << 31,
+#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, Hash, Copy)]
+pub struct DefIndex(u32);
+
+/// The crate root is always assigned index 0 by the AST Map code,
+/// thanks to `NodeCollector::new`.
+pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);
 
-        /// The crate root is always assigned index 0 by the AST Map code,
-        /// thanks to `NodeCollector::new`.
-        const CRATE_DEF_INDEX = 0,
-    });
 
 impl fmt::Debug for DefIndex {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -104,40 +100,50 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl DefIndex {
     #[inline]
-    pub fn from_u32(x: u32) -> DefIndex {
-        DefIndex(x)
+    pub fn address_space(&self) -> DefIndexAddressSpace {
+        match self.0 & 1 {
+            0 => DefIndexAddressSpace::Low,
+            1 => DefIndexAddressSpace::High,
+            _ => unreachable!()
+        }
     }
 
+    /// Converts this DefIndex into a zero-based array index.
+    /// This index is the offset within the given DefIndexAddressSpace.
     #[inline]
-    pub fn as_usize(&self) -> usize {
-        self.0 as usize
+    pub fn as_array_index(&self) -> usize {
+        (self.0 >> 1) as usize
     }
 
     #[inline]
-    pub fn as_u32(&self) -> u32 {
-        self.0
+    pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
+        DefIndex::from_raw_u32(((i << 1) | (address_space as usize)) as u32)
     }
 
-    #[inline]
-    pub fn address_space(&self) -> DefIndexAddressSpace {
-        if self.0 < DEF_INDEX_HI_START.0 {
-            DefIndexAddressSpace::Low
-        } else {
-            DefIndexAddressSpace::High
-        }
+    // Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
+    // function maps the index of the macro within the crate (which is also the
+    // index of the macro in the CrateMetadata::proc_macros array) to the
+    // corresponding DefIndex.
+    pub fn from_proc_macro_index(proc_macro_index: usize) -> DefIndex {
+        let def_index = DefIndex::from_array_index(proc_macro_index,
+                                                   DefIndexAddressSpace::High);
+        assert!(def_index != CRATE_DEF_INDEX);
+        def_index
     }
 
-    /// Converts this DefIndex into a zero-based array index.
-    /// This index is the offset within the given "range" of the DefIndex,
-    /// that is, if the DefIndex is part of the "high" range, the resulting
-    /// index will be (DefIndex - DEF_INDEX_HI_START).
-    #[inline]
-    pub fn as_array_index(&self) -> usize {
-        (self.0 & !DEF_INDEX_HI_START.0) as usize
+    // This function is the reverse of from_proc_macro_index() above.
+    pub fn to_proc_macro_index(self: DefIndex) -> usize {
+        self.as_array_index()
     }
 
-    pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
-        DefIndex::new(address_space.start() + i)
+    // Don't use this if you don't know about the DefIndex encoding.
+    pub fn from_raw_u32(x: u32) -> DefIndex {
+        DefIndex(x)
+    }
+
+    // Don't use this if you don't know about the DefIndex encoding.
+    pub fn as_raw_u32(&self) -> u32 {
+        self.0
     }
 }
 
@@ -155,11 +161,6 @@ impl DefIndexAddressSpace {
     pub fn index(&self) -> usize {
         *self as usize
     }
-
-    #[inline]
-    pub fn start(&self) -> usize {
-        self.index() * DEF_INDEX_HI_START.as_usize()
-    }
 }
 
 /// A DefId identifies a particular *definition*, by combining a crate
index 059181d2a6a579ba2a42be2a10b27ceda0e5bfda..481c551bc292f8d48dcc3ec0b439b93fa2f17022 100644 (file)
@@ -180,7 +180,7 @@ pub fn lower_crate(sess: &Session,
     // We're constructing the HIR here; we don't care what we will
     // read, since we haven't even constructed the *input* to
     // incr. comp. yet.
-    let _ignore = dep_graph.in_ignore();
+    dep_graph.assert_ignored();
 
     LoweringContext {
         crate_root: std_inject::injected_crate_name(),
index 7c2f0bc3cef8440b09f2b289f11dc3e8f0f6b927..43cc437e1e7e32dd65b91548490e67e126a1064f 100644 (file)
@@ -19,7 +19,7 @@
                   CRATE_DEF_INDEX};
 use ich::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::indexed_vec::{IndexVec};
 use rustc_data_structures::stable_hasher::StableHasher;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 use session::CrateDisambiguator;
@@ -61,7 +61,7 @@ fn allocate(&mut self,
                 -> DefIndex {
         let index = {
             let index_to_key = &mut self.index_to_key[address_space.index()];
-            let index = DefIndex::new(index_to_key.len() + address_space.start());
+            let index = DefIndex::from_array_index(index_to_key.len(), address_space);
             debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
             index_to_key.push(key);
             index
@@ -89,8 +89,7 @@ pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
     pub fn add_def_path_hashes_to(&self,
                                   cnum: CrateNum,
                                   out: &mut FxHashMap<DefPathHash, DefId>) {
-        for address_space in &[DefIndexAddressSpace::Low, DefIndexAddressSpace::High] {
-            let start_index = address_space.start();
+        for &address_space in &[DefIndexAddressSpace::Low, DefIndexAddressSpace::High] {
             out.extend(
                 (&self.def_path_hashes[address_space.index()])
                     .iter()
@@ -98,7 +97,7 @@ pub fn add_def_path_hashes_to(&self,
                     .map(|(index, &hash)| {
                         let def_id = DefId {
                             krate: cnum,
-                            index: DefIndex::new(index + start_index),
+                            index: DefIndex::from_array_index(index, address_space),
                         };
                         (hash, def_id)
                     })
index e6af075a2985f4cf5856d62d3dbaaa3ae7bc8bb3..a4c931115833240b3da4ed53b891c3523c337202 100644 (file)
@@ -20,16 +20,16 @@ pub fn check_crate<'hir>(hir_map: &hir::map::Map<'hir>) {
         errors: vec![],
     };
 
-    hir_map.dep_graph.with_ignore(|| {
-        hir_map.krate().visit_all_item_likes(&mut outer_visitor);
-        if !outer_visitor.errors.is_empty() {
-            let message = outer_visitor
-                .errors
-                .iter()
-                .fold(String::new(), |s1, s2| s1 + "\n" + s2);
-            bug!("{}", message);
-        }
-    });
+    hir_map.dep_graph.assert_ignored();
+
+    hir_map.krate().visit_all_item_likes(&mut outer_visitor);
+    if !outer_visitor.errors.is_empty() {
+        let message = outer_visitor
+            .errors
+            .iter()
+            .fold(String::new(), |s1, s2| s1 + "\n" + s2);
+        bug!("{}", message);
+    }
 }
 
 struct HirIdValidator<'a, 'hir: 'a> {
index 33debf6aeb0dde53cdbd1e7bfe8e2a75acdd593f..b386a0c08b0dade97b1ab35b3c43dc61d630ff48 100644 (file)
@@ -1068,7 +1068,7 @@ pub fn map_crate<'hir>(sess: &::session::Session,
                                                   cmdline_args)
     };
 
-    if log_enabled!(::log::LogLevel::Debug) {
+    if log_enabled!(::log::Level::Debug) {
         // This only makes sense for ordered stores; note the
         // enumerate to count the number of entries.
         let (entries_less_1, _) = map.iter().filter(|&x| {
index 7d3699b35eb23b35377978ca5c10c7226e28eb20..6bdb60a6a1239672bc39032f9c758a34f3d4d52d 100644 (file)
@@ -241,7 +241,7 @@ pub struct LifetimeDef {
 }
 
 /// A "Path" is essentially Rust's notion of a name; for instance:
-/// std::cmp::PartialEq  .  It's represented as a sequence of identifiers,
+/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
 /// along with a bunch of supporting information.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
 pub struct Path {
index dc7b9dbe2ef1526e327e2ec6068157ccb7126533..a7adf28c481b95c3fa352aa6345254df6f6a15be 100644 (file)
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::mem;
 use rustc_data_structures::stable_hasher;
+use serialize;
+use serialize::opaque::{EncodeResult, Encoder, Decoder};
 
-#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
 pub struct Fingerprint(u64, u64);
 
 impl Fingerprint {
@@ -46,6 +49,21 @@ pub fn to_hex(&self) -> String {
         format!("{:x}{:x}", self.0, self.1)
     }
 
+    pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
+        let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };
+
+        encoder.emit_raw_bytes(&bytes)
+    }
+
+    pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
+        let mut bytes = [0; 16];
+
+        decoder.read_raw_bytes(&mut bytes)?;
+
+        let [l, r]: [u64; 2] = unsafe { mem::transmute(bytes) };
+
+        Ok(Fingerprint(u64::from_le(l), u64::from_le(r)))
+    }
 }
 
 impl ::std::fmt::Display for Fingerprint {
@@ -69,3 +87,19 @@ fn hash_stable<W: stable_hasher::StableHasherResult>(&self,
         ::std::hash::Hash::hash(self, hasher);
     }
 }
+
+impl serialize::UseSpecializedEncodable for Fingerprint { }
+
+impl serialize::UseSpecializedDecodable for Fingerprint { }
+
+impl<'a> serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder<'a> {
+    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+        f.encode_opaque(self)
+    }
+}
+
+impl<'a> serialize::SpecializedDecoder<Fingerprint> for serialize::opaque::Decoder<'a> {
+    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
+        Fingerprint::decode_opaque(self)
+    }
+}
index 41209487395785981d654d715a1d3fe4fb3cf9cb..d9d08294334db91eca4661e8eb4efdb40773149c 100644 (file)
@@ -19,7 +19,6 @@
 use graphviz as dot;
 
 use hir::def_id::DefIndex;
-use rustc_data_structures::indexed_vec::Idx;
 use ty;
 use middle::free_region::RegionRelations;
 use middle::region;
@@ -68,7 +67,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
     }
 
     let requested_node = env::var("RUST_REGION_GRAPH_NODE")
-        .ok().and_then(|s| s.parse().map(DefIndex::new).ok());
+        .ok().and_then(|s| s.parse().map(DefIndex::from_raw_u32).ok());
 
     if requested_node.is_some() && requested_node != Some(context.index) {
         return;
@@ -102,7 +101,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
             let mut new_str = String::new();
             for c in output_template.chars() {
                 if c == '%' {
-                    new_str.push_str(&context.index.as_usize().to_string());
+                    new_str.push_str(&context.index.as_raw_u32().to_string());
                 } else {
                     new_str.push(c);
                 }
index 44f23c11b04c3f8f0af61bd8505e09df59e34ba0..075ee0b8c7c2874ce62ab77cd44d91eb6f97c906 100644 (file)
@@ -48,6 +48,7 @@
 #![feature(drain_filter)]
 #![feature(dyn_trait)]
 #![feature(from_ref)]
+#![feature(fs_read_write)]
 #![feature(i128)]
 #![feature(i128_type)]
 #![feature(inclusive_range)]
index 32ab458cb91de4a849f389a9507acc301a331d77..5336c1944e8c4d905f66c5928574b5c832cbeafd 100644 (file)
@@ -1046,7 +1046,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
     // calculated the lint levels for all AST nodes.
     for (_id, lints) in cx.buffered.map {
         for early_lint in lints {
-            span_bug!(early_lint.span, "failed to process bufferd lint here");
+            span_bug!(early_lint.span, "failed to process buffered lint here");
         }
     }
 }
index 21eb772b1b37664d09a2c797aa87d0d57c4cc2a2..904d80a4c021bc04774a5e8e9df466d44054391a 100644 (file)
@@ -50,7 +50,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
     live_symbols: Box<FxHashSet<ast::NodeId>>,
-    struct_has_extern_repr: bool,
+    repr_has_repr_c: bool,
     in_pat: bool,
     inherited_pub_visibility: bool,
     ignore_variant_stack: Vec<DefId>,
@@ -102,7 +102,7 @@ fn lookup_and_handle_method(&mut self, id: hir::HirId) {
     fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
         match self.tables.expr_ty_adjusted(lhs).sty {
             ty::TyAdt(def, _) => {
-                self.insert_def_id(def.struct_variant().field_named(name).did);
+                self.insert_def_id(def.non_enum_variant().field_named(name).did);
             }
             _ => span_bug!(lhs.span, "named field access on non-ADT"),
         }
@@ -111,7 +111,7 @@ fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
     fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
         match self.tables.expr_ty_adjusted(lhs).sty {
             ty::TyAdt(def, _) => {
-                self.insert_def_id(def.struct_variant().fields[idx].did);
+                self.insert_def_id(def.non_enum_variant().fields[idx].did);
             }
             ty::TyTuple(..) => {}
             _ => span_bug!(lhs.span, "numeric field access on non-ADT"),
@@ -149,8 +149,8 @@ fn mark_live_symbols(&mut self) {
     }
 
     fn visit_node(&mut self, node: &hir_map::Node<'tcx>) {
-        let had_extern_repr = self.struct_has_extern_repr;
-        self.struct_has_extern_repr = false;
+        let had_repr_c = self.repr_has_repr_c;
+        self.repr_has_repr_c = false;
         let had_inherited_pub_visibility = self.inherited_pub_visibility;
         self.inherited_pub_visibility = false;
         match *node {
@@ -159,7 +159,7 @@ fn visit_node(&mut self, node: &hir_map::Node<'tcx>) {
                     hir::ItemStruct(..) | hir::ItemUnion(..) => {
                         let def_id = self.tcx.hir.local_def_id(item.id);
                         let def = self.tcx.adt_def(def_id);
-                        self.struct_has_extern_repr = def.repr.c();
+                        self.repr_has_repr_c = def.repr.c();
 
                         intravisit::walk_item(self, &item);
                     }
@@ -187,7 +187,7 @@ fn visit_node(&mut self, node: &hir_map::Node<'tcx>) {
             }
             _ => ()
         }
-        self.struct_has_extern_repr = had_extern_repr;
+        self.repr_has_repr_c = had_repr_c;
         self.inherited_pub_visibility = had_inherited_pub_visibility;
     }
 
@@ -223,10 +223,10 @@ fn visit_nested_body(&mut self, body: hir::BodyId) {
 
     fn visit_variant_data(&mut self, def: &'tcx hir::VariantData, _: ast::Name,
                         _: &hir::Generics, _: ast::NodeId, _: syntax_pos::Span) {
-        let has_extern_repr = self.struct_has_extern_repr;
+        let has_repr_c = self.repr_has_repr_c;
         let inherited_pub_visibility = self.inherited_pub_visibility;
         let live_fields = def.fields().iter().filter(|f| {
-            has_extern_repr || inherited_pub_visibility || f.vis == hir::Public
+            has_repr_c || inherited_pub_visibility || f.vis == hir::Public
         });
         self.live_symbols.extend(live_fields.map(|f| f.id));
 
@@ -428,7 +428,7 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         tcx,
         tables: &ty::TypeckTables::empty(None),
         live_symbols: box FxHashSet(),
-        struct_has_extern_repr: false,
+        repr_has_repr_c: false,
         in_pat: false,
         inherited_pub_visibility: false,
         ignore_variant_stack: vec![],
index 3bcde93fde502cd1704ceb77a0d586c497d5e934..c69005101c67141ae474e3dc4274a060160cb564 100644 (file)
@@ -663,7 +663,7 @@ fn walk_struct_expr(&mut self,
         match with_cmt.ty.sty {
             ty::TyAdt(adt, substs) if adt.is_struct() => {
                 // Consume those fields of the with expression that are needed.
-                for with_field in &adt.struct_variant().fields {
+                for with_field in &adt.non_enum_variant().fields {
                     if !contains_field_named(with_field, fields) {
                         let cmt_field = self.mc.cat_field(
                             &*with_expr,
index 0d4429de22a84fe9ecd423fba36137d0b71e6673..a8955723e3ae01da07466a4d5161209ad9992179 100644 (file)
@@ -1248,7 +1248,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
                 Def::StructCtor(_, CtorKind::Fn) => {
                     match self.pat_ty(&pat)?.sty {
                         ty::TyAdt(adt_def, _) => {
-                            (cmt, adt_def.struct_variant().fields.len())
+                            (cmt, adt_def.non_enum_variant().fields.len())
                         }
                         ref ty => {
                             span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty);
index 5f74f088237837dba1d576a80e4a4692adba4c30..efdf4066815f46ac4ba5df358cb440fdf0688bd3 100644 (file)
 use syntax::symbol::InternedString;
 use ty::Instance;
 use util::nodemap::FxHashMap;
+use rustc_data_structures::base_n;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult,
                                            StableHasher};
 use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode};
+use std::hash::Hash;
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
 pub enum MonoItem<'tcx> {
@@ -119,6 +121,16 @@ pub fn items_mut(&mut self)
     {
         &mut self.items
     }
+
+    pub fn mangle_name(human_readable_name: &str) -> String {
+        // We generate a 80 bit hash from the name. This should be enough to
+        // avoid collisions and is still reasonably short for filenames.
+        let mut hasher = StableHasher::new();
+        human_readable_name.hash(&mut hasher);
+        let hash: u128 = hasher.finish();
+        let hash = hash & ((1u128 << 80) - 1);
+        base_n::encode(hash, base_n::CASE_INSENSITIVE)
+    }
 }
 
 impl<'tcx> HashStable<StableHashingContext<'tcx>> for CodegenUnit<'tcx> {
index 05b1d584e9c4e2c08cb4fb006aced0b99f88a20a..8c8108b06046889805c90884eee48c35a05e1dfb 100644 (file)
@@ -1084,8 +1084,6 @@ fn parse_optimization_fuel(slot: &mut Option<(String, u64)>, v: Option<&str>) ->
         "omit landing pads for unwinding"),
     fewer_names: bool = (false, parse_bool, [TRACKED],
         "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR)"),
-    debug_llvm: bool = (false, parse_bool, [UNTRACKED],
-        "enable debug output from LLVM"),
     meta_stats: bool = (false, parse_bool, [UNTRACKED],
         "gather metadata statistics"),
     print_link_args: bool = (false, parse_bool, [UNTRACKED],
@@ -1236,6 +1234,8 @@ fn parse_optimization_fuel(slot: &mut Option<(String, u64)>, v: Option<&str>) ->
         "rewrite operators on i128 and u128 into lang item calls (typically provided \
          by compiler-builtins) so translation doesn't need to support them,
          overriding the default for the current target"),
+    human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
+        "generate human-readable, predictable names for codegen units"),
 }
 
 pub fn default_lib_output() -> CrateType {
@@ -2747,8 +2747,6 @@ fn test_debugging_options_tracking_hash() {
         assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
         opts.debugging_opts.borrowck_stats = true;
         assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
-        opts.debugging_opts.debug_llvm = true;
-        assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
         opts.debugging_opts.meta_stats = true;
         assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
         opts.debugging_opts.print_link_args = true;
index 43dbb8d7e1375862e896ea8381b6fce0716d6d8c..3ae7d01823c8a370124d4b236a7070c6e902de53 100644 (file)
@@ -562,14 +562,14 @@ pub fn generate_plugin_registrar_symbol(&self, disambiguator: CrateDisambiguator
                                             index: DefIndex)
                                             -> String {
         format!("__rustc_plugin_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(),
-                                                   index.as_usize())
+                                                   index.to_proc_macro_index())
     }
 
     pub fn generate_derive_registrar_symbol(&self, disambiguator: CrateDisambiguator,
                                             index: DefIndex)
                                             -> String {
         format!("__rustc_derive_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(),
-                                                   index.as_usize())
+                                                   index.to_proc_macro_index())
     }
 
     pub fn sysroot<'a>(&'a self) -> &'a Path {
index 94605d895a5545c399843428bbe9b8aacc25b0fe..fd47e09aad7f9119270981d8af3d3eb6f2d97b1d 100644 (file)
@@ -658,9 +658,9 @@ pub fn fully_normalize_with_fulfillcx<'a, 'gcx, 'tcx, T>(
 /// environment. If this returns false, then either normalize
 /// encountered an error or one of the predicates did not hold. Used
 /// when creating vtables to check for unsatisfiable methods.
-pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                               predicates: Vec<ty::Predicate<'tcx>>)
-                                               -> bool
+fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                           predicates: Vec<ty::Predicate<'tcx>>)
+                                           -> bool
 {
     debug!("normalize_and_test_predicates(predicates={:?})",
            predicates);
@@ -687,6 +687,22 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     result
 }
 
+fn substitute_normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                                      key: (DefId, &'tcx Substs<'tcx>))
+                                                      -> bool
+{
+    use ty::subst::Subst;
+    debug!("substitute_normalize_and_test_predicates(key={:?})",
+           key);
+
+    let predicates = tcx.predicates_of(key.0).predicates.subst(tcx, key.1);
+    let result = normalize_and_test_predicates(tcx, predicates);
+
+    debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}",
+           key, result);
+    result
+}
+
 /// Given a trait `trait_ref`, iterates the vtable entries
 /// that come from `trait_ref`, including its supertraits.
 #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
@@ -879,6 +895,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
         specializes: specialize::specializes,
         trans_fulfill_obligation: trans::trans_fulfill_obligation,
         vtable_methods,
+        substitute_normalize_and_test_predicates,
         ..*providers
     };
 }
index 34a7d4ad7cfd03b7bd951c832e2f6ec1aba7c08e..50efb73003731af4346c40c25165e25bddbfd3fc 100644 (file)
@@ -2295,6 +2295,13 @@ fn find_niche<C>(&self, cx: C, count: u128)
             }, niche_start))
         };
 
+        // Locals variables which live across yields are stored
+        // in the generator type as fields. These may be uninitialized
+        // so we don't look for niches there.
+        if let ty::TyGenerator(..) = self.ty.sty {
+            return Ok(None);
+        }
+
         match self.abi {
             Abi::Scalar(ref scalar) => {
                 return Ok(scalar_component(scalar, Size::from_bytes(0)));
index f2fe12dedc2ae8de737193529eb7887e0daeaa14..881c59e05aac6268f014ee764e04c53b084e991c 100644 (file)
@@ -625,6 +625,12 @@ fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
+    fn describe(tcx: TyCtxt, key: (DefId, &'tcx Substs<'tcx>)) -> String {
+        format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0))
+    }
+}
+
 macro_rules! impl_disk_cacheable_query(
     ($query_name:ident, |$key:tt| $cond:expr) => {
         impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
index 7c9d274e1fe06b03d8ad5b2f871d68c3e0925bae..bd8c22aab931624714806dca0fde8bf994154995 100644 (file)
     // however, which uses this query as a kind of cache.
     [] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>,
     [] fn fully_normalize_monormophic_ty: normalize_ty_node(Ty<'tcx>) -> Ty<'tcx>,
+
+    [] fn substitute_normalize_and_test_predicates:
+        substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -500,3 +503,8 @@ fn vtable_methods_node<'tcx>(trait_ref: ty::PolyTraitRef<'tcx>) -> DepConstructo
 fn normalize_ty_node<'tcx>(_: Ty<'tcx>) -> DepConstructor<'tcx> {
     DepConstructor::NormalizeTy
 }
+
+fn substitute_normalize_and_test_predicates_node<'tcx>(key: (DefId, &'tcx Substs<'tcx>))
+                                            -> DepConstructor<'tcx> {
+    DepConstructor::SubstituteNormalizeAndTestPredicates { key }
+}
index dd8a7223289c27a1263688f784077f0a21c313fa..4e2421dad21615a4ccd51514ba9f35ba52549207 100644 (file)
@@ -14,7 +14,7 @@
 use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
                   RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
 use hir::map::definitions::DefPathHash;
-use ich::CachingCodemapView;
+use ich::{CachingCodemapView, Fingerprint};
 use mir;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -165,113 +165,113 @@ pub fn serialize<'a, 'tcx, E>(&self,
         where E: ty_codec::TyEncoder
      {
         // Serializing the DepGraph should not modify it:
-        let _in_ignore = tcx.dep_graph.in_ignore();
-
-        // Allocate FileMapIndices
-        let (file_to_file_index, file_index_to_stable_id) = {
-            let mut file_to_file_index = FxHashMap();
-            let mut file_index_to_stable_id = FxHashMap();
-
-            for (index, file) in tcx.sess.codemap().files().iter().enumerate() {
-                let index = FileMapIndex(index as u32);
-                let file_ptr: *const FileMap = &**file as *const _;
-                file_to_file_index.insert(file_ptr, index);
-                file_index_to_stable_id.insert(index, StableFilemapId::new(&file));
-            }
-
-            (file_to_file_index, file_index_to_stable_id)
-        };
-
-        let mut encoder = CacheEncoder {
-            tcx,
-            encoder,
-            type_shorthands: FxHashMap(),
-            predicate_shorthands: FxHashMap(),
-            expn_info_shorthands: FxHashMap(),
-            codemap: CachingCodemapView::new(tcx.sess.codemap()),
-            file_to_file_index,
-        };
-
-        // Load everything into memory so we can write it out to the on-disk
-        // cache. The vast majority of cacheable query results should already
-        // be in memory, so this should be a cheap operation.
-        tcx.dep_graph.exec_cache_promotions(tcx);
-
-        // Encode query results
-        let mut query_result_index = EncodedQueryResultIndex::new();
-
-        {
-            use ty::maps::queries::*;
-            let enc = &mut encoder;
-            let qri = &mut query_result_index;
-
-            // Encode TypeckTables
-            encode_query_results::<typeck_tables_of, _>(tcx, enc, qri)?;
-            encode_query_results::<optimized_mir, _>(tcx, enc, qri)?;
-            encode_query_results::<unsafety_check_result, _>(tcx, enc, qri)?;
-            encode_query_results::<borrowck, _>(tcx, enc, qri)?;
-            encode_query_results::<mir_borrowck, _>(tcx, enc, qri)?;
-            encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
-            encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
-            encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
-            encode_query_results::<contains_extern_indicator, _>(tcx, enc, qri)?;
-            encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
-            encode_query_results::<trans_fulfill_obligation, _>(tcx, enc, qri)?;
-            encode_query_results::<check_match, _>(tcx, enc, qri)?;
-        }
+        tcx.dep_graph.with_ignore(|| {
+            // Allocate FileMapIndices
+            let (file_to_file_index, file_index_to_stable_id) = {
+                let mut file_to_file_index = FxHashMap();
+                let mut file_index_to_stable_id = FxHashMap();
+
+                for (index, file) in tcx.sess.codemap().files().iter().enumerate() {
+                    let index = FileMapIndex(index as u32);
+                    let file_ptr: *const FileMap = &**file as *const _;
+                    file_to_file_index.insert(file_ptr, index);
+                    file_index_to_stable_id.insert(index, StableFilemapId::new(&file));
+                }
 
-        // Encode diagnostics
-        let diagnostics_index = {
-            let mut diagnostics_index = EncodedDiagnosticsIndex::new();
-
-            for (dep_node_index, diagnostics) in self.current_diagnostics
-                                                     .borrow()
-                                                     .iter() {
-                let pos = AbsoluteBytePos::new(encoder.position());
-                // Let's make sure we get the expected type here:
-                let diagnostics: &EncodedDiagnostics = diagnostics;
-                let dep_node_index =
-                    SerializedDepNodeIndex::new(dep_node_index.index());
-                encoder.encode_tagged(dep_node_index, diagnostics)?;
-                diagnostics_index.push((dep_node_index, pos));
+                (file_to_file_index, file_index_to_stable_id)
+            };
+
+            let mut encoder = CacheEncoder {
+                tcx,
+                encoder,
+                type_shorthands: FxHashMap(),
+                predicate_shorthands: FxHashMap(),
+                expn_info_shorthands: FxHashMap(),
+                codemap: CachingCodemapView::new(tcx.sess.codemap()),
+                file_to_file_index,
+            };
+
+            // Load everything into memory so we can write it out to the on-disk
+            // cache. The vast majority of cacheable query results should already
+            // be in memory, so this should be a cheap operation.
+            tcx.dep_graph.exec_cache_promotions(tcx);
+
+            // Encode query results
+            let mut query_result_index = EncodedQueryResultIndex::new();
+
+            {
+                use ty::maps::queries::*;
+                let enc = &mut encoder;
+                let qri = &mut query_result_index;
+
+                // Encode TypeckTables
+                encode_query_results::<typeck_tables_of, _>(tcx, enc, qri)?;
+                encode_query_results::<optimized_mir, _>(tcx, enc, qri)?;
+                encode_query_results::<unsafety_check_result, _>(tcx, enc, qri)?;
+                encode_query_results::<borrowck, _>(tcx, enc, qri)?;
+                encode_query_results::<mir_borrowck, _>(tcx, enc, qri)?;
+                encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
+                encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
+                encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
+                encode_query_results::<contains_extern_indicator, _>(tcx, enc, qri)?;
+                encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
+                encode_query_results::<trans_fulfill_obligation, _>(tcx, enc, qri)?;
+                encode_query_results::<check_match, _>(tcx, enc, qri)?;
             }
 
-            diagnostics_index
-        };
+            // Encode diagnostics
+            let diagnostics_index = {
+                let mut diagnostics_index = EncodedDiagnosticsIndex::new();
+
+                for (dep_node_index, diagnostics) in self.current_diagnostics
+                                                        .borrow()
+                                                        .iter() {
+                    let pos = AbsoluteBytePos::new(encoder.position());
+                    // Let's make sure we get the expected type here:
+                    let diagnostics: &EncodedDiagnostics = diagnostics;
+                    let dep_node_index =
+                        SerializedDepNodeIndex::new(dep_node_index.index());
+                    encoder.encode_tagged(dep_node_index, diagnostics)?;
+                    diagnostics_index.push((dep_node_index, pos));
+                }
 
-        let sorted_cnums = sorted_cnums_including_local_crate(tcx);
-        let prev_cnums: Vec<_> = sorted_cnums.iter().map(|&cnum| {
-            let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
-            let crate_disambiguator = tcx.crate_disambiguator(cnum);
-            (cnum.as_u32(), crate_name, crate_disambiguator)
-        }).collect();
-
-        // Encode the file footer
-        let footer_pos = encoder.position() as u64;
-        encoder.encode_tagged(TAG_FILE_FOOTER, &Footer {
-            file_index_to_stable_id,
-            prev_cnums,
-            query_result_index,
-            diagnostics_index,
-        })?;
-
-        // Encode the position of the footer as the last 8 bytes of the
-        // file so we know where to look for it.
-        IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder)?;
-
-        // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
-        // of the footer must be the last thing in the data stream.
-
-        return Ok(());
-
-        fn sorted_cnums_including_local_crate(tcx: TyCtxt) -> Vec<CrateNum> {
-            let mut cnums = vec![LOCAL_CRATE];
-            cnums.extend_from_slice(&tcx.crates()[..]);
-            cnums.sort_unstable();
-            // Just to be sure...
-            cnums.dedup();
-            cnums
-        }
+                diagnostics_index
+            };
+
+            let sorted_cnums = sorted_cnums_including_local_crate(tcx);
+            let prev_cnums: Vec<_> = sorted_cnums.iter().map(|&cnum| {
+                let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
+                let crate_disambiguator = tcx.crate_disambiguator(cnum);
+                (cnum.as_u32(), crate_name, crate_disambiguator)
+            }).collect();
+
+            // Encode the file footer
+            let footer_pos = encoder.position() as u64;
+            encoder.encode_tagged(TAG_FILE_FOOTER, &Footer {
+                file_index_to_stable_id,
+                prev_cnums,
+                query_result_index,
+                diagnostics_index,
+            })?;
+
+            // Encode the position of the footer as the last 8 bytes of the
+            // file so we know where to look for it.
+            IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder)?;
+
+            // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
+            // of the footer must be the last thing in the data stream.
+
+            return Ok(());
+
+            fn sorted_cnums_including_local_crate(tcx: TyCtxt) -> Vec<CrateNum> {
+                let mut cnums = vec![LOCAL_CRATE];
+                cnums.extend_from_slice(&tcx.crates()[..]);
+                cnums.sort_unstable();
+                // Just to be sure...
+                cnums.dedup();
+                cnums
+            }
+        })
     }
 
     /// Load a diagnostic emitted during the previous compilation session.
@@ -380,30 +380,30 @@ fn compute_cnum_map(tcx: TyCtxt,
                         prev_cnums: &[(u32, String, CrateDisambiguator)])
                         -> IndexVec<CrateNum, Option<CrateNum>>
     {
-        let _in_ignore = tcx.dep_graph.in_ignore();
-
-        let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| {
-            let crate_name = tcx.original_crate_name(cnum)
-                                .as_str()
-                                .to_string();
-            let crate_disambiguator = tcx.crate_disambiguator(cnum);
-            ((crate_name, crate_disambiguator), cnum)
-        }).collect::<FxHashMap<_,_>>();
-
-        let map_size = prev_cnums.iter()
-                                 .map(|&(cnum, ..)| cnum)
-                                 .max()
-                                 .unwrap_or(0) + 1;
-        let mut map = IndexVec::new();
-        map.resize(map_size as usize, None);
-
-        for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
-            let key = (crate_name.clone(), crate_disambiguator);
-            map[CrateNum::from_u32(prev_cnum)] = current_cnums.get(&key).cloned();
-        }
+        tcx.dep_graph.with_ignore(|| {
+            let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| {
+                let crate_name = tcx.original_crate_name(cnum)
+                                    .as_str()
+                                    .to_string();
+                let crate_disambiguator = tcx.crate_disambiguator(cnum);
+                ((crate_name, crate_disambiguator), cnum)
+            }).collect::<FxHashMap<_,_>>();
+
+            let map_size = prev_cnums.iter()
+                                    .map(|&(cnum, ..)| cnum)
+                                    .max()
+                                    .unwrap_or(0) + 1;
+            let mut map = IndexVec::new();
+            map.resize(map_size as usize, None);
+
+            for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
+                let key = (crate_name.clone(), crate_disambiguator);
+                map[CrateNum::from_u32(prev_cnum)] = current_cnums.get(&key).cloned();
+            }
 
-        map[LOCAL_CRATE] = Some(LOCAL_CRATE);
-        map
+            map[LOCAL_CRATE] = Some(LOCAL_CRATE);
+            map
+        })
     }
 }
 
@@ -660,6 +660,12 @@ fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
     }
 }
 
+impl<'a, 'tcx, 'x> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx, 'x> {
+    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
+        Fingerprint::decode_opaque(&mut self.opaque)
+    }
+}
+
 impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
 for CacheDecoder<'a, 'tcx, 'x> {
     #[inline]
@@ -879,6 +885,14 @@ fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
     }
 }
 
+impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
+for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
+{
+    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+        f.encode_opaque(&mut self.encoder)
+    }
+}
+
 impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>>
 for CacheEncoder<'enc, 'a, 'tcx, E>
     where E: 'enc + ty_codec::TyEncoder,
index ea71367d8852f260a3ac6a78d3fedf3f22298151..dd8b8a2e5da8268f5e74c73a13a757e853ce41dd 100644 (file)
@@ -760,6 +760,7 @@ macro_rules! force {
         DepKind::VtableMethods |
         DepKind::EraseRegionsTy |
         DepKind::NormalizeTy |
+        DepKind::SubstituteNormalizeAndTestPredicates |
 
         // This one should never occur in this context
         DepKind::Null => {
index 26ba6f23c2799a04dba3124fd5dc025484ade623..3e4ede9cfc5ec5dca52a26f907e37f43dcc57183 100644 (file)
@@ -1538,7 +1538,7 @@ pub fn new(tcx: TyCtxt, did: DefId) -> ReprOptions {
         for attr in tcx.get_attrs(did).iter() {
             for r in attr::find_repr_attrs(tcx.sess.diagnostic(), attr) {
                 flags.insert(match r {
-                    attr::ReprExtern => ReprFlags::IS_C,
+                    attr::ReprC => ReprFlags::IS_C,
                     attr::ReprPacked => ReprFlags::IS_PACKED,
                     attr::ReprSimd => ReprFlags::IS_SIMD,
                     attr::ReprInt(i) => {
@@ -1686,10 +1686,9 @@ pub fn has_dtor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
         self.destructor(tcx).is_some()
     }
 
-    /// Asserts this is a struct and returns the struct's unique
-    /// variant.
-    pub fn struct_variant(&self) -> &VariantDef {
-        assert!(!self.is_enum());
+    /// Asserts this is a struct or union and returns its unique variant.
+    pub fn non_enum_variant(&self) -> &VariantDef {
+        assert!(self.is_struct() || self.is_union());
         &self.variants[0]
     }
 
@@ -1728,7 +1727,7 @@ pub fn variant_of_def(&self, def: Def) -> &VariantDef {
         match def {
             Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
             Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
-            Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => self.struct_variant(),
+            Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => self.non_enum_variant(),
             _ => bug!("unexpected def {:?} in variant_of_def", def)
         }
     }
@@ -2314,11 +2313,11 @@ pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
                 self.adt_def(enum_did).variant_with_id(did)
             }
             Def::Struct(did) | Def::Union(did) => {
-                self.adt_def(did).struct_variant()
+                self.adt_def(did).non_enum_variant()
             }
             Def::StructCtor(ctor_did, ..) => {
                 let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent");
-                self.adt_def(did).struct_variant()
+                self.adt_def(did).non_enum_variant()
             }
             _ => bug!("expect_variant_def used with unexpected def {:?}", def)
         }
index cf784b7cafb870513d35ee8de6195815a390b9dd..0889efdc142b11e4450b3e2df7828ad51896e191 100644 (file)
@@ -1351,7 +1351,7 @@ pub fn sequence_element_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
     pub fn simd_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
         match self.sty {
             TyAdt(def, substs) => {
-                def.struct_variant().fields[0].ty(tcx, substs)
+                def.non_enum_variant().fields[0].ty(tcx, substs)
             }
             _ => bug!("simd_type called on invalid type")
         }
@@ -1359,7 +1359,7 @@ pub fn simd_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
 
     pub fn simd_size(&self, _cx: TyCtxt) -> usize {
         match self.sty {
-            TyAdt(def, _) => def.struct_variant().fields.len(),
+            TyAdt(def, _) => def.non_enum_variant().fields.len(),
             _ => bug!("simd_size called on invalid type")
         }
     }
index 638859af0f7d3909f53143d7901d6a1dabf35157..de96e9dc8ff2d510ae54602c71658f2318c70035 100644 (file)
@@ -258,7 +258,7 @@ pub fn positional_element_ty(self,
                 adt.variant_with_id(vid).fields.get(i).map(|f| f.ty(self, substs))
             }
             (&TyAdt(adt, substs), None) => {
-                // Don't use `struct_variant`, this may be a univariant enum.
+                // Don't use `non_enum_variant`, this may be a univariant enum.
                 adt.variants[0].fields.get(i).map(|f| f.ty(self, substs))
             }
             (&TyTuple(ref v, _), None) => v.get(i).cloned(),
@@ -277,7 +277,7 @@ pub fn named_element_ty(self,
                 adt.variant_with_id(vid).find_field_named(n).map(|f| f.ty(self, substs))
             }
             (&TyAdt(adt, substs), None) => {
-                adt.struct_variant().find_field_named(n).map(|f| f.ty(self, substs))
+                adt.non_enum_variant().find_field_named(n).map(|f| f.ty(self, substs))
             }
             _ => return None
         }
@@ -293,7 +293,7 @@ pub fn struct_tail(self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
                     if !def.is_struct() {
                         break;
                     }
-                    match def.struct_variant().fields.last() {
+                    match def.non_enum_variant().fields.last() {
                         Some(f) => ty = f.ty(self, substs),
                         None => break,
                     }
@@ -329,7 +329,7 @@ pub fn struct_lockstep_tails(self,
             match (&a.sty, &b.sty) {
                 (&TyAdt(a_def, a_substs), &TyAdt(b_def, b_substs))
                         if a_def == b_def && a_def.is_struct() => {
-                    if let Some(f) = a_def.struct_variant().fields.last() {
+                    if let Some(f) = a_def.non_enum_variant().fields.last() {
                         a = f.ty(self, a_substs);
                         b = f.ty(self, b_substs);
                     } else {
index 29af9bb668e9db87898ced7e5093ad21b02a5df6..2971f3e853a99d06f38e21e3b13b60ada46ebe20 100644 (file)
@@ -218,13 +218,10 @@ pub fn record_time<T, F>(accu: &Cell<Duration>, f: F) -> T where
 // Memory reporting
 #[cfg(unix)]
 fn get_resident() -> Option<usize> {
-    use std::fs::File;
-    use std::io::Read;
+    use std::fs;
 
     let field = 1;
-    let mut f = File::open("/proc/self/statm").ok()?;
-    let mut contents = String::new();
-    f.read_to_string(&mut contents).ok()?;
+    let contents = fs::read_string("/proc/self/statm").ok()?;
     let s = contents.split_whitespace().nth(field)?;
     let npages = s.parse::<usize>().ok()?;
     Some(npages * 4096)
index 92b024b67d4cc3227d8e15e24fc5c2f2aa577a28..d864c5bc6105457bb5f5f576e65ffdfdf59a3d33 100644 (file)
@@ -11,7 +11,7 @@ crate-type = ["dylib"]
 [dependencies]
 syntax = { path = "../libsyntax" }
 serialize = { path = "../libserialize" }
-log = "0.3"
+log = "0.4"
 rand = "0.3"
 
 [features]
index ccf1db778d2967f6e9971c4225efed55245edb5e..8bf60b091a7ad88f141a97296f0cd1e131c87a30 100644 (file)
@@ -28,6 +28,7 @@
 
 #![feature(box_syntax)]
 #![feature(const_fn)]
+#![feature(fs_read_write)]
 
 extern crate syntax;
 extern crate rand;
diff --git a/src/librustc_back/target/i586_unknown_linux_musl.rs b/src/librustc_back/target/i586_unknown_linux_musl.rs
new file mode 100644 (file)
index 0000000..416eacf
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target::TargetResult;
+
+pub fn target() -> TargetResult {
+    let mut base = super::i686_unknown_linux_musl::target()?;
+    base.options.cpu = "pentium".to_string();
+    base.llvm_target = "i586-unknown-linux-musl".to_string();
+    Ok(base)
+}
index 6fcdedfb3404211de8df2d057cf83711826ec2bf..b65b18d0caa8c0d1f7fdcec38e882490d2311353 100644 (file)
@@ -47,7 +47,6 @@
 use serialize::json::{Json, ToJson};
 use std::collections::BTreeMap;
 use std::default::Default;
-use std::io::prelude::*;
 use syntax::abi::{Abi, lookup as lookup_abi};
 
 use {LinkerFlavor, PanicStrategy, RelroLevel};
@@ -147,6 +146,7 @@ fn $module() {
     ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu),
     ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu),
     ("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu),
+    ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
     ("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi),
     ("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf),
     ("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi),
@@ -156,16 +156,17 @@ fn $module() {
     ("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf),
     ("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf),
     ("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu),
+
     ("aarch64-unknown-linux-musl", aarch64_unknown_linux_musl),
     ("x86_64-unknown-linux-musl", x86_64_unknown_linux_musl),
     ("i686-unknown-linux-musl", i686_unknown_linux_musl),
+    ("i586-unknown-linux-musl", i586_unknown_linux_musl),
     ("mips-unknown-linux-musl", mips_unknown_linux_musl),
     ("mipsel-unknown-linux-musl", mipsel_unknown_linux_musl),
+
     ("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc),
     ("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc),
 
-    ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
-
     ("i686-linux-android", i686_linux_android),
     ("x86_64-linux-android", x86_64_linux_android),
     ("arm-linux-androideabi", arm_linux_androideabi),
@@ -809,14 +810,12 @@ macro_rules! key {
     pub fn search(target: &str) -> Result<Target, String> {
         use std::env;
         use std::ffi::OsString;
-        use std::fs::File;
+        use std::fs;
         use std::path::{Path, PathBuf};
         use serialize::json;
 
         fn load_file(path: &Path) -> Result<Target, String> {
-            let mut f = File::open(path).map_err(|e| e.to_string())?;
-            let mut contents = Vec::new();
-            f.read_to_end(&mut contents).map_err(|e| e.to_string())?;
+            let contents = fs::read(path).map_err(|e| e.to_string())?;
             let obj = json::from_reader(&mut &contents[..])
                            .map_err(|e| e.to_string())?;
             Target::from_json(obj)
index 25f02537490fa8d694a52ff0a366692622c54d45..8522fe11fe1c70634bd5b68f638d75c524ccbbee 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-log = "0.3"
+log = "0.4"
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 graphviz = { path = "../libgraphviz" }
index bc01f22d3881ec6690c63732a5fc26365c63e8c2..5cfbe49f77f11bb266aca3e92971ec71af00cc83 100644 (file)
@@ -107,7 +107,7 @@ fn restrict(&self,
                     ty::TyAdt(adt_def, _) if adt_def.is_union() => match result {
                         RestrictionResult::Safe => RestrictionResult::Safe,
                         RestrictionResult::SafeIf(base_lp, mut base_vec) => {
-                            for field in &adt_def.struct_variant().fields {
+                            for field in &adt_def.non_enum_variant().fields {
                                 let field = InteriorKind::InteriorField(mc::NamedField(field.name));
                                 let field_ty = if field == interior {
                                     cmt.ty
index 7915eccbf74451cc447b6d779d949979b03250f2..98de394ae3967cbe67a9493989f96747e385c5bb 100644 (file)
@@ -343,7 +343,7 @@ pub fn add_move(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
             if let (&ty::TyAdt(adt_def, _), LpInterior(opt_variant_id, interior))
                     = (&base_lp.ty.sty, lp_elem) {
                 if adt_def.is_union() {
-                    for field in &adt_def.struct_variant().fields {
+                    for field in &adt_def.non_enum_variant().fields {
                         let field = InteriorKind::InteriorField(mc::NamedField(field.name));
                         if field != interior {
                             let sibling_lp_kind =
@@ -395,7 +395,7 @@ pub fn add_assignment(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
         if let LpExtend(ref base_lp, mutbl, LpInterior(opt_variant_id, interior)) = lp.kind {
             if let ty::TyAdt(adt_def, _) = base_lp.ty.sty {
                 if adt_def.is_union() {
-                    for field in &adt_def.struct_variant().fields {
+                    for field in &adt_def.non_enum_variant().fields {
                         let field = InteriorKind::InteriorField(mc::NamedField(field.name));
                         let field_ty = if field == interior {
                             lp.ty
index e8d404af4defa9a669b2073981e82cb9d3763735..53b8402ab2ad5e7927a2b3464498853e4fd7d11c 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 arena = { path = "../libarena" }
-log = "0.3"
+log = "0.4"
 rustc = { path = "../librustc" }
 rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
index cfbb9623f7dc9ddf29b6f1e44fdf08a5c1dce298..3cfa1d6797d1f098dd4ce6cc46fd5154e923a5a8 100644 (file)
@@ -280,7 +280,8 @@ pub fn from_hir(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         let mut pcx = PatternContext::new(tcx, param_env_and_substs, tables);
         let result = pcx.lower_pattern(pat);
         if !pcx.errors.is_empty() {
-            span_bug!(pat.span, "encountered errors lowering pattern: {:?}", pcx.errors)
+            let msg = format!("encountered errors lowering pattern: {:?}", pcx.errors);
+            tcx.sess.delay_span_bug(pat.span, &msg);
         }
         debug!("Pattern::from_hir({:?}) = {:?}", pat, result);
         result
index 82075ce1f1f792ec36640d80df829cb5412e3b0b..23e42f6a672c6a7cca044a17235a9382b1d3f1dc 100644 (file)
@@ -9,7 +9,7 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
-log = "0.3"
+log = "0.4"
 serialize = { path = "../libserialize" }
 cfg-if = "0.1.2"
 stable_deref_trait = "1.0.0"
@@ -17,4 +17,4 @@ parking_lot_core = "0.2.8"
 
 [dependencies.parking_lot]
 version = "0.5"
-features = ["nightly"]
\ No newline at end of file
+features = ["nightly"]
index cf54229fa7f52e59130cbd39c43ee7656c90d1f4..d333b6393b9cc4466c32a4ac56fec2238db1040b 100644 (file)
 
 use std::str;
 
-pub const MAX_BASE: u64 = 64;
-pub const ALPHANUMERIC_ONLY: u64 = 62;
+pub const MAX_BASE: usize = 64;
+pub const ALPHANUMERIC_ONLY: usize = 62;
+pub const CASE_INSENSITIVE: usize = 36;
 
 const BASE_64: &'static [u8; MAX_BASE as usize] =
     b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@$";
 
 #[inline]
-pub fn push_str(mut n: u64, base: u64, output: &mut String) {
+pub fn push_str(mut n: u128, base: usize, output: &mut String) {
     debug_assert!(base >= 2 && base <= MAX_BASE);
-    let mut s = [0u8; 64];
+    let mut s = [0u8; 128];
     let mut index = 0;
 
+    let base = base as u128;
+
     loop {
         s[index] = BASE_64[(n % base) as usize];
         index += 1;
@@ -39,16 +42,16 @@ pub fn push_str(mut n: u64, base: u64, output: &mut String) {
 }
 
 #[inline]
-pub fn encode(n: u64, base: u64) -> String {
-    let mut s = String::with_capacity(13);
+pub fn encode(n: u128, base: usize) -> String {
+    let mut s = String::new();
     push_str(n, base, &mut s);
     s
 }
 
 #[test]
 fn test_encode() {
-    fn test(n: u64, base: u64) {
-        assert_eq!(Ok(n), u64::from_str_radix(&encode(n, base), base as u32));
+    fn test(n: u128, base: usize) {
+        assert_eq!(Ok(n), u128::from_str_radix(&encode(n, base), base as u32));
     }
 
     for base in 2..37 {
@@ -57,7 +60,8 @@ fn test(n: u64, base: u64) {
         test(35, base);
         test(36, base);
         test(37, base);
-        test(u64::max_value(), base);
+        test(u64::max_value() as u128, base);
+        test(u128::max_value(), base);
 
         for i in 0 .. 1_000 {
             test(i * 983, base);
index 04c0f9b35184ec2e3600ca17ca312107d80d5a1d..4f7bbd7927575ac8b92c69be9b35d2b426a996b7 100644 (file)
@@ -11,7 +11,7 @@ crate-type = ["dylib"]
 [dependencies]
 arena = { path = "../libarena" }
 graphviz = { path = "../libgraphviz" }
-log = { version = "0.3", features = ["release_max_level_info"] }
+log = { version = "0.4", features = ["release_max_level_info"] }
 env_logger = { version = "0.4", default-features = false }
 rustc = { path = "../librustc" }
 rustc_allocator = { path = "../librustc_allocator" }
index c0bbab35e1e9589afc05fcdc458b5ccdbbc3d9dd..b7265762208012bb6b32b5e5fffe95df5567b2f0 100644 (file)
@@ -191,7 +191,7 @@ macro_rules! controller_entry_point {
                            || hir_map::map_crate(sess, cstore, &mut hir_forest, &defs));
 
         {
-            let _ignore = hir_map.dep_graph.in_ignore();
+            hir_map.dep_graph.assert_ignored();
             controller_entry_point!(after_hir_lowering,
                                     sess,
                                     CompileState::state_after_hir_lowering(input,
@@ -233,18 +233,18 @@ macro_rules! controller_entry_point {
                                     |tcx, analysis, rx, result| {
             {
                 // Eventually, we will want to track plugins.
-                let _ignore = tcx.dep_graph.in_ignore();
-
-                let mut state = CompileState::state_after_analysis(input,
-                                                                   sess,
-                                                                   outdir,
-                                                                   output,
-                                                                   opt_crate,
-                                                                   tcx.hir.krate(),
-                                                                   &analysis,
-                                                                   tcx,
-                                                                   &crate_name);
-                (control.after_analysis.callback)(&mut state);
+                tcx.dep_graph.with_ignore(|| {
+                    let mut state = CompileState::state_after_analysis(input,
+                                                                       sess,
+                                                                       outdir,
+                                                                       output,
+                                                                       opt_crate,
+                                                                       tcx.hir.krate(),
+                                                                       &analysis,
+                                                                       tcx,
+                                                                       &crate_name);
+                    (control.after_analysis.callback)(&mut state);
+                });
 
                 if control.after_analysis.stop == Compilation::Stop {
                     return result.and_then(|_| Err(CompileIncomplete::Stopped));
@@ -253,14 +253,14 @@ macro_rules! controller_entry_point {
 
             result?;
 
-            if log_enabled!(::log::LogLevel::Info) {
+            if log_enabled!(::log::Level::Info) {
                 println!("Pre-trans");
                 tcx.print_debug_stats();
             }
 
             let trans = phase_4_translate_to_llvm::<DefaultTransCrate>(tcx, rx);
 
-            if log_enabled!(::log::LogLevel::Info) {
+            if log_enabled!(::log::Level::Info) {
                 println!("Post-trans");
                 tcx.print_debug_stats();
             }
@@ -889,10 +889,11 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
     let dep_graph = match future_dep_graph {
         None => DepGraph::new_disabled(),
         Some(future) => {
-            let prev_graph = future
-                .open()
-                .expect("Could not join with background dep_graph thread")
-                .open(sess);
+            let prev_graph = time(time_passes, "blocked while dep-graph loading finishes", || {
+                future.open()
+                      .expect("Could not join with background dep_graph thread")
+                      .open(sess)
+            });
             DepGraph::new(prev_graph)
         }
     };
index 223c602ccd34a85222dbdd9fb9fe574f8c90fdd4..237656eb43c69d3d0001e4f9e29ed6698c5e0d49 100644 (file)
@@ -167,7 +167,6 @@ mod rustc_trans {
     pub use rustc_trans_utils::trans_crate::TranslatedCrate as CrateTranslation;
 
     pub fn init(_sess: &Session) {}
-    pub fn enable_llvm_debug() {}
     pub fn print_version() {}
     pub fn print_passes() {}
     pub fn print(_req: PrintRequest, _sess: &Session) {}
@@ -205,10 +204,6 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => {
 
     let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
 
-    if sopts.debugging_opts.debug_llvm {
-        rustc_trans::enable_llvm_debug();
-    }
-
     let descriptions = diagnostics_registry();
 
     do_or_return!(callbacks.early_callback(&matches,
index 76923be65cfd70f1481e791706144011716c106a..6ce6929af5cabf6e9b959b4245e607ed2f473a81 100644 (file)
@@ -243,8 +243,9 @@ fn call_with_pp_support_hir<'tcx, A, F>(&self,
                         tcx,
                         tables: Cell::new(&empty_tables)
                     };
-                    let _ignore = tcx.dep_graph.in_ignore();
-                    f(&annotation, hir_map.forest.krate())
+                    tcx.dep_graph.with_ignore(|| {
+                        f(&annotation, hir_map.forest.krate())
+                    })
                 }),
                              sess)
             }
index c4db39fae86197965db25448d8211e2a6642bfbf..c48f1761f28b7aee9004dcbca5ab73e0e2e0365e 100644 (file)
@@ -310,9 +310,13 @@ pub fn set_continue_after_error(&self, continue_after_error: bool) {
         self.continue_after_error.set(continue_after_error);
     }
 
-    // NOTE: DO NOT call this function from rustc, as it relies on `err_count` being non-zero
-    // if an error happened to avoid ICEs. This function should only be called from tools.
+    /// Resets the diagnostic error count as well as the cached emitted diagnostics.
+    ///
+    /// NOTE: DO NOT call this function from rustc. It is only meant to be called from external
+    /// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as
+    /// the overall count of emitted error diagnostics.
     pub fn reset_err_count(&self) {
+        self.emitted_diagnostics.replace(FxHashSet());
         self.err_count.store(0, SeqCst);
     }
 
index b40a1b7c0cb7d7daff9a2c440133a886122e118c..eabc3ab03b1944fe660d2f2198ca99b26ce9a1d3 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 graphviz = { path = "../libgraphviz" }
-log = "0.3"
+log = "0.4"
 rand = "0.3"
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
index acbd3e0d63ddedf387ab9ae620739668df62f1a0..5976b80d90f871f0f8e164b249848e855bf0a5be 100644 (file)
 use rustc::ich::{ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED};
 use graphviz::IntoCow;
 use std::env;
-use std::fs::File;
+use std::fs::{self, File};
 use std::io::Write;
 use syntax::ast;
 use syntax_pos::Span;
 
 pub fn assert_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let _ignore = tcx.dep_graph.in_ignore();
-
-    if tcx.sess.opts.debugging_opts.dump_dep_graph {
-        dump_graph(tcx);
-    }
-
-    // if the `rustc_attrs` feature is not enabled, then the
-    // attributes we are interested in cannot be present anyway, so
-    // skip the walk.
-    if !tcx.sess.features.borrow().rustc_attrs {
-        return;
-    }
+    tcx.dep_graph.with_ignore(|| {
+        if tcx.sess.opts.debugging_opts.dump_dep_graph {
+            dump_graph(tcx);
+        }
 
-    // Find annotations supplied by user (if any).
-    let (if_this_changed, then_this_would_need) = {
-        let mut visitor = IfThisChanged { tcx,
-                                          if_this_changed: vec![],
-                                          then_this_would_need: vec![] };
-        visitor.process_attrs(ast::CRATE_NODE_ID, &tcx.hir.krate().attrs);
-        tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
-        (visitor.if_this_changed, visitor.then_this_would_need)
-    };
+        // if the `rustc_attrs` feature is not enabled, then the
+        // attributes we are interested in cannot be present anyway, so
+        // skip the walk.
+        if !tcx.sess.features.borrow().rustc_attrs {
+            return;
+        }
 
-    if !if_this_changed.is_empty() || !then_this_would_need.is_empty() {
-        assert!(tcx.sess.opts.debugging_opts.query_dep_graph,
-                "cannot use the `#[{}]` or `#[{}]` annotations \
-                 without supplying `-Z query-dep-graph`",
-                ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED);
-    }
+        // Find annotations supplied by user (if any).
+        let (if_this_changed, then_this_would_need) = {
+            let mut visitor = IfThisChanged { tcx,
+                                            if_this_changed: vec![],
+                                            then_this_would_need: vec![] };
+            visitor.process_attrs(ast::CRATE_NODE_ID, &tcx.hir.krate().attrs);
+            tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+            (visitor.if_this_changed, visitor.then_this_would_need)
+        };
+
+        if !if_this_changed.is_empty() || !then_this_would_need.is_empty() {
+            assert!(tcx.sess.opts.debugging_opts.query_dep_graph,
+                    "cannot use the `#[{}]` or `#[{}]` annotations \
+                    without supplying `-Z query-dep-graph`",
+                    ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED);
+        }
 
-    // Check paths.
-    check_paths(tcx, &if_this_changed, &then_this_would_need);
+        // Check paths.
+        check_paths(tcx, &if_this_changed, &then_this_would_need);
+    })
 }
 
 type Sources = Vec<(Span, DefId, DepNode)>;
@@ -260,7 +260,7 @@ fn dump_graph(tcx: TyCtxt) {
         let dot_path = format!("{}.dot", path);
         let mut v = Vec::new();
         dot::render(&GraphvizDepGraph(nodes, edges), &mut v).unwrap();
-        File::create(&dot_path).and_then(|mut f| f.write_all(&v)).unwrap();
+        fs::write(dot_path, v).unwrap();
     }
 }
 
index 5eaf8553ee3d391882af3663c7603375268dd359..0b827a0ee9873e58cb7be015eaefe98aca199c61 100644 (file)
@@ -16,6 +16,7 @@
 #![deny(warnings)]
 
 #![feature(conservative_impl_trait)]
+#![feature(fs_read_write)]
 #![feature(i128_type)]
 #![feature(inclusive_range_syntax)]
 #![feature(specialization)]
index b17503137f508caf3979def53b0e47bcb238f1f9..f543b1c09213ce62a95995f5a5fe134927d6cee6 100644 (file)
@@ -223,25 +223,26 @@ pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         return;
     }
 
-    let _ignore = tcx.dep_graph.in_ignore();
-    let krate = tcx.hir.krate();
-    let mut dirty_clean_visitor = DirtyCleanVisitor {
-        tcx,
-        checked_attrs: FxHashSet(),
-    };
-    krate.visit_all_item_likes(&mut dirty_clean_visitor);
-
-    let mut all_attrs = FindAllAttrs {
-        tcx,
-        attr_names: vec![ATTR_DIRTY, ATTR_CLEAN],
-        found_attrs: vec![],
-    };
-    intravisit::walk_crate(&mut all_attrs, krate);
-
-    // Note that we cannot use the existing "unused attribute"-infrastructure
-    // here, since that is running before trans. This is also the reason why
-    // all trans-specific attributes are `Whitelisted` in syntax::feature_gate.
-    all_attrs.report_unchecked_attrs(&dirty_clean_visitor.checked_attrs);
+    tcx.dep_graph.with_ignore(|| {
+        let krate = tcx.hir.krate();
+        let mut dirty_clean_visitor = DirtyCleanVisitor {
+            tcx,
+            checked_attrs: FxHashSet(),
+        };
+        krate.visit_all_item_likes(&mut dirty_clean_visitor);
+
+        let mut all_attrs = FindAllAttrs {
+            tcx,
+            attr_names: vec![ATTR_DIRTY, ATTR_CLEAN],
+            found_attrs: vec![],
+        };
+        intravisit::walk_crate(&mut all_attrs, krate);
+
+        // Note that we cannot use the existing "unused attribute"-infrastructure
+        // here, since that is running before trans. This is also the reason why
+        // all trans-specific attributes are `Whitelisted` in syntax::feature_gate.
+        all_attrs.report_unchecked_attrs(&dirty_clean_visitor.checked_attrs);
+    })
 }
 
 pub struct DirtyCleanVisitor<'a, 'tcx:'a> {
index 108eccf047efe547bdf672f46435f0b5ac1704ca..d45994adeb67bcf2da10fcbfed2c587ff9632c90 100644 (file)
@@ -21,7 +21,7 @@
 
 use std::io::{self, Read};
 use std::path::Path;
-use std::fs::File;
+use std::fs;
 use std::env;
 
 use rustc::session::config::nightly_options;
@@ -66,11 +66,7 @@ pub fn read_file(report_incremental_info: bool, path: &Path)
         return Ok(None);
     }
 
-    let mut file = File::open(path)?;
-    let file_size = file.metadata()?.len() as usize;
-
-    let mut data = Vec::with_capacity(file_size);
-    file.read_to_end(&mut data)?;
+    let data = fs::read(path)?;
 
     let mut file = io::Cursor::new(data);
 
index 42b1fcccacef2ac900f59670013cf54a9813a498..f4171f951f4076e0a40758b8ea0aa320c345fe7d 100644 (file)
 // or hexadecimal numbers (we want short file and directory names). Since these
 // numbers will be used in file names, we choose an encoding that is not
 // case-sensitive (as opposed to base64, for example).
-const INT_ENCODE_BASE: u64 = 36;
+const INT_ENCODE_BASE: usize = base_n::CASE_INSENSITIVE;
 
 pub fn dep_graph_path(sess: &Session) -> PathBuf {
     in_incr_comp_dir_sess(sess, DEP_GRAPH_FILENAME)
@@ -357,7 +357,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
     let mut new_sub_dir_name = String::from(&old_sub_dir_name[.. dash_indices[2] + 1]);
 
     // Append the svh
-    base_n::push_str(svh.as_u64(), INT_ENCODE_BASE, &mut new_sub_dir_name);
+    base_n::push_str(svh.as_u64() as u128, INT_ENCODE_BASE, &mut new_sub_dir_name);
 
     // Create the full path
     let new_path = incr_comp_session_dir.parent().unwrap().join(new_sub_dir_name);
@@ -465,7 +465,7 @@ fn generate_session_dir_path(crate_dir: &Path) -> PathBuf {
 
     let directory_name = format!("s-{}-{}-working",
                                   timestamp,
-                                  base_n::encode(random_number as u64,
+                                  base_n::encode(random_number as u128,
                                                  INT_ENCODE_BASE));
     debug!("generate_session_dir_path: directory_name = {}", directory_name);
     let directory_path = crate_dir.join(directory_name);
@@ -599,7 +599,7 @@ fn timestamp_to_string(timestamp: SystemTime) -> String {
     let duration = timestamp.duration_since(UNIX_EPOCH).unwrap();
     let micros = duration.as_secs() * 1_000_000 +
                 (duration.subsec_nanos() as u64) / 1000;
-    base_n::encode(micros, INT_ENCODE_BASE)
+    base_n::encode(micros as u128, INT_ENCODE_BASE)
 }
 
 fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
@@ -626,7 +626,8 @@ fn crate_path(sess: &Session,
     // The full crate disambiguator is really long. 64 bits of it should be
     // sufficient.
     let crate_disambiguator = crate_disambiguator.to_fingerprint().to_smaller_hash();
-    let crate_disambiguator = base_n::encode(crate_disambiguator, INT_ENCODE_BASE);
+    let crate_disambiguator = base_n::encode(crate_disambiguator as u128,
+                                             INT_ENCODE_BASE);
 
     let crate_name = format!("{}-{}", crate_name, crate_disambiguator);
     incr_dir.join(crate_name)
index 6eaa14a50f40f84683515cd073a8ec332a625c6f..d44d1d6f260249175b64f9866d8f696b5c5ced36 100644 (file)
@@ -15,8 +15,8 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_serialize::Encodable as RustcEncodable;
 use rustc_serialize::opaque::Encoder;
-use std::io::{self, Cursor, Write};
-use std::fs::{self, File};
+use std::io::{self, Cursor};
+use std::fs;
 use std::path::PathBuf;
 
 use super::data::*;
 
 pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     debug!("save_dep_graph()");
-    let _ignore = tcx.dep_graph.in_ignore();
-    let sess = tcx.sess;
-    if sess.opts.incremental.is_none() {
-        return;
-    }
-
-    time(sess.time_passes(), "persist query result cache", || {
-        save_in(sess,
-                query_cache_path(sess),
-                |e| encode_query_cache(tcx, e));
-    });
+    tcx.dep_graph.with_ignore(|| {
+        let sess = tcx.sess;
+        if sess.opts.incremental.is_none() {
+            return;
+        }
 
-    if tcx.sess.opts.debugging_opts.incremental_queries {
-        time(sess.time_passes(), "persist dep-graph", || {
+        time(sess.time_passes(), "persist query result cache", || {
             save_in(sess,
-                    dep_graph_path(sess),
-                    |e| encode_dep_graph(tcx, e));
+                    query_cache_path(sess),
+                    |e| encode_query_cache(tcx, e));
         });
-    }
 
-    dirty_clean::check_dirty_clean_annotations(tcx);
+        if tcx.sess.opts.debugging_opts.incremental_queries {
+            time(sess.time_passes(), "persist dep-graph", || {
+                save_in(sess,
+                        dep_graph_path(sess),
+                        |e| encode_dep_graph(tcx, e));
+            });
+        }
+
+        dirty_clean::check_dirty_clean_annotations(tcx);
+    })
 }
 
 pub fn save_work_products(sess: &Session, dep_graph: &DepGraph) {
@@ -56,7 +57,7 @@ pub fn save_work_products(sess: &Session, dep_graph: &DepGraph) {
     }
 
     debug!("save_work_products()");
-    let _ignore = dep_graph.in_ignore();
+    dep_graph.assert_ignored();
     let path = work_products_path(sess);
     save_in(sess, path, |e| encode_work_products(dep_graph, e));
 
@@ -124,7 +125,7 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
 
     // write the data out
     let data = wr.into_inner();
-    match File::create(&path_buf).and_then(|mut file| file.write_all(&data)) {
+    match fs::write(&path_buf, data) {
         Ok(_) => {
             debug!("save: data written to disk successfully");
         }
index f23b8dc85b8bb6de03439f2363cd9abbd899d24d..879132bcacfcfcd86a3c6426152e7fc95d016e75 100644 (file)
@@ -35,9 +35,9 @@ pub fn save_trans_partition(sess: &Session,
                  let extension = match kind {
                      WorkProductFileKind::Object => "o",
                      WorkProductFileKind::Bytecode => "bc",
-                     WorkProductFileKind::BytecodeCompressed => "bc-compressed",
+                     WorkProductFileKind::BytecodeCompressed => "bc.z",
                  };
-                 let file_name = format!("cgu-{}.{}", cgu_name, extension);
+                 let file_name = format!("{}.{}", cgu_name, extension);
                  let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
                  match link_or_copy(path, &path_in_incr_dir) {
                      Ok(_) => Some((kind, file_name)),
index cebf52d5af7a9c2cf4f2686617bb3e60fdb5f1cd..9fee2d54e4752e617cba6de8ea0d2ba9a5f104a2 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-log = "0.3"
+log = "0.4"
 rustc = { path = "../librustc" }
 rustc_const_eval = { path = "../librustc_const_eval" }
 syntax = { path = "../libsyntax" }
index ac0bf9f4a99b03f90443fa5f0b9ad1b1de15054d..ad3760eed8019488cc47913b9985dc2c266e2daf 100644 (file)
@@ -120,17 +120,15 @@ fn get_lints(&self) -> LintArray {
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCamelCaseTypes {
     fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
-        let extern_repr_count = it.attrs
+        let has_repr_c = it.attrs
             .iter()
-            .filter(|attr| {
+            .any(|attr| {
                 attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr)
                     .iter()
-                    .any(|r| r == &attr::ReprExtern)
-            })
-            .count();
-        let has_extern_repr = extern_repr_count > 0;
+                    .any(|r| r == &attr::ReprC)
+            });
 
-        if has_extern_repr {
+        if has_repr_c {
             return;
         }
 
index a2a6a0da68ff055034ff393c6b5c211cb706db2f..ffb844632e46fe54e982b7add61c2c401b61fccf 100644 (file)
@@ -1214,8 +1214,13 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
                     // don't have anything to attach a symbol to
                     let msg = "const items should never be #[no_mangle]";
                     let mut err = cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg);
+
+                    // account for "pub const" (#45562)
+                    let start = cx.tcx.sess.codemap().span_to_snippet(it.span)
+                        .map(|snippet| snippet.find("const").unwrap_or(0))
+                        .unwrap_or(0) as u32;
                     // `const` is 5 chars
-                    let const_span = it.span.with_hi(BytePos(it.span.lo().0 + 5));
+                    let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5));
                     err.span_suggestion(const_span,
                                         "try a static value",
                                         "pub static".to_owned());
index 5456b0d252b67283931c4d6a7d700671074303f2..bf5d16696f9cd28f440b94e5e10ef0474ea7b6de 100644 (file)
@@ -422,7 +422,7 @@ fn check_type_for_ffi(&self,
                                               consider adding a #[repr(C)] attribute to the type");
                         }
 
-                        if def.struct_variant().fields.is_empty() {
+                        if def.non_enum_variant().fields.is_empty() {
                             return FfiUnsafe("found zero-size struct in foreign module, consider \
                                               adding a member to this struct");
                         }
@@ -430,7 +430,7 @@ fn check_type_for_ffi(&self,
                         // We can't completely trust repr(C) markings; make sure the
                         // fields are actually safe.
                         let mut all_phantom = true;
-                        for field in &def.struct_variant().fields {
+                        for field in &def.non_enum_variant().fields {
                             let field_ty = cx.fully_normalize_associated_types_in(
                                 &field.ty(cx, substs)
                             );
@@ -458,13 +458,13 @@ fn check_type_for_ffi(&self,
                                               consider adding a #[repr(C)] attribute to the type");
                         }
 
-                        if def.struct_variant().fields.is_empty() {
+                        if def.non_enum_variant().fields.is_empty() {
                             return FfiUnsafe("found zero-size union in foreign module, consider \
                                               adding a member to this union");
                         }
 
                         let mut all_phantom = true;
-                        for field in &def.struct_variant().fields {
+                        for field in &def.non_enum_variant().fields {
                             let field_ty = cx.fully_normalize_associated_types_in(
                                 &field.ty(cx, substs)
                             );
index 6cb1a2b53342bd2b05bd2e9dde66ea40bd68f9fe..2cfb151ae85da6bc41bde3192d8fd50cd453cfae 100644 (file)
@@ -1315,9 +1315,6 @@ pub fn LLVMStructSetBody(StructTy: TypeRef,
                              ElementCount: c_uint,
                              Packed: Bool);
 
-    /// Enables LLVM debug output.
-    pub fn LLVMRustSetDebug(Enabled: c_int);
-
     /// Prepares inline assembly.
     pub fn LLVMRustInlineAsm(Ty: TypeRef,
                              AsmString: *const c_char,
@@ -1610,7 +1607,6 @@ pub fn LLVMRustPrintModule(PM: PassManagerRef,
     pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
     pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef, AddLifetimes: bool);
     pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef, bc: *const c_char, len: size_t) -> bool;
-    pub fn LLVMRustLinkInParsedExternalBitcode(M: ModuleRef, M: ModuleRef) -> bool;
     pub fn LLVMRustRunRestrictionPass(M: ModuleRef, syms: *const *const c_char, len: size_t);
     pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
 
@@ -1646,8 +1642,6 @@ pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef,
     pub fn LLVMRustWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef);
     pub fn LLVMRustGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind;
 
-    pub fn LLVMRustWriteDebugLocToString(C: ContextRef, DL: DebugLocRef, s: RustStringRef);
-
     pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: ContextRef,
                                                  H: InlineAsmDiagHandler,
                                                  CX: *mut c_void);
index 592bd62056455534cfcbb331abb1aa555a2da635..c75a026a0f8b9465740cda6f78dbcf7aecb5a1fd 100644 (file)
@@ -296,11 +296,6 @@ pub unsafe fn twine_to_string(tr: TwineRef) -> String {
     build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM")
 }
 
-pub unsafe fn debug_loc_to_string(c: ContextRef, tr: DebugLocRef) -> String {
-    build_string(|s| LLVMRustWriteDebugLocToString(c, tr, s))
-        .expect("got a non-UTF8 DebugLoc from LLVM")
-}
-
 pub fn initialize_available_targets() {
     macro_rules! init_target(
         ($cfg:meta, $($method:ident),*) => { {
index 45f5e9feaf8889f9a79e580a4c8d944593a7faea..a2dcf7f3f83f29ae75277d4c5b6761dd03fa404b 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 flate2 = "1.0"
-log = "0.3"
+log = "0.4"
 proc_macro = { path = "../libproc_macro" }
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
index 58453066cf34b06e67fe42dd222b0b46eb1a0c4c..946eecaa45f7d6fe76d930258feda93a6b04cbb9 100644 (file)
@@ -1051,7 +1051,7 @@ fn postprocess(&mut self, krate: &ast::Crate) {
         self.inject_allocator_crate(krate);
         self.inject_panic_runtime(krate);
 
-        if log_enabled!(log::LogLevel::Info) {
+        if log_enabled!(log::Level::Info) {
             dump_crates(&self.cstore);
         }
     }
index 955648208cd8b773c68c6f250642ce370aec29fa..436ddc32a743b818cdf11e203c8ec486fee02ea3 100644 (file)
@@ -463,7 +463,7 @@ fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<def::Exp
     fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
         let data = self.get_crate_data(id.krate);
         if let Some(ref proc_macros) = data.proc_macros {
-            return LoadedMacro::ProcMacro(proc_macros[id.index.as_usize() - 1].1.clone());
+            return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone());
         } else if data.name == "proc_macro" &&
                   self.get_crate_data(id.krate).item_name(id.index) == "quote" {
             let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::__internal::Quoter));
index fb4a73891a34e5bc5f2bcb3180b3c1845637a330..c62b8a692d7b7648f85157116b812fd1515a2bb3 100644 (file)
@@ -18,7 +18,8 @@
 use rustc::middle::cstore::{LinkagePreference, ExternConstBody,
                             ExternBodyNestedBodies};
 use rustc::hir::def::{self, Def, CtorKind};
-use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc::hir::def_id::{CrateNum, DefId, DefIndex,
+                         CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc::ich::Fingerprint;
 use rustc::middle::lang_items;
 use rustc::mir;
@@ -36,7 +37,6 @@
 use std::u32;
 
 use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
-use rustc_data_structures::indexed_vec::Idx;
 use syntax::attr;
 use syntax::ast::{self, Ident};
 use syntax::codemap;
@@ -264,25 +264,23 @@ fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
 impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
     #[inline]
     fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
-        Ok(DefIndex::from_u32(self.read_u32()?))
+        Ok(DefIndex::from_raw_u32(self.read_u32()?))
     }
 }
 
 impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
-        let lo = BytePos::decode(self)?;
-        let hi = BytePos::decode(self)?;
+        let tag = u8::decode(self)?;
 
-        if lo == BytePos(0) && hi == BytePos(0) {
-            // Don't try to rebase DUMMY_SP. Otherwise it will look like a valid
-            // Span again.
+        if tag == TAG_INVALID_SPAN {
             return Ok(DUMMY_SP)
         }
 
-        if hi < lo {
-            // Consistently map invalid spans to DUMMY_SP.
-            return Ok(DUMMY_SP)
-        }
+        debug_assert_eq!(tag, TAG_VALID_SPAN);
+
+        let lo = BytePos::decode(self)?;
+        let len = BytePos::decode(self)?;
+        let hi = lo + len;
 
         let sess = if let Some(sess) = self.sess {
             sess
@@ -297,9 +295,7 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
             let last_filemap = &imported_filemaps[self.last_filemap_index];
 
             if lo >= last_filemap.original_start_pos &&
-               lo <= last_filemap.original_end_pos &&
-               hi >= last_filemap.original_start_pos &&
-               hi <= last_filemap.original_end_pos {
+               lo <= last_filemap.original_end_pos {
                 last_filemap
             } else {
                 let mut a = 0;
@@ -323,11 +319,9 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
         debug_assert!(lo >= filemap.original_start_pos &&
                       lo <= filemap.original_end_pos);
 
-        if hi < filemap.original_start_pos || hi > filemap.original_end_pos {
-            // `hi` points to a different FileMap than `lo` which is invalid.
-            // Again, map invalid Spans to DUMMY_SP.
-            return Ok(DUMMY_SP)
-        }
+        // Make sure we correctly filtered out invalid spans during encoding
+        debug_assert!(hi >= filemap.original_start_pos &&
+                      hi <= filemap.original_end_pos);
 
         let lo = (lo + filemap.translated_filemap.start_pos) - filemap.original_start_pos;
         let hi = (hi + filemap.translated_filemap.start_pos) - filemap.original_start_pos;
@@ -336,6 +330,12 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
     }
 }
 
+impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
+    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
+        Fingerprint::decode_opaque(&mut self.opaque)
+    }
+}
+
 impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
 for DecodeContext<'a, 'tcx> {
     #[inline]
@@ -453,7 +453,7 @@ pub fn get_def(&self, index: DefIndex) -> Option<Def> {
         if !self.is_proc_macro(index) {
             self.entry(index).kind.to_def(self.local_def_id(index))
         } else {
-            let kind = self.proc_macros.as_ref().unwrap()[index.as_usize() - 1].1.kind();
+            let kind = self.proc_macros.as_ref().unwrap()[index.to_proc_macro_index()].1.kind();
             Some(Def::Macro(self.local_def_id(index), kind))
         }
     }
@@ -634,7 +634,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Sessio
                     let def = Def::Macro(
                         DefId {
                             krate: self.cnum,
-                            index: DefIndex::new(id + 1)
+                            index: DefIndex::from_proc_macro_index(id),
                         },
                         ext.kind()
                     );
index 5ddbb18450e2ea22a3a6e12be2074abf130e5be3..d52a31d50cd973c2bc14a018c29533f5193b00fb 100644 (file)
@@ -18,6 +18,7 @@
 use rustc::hir::def::CtorKind;
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
 use rustc::hir::map::definitions::DefPathTable;
+use rustc::ich::Fingerprint;
 use rustc::middle::dependency_format::Linkage;
 use rustc::middle::lang_items;
 use rustc::mir;
@@ -41,7 +42,7 @@
 use syntax::codemap::Spanned;
 use syntax::attr;
 use syntax::symbol::Symbol;
-use syntax_pos::{self, FileName};
+use syntax_pos::{self, FileName, FileMap, Span, DUMMY_SP};
 
 use rustc::hir::{self, PatKind};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
@@ -57,6 +58,9 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
     lazy_state: LazyState,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
     predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
+
+    // This is used to speed up Span encoding.
+    filemap_cache: Rc<FileMap>,
 }
 
 macro_rules! encoder_methods {
@@ -136,7 +140,42 @@ fn specialized_encode(&mut self, def_id: &DefId) -> Result<(), Self::Error> {
 impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
     #[inline]
     fn specialized_encode(&mut self, def_index: &DefIndex) -> Result<(), Self::Error> {
-        self.emit_u32(def_index.as_u32())
+        self.emit_u32(def_index.as_raw_u32())
+    }
+}
+
+impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> {
+    fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
+        if *span == DUMMY_SP {
+            return TAG_INVALID_SPAN.encode(self)
+        }
+
+        let span = span.data();
+
+        // The Span infrastructure should make sure that this invariant holds:
+        debug_assert!(span.lo <= span.hi);
+
+        if !self.filemap_cache.contains(span.lo) {
+            let codemap = self.tcx.sess.codemap();
+            let filemap_index = codemap.lookup_filemap_idx(span.lo);
+            self.filemap_cache = codemap.files()[filemap_index].clone();
+        }
+
+        if !self.filemap_cache.contains(span.hi) {
+            // Unfortunately, macro expansion still sometimes generates Spans
+            // that malformed in this way.
+            return TAG_INVALID_SPAN.encode(self)
+        }
+
+        TAG_VALID_SPAN.encode(self)?;
+        span.lo.encode(self)?;
+
+        // Encode length which is usually less than span.hi and profits more
+        // from the variable-length integer encoding that we use.
+        let len = span.hi - span.lo;
+        len.encode(self)
+
+        // Don't encode the expansion context.
     }
 }
 
@@ -154,6 +193,12 @@ fn specialized_encode(&mut self,
     }
 }
 
+impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'a, 'tcx> {
+    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+        f.encode_opaque(&mut self.opaque)
+    }
+}
+
 impl<'a, 'tcx, T: Encodable> SpecializedEncoder<mir::ClearCrossCrate<T>>
 for EncodeContext<'a, 'tcx> {
     fn specialized_encode(&mut self,
@@ -587,7 +632,7 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<
         debug!("IsolatedEncoder::encode_struct_ctor({:?})", def_id);
         let tcx = self.tcx;
         let adt_def = tcx.adt_def(adt_def_id);
-        let variant = adt_def.struct_variant();
+        let variant = adt_def.non_enum_variant();
 
         let data = VariantData {
             ctor_kind: variant.ctor_kind,
@@ -820,14 +865,15 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
 
     fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId)
                                     -> LazySeq<ast::Name> {
-        let _ignore = self.tcx.dep_graph.in_ignore();
-        let body = self.tcx.hir.body(body_id);
-        self.lazy_seq(body.arguments.iter().map(|arg| {
-            match arg.pat.node {
-                PatKind::Binding(_, _, name, _) => name.node,
-                _ => Symbol::intern("")
-            }
-        }))
+        self.tcx.dep_graph.with_ignore(|| {
+            let body = self.tcx.hir.body(body_id);
+            self.lazy_seq(body.arguments.iter().map(|arg| {
+                match arg.pat.node {
+                    PatKind::Binding(_, _, name, _) => name.node,
+                    _ => Symbol::intern("")
+                }
+            }))
+        })
     }
 
     fn encode_fn_arg_names(&mut self, names: &[Spanned<ast::Name>])
@@ -897,7 +943,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
             hir::ItemTy(..) => EntryKind::Type,
             hir::ItemEnum(..) => EntryKind::Enum(get_repr_options(&tcx, def_id)),
             hir::ItemStruct(ref struct_def, _) => {
-                let variant = tcx.adt_def(def_id).struct_variant();
+                let variant = tcx.adt_def(def_id).non_enum_variant();
 
                 // Encode def_ids for each field and method
                 // for methods, write all the stuff get_trait_method
@@ -918,7 +964,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 }), repr_options)
             }
             hir::ItemUnion(..) => {
-                let variant = tcx.adt_def(def_id).struct_variant();
+                let variant = tcx.adt_def(def_id).non_enum_variant();
                 let repr_options = get_repr_options(&tcx, def_id);
 
                 EntryKind::Union(self.lazy(&VariantData {
@@ -1011,7 +1057,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) => {
                     let def = self.tcx.adt_def(def_id);
-                    self.lazy_seq(def.struct_variant().fields.iter().map(|f| {
+                    self.lazy_seq(def.non_enum_variant().fields.iter().map(|f| {
                         assert!(f.did.is_local());
                         f.did.index
                     }))
@@ -1648,6 +1694,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             lazy_state: LazyState::NoNode,
             type_shorthands: Default::default(),
             predicate_shorthands: Default::default(),
+            filemap_cache: tcx.sess.codemap().files()[0].clone(),
         };
 
         // Encode the rustc version string in a predictable location.
index 69fbc9354610d9aabc1d94334069ab86e5249abe..157b8385a6922e9d3e77e44b4bf0ab238ea89f24 100644 (file)
@@ -74,10 +74,9 @@ impl<'tcx> LazySeq<Index> {
     #[inline(never)]
     pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
         let words = &bytes_to_words(&bytes[self.position..])[..self.len];
-        let index = def_index.as_usize();
 
         debug!("Index::lookup: index={:?} words.len={:?}",
-               index,
+               def_index,
                words.len());
 
         let positions = match def_index.address_space() {
index f218268914300d6e98b122b10f69e6c58f651fbe..fd2c2237c32d68de07325e0f0db474c3e0da146c 100644 (file)
@@ -119,19 +119,18 @@ pub fn record<'x, DATA>(&'x mut self,
         where DATA: DepGraphRead
     {
         assert!(id.is_local());
-        let tcx: TyCtxt<'b, 'tcx, 'tcx> = self.ecx.tcx;
 
         // We don't track this since we are explicitly computing the incr. comp.
         // hashes anyway. In theory we could do some tracking here and use it to
         // avoid rehashing things (and instead cache the hashes) but it's
         // unclear whether that would be a win since hashing is cheap enough.
-        let _task = tcx.dep_graph.in_ignore();
+        self.ecx.tcx.dep_graph.with_ignore(move || {
+            let mut entry_builder = IsolatedEncoder::new(self.ecx);
+            let entry = op(&mut entry_builder, data);
+            let entry = entry_builder.lazy(&entry);
 
-        let mut entry_builder = IsolatedEncoder::new(self.ecx);
-        let entry = op(&mut entry_builder, data);
-        let entry = entry_builder.lazy(&entry);
-
-        self.items.record(id, entry);
+            self.items.record(id, entry);
+        })
     }
 
     pub fn into_items(self) -> Index {
index 18117533c18f1479c4f4f2671b7ac2bfb066a33c..33075e404321c57fcc86a037706665873519b82b 100644 (file)
@@ -15,6 +15,7 @@
 
 #![feature(box_patterns)]
 #![feature(conservative_impl_trait)]
+#![feature(fs_read_write)]
 #![feature(i128_type)]
 #![feature(libc)]
 #![feature(proc_macro_internals)]
index 90c469eea843dca2532655c8ba5e93689adb4163..e0fb924f1aa3e41a38a122e691449c9e19c74386 100644 (file)
 
 use std::cmp;
 use std::fmt;
-use std::fs::{self, File};
+use std::fs;
 use std::io::{self, Read};
 use std::path::{Path, PathBuf};
 use std::time::Instant;
@@ -870,10 +870,7 @@ fn get_metadata_section_imp(target: &Target,
             }
         }
         CrateFlavor::Rmeta => {
-            let mut file = File::open(filename).map_err(|_|
-                format!("could not open file: '{}'", filename.display()))?;
-            let mut buf = vec![];
-            file.read_to_end(&mut buf).map_err(|_|
+            let buf = fs::read(filename).map_err(|_|
                 format!("failed to read rmeta metadata: '{}'", filename.display()))?;
             OwningRef::new(buf).map_owner_box().erase_owner()
         }
index 8ff327463917ac36db7c52841c289178c9dae36e..5510d66b55bfb7a2c9160e44cb64dc7550f22805 100644 (file)
@@ -521,3 +521,7 @@ pub struct GeneratorData<'tcx> {
     pub layout: mir::GeneratorLayout<'tcx>,
 }
 impl_stable_hash_for!(struct GeneratorData<'tcx> { layout });
+
+// Tags used for encoding Spans:
+pub const TAG_VALID_SPAN: u8 = 0;
+pub const TAG_INVALID_SPAN: u8 = 1;
index ad64244f7c5af1bcd779a0886fab3fa8bc30cae0..195335dd64c1349aa0692784295af8737e9b39a2 100644 (file)
@@ -11,7 +11,7 @@ crate-type = ["dylib"]
 [dependencies]
 bitflags = "1.0"
 graphviz = { path = "../libgraphviz" }
-log = "0.3"
+log = "0.4"
 log_settings = "0.1.1"
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
index 19bebea7cb8f100794e11e0fb09274111fa0da2e..b65452fa2e27b5cacada8760c2f9ba2fe4e2dbeb 100644 (file)
@@ -719,7 +719,7 @@ fn describe_field_from_ty(&self, ty: &ty::Ty, field: Field) -> String {
                 ty::TyAdt(def, _) => if def.is_enum() {
                     format!("{}", field.index())
                 } else {
-                    format!("{}", def.struct_variant().fields[field.index()].name)
+                    format!("{}", def.non_enum_variant().fields[field.index()].name)
                 },
                 ty::TyTuple(_, _) => format!("{}", field.index()),
                 ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => {
index b79e044b24f202db76cda68c2aa8658a29bad866..fb3cb1518cbb87169031be6cc2cff169f7f0edfc 100644 (file)
@@ -18,7 +18,7 @@
 use dot;
 use dot::IntoCow;
 
-use std::fs::File;
+use std::fs;
 use std::io;
 use std::io::prelude::*;
 use std::marker::PhantomData;
@@ -67,7 +67,7 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
     dot::render(&g, &mut v)?;
     debug!("print_borrowck_graph_to path: {} node_id: {}",
            path.display(), mbcx.node_id);
-    File::create(path).and_then(|mut f| f.write_all(&v))
+    fs::write(path, v)
 }
 
 pub type Node = BasicBlock;
index ef27c636ce08c0bdb88428df848b191d14cce553..2b95449f767dd69a5e7d2abe535e02c0d5c039db 100644 (file)
@@ -488,7 +488,7 @@ fn check_ctfe_against_miri<'a, 'tcx>(
                 miri_place = ecx.place_downcast(miri_place, variant).unwrap();
                 &def.variants[variant]
             } else {
-                def.struct_variant()
+                def.non_enum_variant()
             };
             let vec = match ctfe {
                 ConstVal::Aggregate(Struct(v)) => v,
index 3af914a6c13602d76cb4412a0a30633f18b76fe3..baec0fea50f1ef18df029ea03cc885403679d8f7 100644 (file)
@@ -781,7 +781,7 @@ pub(super) fn eval_rvalue_into_place(
             }
         }
 
-        if log_enabled!(::log::LogLevel::Trace) {
+        if log_enabled!(::log::Level::Trace) {
             self.dump_local(dest);
         }
 
index ac16118c7afd70d72ac311a8a9fa50948413d3f8..c2c6b23c083a25eecb90189f67a99ff3a35aa949 100644 (file)
@@ -209,7 +209,7 @@ pub fn eval_place(&mut self, mir_place: &mir::Place<'tcx>) -> EvalResult<'tcx, P
             }
         };
 
-        if log_enabled!(::log::LogLevel::Trace) {
+        if log_enabled!(::log::Level::Trace) {
             self.dump_local(place);
         }
 
index e9e7e688f1f072170625b30e28bd1bf5c7feebfa..5379bf3f5a7aeed0db424d3ab5617e611b170eef 100644 (file)
@@ -24,6 +24,7 @@
 #![feature(core_intrinsics)]
 #![feature(decl_macro)]
 #![feature(dyn_trait)]
+#![feature(fs_read_write)]
 #![feature(i128_type)]
 #![feature(inclusive_range_syntax)]
 #![feature(inclusive_range)]
index e9a8c2427b3734ba5135ad7e28822bf4aa622998..aa3cacae874b93d2c3a603469867ccf0d56cce7c 100644 (file)
@@ -838,8 +838,8 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 CustomCoerceUnsized::Struct(i) => i
             };
 
-            let source_fields = &source_adt_def.struct_variant().fields;
-            let target_fields = &target_adt_def.struct_variant().fields;
+            let source_fields = &source_adt_def.non_enum_variant().fields;
+            let target_fields = &target_adt_def.non_enum_variant().fields;
 
             assert!(coerce_index < source_fields.len() &&
                     source_fields.len() == target_fields.len());
index 9e547285b16badd6950cf899be3576481bec1fdf..024334f1c849c2f0464a560658a3b52d078fffb3 100644 (file)
@@ -18,9 +18,8 @@
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::session::config::OptLevel;
-use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::subst::{Subst, Substs};
+use rustc::ty::subst::Substs;
 use syntax::ast;
 use syntax::attr::{self, InlineAttr};
 use std::fmt::{self, Write};
@@ -214,8 +213,7 @@ fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
             MonoItem::GlobalAsm(..) => return true
         };
 
-        let predicates = tcx.predicates_of(def_id).predicates.subst(tcx, substs);
-        traits::normalize_and_test_predicates(tcx, predicates)
+        tcx.substitute_normalize_and_test_predicates((def_id, &substs))
     }
 
     fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
index 11c68a116696b29f8f2c54568d0d7441b8c47eef..e899cc072e07288e1689ec715c60b3332b61d9b9 100644 (file)
@@ -200,7 +200,16 @@ fn as_codegen_unit(&self) -> &CodegenUnit<'tcx> {
 }
 
 // Anything we can't find a proper codegen unit for goes into this.
-const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
+fn fallback_cgu_name(tcx: TyCtxt) -> InternedString {
+    const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
+
+    if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
+        Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str()
+    } else {
+        Symbol::intern(&CodegenUnit::mangle_name(FALLBACK_CODEGEN_UNIT)).as_str()
+    }
+}
+
 
 pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               trans_items: I,
@@ -297,7 +306,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         let codegen_unit_name = match characteristic_def_id {
             Some(def_id) => compute_codegen_unit_name(tcx, def_id, is_volatile),
-            None => Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str(),
+            None => fallback_cgu_name(tcx),
         };
 
         let make_codegen_unit = || {
@@ -381,7 +390,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // always ensure we have at least one CGU; otherwise, if we have a
     // crate with just types (for example), we could wind up with no CGU
     if codegen_units.is_empty() {
-        let codegen_unit_name = Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str();
+        let codegen_unit_name = fallback_cgu_name(tcx);
         codegen_units.insert(codegen_unit_name.clone(),
                              CodegenUnit::new(codegen_unit_name.clone()));
     }
@@ -630,10 +639,10 @@ fn compute_codegen_unit_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // Unfortunately we cannot just use the `ty::item_path` infrastructure here
     // because we need paths to modules and the DefIds of those are not
     // available anymore for external items.
-    let mut mod_path = String::with_capacity(64);
+    let mut cgu_name = String::with_capacity(64);
 
     let def_path = tcx.def_path(def_id);
-    mod_path.push_str(&tcx.crate_name(def_path.krate).as_str());
+    cgu_name.push_str(&tcx.crate_name(def_path.krate).as_str());
 
     for part in tcx.def_path(def_id)
                    .data
@@ -644,15 +653,21 @@ fn compute_codegen_unit_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             _ => false,
                         }
                     }) {
-        mod_path.push_str("-");
-        mod_path.push_str(&part.data.as_interned_str());
+        cgu_name.push_str("-");
+        cgu_name.push_str(&part.data.as_interned_str());
     }
 
     if volatile {
-        mod_path.push_str(".volatile");
+        cgu_name.push_str(".volatile");
     }
 
-    return Symbol::intern(&mod_path[..]).as_str();
+    let cgu_name = if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
+        cgu_name
+    } else {
+        CodegenUnit::mangle_name(&cgu_name)
+    };
+
+    Symbol::intern(&cgu_name[..]).as_str()
 }
 
 fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString {
index f0871bb188d494582c63225592bf173f031f6a40..b896e6ca85343d0460d18ff45df868b7949ea769 100644 (file)
@@ -122,7 +122,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     return_qualif: Option<Qualif>,
     qualif: Qualif,
     const_fn_arg_vars: BitVector,
-    local_needs_drop: IndexVec<Local, Option<Span>>,
     temp_promotion_state: IndexVec<Local, TempState>,
     promotion_candidates: Vec<Candidate>
 }
@@ -136,6 +135,16 @@ fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         let mut rpo = traversal::reverse_postorder(mir);
         let temps = promote_consts::collect_temps(mir, &mut rpo);
         rpo.reset();
+
+        let param_env = tcx.param_env(def_id);
+
+        let mut temp_qualif = IndexVec::from_elem(None, &mir.local_decls);
+        for arg in mir.args_iter() {
+            let mut qualif = Qualif::NEEDS_DROP;
+            qualif.restrict(mir.local_decls[arg].ty, tcx, param_env);
+            temp_qualif[arg] = Some(qualif);
+        }
+
         Qualifier {
             mode,
             span: mir.span,
@@ -143,12 +152,11 @@ fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             mir,
             rpo,
             tcx,
-            param_env: tcx.param_env(def_id),
-            temp_qualif: IndexVec::from_elem(None, &mir.local_decls),
+            param_env,
+            temp_qualif,
             return_qualif: None,
             qualif: Qualif::empty(),
             const_fn_arg_vars: BitVector::new(mir.local_decls.len()),
-            local_needs_drop: IndexVec::from_elem(None, &mir.local_decls),
             temp_promotion_state: temps,
             promotion_candidates: vec![]
         }
@@ -255,15 +263,6 @@ fn assign(&mut self, dest: &Place<'tcx>, location: Location) {
             return;
         }
 
-        // When initializing a local, record whether the *value* being
-        // stored in it needs dropping, which it may not, even if its
-        // type does, e.g. `None::<String>`.
-        if let Place::Local(local) = *dest {
-            if qualif.intersects(Qualif::NEEDS_DROP) {
-                self.local_needs_drop[local] = Some(self.span);
-            }
-        }
-
         match *dest {
             Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp => {
                 debug!("store to temp {:?}", index);
@@ -424,17 +423,20 @@ fn visit_local(&mut self,
                    &local: &Local,
                    _: PlaceContext<'tcx>,
                    _: Location) {
-        match self.mir.local_kind(local) {
+        let kind = self.mir.local_kind(local);
+        match kind {
             LocalKind::ReturnPointer => {
                 self.not_const();
             }
-            LocalKind::Arg => {
-                self.add(Qualif::FN_ARGUMENT);
-            }
             LocalKind::Var => {
                 self.add(Qualif::NOT_CONST);
             }
+            LocalKind::Arg |
             LocalKind::Temp => {
+                if let LocalKind::Arg = kind {
+                    self.add(Qualif::FN_ARGUMENT);
+                }
+
                 if !self.temp_promotion_state[local].is_promotable() {
                     self.add(Qualif::NOT_PROMOTABLE);
                 }
@@ -529,16 +531,18 @@ fn visit_place(&mut self,
 
     fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
         match *operand {
-            Operand::Copy(ref place) |
-            Operand::Move(ref place) => {
+            Operand::Copy(_) |
+            Operand::Move(_) => {
                 self.nest(|this| {
                     this.super_operand(operand, location);
                     this.try_consume();
                 });
 
                 // Mark the consumed locals to indicate later drops are noops.
-                if let Place::Local(local) = *place {
-                    self.local_needs_drop[local] = None;
+                if let Operand::Move(Place::Local(local)) = *operand {
+                    self.temp_qualif[local] = self.temp_qualif[local].map(|q|
+                        q - Qualif::NEEDS_DROP
+                    );
                 }
             }
             Operand::Constant(ref constant) => {
@@ -847,9 +851,13 @@ struct and enum constructors",
                 // HACK(eddyb) Emulate a bit of dataflow analysis,
                 // conservatively, that drop elaboration will do.
                 let needs_drop = if let Place::Local(local) = *place {
-                    self.local_needs_drop[local]
+                    if self.temp_qualif[local].map_or(true, |q| q.intersects(Qualif::NEEDS_DROP)) {
+                        Some(self.mir.local_decls[local].source_info.span)
+                    } else {
+                        None
+                    }
                 } else {
-                    None
+                    Some(self.span)
                 };
 
                 if let Some(span) = needs_drop {
index d2560c2f8203f0557957ea0bbb968fbaa127bba3..776f330a58bdd571e4f1498308630ae0fc0de4cc 100644 (file)
@@ -9,7 +9,7 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
-log = "0.3"
+log = "0.4"
 rustc = { path = "../librustc" }
 rustc_const_eval = { path = "../librustc_const_eval" }
 rustc_const_math = { path = "../librustc_const_math" }
index ab2d152b724a7227be3528a9cf48a9bf4e054f25..4c8d42cf02f9832f216441a2ff1c192d845ba85c 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-log = "0.3"
+log = "0.4"
 syntax = { path = "../libsyntax" }
 rustc = { path = "../librustc" }
 arena = { path = "../libarena" }
index 5866c8f93f094cfe51f122856c6b8d807af1a75b..50efd89f6fedb66b112b5f9f2fc370d10357c7f0 100644 (file)
@@ -156,7 +156,7 @@ fn build_reduced_graph_for_use_tree(&mut self,
 
                     // Disallow `use $crate;`
                     if source.name == keywords::DollarCrate.name() && path.segments.len() == 1 {
-                        let crate_root = self.resolve_crate_root(source.ctxt);
+                        let crate_root = self.resolve_crate_root(source.ctxt, true);
                         let crate_name = match crate_root.kind {
                             ModuleKind::Def(_, name) => name,
                             ModuleKind::Block(..) => unreachable!(),
index 9f00bf97deba1f0301a6e7a73b8c503b39e3a8b5..fd9808012131991421d338c598f5a7f98cac5a11 100644 (file)
@@ -42,7 +42,7 @@
 use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
 
 use syntax::codemap::{dummy_spanned, respan};
-use syntax::ext::hygiene::{Mark, SyntaxContext};
+use syntax::ext::hygiene::{Mark, MarkKind, SyntaxContext};
 use syntax::ast::{self, Name, NodeId, Ident, SpannedIdent, FloatTy, IntTy, UintTy};
 use syntax::ext::base::SyntaxExtension;
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
@@ -1789,8 +1789,17 @@ fn resolve_ident_in_module(&mut self,
         result
     }
 
-    fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext) -> Module<'a> {
-        let module = match ctxt.adjust(Mark::root()) {
+    fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext, legacy: bool) -> Module<'a> {
+        let mark = if legacy {
+            // When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
+            // we don't want to pretend that the `macro_rules!` definition is in the `macro`
+            // as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks.
+            ctxt.marks().into_iter().find(|&mark| mark.kind() != MarkKind::Modern)
+        } else {
+            ctxt = ctxt.modern();
+            ctxt.adjust(Mark::root())
+        };
+        let module = match mark {
             Some(def) => self.macro_def_scope(def),
             None => return self.graph_root,
         };
@@ -2982,6 +2991,8 @@ fn resolve_path(&mut self,
                     let msg = "There are too many initial `super`s.".to_string();
                     return PathResult::Failed(ident.span, msg, false);
                 }
+            } else if i == 0 && ns == TypeNS && name == keywords::Extern.name() {
+                continue;
             }
             allow_super = false;
 
@@ -2990,22 +3001,25 @@ fn resolve_path(&mut self,
                    (i == 1 && name == keywords::Crate.name() &&
                               path[0].node.name == keywords::CrateRoot.name()) {
                     // `::a::b` or `::crate::a::b`
-                    module = Some(self.resolve_crate_root(ident.node.ctxt.modern()));
+                    module = Some(self.resolve_crate_root(ident.node.ctxt, false));
                     continue
                 } else if i == 0 && name == keywords::DollarCrate.name() {
                     // `$crate::a::b`
-                    module = Some(self.resolve_crate_root(ident.node.ctxt));
-                    continue
-                } else if i == 1 && self.session.features.borrow().extern_absolute_paths &&
-                                    path[0].node.name == keywords::CrateRoot.name() &&
-                                    !token::Ident(ident.node).is_path_segment_keyword() {
-                    // `::extern_crate::a::b`
-                    let crate_id = self.crate_loader.resolve_crate_from_path(name, ident.span);
-                    let crate_root =
-                        self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
-                    self.populate_module_if_necessary(crate_root);
-                    module = Some(crate_root);
+                    module = Some(self.resolve_crate_root(ident.node.ctxt, true));
                     continue
+                } else if i == 1 && !token::Ident(ident.node).is_path_segment_keyword() {
+                    let prev_name = path[0].node.name;
+                    if prev_name == keywords::Extern.name() ||
+                       prev_name == keywords::CrateRoot.name() &&
+                       self.session.features.borrow().extern_absolute_paths {
+                        // `::extern_crate::a::b`
+                        let crate_id = self.crate_loader.resolve_crate_from_path(name, ident.span);
+                        let crate_root =
+                            self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+                        self.populate_module_if_necessary(crate_root);
+                        module = Some(crate_root);
+                        continue
+                    }
                 }
             }
 
@@ -3015,6 +3029,7 @@ fn resolve_path(&mut self,
                name == keywords::SelfValue.name() && i != 0 ||
                name == keywords::SelfType.name() && i != 0 ||
                name == keywords::Super.name() && i != 0 ||
+               name == keywords::Extern.name() && i != 0 ||
                name == keywords::Crate.name() && i != 1 &&
                     path[0].node.name != keywords::CrateRoot.name() {
                 let name_str = if name == keywords::CrateRoot.name() {
index 14b5c6c9a5e8b860199d1bb6920c02e2974d5192..2b0c839152ccb4d70b408aaa4437174246e64cdd 100644 (file)
@@ -13,8 +13,8 @@
 use Namespace::{self, MacroNS};
 use build_reduced_graph::BuildReducedGraphVisitor;
 use resolve_imports::ImportResolver;
-use rustc_data_structures::indexed_vec::Idx;
-use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex};
+use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex,
+                         DefIndexAddressSpace};
 use rustc::hir::def::{Def, Export};
 use rustc::hir::map::{self, DefCollector};
 use rustc::{ty, lint};
@@ -140,7 +140,7 @@ fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
                 let ident = path.segments[0].identifier;
                 if ident.name == keywords::DollarCrate.name() {
                     path.segments[0].identifier.name = keywords::CrateRoot.name();
-                    let module = self.0.resolve_crate_root(ident.ctxt);
+                    let module = self.0.resolve_crate_root(ident.ctxt, true);
                     if !module.is_local() {
                         let span = path.segments[0].span;
                         path.segments.insert(1, match module.kind {
@@ -188,7 +188,8 @@ fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion, derives: &[Mark
     fn add_builtin(&mut self, ident: ast::Ident, ext: Rc<SyntaxExtension>) {
         let def_id = DefId {
             krate: BUILTIN_MACROS_CRATE,
-            index: DefIndex::new(self.macro_map.len()),
+            index: DefIndex::from_array_index(self.macro_map.len(),
+                                              DefIndexAddressSpace::Low),
         };
         let kind = ext.kind();
         self.macro_map.insert(def_id, ext);
index e249ecfca588e750a34eda2d353a8aceb737b083..132119e961bc377459d8af78f84872523c49a127 100644 (file)
@@ -604,26 +604,28 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
         self.current_module = directive.parent;
         let ImportDirective { ref module_path, span, .. } = *directive;
 
-        // Extern crate mode for absolute paths needs some
-        // special support for single-segment imports.
-        let extern_absolute_paths = self.session.features.borrow().extern_absolute_paths;
-        if module_path.len() == 1 && module_path[0].node.name == keywords::CrateRoot.name() {
+        // FIXME: Last path segment is treated specially in import resolution, so extern crate
+        // mode for absolute paths needs some special support for single-segment imports.
+        if module_path.len() == 1 && (module_path[0].node.name == keywords::CrateRoot.name() ||
+                                      module_path[0].node.name == keywords::Extern.name()) {
+            let is_extern = module_path[0].node.name == keywords::Extern.name() ||
+                            self.session.features.borrow().extern_absolute_paths;
             match directive.subclass {
-                GlobImport { .. } if extern_absolute_paths => {
+                GlobImport { .. } if is_extern => {
                     return Some((directive.span,
                                  "cannot glob-import all possible crates".to_string()));
                 }
                 SingleImport { source, target, .. } => {
-                    let crate_root = if source.name == keywords::Crate.name() {
+                    let crate_root = if source.name == keywords::Crate.name() &&
+                                        module_path[0].node.name != keywords::Extern.name() {
                         if target.name == keywords::Crate.name() {
                             return Some((directive.span,
                                          "crate root imports need to be explicitly named: \
                                           `use crate as name;`".to_string()));
                         } else {
-                            Some(self.resolve_crate_root(source.ctxt.modern()))
+                            Some(self.resolve_crate_root(source.ctxt.modern(), false))
                         }
-                    } else if extern_absolute_paths &&
-                              !token::Ident(source).is_path_segment_keyword() {
+                    } else if is_extern && !token::Ident(source).is_path_segment_keyword() {
                         let crate_id =
                             self.crate_loader.resolve_crate_from_path(source.name, directive.span);
                         let crate_root =
index d8581f52d0d1b3616e8f7eec217b08951fc18d98..8b2658b2a88c4b8da592eb191ebd5d21a10054bb 100644 (file)
@@ -9,7 +9,7 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
-log = "0.3"
+log = "0.4"
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_typeck = { path = "../librustc_typeck" }
index ed3b8eadad74c6c4b4d6abb7b33f7fa98bb016d9..30e3c9c4ca8a3ed30c201b9b480cc2dce8f5bf66 100644 (file)
@@ -1252,7 +1252,13 @@ fn process_use_tree(&mut self,
                          root_item: &'l ast::Item,
                          prefix: &ast::Path) {
         let path = &use_tree.prefix;
-        let access = access_from!(self.save_ctxt, root_item);
+
+        // The access is calculated using the current tree ID, but with the root tree's visibility
+        // (since nested trees don't have their own visibility).
+        let access = Access {
+            public: root_item.vis == ast::Visibility::Public,
+            reachable: self.save_ctxt.analysis.access_levels.is_reachable(id),
+        };
 
         // The parent def id of a given use tree is always the enclosing item.
         let parent = self.save_ctxt.tcx.hir.opt_local_def_id(id)
@@ -1583,10 +1589,12 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) {
                         if !self.span.filter_generated(sub_span, ex.span) {
                             let span =
                                 self.span_from_span(sub_span.expect("No span found for var ref"));
+                            let ref_id =
+                                ::id_from_def_id(def.non_enum_variant().fields[idx.node].did);
                             self.dumper.dump_ref(Ref {
                                 kind: RefKind::Variable,
                                 span,
-                                ref_id: ::id_from_def_id(def.struct_variant().fields[idx.node].did),
+                                ref_id,
                             });
                         }
                     }
index 93fb22a2dc0c9c26f8e1613d72646df2d86ce902..2e494fdfad8b894bee857ce1be51491e6076dbba 100644 (file)
@@ -528,7 +528,7 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
                 };
                 match self.tables.expr_ty_adjusted(&hir_node).sty {
                     ty::TyAdt(def, _) if !def.is_enum() => {
-                        let f = def.struct_variant().field_named(ident.node.name);
+                        let f = def.non_enum_variant().field_named(ident.node.name);
                         let sub_span = self.span_utils.span_for_last_ident(expr.span);
                         filter!(self.span_utils, sub_span, expr.span, None);
                         let span = self.span_from_span(sub_span.unwrap());
@@ -1077,21 +1077,21 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
     config: Option<Config>,
     mut handler: H,
 ) {
-    let _ignore = tcx.dep_graph.in_ignore();
+    tcx.dep_graph.with_ignore(|| {
+        assert!(analysis.glob_map.is_some());
 
-    assert!(analysis.glob_map.is_some());
+        info!("Dumping crate {}", cratename);
 
-    info!("Dumping crate {}", cratename);
-
-    let save_ctxt = SaveContext {
-        tcx,
-        tables: &ty::TypeckTables::empty(None),
-        analysis,
-        span_utils: SpanUtils::new(&tcx.sess),
-        config: find_config(config),
-    };
+        let save_ctxt = SaveContext {
+            tcx,
+            tables: &ty::TypeckTables::empty(None),
+            analysis,
+            span_utils: SpanUtils::new(&tcx.sess),
+            config: find_config(config),
+        };
 
-    handler.save(save_ctxt, krate, cratename)
+        handler.save(save_ctxt, krate, cratename)
+    })
 }
 
 fn find_config(supplied: Option<Config>) -> Config {
@@ -1123,7 +1123,7 @@ fn generated_code(span: Span) -> bool {
 fn id_from_def_id(id: DefId) -> rls_data::Id {
     rls_data::Id {
         krate: id.krate.as_u32(),
-        index: id.index.as_u32(),
+        index: id.index.as_raw_u32(),
     }
 }
 
index 7b242d2b867b60b66f6bdbdd7767dba0ed9ecd9e..79dd57b37f41fdead93d80145de0f452ab39cf42 100644 (file)
@@ -13,7 +13,7 @@ test = false
 bitflags = "1.0"
 flate2 = "1.0"
 jobserver = "0.1.5"
-log = "0.3"
+log = "0.4"
 num_cpus = "1.0"
 rustc = { path = "../librustc" }
 rustc-demangle = "0.1.4"
index c891bd8aaf44f06d499dc68bbe2c51e769ad37fd..745197d64f2f676487e2c7279064321a6f1d98e7 100644 (file)
 //! perturb the reuse results.
 
 use rustc::dep_graph::{DepNode, DepConstructor};
+use rustc::mir::mono::CodegenUnit;
 use rustc::ty::TyCtxt;
 use syntax::ast;
+use syntax_pos::symbol::Symbol;
 use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_TRANSLATED};
 
 const MODULE: &'static str = "module";
 enum Disposition { Reused, Translated }
 
 pub(crate) fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let _ignore = tcx.dep_graph.in_ignore();
-
-    if tcx.sess.opts.incremental.is_none() {
-        return;
-    }
+    tcx.dep_graph.with_ignore(|| {
+        if tcx.sess.opts.incremental.is_none() {
+            return;
+        }
 
-    let ams = AssertModuleSource { tcx };
-    for attr in &tcx.hir.krate().attrs {
-        ams.check_attr(attr);
-    }
+        let ams = AssertModuleSource { tcx };
+        for attr in &tcx.hir.krate().attrs {
+            ams.check_attr(attr);
+        }
+    })
 }
 
 struct AssertModuleSource<'a, 'tcx: 'a> {
@@ -71,9 +73,11 @@ fn check_attr(&self, attr: &ast::Attribute) {
         }
 
         let mname = self.field(attr, MODULE);
+        let mangled_cgu_name = CodegenUnit::mangle_name(&mname.as_str());
+        let mangled_cgu_name = Symbol::intern(&mangled_cgu_name).as_str();
 
         let dep_node = DepNode::new(self.tcx,
-                                    DepConstructor::CompileCodegenUnit(mname.as_str()));
+                                    DepConstructor::CompileCodegenUnit(mangled_cgu_name));
 
         if let Some(loaded_from_cache) = self.tcx.dep_graph.was_loaded_from_cache(&dep_node) {
             match (disposition, loaded_from_cache) {
index 9e4630c08f9f8a07d8a90c3c7a6322492766a8c7..212d1aaf055d183840548cb8c75c94921ef3801f 100644 (file)
@@ -47,7 +47,7 @@
 // The version number this compiler will write to bytecode objects in rlibs
 pub const RLIB_BYTECODE_OBJECT_VERSION: u8 = 2;
 
-pub const RLIB_BYTECODE_EXTENSION: &str = "bytecode.encoded";
+pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z";
 
 pub fn encode(identifier: &str, bytecode: &[u8]) -> Vec<u8> {
     let mut encoded = Vec::new();
index 42538c5a3ad96554ed63360bdf029406fb88698d..13a319d31bf0663832e7a31140062168b409ede6 100644 (file)
@@ -342,9 +342,7 @@ fn archive_config<'a>(sess: &'a Session,
 fn emit_metadata<'a>(sess: &'a Session, trans: &CrateTranslation, tmpdir: &TempDir)
                      -> PathBuf {
     let out_filename = tmpdir.path().join(METADATA_FILENAME);
-    let result = fs::File::create(&out_filename).and_then(|mut f| {
-        f.write_all(&trans.metadata.raw_data)
-    });
+    let result = fs::write(&out_filename, &trans.metadata.raw_data);
 
     if let Err(e) = result {
         sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
index 4d1bcd9bf467d8d046acfc8d49f210e17622fcde..1ee04a46243a264f1e73aa7e2149e47ddf58e5fa 100644 (file)
@@ -46,9 +46,8 @@
 
 use std::any::Any;
 use std::ffi::{CString, CStr};
-use std::fs::{self, File};
-use std::io;
-use std::io::{Read, Write};
+use std::fs;
+use std::io::{self, Write};
 use std::mem;
 use std::path::{Path, PathBuf};
 use std::str;
@@ -666,7 +665,7 @@ unsafe fn with_codegen<F, R>(tm: TargetMachineRef,
         timeline.record("make-bc");
 
         if write_bc {
-            if let Err(e) = File::create(&bc_out).and_then(|mut f| f.write_all(data)) {
+            if let Err(e) = fs::write(&bc_out, data) {
                 diag_handler.err(&format!("failed to write bytecode: {}", e));
             }
             timeline.record("write-bc");
@@ -675,7 +674,7 @@ unsafe fn with_codegen<F, R>(tm: TargetMachineRef,
         if config.emit_bc_compressed {
             let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
             let data = bytecode::encode(&mtrans.llmod_id, data);
-            if let Err(e) = File::create(&dst).and_then(|mut f| f.write_all(&data)) {
+            if let Err(e) = fs::write(&dst, data) {
                 diag_handler.err(&format!("failed to write bytecode: {}", e));
             }
             timeline.record("compress-bc");
@@ -799,9 +798,7 @@ fn binaryen_assemble(cgcx: &CodegenContext,
                      object: &Path) {
     use rustc_binaryen::{Module, ModuleOptions};
 
-    let input = File::open(&assembly).and_then(|mut f| {
-        let mut contents = Vec::new();
-        f.read_to_end(&mut contents)?;
+    let input = fs::read(&assembly).and_then(|contents| {
         Ok(CString::new(contents)?)
     });
     let mut options = ModuleOptions::new();
@@ -818,7 +815,7 @@ fn binaryen_assemble(cgcx: &CodegenContext,
             .map_err(|e| io::Error::new(io::ErrorKind::Other, e))
     });
     let err = assembled.and_then(|binary| {
-        File::create(&object).and_then(|mut f| f.write_all(binary.data()))
+        fs::write(&object, binary.data())
     });
     if let Err(e) = err {
         handler.err(&format!("failed to run binaryen assembler: {}", e));
index 248b37c43b42e2cb4991ac0a5c5d7daa2affc0a4..3014963a97ff4cc23ecfb33fdabf6b32704ec6c0 100644 (file)
@@ -572,7 +572,7 @@ pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
         let mut name = String::with_capacity(prefix.len() + 6);
         name.push_str(prefix);
         name.push_str(".");
-        base_n::push_str(idx as u64, base_n::ALPHANUMERIC_ONLY, &mut name);
+        base_n::push_str(idx as u128, base_n::ALPHANUMERIC_ONLY, &mut name);
         name
     }
 
index 871f255951483f9eee0d8cd9e47f068a6f7aba8e..6f3556516c4cb1ab522293bd94f93ebe860d4284 100644 (file)
@@ -969,7 +969,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
 
     let (struct_def_id, variant) = match struct_type.sty {
-        ty::TyAdt(def, _) => (def.did, def.struct_variant()),
+        ty::TyAdt(def, _) => (def.did, def.non_enum_variant()),
         _ => bug!("prepare_struct_metadata on a non-ADT")
     };
 
@@ -1084,7 +1084,7 @@ fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let union_name = compute_debuginfo_type_name(cx, union_type, false);
 
     let (union_def_id, variant) = match union_type.sty {
-        ty::TyAdt(def, _) => (def.did, def.struct_variant()),
+        ty::TyAdt(def, _) => (def.did, def.non_enum_variant()),
         _ => bug!("prepare_union_metadata on a non-ADT")
     };
 
index 039dd94465d5b72d06c14e7fa43712d006b41441..ee08a7f1ec471c53bceaef2b6033e3e2cf8abdb5 100644 (file)
@@ -22,6 +22,7 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(custom_attribute)]
+#![feature(fs_read_write)]
 #![allow(unused_attributes)]
 #![feature(i128_type)]
 #![feature(i128)]
@@ -69,7 +70,7 @@
 use back::bytecode::RLIB_BYTECODE_EXTENSION;
 
 pub use metadata::LlvmMetadataLoader;
-pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug};
+pub use llvm_util::{init, target_features, print_version, print_passes, print};
 
 use std::any::Any;
 use std::path::PathBuf;
index a9ea96134faf2aa7f7d2691c8138b5b1c6c65cf2..b3d0b574d1d432bd08f9e7f7101564b9baf78bd1 100644 (file)
@@ -140,7 +140,3 @@ pub fn print(req: PrintRequest, sess: &Session) {
         }
     }
 }
-
-pub fn enable_llvm_debug() {
-    unsafe { llvm::LLVMRustSetDebug(1); }
-}
index d96757be9f3a5e046f9ba0f1522e4d36bfe7e879..15c142cf947c89b5e2a476b2d19fc475580766aa 100644 (file)
@@ -32,10 +32,11 @@ pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         return;
     }
 
-    let _ignore = tcx.dep_graph.in_ignore();
-    let mut visitor = SymbolNamesTest { tcx: tcx };
-    // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like
-    tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+    tcx.dep_graph.with_ignore(|| {
+        let mut visitor = SymbolNamesTest { tcx: tcx };
+        // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like
+        tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+    })
 }
 
 struct SymbolNamesTest<'a, 'tcx:'a> {
index 83f06bff33441199dcc7d65396438aecd2433d33..7b9537ee23e23c8f729a6f622e82390f5126c7dc 100644 (file)
@@ -12,7 +12,7 @@ test = false
 [dependencies]
 ar = "0.3.0"
 flate2 = "1.0"
-log = "0.3"
+log = "0.4"
 
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
index c3245842b42562453cede6656306ffc69091fc8b..c7868cc1e9507f6e96ac7eb5cb8e4b4001dc6378 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-log = "0.3"
+log = "0.4"
 syntax = { path = "../libsyntax" }
 arena = { path = "../libarena" }
 fmt_macros = { path = "../libfmt_macros" }
index 7832db7dcb5423b77ea7e3fb1d617dd4524dcc2c..169959d12b5d556dd09c5c688146f60004d1ade5 100644 (file)
@@ -14,6 +14,7 @@
 use super::method::MethodCallee;
 
 use rustc::infer::InferOk;
+use rustc::session::DiagnosticMessageId;
 use rustc::traits;
 use rustc::ty::{self, Ty, TraitRef};
 use rustc::ty::{ToPredicate, TypeFoldable};
@@ -56,19 +57,25 @@ fn next(&mut self) -> Option<Self::Item> {
             return Some((self.cur_ty, 0));
         }
 
-        if self.steps.len() == tcx.sess.recursion_limit.get() {
+        if self.steps.len() >= tcx.sess.recursion_limit.get() {
             // We've reached the recursion limit, error gracefully.
             let suggested_limit = tcx.sess.recursion_limit.get() * 2;
-            struct_span_err!(tcx.sess,
-                             self.span,
-                             E0055,
-                             "reached the recursion limit while auto-dereferencing {:?}",
-                             self.cur_ty)
-                .span_label(self.span, "deref recursion limit reached")
-                .help(&format!(
-                        "consider adding a `#[recursion_limit=\"{}\"]` attribute to your crate",
+            let msg = format!("reached the recursion limit while auto-dereferencing {:?}",
+                              self.cur_ty);
+            let error_id = (DiagnosticMessageId::ErrorId(55), Some(self.span), msg.clone());
+            let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
+            if fresh {
+                struct_span_err!(tcx.sess,
+                                 self.span,
+                                 E0055,
+                                 "reached the recursion limit while auto-dereferencing {:?}",
+                                 self.cur_ty)
+                    .span_label(self.span, "deref recursion limit reached")
+                    .help(&format!(
+                        "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
                         suggested_limit))
-                .emit();
+                    .emit();
+            }
             return None;
         }
 
index 201997a74b73f3b6e4561645d2dfc84630137678..d2f759f5d99a47c2a5fe4d4f90a4a346052bd871 100644 (file)
@@ -107,7 +107,7 @@ fn pointer_kind(&self, t: Ty<'tcx>, span: Span) ->
             ty::TyDynamic(ref tty, ..) =>
                 Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))),
             ty::TyAdt(def, substs) if def.is_struct() => {
-                match def.struct_variant().fields.last() {
+                match def.non_enum_variant().fields.last() {
                     None => Some(PointerKind::Thin),
                     Some(f) => {
                         let field_ty = self.field_ty(span, f, substs);
index 45ddae5c644f4c81f1e611271b709bcc8140f26a..6703bbba86b1c9db37271eefd9767c4477e1ac90 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::iter;
 
 use check::FnCtxt;
 use rustc::infer::InferOk;
@@ -137,49 +138,45 @@ pub fn demand_coerce_diag(&self,
         if let Some((msg, suggestion)) = self.check_ref(expr, checked_ty, expected) {
             err.span_suggestion(expr.span, msg, suggestion);
         } else {
-            let mode = probe::Mode::MethodCall;
-            let suggestions = self.probe_for_return_type(syntax_pos::DUMMY_SP,
-                                                         mode,
-                                                         expected,
-                                                         checked_ty,
-                                                         ast::DUMMY_NODE_ID);
-            if suggestions.len() > 0 {
-                err.help(&format!("here are some functions which \
-                                   might fulfill your needs:\n{}",
-                                  self.get_best_match(&suggestions).join("\n")));
+            let methods = self.get_conversion_methods(expected, checked_ty);
+            if let Ok(expr_text) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
+                let suggestions = iter::repeat(expr_text).zip(methods.iter())
+                    .map(|(receiver, method)| format!("{}.{}()", receiver, method.name))
+                    .collect::<Vec<_>>();
+                if !suggestions.is_empty() {
+                    err.span_suggestions(expr.span,
+                                         "try using a conversion method",
+                                         suggestions);
+                }
             }
         }
         (expected, Some(err))
     }
 
-    fn format_method_suggestion(&self, method: &AssociatedItem) -> String {
-        format!("- .{}({})",
-                method.name,
-                if self.has_no_input_arg(method) {
-                    ""
-                } else {
-                    "..."
-                })
-    }
-
-    fn display_suggested_methods(&self, methods: &[AssociatedItem]) -> Vec<String> {
-        methods.iter()
-               .take(5)
-               .map(|method| self.format_method_suggestion(&*method))
-               .collect::<Vec<String>>()
-    }
+    fn get_conversion_methods(&self, expected: Ty<'tcx>, checked_ty: Ty<'tcx>)
+                              -> Vec<AssociatedItem> {
+        let mut methods = self.probe_for_return_type(syntax_pos::DUMMY_SP,
+                                                     probe::Mode::MethodCall,
+                                                     expected,
+                                                     checked_ty,
+                                                     ast::DUMMY_NODE_ID);
+        methods.retain(|m| {
+            self.has_no_input_arg(m) &&
+                self.tcx.get_attrs(m.def_id).iter()
+                // This special internal attribute is used to whitelist
+                // "identity-like" conversion methods to be suggested here.
+                //
+                // FIXME (#46459 and #46460): ideally
+                // `std::convert::Into::into` and `std::borrow:ToOwned` would
+                // also be `#[rustc_conversion_suggestion]`, if not for
+                // method-probing false-positives and -negatives (respectively).
+                //
+                // FIXME? Other potential candidate methods: `as_ref` and
+                // `as_mut`?
+                .find(|a| a.check_name("rustc_conversion_suggestion")).is_some()
+        });
 
-    fn get_best_match(&self, methods: &[AssociatedItem]) -> Vec<String> {
-        let no_argument_methods: Vec<_> =
-            methods.iter()
-                   .filter(|ref x| self.has_no_input_arg(&*x))
-                   .map(|x| x.clone())
-                   .collect();
-        if no_argument_methods.len() > 0 {
-            self.display_suggested_methods(&no_argument_methods)
-        } else {
-            self.display_suggested_methods(&methods)
-        }
+        methods
     }
 
     // This function checks if the method isn't static and takes other arguments than `self`.
index 6f83ecab01a1c799a06a2eb0096148018fdc3cdd..c88bbd03af82bedde4b938cf18c22f0c09abcc44 100644 (file)
@@ -190,7 +190,7 @@ pub fn probe_for_return_type(&self,
                scope_expr_id);
         let method_names =
             self.probe_op(span, mode, None, Some(return_type), IsSuggestion(true),
-                          self_ty, scope_expr_id, ProbeScope::TraitsInScope,
+                          self_ty, scope_expr_id, ProbeScope::AllTraits,
                           |probe_cx| Ok(probe_cx.candidate_method_names()))
                 .unwrap_or(vec![]);
          method_names
@@ -199,7 +199,7 @@ pub fn probe_for_return_type(&self,
                  self.probe_op(
                      span, mode, Some(method_name), Some(return_type),
                      IsSuggestion(true), self_ty, scope_expr_id,
-                     ProbeScope::TraitsInScope, |probe_cx| probe_cx.pick()
+                     ProbeScope::AllTraits, |probe_cx| probe_cx.pick()
                  ).ok().map(|pick| pick.item)
              })
             .collect()
index f29009c1973a274e017c6850718bd78379f763be..3f8792aa637a9cb711303f1f064faa86da2250c3 100644 (file)
@@ -195,15 +195,76 @@ pub fn report_method_error(&self,
                     }
                 };
                 let mut err = if !actual.references_error() {
-                    struct_span_err!(
-                        tcx.sess,
-                        span,
-                        E0599,
-                        "no {} named `{}` found for type `{}` in the current scope",
-                        type_str,
-                        item_name,
-                        ty_string
-                    )
+                    // Suggest clamping down the type if the method that is being attempted to
+                    // be used exists at all, and the type is an ambiuous numeric type
+                    // ({integer}/{float}).
+                    let mut candidates = all_traits(self.tcx)
+                        .filter(|info| {
+                            self.associated_item(info.def_id, item_name, Namespace::Value).is_some()
+                        });
+                    if let (true, false, Some(expr), Some(_)) = (actual.is_numeric(),
+                                                                 actual.has_concrete_skeleton(),
+                                                                 rcvr_expr,
+                                                                 candidates.next()) {
+                        let mut err = struct_span_err!(
+                            tcx.sess,
+                            span,
+                            E0689,
+                            "can't call {} `{}` on ambiguous numeric type `{}`",
+                            type_str,
+                            item_name,
+                            ty_string
+                        );
+                        let concrete_type = if actual.is_integral() {
+                            "i32"
+                        } else {
+                            "f32"
+                        };
+                        match expr.node {
+                            hir::ExprLit(_) => {  // numeric literal
+                                let snippet = tcx.sess.codemap().span_to_snippet(expr.span)
+                                    .unwrap_or("<numeric literal>".to_string());
+                                // FIXME: use the literal for missing snippet
+
+                                err.span_suggestion(expr.span,
+                                                    &format!("you must specify a concrete type for \
+                                                              this numeric value, like `{}`",
+                                                             concrete_type),
+                                                    format!("{}_{}",
+                                                            snippet,
+                                                            concrete_type));
+                            }
+                            hir::ExprPath(ref qpath) => {  // local binding
+                                if let &hir::QPath::Resolved(_, ref path) = &qpath {
+                                    if let hir::def::Def::Local(node_id) = path.def {
+                                        let span = tcx.hir.span(node_id);
+                                        let snippet = tcx.sess.codemap().span_to_snippet(span)
+                                            .unwrap();
+                                        err.span_suggestion(span,
+                                                            &format!("you must specify a type for \
+                                                                      this binding, like `{}`",
+                                                                     concrete_type),
+                                                            format!("{}: {}",
+                                                                    snippet,
+                                                                    concrete_type));
+                                    }
+                                }
+                            }
+                            _ => {}
+                        }
+                        err.emit();
+                        return;
+                    } else {
+                        struct_span_err!(
+                            tcx.sess,
+                            span,
+                            E0599,
+                            "no {} named `{}` found for type `{}` in the current scope",
+                            type_str,
+                            item_name,
+                            ty_string
+                        )
+                    }
                 } else {
                     tcx.sess.diagnostic().struct_dummy()
                 };
@@ -228,7 +289,7 @@ pub fn report_method_error(&self,
                     for (ty, _) in self.autoderef(span, rcvr_ty) {
                         match ty.sty {
                             ty::TyAdt(def, substs) if !def.is_enum() => {
-                                if let Some(field) = def.struct_variant()
+                                if let Some(field) = def.non_enum_variant()
                                     .find_field_named(item_name) {
                                     let snippet = tcx.sess.codemap().span_to_snippet(expr.span);
                                     let expr_string = match snippet {
@@ -305,12 +366,16 @@ macro_rules! report_function {
                                       bound_list));
                 }
 
-                self.suggest_traits_to_import(&mut err,
-                                              span,
-                                              rcvr_ty,
-                                              item_name,
-                                              rcvr_expr,
-                                              out_of_scope_traits);
+                if actual.is_numeric() && actual.is_fresh() {
+
+                } else {
+                    self.suggest_traits_to_import(&mut err,
+                                                  span,
+                                                  rcvr_ty,
+                                                  item_name,
+                                                  rcvr_expr,
+                                                  out_of_scope_traits);
+                }
 
                 if let Some(lev_candidate) = lev_candidate {
                     err.help(&format!("did you mean `{}`?", lev_candidate.name));
index 6d68824980b6af0a36f03d30336791b012d0defb..69236d77ed328a44fa97f3f559f9713abe18f11d 100644 (file)
@@ -1444,7 +1444,7 @@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId
     let t = tcx.type_of(def_id);
     match t.sty {
         ty::TyAdt(def, substs) if def.is_struct() => {
-            let fields = &def.struct_variant().fields;
+            let fields = &def.non_enum_variant().fields;
             if fields.is_empty() {
                 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
                 return;
@@ -1498,7 +1498,7 @@ fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
             // push struct def_id before checking fields
             stack.push(def_id);
-            for field in &def.struct_variant().fields {
+            for field in &def.non_enum_variant().fields {
                 let f = field.ty(tcx, substs);
                 match f.sty {
                     ty::TyAdt(def, _) => {
@@ -2217,18 +2217,6 @@ fn try_index_step(&self,
                adjusted_ty,
                index_ty);
 
-        // First, try built-in indexing.
-        match (adjusted_ty.builtin_index(), &index_ty.sty) {
-            (Some(ty), &ty::TyUint(ast::UintTy::Usize)) |
-            (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
-                debug!("try_index_step: success, using built-in indexing");
-                let adjustments = autoderef.adjust_steps(lvalue_pref);
-                self.apply_adjustments(base_expr, adjustments);
-                return Some((self.tcx.types.usize, ty));
-            }
-            _ => {}
-        }
-
         for &unsize in &[false, true] {
             let mut self_ty = adjusted_ty;
             if unsize {
@@ -2945,7 +2933,7 @@ fn check_field(&self,
                     debug!("struct named {:?}",  base_t);
                     let (ident, def_scope) =
                         self.tcx.adjust(field.node, base_def.did, self.body_id);
-                    let fields = &base_def.struct_variant().fields;
+                    let fields = &base_def.non_enum_variant().fields;
                     if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
                         let field_ty = self.field_ty(expr.span, field, substs);
                         if field.vis.is_accessible_from(def_scope, self.tcx) {
@@ -2993,12 +2981,12 @@ fn check_field(&self,
                 match expr_t.sty {
                     ty::TyAdt(def, _) if !def.is_enum() => {
                         if let Some(suggested_field_name) =
-                            Self::suggest_field_name(def.struct_variant(), field, vec![]) {
+                            Self::suggest_field_name(def.non_enum_variant(), field, vec![]) {
                                 err.span_label(field.span,
                                                format!("did you mean `{}`?", suggested_field_name));
                             } else {
                                 err.span_label(field.span, "unknown field");
-                                let struct_variant_def = def.struct_variant();
+                                let struct_variant_def = def.non_enum_variant();
                                 let field_names = self.available_field_names(struct_variant_def);
                                 if !field_names.is_empty() {
                                     err.note(&format!("available fields are: {}",
@@ -3080,7 +3068,7 @@ fn check_tup_field(&self,
         while let Some((base_t, _)) = autoderef.next() {
             let field = match base_t.sty {
                 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
-                    tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
+                    tuple_like = base_def.non_enum_variant().ctor_kind == CtorKind::Fn;
                     if !tuple_like { continue }
 
                     debug!("tuple struct named {:?}",  base_t);
@@ -3090,7 +3078,7 @@ fn check_tup_field(&self,
                     };
                     let (ident, def_scope) =
                         self.tcx.adjust_ident(ident, base_def.did, self.body_id);
-                    let fields = &base_def.struct_variant().fields;
+                    let fields = &base_def.non_enum_variant().fields;
                     if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
                         let field_ty = self.field_ty(expr.span, field, substs);
                         if field.vis.is_accessible_from(def_scope, self.tcx) {
@@ -3350,7 +3338,7 @@ pub fn check_struct_path(&self,
             Def::AssociatedTy(..) | Def::SelfTy(..) => {
                 match ty.sty {
                     ty::TyAdt(adt, substs) if !adt.is_enum() => {
-                        Some((adt.struct_variant(), adt.did, substs))
+                        Some((adt.non_enum_variant(), adt.did, substs))
                     }
                     _ => None,
                 }
@@ -3412,7 +3400,7 @@ fn check_expr_struct(&self,
             self.check_expr_has_type_or_error(base_expr, struct_ty);
             match struct_ty.sty {
                 ty::TyAdt(adt, substs) if adt.is_struct() => {
-                    let fru_field_types = adt.struct_variant().fields.iter().map(|f| {
+                    let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
                         self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
                     }).collect();
 
index 385b9321db71ab10c50c8ac94a8e0a869cc4d719..aefee1ce30a422faf9529c0abc9f72416136acfe 100644 (file)
@@ -130,14 +130,14 @@ fn check_item_well_formed(&mut self, item: &hir::Item) {
             }
             hir::ItemStruct(ref struct_def, ref ast_generics) => {
                 self.check_type_defn(item, false, |fcx| {
-                    vec![fcx.struct_variant(struct_def)]
+                    vec![fcx.non_enum_variant(struct_def)]
                 });
 
                 self.check_variances_for_type_defn(item, ast_generics);
             }
             hir::ItemUnion(ref struct_def, ref ast_generics) => {
                 self.check_type_defn(item, true, |fcx| {
-                    vec![fcx.struct_variant(struct_def)]
+                    vec![fcx.non_enum_variant(struct_def)]
                 });
 
                 self.check_variances_for_type_defn(item, ast_generics);
@@ -689,7 +689,7 @@ struct AdtField<'tcx> {
 }
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
-    fn struct_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
+    fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
         let fields =
             struct_def.fields().iter()
             .map(|field| {
@@ -704,7 +704,7 @@ fn struct_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
 
     fn enum_variants(&self, enum_def: &hir::EnumDef) -> Vec<AdtVariant<'tcx>> {
         enum_def.variants.iter()
-            .map(|variant| self.struct_variant(&variant.node.data))
+            .map(|variant| self.non_enum_variant(&variant.node.data))
             .collect()
     }
 
index 29dc983ab560b9c09066f3c2bcf570013fba72d9..5e102c7a4451684c16acb551a29b87fda97788e3 100644 (file)
@@ -18,6 +18,7 @@
 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc::infer::InferCtxt;
 use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::adjustment::{Adjust, Adjustment};
 use rustc::ty::fold::{TypeFoldable, TypeFolder};
 use rustc::util::nodemap::DefIdSet;
 use syntax::ast;
@@ -159,8 +160,52 @@ fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr) {
             _ => {}
         }
     }
+
+    // Similar to operators, indexing is always assumed to be overloaded
+    // Here, correct cases where an indexing expression can be simplified
+    // to use builtin indexing because the index type is known to be
+    // usize-ish
+    fn fix_index_builtin_expr(&mut self, e: &hir::Expr) {
+        if let hir::ExprIndex(ref base, ref index) = e.node {
+            let mut tables = self.fcx.tables.borrow_mut();
+
+            match tables.expr_ty_adjusted(&base).sty {
+                // All valid indexing looks like this
+                ty::TyRef(_, ty::TypeAndMut { ty: ref base_ty, .. }) => {
+                    let index_ty = tables.expr_ty_adjusted(&index);
+                    let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty);
+
+                    if base_ty.builtin_index().is_some()
+                        && index_ty == self.fcx.tcx.types.usize {
+                        // Remove the method call record
+                        tables.type_dependent_defs_mut().remove(e.hir_id);
+                        tables.node_substs_mut().remove(e.hir_id);
+
+                        tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
+                            // Discard the need for a mutable borrow
+                            match a.pop() {
+                                // Extra adjustment made when indexing causes a drop
+                                // of size information - we need to get rid of it
+                                // Since this is "after" the other adjustment to be
+                                // discarded, we do an extra `pop()`
+                                Some(Adjustment { kind: Adjust::Unsize, .. }) => {
+                                    // So the borrow discard actually happens here
+                                    a.pop();
+                                },
+                                _ => {}
+                            }
+                        });
+                    }
+                },
+                // Might encounter non-valid indexes at this point, so there
+                // has to be a fall-through
+                _ => {},
+            }
+        }
+    }
 }
 
+
 ///////////////////////////////////////////////////////////////////////////
 // Impl of Visitor for Resolver
 //
@@ -176,6 +221,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
 
     fn visit_expr(&mut self, e: &'gcx hir::Expr) {
         self.fix_scalar_builtin_expr(e);
+        self.fix_index_builtin_expr(e);
 
         self.visit_node_id(e.span, e.hir_id);
 
index d63980eaa506b8d79912cab5b68add9df5fc5319..2f1c42bbef8ca27e8d817e05ad19042a43f941c2 100644 (file)
@@ -288,7 +288,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 // conversion). This will work out because `U:
                 // Unsize<V>`, and we have a builtin rule that `*mut
                 // U` can be coerced to `*mut V` if `U: Unsize<V>`.
-                let fields = &def_a.struct_variant().fields;
+                let fields = &def_a.non_enum_variant().fields;
                 let diff_fields = fields.iter()
                     .enumerate()
                     .filter_map(|(i, f)| {
index 770d0cd4f1fc4997daa6f01ccc64906f85c7323a..defcbdfe03d053633ef88df88585af1d1529db87 100644 (file)
@@ -4641,6 +4641,32 @@ fn foo<U: Iterator>(&self, _: &U) { } // error method `foo` has incompatible
 ```
 "##,
 
+E0689: r##"
+This error indicates that the numeric value for the method being passed exists
+but the type of the numeric value or binding could not be identified.
+
+The error happens on numeric literals:
+
+```compile_fail,E0689
+2.0.powi(2);
+```
+
+and on numeric bindings without an identified concrete type:
+
+```compile_fail,E0689
+let x = 2.0;
+x.powi(2);  // same error as above
+```
+
+Because of this, you must give the numeric literal or binding a type:
+
+```
+let _ = 2.0_f32.powi(2);
+let x: f32 = 2.0;
+let _ = x.powi(2);
+let _ = (2.0 as f32).powi(2);
+```
+"##,
 }
 
 register_diagnostics! {
index 914365b003e18472a7a909020138e70daca7bd61..8a9dc3ca122488b2f769fba4aa30188781d56a17 100644 (file)
@@ -186,7 +186,7 @@ fn build_enum(cx: &DocContext, did: DefId) -> clean::Enum {
 
 fn build_struct(cx: &DocContext, did: DefId) -> clean::Struct {
     let predicates = cx.tcx.predicates_of(did);
-    let variant = cx.tcx.adt_def(did).struct_variant();
+    let variant = cx.tcx.adt_def(did).non_enum_variant();
 
     clean::Struct {
         struct_type: match variant.ctor_kind {
@@ -202,7 +202,7 @@ fn build_struct(cx: &DocContext, did: DefId) -> clean::Struct {
 
 fn build_union(cx: &DocContext, did: DefId) -> clean::Union {
     let predicates = cx.tcx.predicates_of(did);
-    let variant = cx.tcx.adt_def(did).struct_variant();
+    let variant = cx.tcx.adt_def(did).non_enum_variant();
 
     clean::Union {
         struct_type: doctree::Plain,
index 2f7bd5e39a14927aad28c8988b82ae497e66680f..f8320330ad2652bd37518a8473f910beae480be8 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fs::File;
-use std::io::prelude::*;
+use std::fs;
 use std::path::Path;
 use std::str;
 use html::markdown::{Markdown, RenderType};
@@ -65,13 +64,13 @@ pub enum LoadStringError {
 
 pub fn load_string<P: AsRef<Path>>(file_path: P) -> Result<String, LoadStringError> {
     let file_path = file_path.as_ref();
-    let mut contents = vec![];
-    let result = File::open(file_path)
-                      .and_then(|mut f| f.read_to_end(&mut contents));
-    if let Err(e) = result {
-        eprintln!("error reading `{}`: {}", file_path.display(), e);
-        return Err(LoadStringError::ReadFail);
-    }
+    let contents = match fs::read(file_path) {
+        Ok(bytes) => bytes,
+        Err(e) => {
+            eprintln!("error reading `{}`: {}", file_path.display(), e);
+            return Err(LoadStringError::ReadFail);
+        }
+    };
     match str::from_utf8(&contents) {
         Ok(s) => Ok(s.to_string()),
         Err(_) => {
index a389b26a5879bbf2bde93626dead762a1e452409..93a3035e06ace30ad2e616f06d90d96690d91cda 100644 (file)
@@ -173,14 +173,7 @@ pub enum ExternalLocation {
     Unknown,
 }
 
-/// Metadata about an implementor of a trait.
-pub struct Implementor {
-    pub def_id: DefId,
-    pub stability: Option<clean::Stability>,
-    pub impl_: clean::Impl,
-}
-
-/// Metadata about implementations for a type.
+/// Metadata about implementations for a type or trait.
 #[derive(Clone)]
 pub struct Impl {
     pub impl_item: clean::Item,
@@ -279,7 +272,7 @@ pub struct Cache {
     /// When rendering traits, it's often useful to be able to list all
     /// implementors of the trait, and this mapping is exactly, that: a mapping
     /// of trait ids to the list of known implementors of the trait
-    pub implementors: FxHashMap<DefId, Vec<Implementor>>,
+    pub implementors: FxHashMap<DefId, Vec<Impl>>,
 
     /// Cache of where external crate documentation can be found.
     pub extern_locations: FxHashMap<CrateNum, (String, PathBuf, ExternalLocation)>,
@@ -873,15 +866,8 @@ fn write_shared(cx: &Context,
     write(cx.dst.join("main.css"),
           include_bytes!("static/styles/main.css"))?;
     if let Some(ref css) = cx.shared.css_file_extension {
-        let mut content = String::new();
-        let css = css.as_path();
-        let mut f = try_err!(File::open(css), css);
-
-        try_err!(f.read_to_string(&mut content), css);
-        let css = cx.dst.join("theme.css");
-        let css = css.as_path();
-        let mut f = try_err!(File::create(css), css);
-        try_err!(write!(f, "{}", &content), css);
+        let out = cx.dst.join("theme.css");
+        try_err!(fs::copy(css, out), css);
     }
     write(cx.dst.join("normalize.css"),
           include_bytes!("static/normalize.css"))?;
@@ -971,12 +957,12 @@ fn collect(path: &Path, krate: &str,
             // there's no need to emit information about it (there's inlining
             // going on). If they're in different crates then the crate defining
             // the trait will be interested in our implementation.
-            if imp.def_id.krate == did.krate { continue }
+            if imp.impl_item.def_id.krate == did.krate { continue }
             // If the implementation is from another crate then that crate
             // should add it.
-            if !imp.def_id.is_local() { continue }
+            if !imp.impl_item.def_id.is_local() { continue }
             have_impls = true;
-            write!(implementors, "{},", as_json(&imp.impl_.to_string())).unwrap();
+            write!(implementors, "{},", as_json(&imp.inner_impl().to_string())).unwrap();
         }
         implementors.push_str("];");
 
@@ -1034,7 +1020,7 @@ fn render_sources(dst: &Path, scx: &mut SharedContext,
 /// Writes the entire contents of a string to a destination, not attempting to
 /// catch any errors.
 fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> {
-    Ok(try_err!(try_err!(File::create(&dst), &dst).write_all(contents), &dst))
+    Ok(try_err!(fs::write(&dst, contents), &dst))
 }
 
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
@@ -1131,16 +1117,13 @@ fn emit_source(&mut self, filename: &FileName) -> io::Result<()> {
             return Ok(());
         }
 
-        let mut contents = Vec::new();
-        File::open(&p).and_then(|mut f| f.read_to_end(&mut contents))?;
-
-        let contents = str::from_utf8(&contents).unwrap();
+        let contents = fs::read_string(&p)?;
 
         // Remove the utf-8 BOM if any
         let contents = if contents.starts_with("\u{feff}") {
             &contents[3..]
         } else {
-            contents
+            &contents[..]
         };
 
         // Create the intermediate directories
@@ -1208,10 +1191,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
             if !self.masked_crates.contains(&item.def_id.krate) {
                 if let Some(did) = i.trait_.def_id() {
                     if i.for_.def_id().map_or(true, |d| !self.masked_crates.contains(&d.krate)) {
-                        self.implementors.entry(did).or_insert(vec![]).push(Implementor {
-                            def_id: item.def_id,
-                            stability: item.stability.clone(),
-                            impl_: i.clone(),
+                        self.implementors.entry(did).or_insert(vec![]).push(Impl {
+                            impl_item: item.clone(),
                         });
                     }
                 }
@@ -2338,18 +2319,6 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     document(w, cx, it)
 }
 
-fn implementor2item<'a>(cache: &'a Cache, imp : &Implementor) -> Option<&'a clean::Item> {
-    if let Some(t_did) = imp.impl_.for_.def_id() {
-        if let Some(impl_item) = cache.impls.get(&t_did).and_then(|i| i.iter()
-            .find(|i| i.impl_item.def_id == imp.def_id))
-        {
-            let i = &impl_item.impl_item;
-            return Some(i);
-        }
-    }
-    None
-}
-
 fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
               t: &clean::Trait) -> fmt::Result {
     let mut bounds = String::new();
@@ -2533,7 +2502,7 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
         // if any Types with the same name but different DefId have been found.
         let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap();
         for implementor in implementors {
-            match implementor.impl_.for_ {
+            match implementor.inner_impl().for_ {
                 clean::ResolvedPath { ref path, did, is_generic: false, .. } |
                 clean::BorrowedRef {
                     type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. },
@@ -2550,7 +2519,7 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
         }
 
         let (local, foreign) = implementors.iter()
-            .partition::<Vec<_>, _>(|i| i.impl_.for_.def_id()
+            .partition::<Vec<_>, _>(|i| i.inner_impl().for_.def_id()
                                          .map_or(true, |d| cache.paths.contains_key(&d)));
 
         if !foreign.is_empty() {
@@ -2561,14 +2530,11 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
             ")?;
 
             for implementor in foreign {
-                if let Some(i) = implementor2item(&cache, implementor) {
-                    let impl_ = Impl { impl_item: i.clone() };
-                    let assoc_link = AssocItemLink::GotoSource(
-                        i.def_id, &implementor.impl_.provided_trait_methods
-                    );
-                    render_impl(w, cx, &impl_, assoc_link,
-                                RenderMode::Normal, i.stable_since(), false)?;
-                }
+                let assoc_link = AssocItemLink::GotoSource(
+                    implementor.impl_item.def_id, &implementor.inner_impl().provided_trait_methods
+                );
+                render_impl(w, cx, &implementor, assoc_link,
+                            RenderMode::Normal, implementor.impl_item.stable_since(), false)?;
             }
         }
 
@@ -2576,18 +2542,16 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
 
         for implementor in local {
             write!(w, "<li>")?;
-            if let Some(item) = implementor2item(&cache, implementor) {
-                if let Some(l) = (Item { cx, item }).src_href() {
-                    write!(w, "<div class='out-of-band'>")?;
-                    write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
-                                l, "goto source code")?;
-                    write!(w, "</div>")?;
-                }
+            if let Some(l) = (Item { cx, item: &implementor.impl_item }).src_href() {
+                write!(w, "<div class='out-of-band'>")?;
+                write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
+                            l, "goto source code")?;
+                write!(w, "</div>")?;
             }
             write!(w, "<code>")?;
             // If there's already another implementor that has the same abbridged name, use the
             // full path, for example in `std::iter::ExactSizeIterator`
-            let use_absolute = match implementor.impl_.for_ {
+            let use_absolute = match implementor.inner_impl().for_ {
                 clean::ResolvedPath { ref path, is_generic: false, .. } |
                 clean::BorrowedRef {
                     type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
@@ -2595,8 +2559,8 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
                 } => implementor_dups[path.last_name()].1,
                 _ => false,
             };
-            fmt_impl_for_trait_page(&implementor.impl_, w, use_absolute)?;
-            for it in &implementor.impl_.items {
+            fmt_impl_for_trait_page(&implementor.inner_impl(), w, use_absolute)?;
+            for it in &implementor.inner_impl().items {
                 if let clean::TypedefItem(ref tydef, _) = it.inner {
                     write!(w, "<span class=\"where fmt-newline\">  ")?;
                     assoc_type(w, it, &vec![], Some(&tydef.type_), AssocItemLink::Anchor(None))?;
@@ -3886,20 +3850,16 @@ fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item,
 
     if let Some(implementors) = c.implementors.get(&it.def_id) {
         let res = implementors.iter()
-                              .filter(|i| i.impl_.for_.def_id()
-                                                      .map_or(false, |d| !c.paths.contains_key(&d)))
+                              .filter(|i| i.inner_impl().for_.def_id()
+                                           .map_or(false, |d| !c.paths.contains_key(&d)))
                               .filter_map(|i| {
-                                  if let Some(item) = implementor2item(&c, i) {
-                                      match extract_for_impl_name(&item) {
-                                          Some((ref name, ref url)) => {
-                                              Some(format!("<a href=\"#impl-{}\">{}</a>",
-                                                           small_url_encode(url),
-                                                           Escape(name)))
-                                          }
-                                          _ => None,
+                                  match extract_for_impl_name(&i.impl_item) {
+                                      Some((ref name, ref url)) => {
+                                          Some(format!("<a href=\"#impl-{}\">{}</a>",
+                                                      small_url_encode(url),
+                                                      Escape(name)))
                                       }
-                                  } else {
-                                      None
+                                      _ => None,
                                   }
                               })
                               .collect::<String>();
index 1740816ef6b16eeb4ffdb6b07b0d80b2045ff914..3b43eafb849bdc10f3f69bbc27c2277fb1098ccd 100644 (file)
@@ -18,6 +18,7 @@
 #![feature(rustc_private)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(fs_read_write)]
 #![feature(libc)]
 #![feature(set_stdio)]
 #![feature(slice_patterns)]
index be78935cadfbb1897c12a3f4a54cbe5db364ca7a..5d80611d6a209ae2ad4db779191ae3d96ebdf402 100644 (file)
@@ -23,6 +23,7 @@
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::middle::cstore::{LoadedMacro, CrateStore};
 use rustc::middle::privacy::AccessLevel;
+use rustc::ty::Visibility;
 use rustc::util::nodemap::FxHashSet;
 
 use rustc::hir;
@@ -204,7 +205,7 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
         self.inside_public_path = orig_inside_public_path;
         let def_id = self.cx.tcx.hir.local_def_id(id);
         if let Some(exports) = self.cx.tcx.module_exports(def_id) {
-            for export in exports.iter() {
+            for export in exports.iter().filter(|e| e.vis == Visibility::Public) {
                 if let Def::Macro(def_id, ..) = export.def {
                     if def_id.krate == LOCAL_CRATE || self.reexported_macros.contains(&def_id) {
                         continue // These are `krate.exported_macros`, handled in `self.visit()`.
index 99557659b297bfbb794220802b66c8a700439763..409366102bacd81e2678169a152c6c69e4f6dd0d 100644 (file)
@@ -27,6 +27,10 @@ impl<'a> Encoder<'a> {
     pub fn new(cursor: &'a mut io::Cursor<Vec<u8>>) -> Encoder<'a> {
         Encoder { cursor: cursor }
     }
+
+    pub fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
+        self.cursor.write_all(s)
+    }
 }
 
 
@@ -169,6 +173,17 @@ pub fn set_position(&mut self, pos: usize) {
     pub fn advance(&mut self, bytes: usize) {
         self.position += bytes;
     }
+
+    pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> {
+        let start = self.position;
+        let end = start + s.len();
+
+        s.copy_from_slice(&self.data[start..end]);
+
+        self.position = end;
+
+        Ok(())
+    }
 }
 
 macro_rules! read_uleb128 {
index 7a79a472d58d9b8701aa8546c075651cebec9896..4e5385c17e9857678b07a04be842e4930288d814 100644 (file)
@@ -1241,6 +1241,46 @@ pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
         self.search_mut(k).into_occupied_bucket().map(|bucket| pop_internal(bucket).1)
     }
 
+    /// Removes a key from the map, returning the stored key and value if the
+    /// key was previously in the map.
+    ///
+    /// The key may be any borrowed form of the map's key type, but
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// [`Eq`]: ../../std/cmp/trait.Eq.html
+    /// [`Hash`]: ../../std/hash/trait.Hash.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_map_remove_entry)]
+    /// use std::collections::HashMap;
+    ///
+    /// # fn main() {
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.remove_entry(&1), Some((1, "a")));
+    /// assert_eq!(map.remove(&1), None);
+    /// # }
+    /// ```
+    #[unstable(feature = "hash_map_remove_entry", issue = "46344")]
+    pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>
+        where K: Borrow<Q>,
+              Q: Hash + Eq
+    {
+        if self.table.size() == 0 {
+            return None;
+        }
+
+        self.search_mut(k)
+            .into_occupied_bucket()
+            .map(|bucket| {
+                let (k, v, _) = pop_internal(bucket);
+                (k, v)
+            })
+    }
+
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all pairs `(k, v)` such that `f(&k,&mut v)` returns `false`.
@@ -3040,13 +3080,21 @@ fn test_is_empty() {
     }
 
     #[test]
-    fn test_pop() {
+    fn test_remove() {
         let mut m = HashMap::new();
         m.insert(1, 2);
         assert_eq!(m.remove(&1), Some(2));
         assert_eq!(m.remove(&1), None);
     }
 
+    #[test]
+    fn test_remove_entry() {
+        let mut m = HashMap::new();
+        m.insert(1, 2);
+        assert_eq!(m.remove_entry(&1), Some((1, 2)));
+        assert_eq!(m.remove(&1), None);
+    }
+
     #[test]
     fn test_iterate() {
         let mut m = HashMap::with_capacity(4);
index a75596351e4cf3ec073fa809c29847b2e179969e..a37a5e8ae820b90949aa81c3fe5daa3a2ea007c7 100644 (file)
@@ -53,7 +53,7 @@
 //! terminator, so the buffer length is really `len+1` characters.
 //! Rust strings don't have a nul terminator; their length is always
 //! stored and does not need to be calculated. While in Rust
-//! accessing a string's length is a O(1) operation (becasue the
+//! accessing a string's length is a O(1) operation (because the
 //! length is stored); in C it is an O(length) operation because the
 //! length needs to be computed by scanning the string for the nul
 //! terminator.
index 109173d31c501ee15bcd50cb0fb0127a8864caa5..3959e8533be5fb2534b60789a3b3fc9da66801fd 100644 (file)
@@ -36,7 +36,7 @@
 /// and platform-native string values, and in particular allowing a Rust string
 /// to be converted into an "OS" string with no cost if possible.
 ///
-/// `OsString` is to [`OsStr`] as [`String`] is to [`&str`]: the former
+/// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
 /// in each pair are owned strings; the latter are borrowed
 /// references.
 ///
@@ -64,6 +64,7 @@
 /// the traits which `OsString` implements for conversions from/to native representations.
 ///
 /// [`OsStr`]: struct.OsStr.html
+/// [`&OsStr`]: struct.OsStr.html
 /// [`From`]: ../convert/trait.From.html
 /// [`String`]: ../string/struct.String.html
 /// [`&str`]: ../primitive.str.html
@@ -84,13 +85,15 @@ pub struct OsString {
 /// This type represents a borrowed reference to a string in the operating system's preferred
 /// representation.
 ///
-/// `OsStr` is to [`OsString`] as [`String`] is to [`&str`]: the former in each pair are borrowed
+/// `&OsStr` is to [`OsString`] as [`&str`] is to [`String`]: the former in each pair are borrowed
 /// references; the latter are owned strings.
 ///
 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
 /// the traits which `OsStr` implements for conversions from/to native representations.
 ///
 /// [`OsString`]: struct.OsString.html
+/// [`&str`]: ../primitive.str.html
+/// [`String`]: ../string/struct.String.html
 /// [conversions]: index.html#conversions
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct OsStr {
index f40aed2478a17845c0920c9c55f3859b3f9f9fb1..51cb9609120e36a5657aa5aa1f75d15979e54de7 100644 (file)
@@ -211,6 +211,14 @@ pub struct DirBuilder {
     recursive: bool,
 }
 
+/// How large a buffer to pre-allocate before reading the entire file at `path`.
+fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize {
+    // Allocate one extra byte so the buffer doesn't need to grow before the
+    // final `read` call at the end of the file.  Don't worry about `usize`
+    // overflow because reading will fail regardless in that case.
+    metadata(path).map(|m| m.len() as usize + 1).unwrap_or(0)
+}
+
 /// Read the entire contents of a file into a bytes vector.
 ///
 /// This is a convenience function for using [`File::open`] and [`read_to_end`]
@@ -246,7 +254,7 @@ pub struct DirBuilder {
 /// ```
 #[unstable(feature = "fs_read_write", issue = "46588")]
 pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
-    let mut bytes = Vec::new();
+    let mut bytes = Vec::with_capacity(initial_buffer_size(&path));
     File::open(path)?.read_to_end(&mut bytes)?;
     Ok(bytes)
 }
@@ -287,7 +295,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
 /// ```
 #[unstable(feature = "fs_read_write", issue = "46588")]
 pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
-    let mut string = String::new();
+    let mut string = String::with_capacity(initial_buffer_size(&path));
     File::open(path)?.read_to_string(&mut string)?;
     Ok(string)
 }
index b5ea5531b65a72db087b4a306d4441ef2765119b..c8447707d5bafdbcb1d73d54927857d8c3977994 100644 (file)
@@ -252,14 +252,54 @@ fn fill_buf(&mut self) -> io::Result<&[u8]> {
     fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
 }
 
+// Non-resizing write implementation
+fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> {
+    let pos = cmp::min(*pos_mut, slice.len() as u64);
+    let amt = (&mut slice[(pos as usize)..]).write(buf)?;
+    *pos_mut += amt as u64;
+    Ok(amt)
+}
+
+// Resizing write implementation
+fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
+    let pos: usize = (*pos_mut).try_into().map_err(|_| {
+        Error::new(ErrorKind::InvalidInput,
+                    "cursor position exceeds maximum possible vector length")
+    })?;
+    // Make sure the internal buffer is as least as big as where we
+    // currently are
+    let len = vec.len();
+    if len < pos {
+        // use `resize` so that the zero filling is as efficient as possible
+        vec.resize(pos, 0);
+    }
+    // Figure out what bytes will be used to overwrite what's currently
+    // there (left), and what will be appended on the end (right)
+    {
+        let space = vec.len() - pos;
+        let (left, right) = buf.split_at(cmp::min(space, buf.len()));
+        vec[pos..pos + left.len()].copy_from_slice(left);
+        vec.extend_from_slice(right);
+    }
+
+    // Bump us forward
+    *pos_mut = (pos + buf.len()) as u64;
+    Ok(buf.len())
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for Cursor<&'a mut [u8]> {
     #[inline]
-    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-        let pos = cmp::min(self.pos, self.inner.len() as u64);
-        let amt = (&mut self.inner[(pos as usize)..]).write(data)?;
-        self.pos += amt as u64;
-        Ok(amt)
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        slice_write(&mut self.pos, self.inner, buf)
+    }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
+#[unstable(feature = "cursor_mut_vec", issue = "30132")]
+impl<'a> Write for Cursor<&'a mut Vec<u8>> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        vec_write(&mut self.pos, self.inner, buf)
     }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
@@ -267,29 +307,7 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Cursor<Vec<u8>> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        let pos: usize = self.position().try_into().map_err(|_| {
-            Error::new(ErrorKind::InvalidInput,
-                       "cursor position exceeds maximum possible vector length")
-        })?;
-        // Make sure the internal buffer is as least as big as where we
-        // currently are
-        let len = self.inner.len();
-        if len < pos {
-            // use `resize` so that the zero filling is as efficient as possible
-            self.inner.resize(pos, 0);
-        }
-        // Figure out what bytes will be used to overwrite what's currently
-        // there (left), and what will be appended on the end (right)
-        {
-            let space = self.inner.len() - pos;
-            let (left, right) = buf.split_at(cmp::min(space, buf.len()));
-            self.inner[pos..pos + left.len()].copy_from_slice(left);
-            self.inner.extend_from_slice(right);
-        }
-
-        // Bump us forward
-        self.set_position((pos + buf.len()) as u64);
-        Ok(buf.len())
+        vec_write(&mut self.pos, &mut self.inner, buf)
     }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
@@ -298,10 +316,7 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 impl Write for Cursor<Box<[u8]>> {
     #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        let pos = cmp::min(self.pos, self.inner.len() as u64);
-        let amt = (&mut self.inner[(pos as usize)..]).write(buf)?;
-        self.pos += amt as u64;
-        Ok(amt)
+        slice_write(&mut self.pos, &mut self.inner, buf)
     }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
@@ -331,6 +346,17 @@ fn test_mem_writer() {
         assert_eq!(&writer.get_ref()[..], b);
     }
 
+    #[test]
+    fn test_mem_mut_writer() {
+        let mut vec = Vec::new();
+        let mut writer = Cursor::new(&mut vec);
+        assert_eq!(writer.write(&[0]).unwrap(), 1);
+        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
+        assert_eq!(&writer.get_ref()[..], b);
+    }
+
     #[test]
     fn test_box_slice_writer() {
         let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
index ad9cf1eed7013374e669fd006584831af76af77a..33d11ebb35022b2ad411e2de6d76fc8ac9077900 100644 (file)
@@ -997,9 +997,9 @@ pub trait Write {
     ///
     /// Calls to `write` are not guaranteed to block waiting for data to be
     /// written, and a write which would otherwise block can be indicated through
-    /// an `Err` variant.
+    /// an [`Err`] variant.
     ///
-    /// If the return value is `Ok(n)` then it must be guaranteed that
+    /// If the return value is [`Ok(n)`] then it must be guaranteed that
     /// `0 <= n <= buf.len()`. A return value of `0` typically means that the
     /// underlying object is no longer able to accept bytes and will likely not
     /// be able to in the future as well, or that the buffer provided is empty.
@@ -1013,9 +1013,13 @@ pub trait Write {
     /// It is **not** considered an error if the entire buffer could not be
     /// written to this writer.
     ///
-    /// An error of the `ErrorKind::Interrupted` kind is non-fatal and the
+    /// An error of the [`ErrorKind::Interrupted`] kind is non-fatal and the
     /// write operation should be retried if there is nothing else to do.
     ///
+    /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+    /// [`Ok(n)`]:  ../../std/result/enum.Result.html#variant.Ok
+    /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
+    ///
     /// # Examples
     ///
     /// ```
@@ -1061,17 +1065,20 @@ pub trait Write {
 
     /// Attempts to write an entire buffer into this write.
     ///
-    /// This method will continuously call `write` until there is no more data
-    /// to be written or an error of non-`ErrorKind::Interrupted` kind is
+    /// This method will continuously call [`write`] until there is no more data
+    /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
     /// returned. This method will not return until the entire buffer has been
     /// successfully written or such an error occurs. The first error that is
-    /// not of `ErrorKind::Interrupted` kind generated from this method will be
+    /// not of [`ErrorKind::Interrupted`] kind generated from this method will be
     /// returned.
     ///
     /// # Errors
     ///
     /// This function will return the first error of
-    /// non-`ErrorKind::Interrupted` kind that `write` returns.
+    /// non-[`ErrorKind::Interrupted`] kind that [`write`] returns.
+    ///
+    /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
+    /// [`write`]: #tymethod.write
     ///
     /// # Examples
     ///
index 29ea87aaf786ac168b05397f8382b6d028113d03..28040bc20e2e02cc1a1d5b7a5077b1fcb6e6c704 100644 (file)
 
 // Turn warnings into errors, but only after stage0, where it can be useful for
 // code to emit warnings during language transitions
-#![deny(warnings)]
+#![cfg_attr(not(stage0), deny(warnings))]
 
 // std may use features in a platform-specific way
 #![allow(unused_features)]
 #![feature(rand)]
 #![feature(raw)]
 #![feature(repr_align)]
-#![feature(repr_simd)]
 #![feature(rustc_attrs)]
 #![feature(shared)]
 #![feature(sip_hash_13)]
index 9f3f0ea274217bd59342e48995c4db89ba515ded..f058b1caef509c87213e4d3215e6b0f632561b8f 100644 (file)
@@ -283,7 +283,7 @@ pub mod builtin {
     /// Unconditionally causes compilation to fail with the given error message when encountered.
     ///
     /// This macro should be used when a crate uses a conditional compilation strategy to provide
-    /// better error messages for errornous conditions.
+    /// better error messages for erroneous conditions.
     ///
     /// # Examples
     ///
index 80ce15944a5c374cdcb99322bc998ee2880a4f0c..f91eaf433d766de3de583b3b95d2cadb2c8ef362 100644 (file)
@@ -316,7 +316,6 @@ pub fn line(&self) -> u32 {
     /// # Examples
     ///
     /// ```should_panic
-    /// #![feature(panic_col)]
     /// use std::panic;
     ///
     /// panic::set_hook(Box::new(|panic_info| {
@@ -329,7 +328,7 @@ pub fn line(&self) -> u32 {
     ///
     /// panic!("Normal panic");
     /// ```
-    #[unstable(feature = "panic_col", reason = "recently added", issue = "42939")]
+    #[stable(feature = "panic_col", since = "1.25")]
     pub fn column(&self) -> u32 {
         self.col
     }
index bed9efcb8469d358ab33c5c4e01bfdbade037b48..7631a9a44bbe72f1b1c2b911a0638fbe554755ab 100644 (file)
@@ -576,6 +576,13 @@ fn as_ref(&self) -> &OsStr {
     }
 }
 
+#[stable(feature = "path_component_asref", since = "1.24.0")]
+impl<'a> AsRef<Path> for Component<'a> {
+    fn as_ref(&self) -> &Path {
+        self.as_os_str().as_ref()
+    }
+}
+
 /// An iterator over the [`Component`]s of a [`Path`].
 ///
 /// This `struct` is created by the [`components`] method on [`Path`].
@@ -1702,6 +1709,7 @@ pub fn to_string_lossy(&self) -> Cow<str> {
     /// let path_buf = Path::new("foo.txt").to_path_buf();
     /// assert_eq!(path_buf, std::path::PathBuf::from("foo.txt"));
     /// ```
+    #[rustc_conversion_suggestion]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_path_buf(&self) -> PathBuf {
         PathBuf::from(self.inner.to_os_string())
index 0f3f4e50f7e321ec2e59d60a9fc9903a873ce29d..2edf02efc477c2cf26a2b0a45c6f78d41528a785 100644 (file)
@@ -36,7 +36,7 @@
 /// required that `T` satisfies [`Send`] to be shared across threads and
 /// [`Sync`] to allow concurrent access through readers. The RAII guards
 /// returned from the locking methods implement [`Deref`][] (and [`DerefMut`]
-/// for the `write` methods) to allow access to the contained of the lock.
+/// for the `write` methods) to allow access to the content of the lock.
 ///
 /// # Poisoning
 ///
index b838dbafd6f0c368cdef871d3ffb1165ce99c135..ba3d6a2813a451a28573303ccbd08cfe625584db 100644 (file)
@@ -39,6 +39,7 @@
 const DEBUG: bool = false;
 
 pub mod args;
+#[cfg(feature = "backtrace")]
 pub mod backtrace;
 pub mod cmath;
 pub mod condvar;
index 6e0cccff0019317419d934cb9f450c6c796c8309..66b44f1402fc6989df09805b7153d0b95b2cb651 100644 (file)
 use libc::{wchar_t, size_t, c_void};
 use ptr;
 
-#[repr(simd)]
-#[repr(C)]
-#[cfg(target_arch = "x86_64")]
-struct u64x2(u64, u64);
-
 pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
 pub use self::EXCEPTION_DISPOSITION::*;
 
@@ -700,9 +695,8 @@ pub struct FLOATING_SAVE_AREA {
 }
 
 #[cfg(target_arch = "x86_64")]
-#[repr(C)]
+#[repr(C, align(16))]
 pub struct CONTEXT {
-    _align_hack: [u64x2; 0], // FIXME align on 16-byte
     pub P1Home: DWORDLONG,
     pub P2Home: DWORDLONG,
     pub P3Home: DWORDLONG,
@@ -760,17 +754,15 @@ pub struct CONTEXT {
 }
 
 #[cfg(target_arch = "x86_64")]
-#[repr(C)]
+#[repr(C, align(16))]
 pub struct M128A {
-    _align_hack: [u64x2; 0], // FIXME align on 16-byte
     pub Low:  c_ulonglong,
     pub High: c_longlong
 }
 
 #[cfg(target_arch = "x86_64")]
-#[repr(C)]
+#[repr(C, align(16))]
 pub struct FLOATING_SAVE_AREA {
-    _align_hack: [u64x2; 0], // FIXME align on 16-byte
     _Dummy: [u8; 512] // FIXME: Fill this out
 }
 
index 15ddb62bab5c8635c39e8932da0056fd6b9c9f23..cb5bfb9176ec74b6f22825f9620e840249da8836 100644 (file)
@@ -206,7 +206,7 @@ pub fn as_secs(&self) -> u64 { self.secs }
     ///
     /// let duration = Duration::from_millis(5432);
     /// assert_eq!(duration.as_secs(), 5);
-    /// assert_eq!(duration.subsec_nanos(), 432_000_000);
+    /// assert_eq!(duration.subsec_millis(), 432);
     /// ```
     #[unstable(feature = "duration_extras", issue = "46507")]
     #[inline]
@@ -226,7 +226,7 @@ pub fn subsec_millis(&self) -> u32 { self.nanos / NANOS_PER_MILLI }
     ///
     /// let duration = Duration::from_micros(1_234_567);
     /// assert_eq!(duration.as_secs(), 1);
-    /// assert_eq!(duration.subsec_nanos(), 234_567_000);
+    /// assert_eq!(duration.subsec_micros(), 234_567);
     /// ```
     #[unstable(feature = "duration_extras", issue = "46507")]
     #[inline]
index fb1f300f63cc320e469f8b8e6061219c99cbc43d..07631e0dcfc1bed04da447ea72915431fdf2d52f 100644 (file)
@@ -11,7 +11,7 @@ crate-type = ["dylib"]
 [dependencies]
 bitflags = "1.0"
 serialize = { path = "../libserialize" }
-log = "0.3"
+log = "0.4"
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
 rustc_errors = { path = "../librustc_errors" }
index 0b868b514fe960a09552365bb103ffb81dda6ca2..4291f811f3f74ba1e63b65e91bdbf0c9aaaa608a 100644 (file)
@@ -1008,8 +1008,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
                 if let Some(mi) = item.word() {
                     let word = &*mi.name().as_str();
                     let hint = match word {
-                        // Can't use "extern" because it's not a lexical identifier.
-                        "C" => Some(ReprExtern),
+                        "C" => Some(ReprC),
                         "packed" => Some(ReprPacked),
                         "simd" => Some(ReprSimd),
                         _ => match int_type_of_word(word) {
@@ -1080,7 +1079,7 @@ fn int_type_of_word(s: &str) -> Option<IntType> {
 #[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
 pub enum ReprAttr {
     ReprInt(IntType),
-    ReprExtern,
+    ReprC,
     ReprPacked,
     ReprSimd,
     ReprAlign(u32),
index d5dd22fb8ae73f95eba365f809d6bcb88ea60a33..b474a299058c6285e273d9b94cbb523dce5c501b 100644 (file)
@@ -449,6 +449,9 @@ pub fn new() -> Features {
 
     // Allows use of the :lifetime macro fragment specifier
     (active, macro_lifetime_matcher, "1.24.0", Some(46895)),
+
+    // `extern` in paths
+    (active, extern_in_paths, "1.23.0", Some(44660)),
 );
 
 declare_features! (
@@ -966,6 +969,13 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
                                       never be stable",
                                      cfg_fn!(rustc_attrs))),
 
+    // whitelists "identity-like" conversion methods to suggest on type mismatch
+    ("rustc_conversion_suggestion", Whitelisted, Gated(Stability::Unstable,
+                                                       "rustc_attrs",
+                                                       "this is an internal attribute that will \
+                                                        never be stable",
+                                                       cfg_fn!(rustc_attrs))),
+
     ("wasm_import_memory", Whitelisted, Gated(Stability::Unstable,
                                  "wasm_import_memory",
                                  "wasm_import_memory attribute is currently unstable",
@@ -1782,6 +1792,9 @@ fn visit_path(&mut self, path: &'a ast::Path, _id: NodeId) {
             if segment.identifier.name == keywords::Crate.name() {
                 gate_feature_post!(&self, crate_in_paths, segment.span,
                                    "`crate` in paths is experimental");
+            } else if segment.identifier.name == keywords::Extern.name() {
+                gate_feature_post!(&self, extern_in_paths, segment.span,
+                                   "`extern` in paths is experimental");
             }
         }
 
index 23449ee69abb3722ae4c553f5fe860201ed5a490..49362f077992145d08abde3248857ad56786b98d 100644 (file)
@@ -101,7 +101,7 @@ fn horizontal_trim(lines: Vec<String>) -> Vec<String> {
                     break;
                 }
             }
-            if i > line.len() {
+            if i >= line.len() {
                 can_trim = false;
             }
             if !can_trim {
index 812e3c4967a9de70183b6698a8a9ddd542144275..489e5e78cceafebe32c80f7962fa1fa6c8a990cd 100644 (file)
@@ -609,14 +609,21 @@ pub fn this_token_to_string(&self) -> String {
         Parser::token_to_string(&self.token)
     }
 
+    pub fn token_descr(&self) -> Option<&'static str> {
+        Some(match &self.token {
+            t if t.is_special_ident() => "reserved identifier",
+            t if t.is_used_keyword() => "keyword",
+            t if t.is_unused_keyword() => "reserved keyword",
+            _ => return None,
+        })
+    }
+
     pub fn this_token_descr(&self) -> String {
-        let prefix = match &self.token {
-            t if t.is_special_ident() => "reserved identifier ",
-            t if t.is_used_keyword() => "keyword ",
-            t if t.is_unused_keyword() => "reserved keyword ",
-            _ => "",
-        };
-        format!("{}`{}`", prefix, self.this_token_to_string())
+        if let Some(prefix) = self.token_descr() {
+            format!("{} `{}`", prefix, self.this_token_to_string())
+        } else {
+            format!("`{}`", self.this_token_to_string())
+        }
     }
 
     pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
@@ -752,11 +759,27 @@ fn interpolated_or_expr_span(&self,
     }
 
     pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
+        self.parse_ident_common(true)
+    }
+
+    fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
         match self.token {
             token::Ident(i) => {
                 if self.token.is_reserved_ident() {
-                    self.span_err(self.span, &format!("expected identifier, found {}",
-                                                      self.this_token_descr()));
+                    let mut err = self.struct_span_err(self.span,
+                                                       &format!("expected identifier, found {}",
+                                                                self.this_token_descr()));
+                    if let Some(token_descr) = self.token_descr() {
+                        err.span_label(self.span, format!("expected identifier, found {}",
+                                                          token_descr));
+                    } else {
+                        err.span_label(self.span, "expected identifier");
+                    }
+                    if recover {
+                        err.emit();
+                    } else {
+                        return Err(err);
+                    }
                 }
                 self.bump();
                 Ok(i)
@@ -767,6 +790,12 @@ pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
                     } else {
                         let mut err = self.fatal(&format!("expected identifier, found `{}`",
                                                           self.this_token_to_string()));
+                        if let Some(token_descr) = self.token_descr() {
+                            err.span_label(self.span, format!("expected identifier, found {}",
+                                                              token_descr));
+                        } else {
+                            err.span_label(self.span, "expected identifier");
+                        }
                         if self.token == token::Underscore {
                             err.note("`_` is a wildcard pattern, not an identifier");
                         }
@@ -1387,7 +1416,7 @@ fn parse_trait_item_(&mut self,
                 None
             };
             (ident, TraitItemKind::Const(ty, default), ast::Generics::default())
-        } else if self.token.is_path_start() {
+        } else if self.token.is_path_start() && !self.is_extern_non_path() {
             // trait item macro.
             // code copied from parse_macro_use_or_failure... abstraction!
             let prev_span = self.prev_span;
@@ -2058,7 +2087,7 @@ pub fn parse_field_name(&mut self) -> PResult<'a, Ident> {
             self.bump();
             Ok(Ident::with_empty_ctxt(name))
         } else {
-            self.parse_ident()
+            self.parse_ident_common(false)
         }
     }
 
@@ -2075,7 +2104,7 @@ pub fn parse_field(&mut self) -> PResult<'a, Field> {
             hi = self.prev_span;
             (fieldname, self.parse_expr()?, false)
         } else {
-            let fieldname = self.parse_ident()?;
+            let fieldname = self.parse_ident_common(false)?;
             hi = self.prev_span;
 
             // Mimic `x: x` for the `x` field shorthand.
@@ -2426,6 +2455,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
 
     fn parse_struct_expr(&mut self, lo: Span, pth: ast::Path, mut attrs: ThinVec<Attribute>)
                          -> PResult<'a, P<Expr>> {
+        let struct_sp = lo.to(self.prev_span);
         self.bump();
         let mut fields = Vec::new();
         let mut base = None;
@@ -2460,6 +2490,7 @@ fn parse_struct_expr(&mut self, lo: Span, pth: ast::Path, mut attrs: ThinVec<Att
             match self.parse_field() {
                 Ok(f) => fields.push(f),
                 Err(mut e) => {
+                    e.span_label(struct_sp, "while parsing this struct");
                     e.emit();
                     self.recover_stmt();
                     break;
@@ -3431,8 +3462,20 @@ fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
         let mut pats = Vec::new();
         loop {
             pats.push(self.parse_pat()?);
-            if self.check(&token::BinOp(token::Or)) { self.bump();}
-            else { return Ok(pats); }
+
+            if self.token == token::OrOr {
+                let mut err = self.struct_span_err(self.span,
+                                                   "unexpected token `||` after pattern");
+                err.span_suggestion(self.span,
+                                    "use a single `|` to specify multiple patterns",
+                                    "|".to_owned());
+                err.emit();
+                self.bump();
+            } else if self.check(&token::BinOp(token::Or)) {
+                self.bump();
+            } else {
+                return Ok(pats);
+            }
         };
     }
 
@@ -4037,6 +4080,10 @@ fn is_crate_vis(&self) -> bool {
         self.token.is_keyword(keywords::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
     }
 
+    fn is_extern_non_path(&self) -> bool {
+        self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
+    }
+
     fn eat_auto_trait(&mut self) -> bool {
         if self.token.is_keyword(keywords::Auto)
             && self.look_ahead(1, |t| t.is_keyword(keywords::Trait))
@@ -4152,10 +4199,12 @@ fn parse_stmt_without_recovery(&mut self,
         // like a path (1 token), but it fact not a path.
         // `union::b::c` - path, `union U { ... }` - not a path.
         // `crate::b::c` - path, `crate struct S;` - not a path.
+        // `extern::b::c` - path, `extern crate c;` - not a path.
         } else if self.token.is_path_start() &&
                   !self.token.is_qpath_start() &&
                   !self.is_union_item() &&
-                  !self.is_crate_vis() {
+                  !self.is_crate_vis() &&
+                  !self.is_extern_non_path() {
             let pth = self.parse_path(PathStyle::Expr)?;
 
             if !self.eat(&token::Not) {
@@ -5236,7 +5285,7 @@ fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
                          -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::Generics,
                              ast::ImplItemKind)> {
         // code copied from parse_macro_use_or_failure... abstraction!
-        if self.token.is_path_start() {
+        if self.token.is_path_start() && !self.is_extern_non_path() {
             // Method macro.
 
             let prev_span = self.prev_span;
@@ -5876,10 +5925,14 @@ fn submod_path(&mut self,
         if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
             return Ok(ModulePathSuccess {
                 directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
-                    Some("mod.rs") => DirectoryOwnership::Owned { relative: None },
-                    Some(_) => {
-                        DirectoryOwnership::Owned { relative: Some(id) }
-                    }
+                    // All `#[path]` files are treated as though they are a `mod.rs` file.
+                    // This means that `mod foo;` declarations inside `#[path]`-included
+                    // files are siblings,
+                    //
+                    // Note that this will produce weirdness when a file named `foo.rs` is
+                    // `#[path]` included and contains a `mod foo;` declaration.
+                    // If you encounter this, it's your own darn fault :P
+                    Some(_) => DirectoryOwnership::Owned { relative: None },
                     _ => DirectoryOwnership::UnownedViaMod(true),
                 },
                 path,
@@ -6238,7 +6291,8 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             return Ok(Some(item));
         }
 
-        if self.eat_keyword(keywords::Extern) {
+        if self.check_keyword(keywords::Extern) && self.is_extern_non_path() {
+            self.bump(); // `extern`
             if self.eat_keyword(keywords::Crate) {
                 return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?));
             }
index bd4f7f9853d768e1a67376626464e2990df89ac3..2be93c07d5ad771774fd5beaa727d9a284db04d1 100644 (file)
@@ -359,6 +359,7 @@ pub fn is_path_segment_keyword(&self) -> bool {
             Some(id) => id.name == keywords::Super.name() ||
                         id.name == keywords::SelfValue.name() ||
                         id.name == keywords::SelfType.name() ||
+                        id.name == keywords::Extern.name() ||
                         id.name == keywords::Crate.name() ||
                         id.name == keywords::DollarCrate.name(),
             None => false,
index 870f54e4396aff5d4224ded8629360d79e086f4b..ad04b6ab2b5599fbef1bea1f8ce8c5dffcb10cf0 100644 (file)
@@ -286,12 +286,12 @@ pub fn map<F: FnMut(TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
         TokenStream::concat(result)
     }
 
-    fn first_tree(&self) -> Option<TokenTree> {
+    fn first_tree_and_joint(&self) -> Option<(TokenTree, bool)> {
         match self.kind {
             TokenStreamKind::Empty => None,
-            TokenStreamKind::Tree(ref tree) |
-            TokenStreamKind::JointTree(ref tree) => Some(tree.clone()),
-            TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree(),
+            TokenStreamKind::Tree(ref tree) => Some((tree.clone(), false)),
+            TokenStreamKind::JointTree(ref tree) => Some((tree.clone(), true)),
+            TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree_and_joint(),
         }
     }
 
@@ -315,12 +315,18 @@ pub fn push<T: Into<TokenStream>>(&mut self, stream: T) {
         let stream = stream.into();
         let last_tree_if_joint = self.0.last().and_then(TokenStream::last_tree_if_joint);
         if let Some(TokenTree::Token(last_span, last_tok)) = last_tree_if_joint {
-            if let Some(TokenTree::Token(span, tok)) = stream.first_tree() {
+            if let Some((TokenTree::Token(span, tok), is_joint)) = stream.first_tree_and_joint() {
                 if let Some(glued_tok) = last_tok.glue(tok) {
                     let last_stream = self.0.pop().unwrap();
                     self.push_all_but_last_tree(&last_stream);
                     let glued_span = last_span.to(span);
-                    self.0.push(TokenTree::Token(glued_span, glued_tok).into());
+                    let glued_tt = TokenTree::Token(glued_span, glued_tok);
+                    let glued_tokenstream = if is_joint {
+                        glued_tt.joint()
+                    } else {
+                        glued_tt.into()
+                    };
+                    self.0.push(glued_tokenstream);
                     self.push_all_but_first_tree(&stream);
                     return
                 }
@@ -669,4 +675,16 @@ fn test_is_empty() {
         assert_eq!(test1.is_empty(), false);
         assert_eq!(test2.is_empty(), false);
     }
+
+    #[test]
+    fn test_dotdotdot() {
+        let mut builder = TokenStreamBuilder::new();
+        builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint());
+        builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint());
+        builder.push(TokenTree::Token(sp(2, 3), Token::Dot));
+        let stream = builder.build();
+        assert!(stream.eq_unspanned(&string_to_ts("...")));
+        assert_eq!(stream.trees().count(), 1);
+    }
+
 }
index 48872cb1313d727d0884303b80014c76927ff1cd..08a7f85d14b2f5be0b2b419825780bde38612a7e 100644 (file)
@@ -831,7 +831,7 @@ fn find_repr_type_name(diagnostic: &Handler, type_attrs: &[ast::Attribute]) -> &
         for r in &attr::find_repr_attrs(diagnostic, a) {
             repr_type_name = match *r {
                 attr::ReprPacked | attr::ReprSimd | attr::ReprAlign(_) => continue,
-                attr::ReprExtern => "i32",
+                attr::ReprC => "i32",
 
                 attr::ReprInt(attr::SignedInt(ast::IntTy::Isize)) => "isize",
                 attr::ReprInt(attr::SignedInt(ast::IntTy::I8)) => "i8",
index 06a9306501c04fa24e41d98647509d11c272ddda..b7fba9fe8dfb0671728f590523b9513e0f12d212 100644 (file)
@@ -188,6 +188,33 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
 
     /// Extend a syntax context with a given mark
     pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
+        if mark.kind() == MarkKind::Modern {
+            return self.apply_mark_internal(mark);
+        }
+
+        let call_site_ctxt =
+            mark.expn_info().map_or(SyntaxContext::empty(), |info| info.call_site.ctxt()).modern();
+        if call_site_ctxt == SyntaxContext::empty() {
+            return self.apply_mark_internal(mark);
+        }
+
+        // Otherwise, `mark` is a macros 1.0 definition and the call site is in a
+        // macros 2.0 expansion, i.e. a macros 1.0 invocation is in a macros 2.0 definition.
+        //
+        // In this case, the tokens from the macros 1.0 definition inherit the hygiene
+        // at their invocation. That is, we pretend that the macros 1.0 definition
+        // was defined at its invocation (i.e. inside the macros 2.0 definition)
+        // so that the macros 2.0 definition remains hygienic.
+        //
+        // See the example at `test/run-pass/hygiene/legacy_interaction.rs`.
+        let mut ctxt = call_site_ctxt;
+        for mark in self.marks() {
+            ctxt = ctxt.apply_mark_internal(mark);
+        }
+        ctxt.apply_mark_internal(mark)
+    }
+
+    fn apply_mark_internal(self, mark: Mark) -> SyntaxContext {
         HygieneData::with(|data| {
             let syntax_contexts = &mut data.syntax_contexts;
             let mut modern = syntax_contexts[self.0 as usize].modern;
@@ -222,6 +249,18 @@ pub fn remove_mark(&mut self) -> Mark {
         })
     }
 
+    pub fn marks(mut self) -> Vec<Mark> {
+        HygieneData::with(|data| {
+            let mut marks = Vec::new();
+            while self != SyntaxContext::empty() {
+                marks.push(data.syntax_contexts[self.0 as usize].outer_mark);
+                self = data.syntax_contexts[self.0 as usize].prev_ctxt;
+            }
+            marks.reverse();
+            marks
+        })
+    }
+
     /// Adjust this context for resolution in a scope created by the given expansion.
     /// For example, consider the following three resolutions of `f`:
     ///
index 76557982a0276797c0623f61ee27c55b13e5f706..f7880d3c4d854f7afaa8018a9b949e32003cbae6 100644 (file)
 
 #![feature(asm)]
 #![feature(fnbox)]
-#![cfg_attr(unix, feature(libc))]
+#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))]
 #![feature(set_stdio)]
 #![feature(panic_unwind)]
 #![feature(staged_api)]
 
 extern crate getopts;
 extern crate term;
-#[cfg(unix)]
+#[cfg(any(unix, target_os = "cloudabi"))]
 extern crate libc;
 extern crate panic_unwind;
 
@@ -1191,13 +1191,14 @@ fn num_cpus() -> usize {
         1
     }
 
-    #[cfg(any(target_os = "linux",
-              target_os = "macos",
-              target_os = "ios",
-              target_os = "android",
-              target_os = "solaris",
+    #[cfg(any(target_os = "android",
+              target_os = "cloudabi",
               target_os = "emscripten",
-              target_os = "fuchsia"))]
+              target_os = "fuchsia",
+              target_os = "ios",
+              target_os = "linux",
+              target_os = "macos",
+              target_os = "solaris"))]
     fn num_cpus() -> usize {
         unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }
     }
index 0fac7f7bf28b121d5cbdeead03aae6e6f65bb2a9..95130d596e165b05498143c96feb0805d7dc78ba 100644 (file)
@@ -384,12 +384,6 @@ LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
   return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
 }
 
-extern "C" void LLVMRustSetDebug(int Enabled) {
-#ifndef NDEBUG
-  DebugFlag = Enabled;
-#endif
-}
-
 enum class LLVMRustAsmDialect {
   Other,
   Att,
@@ -933,23 +927,6 @@ extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef DstRef, char *BC,
   return true;
 }
 
-extern "C" bool LLVMRustLinkInParsedExternalBitcode(
-    LLVMModuleRef DstRef, LLVMModuleRef SrcRef) {
-#if LLVM_VERSION_GE(4, 0)
-  Module *Dst = unwrap(DstRef);
-  std::unique_ptr<Module> Src(unwrap(SrcRef));
-
-  if (Linker::linkModules(*Dst, std::move(Src))) {
-    LLVMRustSetLastError("failed to link modules");
-    return false;
-  }
-  return true;
-#else
-  LLVMRustSetLastError("can't link parsed modules on this LLVM");
-  return false;
-#endif
-}
-
 // Note that the two following functions look quite similar to the
 // LLVMGetSectionName function. Sadly, it appears that this function only
 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
@@ -981,7 +958,6 @@ extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
 }
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
 
 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
   RawRustStringOstream OS(Str);
@@ -1130,13 +1106,6 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
   report_fatal_error("Unhandled TypeID.");
 }
 
-extern "C" void LLVMRustWriteDebugLocToString(LLVMContextRef C,
-                                              LLVMDebugLocRef DL,
-                                              RustStringRef Str) {
-  RawRustStringOstream OS(Str);
-  unwrap(DL)->print(OS);
-}
-
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
 
 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
index 714173f86020da25c53cc3648fa5adf075d35106..f4bd78147f6316ed0d0e4c6330c68b68291a5642 100644 (file)
@@ -103,9 +103,7 @@ enum LLVMRustAttribute {
 
 typedef struct OpaqueRustString *RustStringRef;
 typedef struct LLVMOpaqueTwine *LLVMTwineRef;
-typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;
 typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef;
-typedef struct LLVMOpaqueRustJITMemoryManager *LLVMRustJITMemoryManagerRef;
 
 extern "C" void LLVMRustStringWriteImpl(RustStringRef Str, const char *Ptr,
                                         size_t Size);
diff --git a/src/test/compile-fail/directory_ownership/backcompat-warnings.rs b/src/test/compile-fail/directory_ownership/backcompat-warnings.rs
deleted file mode 100644 (file)
index 2da07a2..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern: mod statements in non-mod.rs files are unstable
-
-#[path="mod_file_not_owning_aux3.rs"]
-mod foo;
-
-fn main() {}
index 018a40e28ef32bf90a18b242cf3cdc0648886f8b..9253a490733eda30bb133d682db36fb4ff1374ba 100644 (file)
@@ -13,7 +13,7 @@
 enum bird {
     pub duck,
     //~^ ERROR: expected identifier, found keyword `pub`
-    //~^^ ERROR: expected
+    //~| ERROR: expected
     goose
 }
 
diff --git a/src/test/compile-fail/issue-39687.rs b/src/test/compile-fail/issue-39687.rs
new file mode 100644 (file)
index 0000000..404465e
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(fn_traits)]
+
+fn main() {
+    <fn() as Fn()>::call;
+    //~^ ERROR associated type bindings are not allowed here [E0229]
+}
diff --git a/src/test/compile-fail/issue-43105.rs b/src/test/compile-fail/issue-43105.rs
new file mode 100644 (file)
index 0000000..fb419d7
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn xyz() -> u8 { 42 }
+
+const NUM: u8 = xyz();
+//~^ ERROR calls in constants are limited to constant functions, struct and enum constructors
+
+fn main() {
+    match 1 {
+        NUM => unimplemented!(),
+        _ => unimplemented!(),
+    }
+}
diff --git a/src/test/compile-fail/keyword-extern-as-identifier.rs b/src/test/compile-fail/keyword-extern-as-identifier.rs
new file mode 100644 (file)
index 0000000..e5927d0
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_in_paths)]
+
+fn main() {
+    let extern = 0; //~ ERROR expected unit struct/variant or constant, found module `extern`
+}
diff --git a/src/test/compile-fail/rfc-2126-extern-in-paths/auxiliary/xcrate.rs b/src/test/compile-fail/rfc-2126-extern-in-paths/auxiliary/xcrate.rs
new file mode 100644 (file)
index 0000000..c3da4a5
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[derive(Debug)]
+pub struct S;
+
+#[derive(Debug)]
+pub struct Z;
diff --git a/src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-1.rs b/src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-1.rs
new file mode 100644 (file)
index 0000000..7eba02e
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_in_paths)]
+
+use extern::xcrate::S; //~ ERROR can't find crate for `xcrate`
+
+fn main() {}
diff --git a/src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-2.rs b/src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-2.rs
new file mode 100644 (file)
index 0000000..4d09a05
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_in_paths)]
+
+fn main() {
+    let s = extern::xcrate::S; //~ ERROR can't find crate for `xcrate`
+}
diff --git a/src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-3.rs b/src/test/compile-fail/rfc-2126-extern-in-paths/non-existent-3.rs
new file mode 100644 (file)
index 0000000..402d294
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_in_paths)]
+
+use extern::ycrate; //~ ERROR can't find crate for `ycrate`
+
+fn main() {}
diff --git a/src/test/compile-fail/rfc-2126-extern-in-paths/single-segment.rs b/src/test/compile-fail/rfc-2126-extern-in-paths/single-segment.rs
new file mode 100644 (file)
index 0000000..ebc42aa
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:xcrate.rs
+
+#![feature(extern_in_paths)]
+
+use extern; //~ ERROR unresolved import `extern`
+            //~^ NOTE no `extern` in the root
+use extern::*; //~ ERROR unresolved import `extern::*`
+               //~^ NOTE cannot glob-import all possible crates
+
+fn main() {
+    let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate`
+                            //~^ NOTE not a value
+}
index c96cadece97a5bc50c115d7672f6db6fcf976014..e22eb7e4484d6f58fdf6b1b8d9ba84e3e3f6f10c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(const_fn)]
+
 struct WithDtor;
 
 impl Drop for WithDtor {
@@ -28,4 +30,12 @@ fn drop(&mut self) {}
 const EARLY_DROP_C: i32 = (WithDtor, 0).1;
 //~^ ERROR destructors cannot be evaluated at compile-time
 
+const fn const_drop<T>(_: T) {}
+//~^ ERROR destructors cannot be evaluated at compile-time
+
+const fn const_drop2<T>(x: T) {
+    (x, ()).1
+    //~^ ERROR destructors cannot be evaluated at compile-time
+}
+
 fn main () {}
index 10df093423cf088d0892504184cf7d9240fb3669..f29c1fa27940071dff6f6e2677ddbf0ce1ad5ae4 100644 (file)
@@ -18,4 +18,5 @@ fn main() {
     let mut _b = 0;
     let mut _ = 0; //~ ERROR expected identifier, found `_`
     //~^ NOTE `_` is a wildcard pattern, not an identifier
+    //~| NOTE expected identifier
 }
diff --git a/src/test/parse-fail/keyword-extern-as-identifier.rs b/src/test/parse-fail/keyword-extern-as-identifier.rs
deleted file mode 100644 (file)
index 3bbe24e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -Z parse-only
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py extern'
-
-fn main() {
-    let extern = "foo"; //~ error: expected pattern, found keyword `extern`
-}
index 76d4b133defe2f4c84e31f84d69484315ff15552..5f1577ab44dc52c0d57bbc8934035b509b0a6162 100644 (file)
@@ -2,15 +2,16 @@
 
 # Make sure we don't ICE if the linker prints a non-UTF-8 error message.
 
-ifdef IS_WINDOWS
-# ignore windows
+# Ignore Windows and Apple
 
 # This does not work in its current form on windows, possibly due to
 # gcc bugs or something about valid Windows paths.  See issue #29151
 # for more information.
-all:
+ifndef IS_WINDOWS
 
-else
+# This also does not work on Apple APFS due to the filesystem requiring
+# valid UTF-8 paths.
+ifneq ($(shell uname),Darwin)
 
 # The zzz it to allow humans to tab complete or glob this thing.
 bad_dir := $(TMPDIR)/zzz$$'\xff'
@@ -20,5 +21,12 @@ all:
        mkdir $(bad_dir)
        mv $(TMPDIR)/liblibrary.a $(bad_dir)
        LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined
+else
+all:
+
+endif
+
+else
+all:
 
 endif
diff --git a/src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs b/src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs
new file mode 100644 (file)
index 0000000..c614ee4
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty pretty-printing is unhygienic
+
+#[macro_export]
+macro_rules! m {
+    () => {
+        fn f() {} // (2)
+        g(); // (1)
+    }
+}
diff --git a/src/test/run-pass/hygiene/auxiliary/my_crate.rs b/src/test/run-pass/hygiene/auxiliary/my_crate.rs
new file mode 100644 (file)
index 0000000..e10d20b
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn f() {}
diff --git a/src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs b/src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs
new file mode 100644 (file)
index 0000000..298e020
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+
+extern crate my_crate;
+
+pub fn g() {} // (a)
+
+#[macro_export]
+macro_rules! unhygienic_macro {
+    () => {
+        // (1) unhygienic: depends on `my_crate` in the crate root at the invocation site.
+        ::my_crate::f();
+
+        // (2) unhygienic: defines `f` at the invocation site (in addition to the above point).
+        use my_crate::f;
+        f();
+
+        g(); // (3) unhygienic: `g` needs to be in scope at use site.
+
+        $crate::g(); // (4) hygienic: this always resolves to (a)
+    }
+}
+
+#[allow(unused)]
+fn test_unhygienic() {
+    unhygienic_macro!();
+    f(); // `f` was defined at the use site
+}
diff --git a/src/test/run-pass/hygiene/legacy_interaction.rs b/src/test/run-pass/hygiene/legacy_interaction.rs
new file mode 100644 (file)
index 0000000..683a15b
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty pretty-printing is unhygienic
+
+// aux-build:legacy_interaction.rs
+
+#![feature(decl_macro)]
+#[allow(unused)]
+
+extern crate legacy_interaction;
+// ^ defines
+// ```rust
+//  macro_rules! m {
+//     () => {
+//         fn f() // (1)
+//         g() // (2)
+//     }
+// }
+// ```rust
+
+mod def_site {
+    // Unless this macro opts out of hygiene, it should resolve the same wherever it is invoked.
+    pub macro m2() {
+        ::legacy_interaction::m!();
+        f(); // This should resolve to (1)
+        fn g() {} // We want (2) resolve to this, not to (4)
+    }
+}
+
+mod use_site {
+    fn test() {
+        fn f() -> bool { true } // (3)
+        fn g() -> bool { true } // (4)
+
+        ::def_site::m2!();
+
+        let _: bool = f(); // This should resolve to (3)
+        let _: bool = g(); // This should resolve to (4)
+    }
+}
+
+fn main() {}
diff --git a/src/test/run-pass/hygiene/wrap_unhygienic_example.rs b/src/test/run-pass/hygiene/wrap_unhygienic_example.rs
new file mode 100644 (file)
index 0000000..5520695
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty pretty-printing is unhygienic
+
+// aux-build:my_crate.rs
+// aux-build:unhygienic_example.rs
+
+#![feature(decl_macro)]
+
+extern crate unhygienic_example;
+extern crate my_crate; // (b)
+
+// Hygienic version of `unhygienic_macro`.
+pub macro hygienic_macro() {
+    fn g() {} // (c)
+    ::unhygienic_example::unhygienic_macro!();
+    // ^ Even though we invoke an unhygienic macro, `hygienic_macro` remains hygienic.
+    // In the above expansion:
+    // (1) `my_crate` always resolves to (b) regardless of invocation site.
+    // (2) The defined function `f` is only usable inside this macro definition.
+    // (3) `g` always resolves to (c) regardless of invocation site.
+    // (4) `$crate::g` remains hygienic and continues to resolve to (a).
+
+    f();
+}
+
+#[allow(unused)]
+fn test_hygienic_macro() {
+    hygienic_macro!();
+
+    fn f() {} // (d) no conflict
+    f(); // resolves to (d)
+}
+
+fn main() {}
index 8d035bafab78d6df6bf4184f0a0b213df76782fc..aca100591ddeca54a0fce560cdaa95c8f9ddeae0 100644 (file)
@@ -15,7 +15,9 @@
            universal_impl_trait,
            fn_traits,
            step_trait,
-           unboxed_closures
+           unboxed_closures,
+           copy_closures,
+           clone_closures
 )]
 
 //! Derived from: <https://raw.githubusercontent.com/quickfur/dcal/master/dcal.d>.
@@ -234,42 +236,6 @@ pub fn num_days_from_sunday(&self) -> u32 {
     }
 }
 
-/// Wrapper for zero-sized closures.
-// HACK(eddyb) Only needed because closures can't implement Copy.
-struct Fn0<F>(std::marker::PhantomData<F>);
-
-impl<F> Copy for Fn0<F> {}
-impl<F> Clone for Fn0<F> {
-    fn clone(&self) -> Self { *self }
-}
-
-impl<F: FnOnce<A>, A> FnOnce<A> for Fn0<F> {
-    type Output = F::Output;
-
-    extern "rust-call" fn call_once(self, args: A) -> Self::Output {
-        let f = unsafe { std::mem::uninitialized::<F>() };
-        f.call_once(args)
-    }
-}
-
-impl<F: FnMut<A>, A> FnMut<A> for Fn0<F> {
-    extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output {
-        let mut f = unsafe { std::mem::uninitialized::<F>() };
-        f.call_mut(args)
-    }
-}
-
-trait AsFn0<A>: Sized {
-    fn copyable(self) -> Fn0<Self>;
-}
-
-impl<F: FnMut<A>, A> AsFn0<A> for F {
-    fn copyable(self) -> Fn0<Self> {
-        assert_eq!(std::mem::size_of::<F>(), 0);
-        Fn0(std::marker::PhantomData)
-    }
-}
-
 /// GroupBy implementation.
 struct GroupBy<It: Iterator, F> {
     it: std::iter::Peekable<It>,
@@ -277,11 +243,15 @@ struct GroupBy<It: Iterator, F> {
 }
 
 impl<It, F> Clone for GroupBy<It, F>
-where It: Iterator + Clone, It::Item: Clone, F: Clone {
-    fn clone(&self) -> GroupBy<It, F> {
+where
+    It: Iterator + Clone,
+    It::Item: Clone,
+    F: Clone,
+{
+    fn clone(&self) -> Self {
         GroupBy {
             it: self.it.clone(),
-            f: self.f.clone()
+            f: self.f.clone(),
         }
     }
 }
@@ -331,14 +301,11 @@ fn next(&mut self) -> Option<It::Item> {
 }
 
 trait IteratorExt: Iterator + Sized {
-    fn group_by<G, F>(self, f: F) -> GroupBy<Self, Fn0<F>>
-    where F: FnMut(&Self::Item) -> G,
+    fn group_by<G, F>(self, f: F) -> GroupBy<Self, F>
+    where F: Clone + FnMut(&Self::Item) -> G,
           G: Eq
     {
-        GroupBy {
-            it: self.peekable(),
-            f: f.copyable(),
-        }
+        GroupBy { it: self.peekable(), f }
     }
 
     fn join(mut self, sep: &str) -> String
@@ -382,7 +349,7 @@ fn test_spaces() {
 fn dates_in_year(year: i32) -> impl Iterator<Item=NaiveDate>+Clone {
     InGroup {
         it: NaiveDate::from_ymd(year, 1, 1)..,
-        f: (|d: &NaiveDate| d.year()).copyable(),
+        f: |d: &NaiveDate| d.year(),
         g: year
     }
 }
diff --git a/src/test/run-pass/issue-33903.rs b/src/test/run-pass/issue-33903.rs
new file mode 100644 (file)
index 0000000..ab36853
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Issue 33903:
+// Built-in indexing should be used even when the index is not
+// trivially an integer
+// Only built-in indexing can be used in constant expresssions
+
+const FOO: i32 = [12, 34][0 + 1];
+
+fn main() {}
+
diff --git a/src/test/run-pass/issue-36792.rs b/src/test/run-pass/issue-36792.rs
new file mode 100644 (file)
index 0000000..faf983f
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(conservative_impl_trait)]
+fn foo() -> impl Copy {
+    foo
+}
+fn main() {
+    foo();
+}
diff --git a/src/test/run-pass/issue-38091.rs b/src/test/run-pass/issue-38091.rs
new file mode 100644 (file)
index 0000000..3405024
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(specialization)]
+
+trait Iterate<'a> {
+    type Ty: Valid;
+    fn iterate(self);
+}
+impl<'a, T> Iterate<'a> for T where T: Check {
+    default type Ty = ();
+    default fn iterate(self) {}
+}
+
+trait Check {}
+impl<'a, T> Check for T where <T as Iterate<'a>>::Ty: Valid {}
+
+trait Valid {}
+
+fn main() {
+    Iterate::iterate(0);
+}
diff --git a/src/test/run-pass/issue-42148.rs b/src/test/run-pass/issue-42148.rs
new file mode 100644 (file)
index 0000000..0196649
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Zst;
+
+fn main() {
+    unsafe { ::std::ptr::write_volatile(1 as *mut Zst, Zst) }
+}
diff --git a/src/test/run-pass/issue-42956.rs b/src/test/run-pass/issue-42956.rs
new file mode 100644 (file)
index 0000000..9bda6ee
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_consts)]
+
+impl A for i32 {
+    type Foo = u32;
+}
+impl B for u32 {
+    const BAR: i32 = 0;
+}
+
+trait A {
+    type Foo: B;
+}
+
+trait B {
+    const BAR: i32;
+}
+
+fn generic<T: A>() {
+    // This panics if the universal function call syntax is used as well
+    println!("{}", T::Foo::BAR);
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-46095.rs b/src/test/run-pass/issue-46095.rs
new file mode 100644 (file)
index 0000000..35e51eb
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct A;
+
+impl A {
+    fn take_mutably(&mut self) {}
+}
+
+fn identity<T>(t: T) -> T {
+    t
+}
+
+// Issue 46095
+// Built-in indexing should be used even when the index is not
+// trivially an integer
+// Overloaded indexing would cause wrapped to be borrowed mutably
+
+fn main() {
+    let mut a1 = A;
+    let mut a2 = A;
+
+    let wrapped = [&mut a1, &mut a2];
+
+    {
+        wrapped[0 + 1 - 1].take_mutably();
+    }
+
+    {
+        wrapped[identity(0)].take_mutably();
+    }
+}
diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs
deleted file mode 100644 (file)
index b61667c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub fn foo() {}
diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs
deleted file mode 100644 (file)
index 77cab97..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub mod innest;
diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs
new file mode 100644 (file)
index 0000000..b61667c
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() {}
diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs
new file mode 100644 (file)
index 0000000..77cab97
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod innest;
diff --git a/src/test/run-pass/rfc-2126-extern-absolute-paths/extern.rs b/src/test/run-pass/rfc-2126-extern-absolute-paths/extern.rs
new file mode 100644 (file)
index 0000000..52b52b2
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:xcrate.rs
+
+#![feature(extern_in_paths)]
+
+use extern::xcrate::Z;
+
+fn f() {
+    use extern::xcrate;
+    use extern::xcrate as ycrate;
+    let s = xcrate::S;
+    assert_eq!(format!("{:?}", s), "S");
+    let z = ycrate::Z;
+    assert_eq!(format!("{:?}", z), "Z");
+}
+
+fn main() {
+    let s = extern::xcrate::S;
+    assert_eq!(format!("{:?}", s), "S");
+    let z = Z;
+    assert_eq!(format!("{:?}", z), "Z");
+}
index 96bd9d7dc3cc539644947f187662535db5937c07..a5e343ade38637da0d5dc82176bc7bf169464a10 100644 (file)
@@ -22,3 +22,8 @@ impl SomeTrait for usize {}
 impl SomeTrait for SomeStruct {
     // deliberately multi-line impl
 }
+
+pub trait AnotherTrait {}
+
+// @has foo/trait.AnotherTrait.html '//a/@href' '../src/foo/issue-43893.rs.html#29'
+impl<T> AnotherTrait for T {}
diff --git a/src/test/rustdoc/issue-47038.rs b/src/test/rustdoc/issue-47038.rs
new file mode 100644 (file)
index 0000000..453cd66
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(decl_macro)]
+
+#![crate_name = "foo"]
+
+use std::vec;
+
+// @has 'foo/index.html'
+// @!has - '//*[@id="macros"]' 'Macros'
+// @!has - '//a/@href' 'macro.vec.html'
+// @!has 'foo/macro.vec.html'
diff --git a/src/test/rustdoc/issue-47197-blank-line-in-doc-block.rs b/src/test/rustdoc/issue-47197-blank-line-in-doc-block.rs
new file mode 100644 (file)
index 0000000..8c4d984
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// @has issue_47197_blank_line_in_doc_block/fn.whose_woods_these_are_i_think_i_know.html
+
+/**
+* snow
+
+* ice
+*/
+pub fn whose_woods_these_are_i_think_i_know() {}
index 98ec3d9693fb8488f63381e9c4399dabff217d5c..4c2896e220735e12dad0291414fc8814e1e5f1c3 100644 (file)
@@ -2,16 +2,13 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:18:9
    |
 18 |     foo(s); //~ ERROR mismatched types
-   |         ^ expected struct `std::string::String`, found reference
+   |         ^
+   |         |
+   |         expected struct `std::string::String`, found reference
+   |         help: try using a conversion method: `s.to_string()`
    |
    = note: expected type `std::string::String`
               found type `&std::string::String`
-   = help: here are some functions which might fulfill your needs:
-           - .escape_debug()
-           - .escape_default()
-           - .escape_unicode()
-           - .to_ascii_lowercase()
-           - .to_ascii_uppercase()
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:23:10
diff --git a/src/test/ui/did_you_mean/multiple-pattern-typo.rs b/src/test/ui/did_you_mean/multiple-pattern-typo.rs
new file mode 100644 (file)
index 0000000..a8994fd
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let x = 3;
+    match x {
+        1 | 2 || 3 => (), //~ ERROR unexpected token `||` after pattern
+        _ => (),
+    }
+}
diff --git a/src/test/ui/did_you_mean/multiple-pattern-typo.stderr b/src/test/ui/did_you_mean/multiple-pattern-typo.stderr
new file mode 100644 (file)
index 0000000..a35aa6f
--- /dev/null
@@ -0,0 +1,8 @@
+error: unexpected token `||` after pattern
+  --> $DIR/multiple-pattern-typo.rs:14:15
+   |
+14 |         1 | 2 || 3 => (), //~ ERROR unexpected token `||` after pattern
+   |               ^^ help: use a single `|` to specify multiple patterns: `|`
+
+error: aborting due to previous error
+
index 951b0b10580609649035ba3ef29c5ae2b07fec9d..860c6bb5b909f821ec296b897c050d8d2fc48759 100644 (file)
@@ -4,11 +4,11 @@ error[E0055]: reached the recursion limit while auto-dereferencing I
 62 |     let x: &Bottom = &t; //~ ERROR mismatched types
    |                      ^^ deref recursion limit reached
    |
-   = help: consider adding a `#[recursion_limit="20"]` attribute to your crate
+   = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
 
 error[E0055]: reached the recursion limit while auto-dereferencing I
   |
-  = help: consider adding a `#[recursion_limit="20"]` attribute to your crate
+  = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
 
 error[E0308]: mismatched types
   --> $DIR/recursion_limit_deref.rs:62:22
diff --git a/src/test/ui/feature-gate-extern_in_paths.rs b/src/test/ui/feature-gate-extern_in_paths.rs
new file mode 100644 (file)
index 0000000..3c01fcf
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct S;
+
+fn main() {
+    let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental
+}
diff --git a/src/test/ui/feature-gate-extern_in_paths.stderr b/src/test/ui/feature-gate-extern_in_paths.stderr
new file mode 100644 (file)
index 0000000..ac68e79
--- /dev/null
@@ -0,0 +1,10 @@
+error: `extern` in paths is experimental (see issue #44660)
+  --> $DIR/feature-gate-extern_in_paths.rs:14:13
+   |
+14 |     let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental
+   |             ^^^^^^
+   |
+   = help: add #![feature(extern_in_paths)] to the crate attributes to enable
+
+error: aborting due to previous error
+
index f38c682d31974c4bc8ca1640967ae43453eff0fd..a4e92820e21e518fb377afb1809b3c62c476da44 100644 (file)
@@ -17,7 +17,7 @@
 impl issue_41652_b::Tr for S {
     fn f() {
         3.f()
-        //~^ ERROR no method named `f` found for type `{integer}` in the current scope
+        //~^ ERROR can't call method `f` on ambiguous numeric type `{integer}`
     }
 }
 
index 5d1436979082379bc4a2453bf36a76cdba05df96..373dff27f2e413694bc682684bcd0a07da5f33a1 100644 (file)
@@ -1,18 +1,12 @@
-error[E0599]: no method named `f` found for type `{integer}` in the current scope
+error[E0689]: can't call method `f` on ambiguous numeric type `{integer}`
   --> $DIR/issue_41652.rs:19:11
    |
 19 |         3.f()
    |           ^
+help: you must specify a concrete type for this numeric value, like `i32`
    |
-   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-   = help: try with `{integer}::f`
-note: candidate #1 is defined in the trait `issue_41652_b::Tr`
-  --> $DIR/auxiliary/issue_41652_b.rs:14:5
-   |
-14 | /     fn f()
-15 | |         where Self: Sized;
-   | |__________________________^
-   = help: to disambiguate the method call, write `issue_41652_b::Tr::f(3)` instead
+19 |         3_i32.f()
+   |         ^^^^^
 
 error: aborting due to previous error
 
index dd6435a954eee7c9c1366b27099216f3afb1179e..32deabd0229d895d72d0378c4f8659bb851931cb 100644 (file)
@@ -2,7 +2,7 @@ error: expected identifier, found keyword `true`
   --> $DIR/issue-44406.rs:18:10
    |
 18 |     foo!(true); //~ ERROR expected type, found keyword
-   |          ^^^^
+   |          ^^^^ expected identifier, found keyword
 
 error: expected type, found keyword `true`
   --> $DIR/issue-44406.rs:18:10
index 037f0d839e2b689aab689bcb8fb2598ceefb5bf4..58a30e86f222bd288b0f6ca5f0f73a8eadb11287 100644 (file)
@@ -46,12 +46,26 @@ macro_rules! fake_anon_field_expr {
      }
 }
 
+macro_rules! real_method_stmt {
+     () => {
+          2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+     }
+}
+
+macro_rules! real_method_expr {
+     () => {
+          2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+     }
+}
+
 fn main() {
     fake_method_stmt!();
     fake_field_stmt!();
     fake_anon_field_stmt!();
+    real_method_stmt!();
 
     let _ = fake_method_expr!();
     let _ = fake_field_expr!();
     let _ = fake_anon_field_expr!();
+    let _ = real_method_expr!();
 }
index 42144f63c371021e6d869629c337599f65073eda..b9cad7e113dbf90aa10a4195dc0099a2a8182004 100644 (file)
@@ -4,7 +4,7 @@ error[E0599]: no method named `fake` found for type `{integer}` in the current s
 15 |           1.fake() //~ ERROR no method
    |             ^^^^
 ...
-50 |     fake_method_stmt!();
+62 |     fake_method_stmt!();
    |     -------------------- in this macro invocation
 
 error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
@@ -13,7 +13,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 21 |           1.fake //~ ERROR doesn't have fields
    |             ^^^^
 ...
-51 |     fake_field_stmt!();
+63 |     fake_field_stmt!();
    |     ------------------- in this macro invocation
 
 error[E0609]: no field `0` on type `{integer}`
@@ -22,16 +22,29 @@ error[E0609]: no field `0` on type `{integer}`
 27 |           (1).0 //~ ERROR no field
    |           ^^^^^
 ...
-52 |     fake_anon_field_stmt!();
+64 |     fake_anon_field_stmt!();
    |     ------------------------ in this macro invocation
 
+error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+  --> $DIR/macro-backtrace-invalid-internals.rs:51:15
+   |
+51 |           2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+   |               ^^^^
+...
+65 |     real_method_stmt!();
+   |     -------------------- in this macro invocation
+help: you must specify a concrete type for this numeric value, like `f32`
+   |
+51 |           2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+   |           ^^^^^^^
+
 error[E0599]: no method named `fake` found for type `{integer}` in the current scope
   --> $DIR/macro-backtrace-invalid-internals.rs:33:13
    |
 33 |           1.fake() //~ ERROR no method
    |             ^^^^
 ...
-54 |     let _ = fake_method_expr!();
+67 |     let _ = fake_method_expr!();
    |             ------------------- in this macro invocation
 
 error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
@@ -40,7 +53,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 39 |           1.fake //~ ERROR doesn't have fields
    |             ^^^^
 ...
-55 |     let _ = fake_field_expr!();
+68 |     let _ = fake_field_expr!();
    |             ------------------ in this macro invocation
 
 error[E0609]: no field `0` on type `{integer}`
@@ -49,8 +62,21 @@ error[E0609]: no field `0` on type `{integer}`
 45 |           (1).0 //~ ERROR no field
    |           ^^^^^
 ...
-56 |     let _ = fake_anon_field_expr!();
+69 |     let _ = fake_anon_field_expr!();
    |             ----------------------- in this macro invocation
 
-error: aborting due to 6 previous errors
+error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+  --> $DIR/macro-backtrace-invalid-internals.rs:57:15
+   |
+57 |           2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+   |               ^^^^
+...
+70 |     let _ = real_method_expr!();
+   |             ------------------- in this macro invocation
+help: you must specify a concrete type for this numeric value, like `f32`
+   |
+57 |           2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+   |           ^^^^^^^
+
+error: aborting due to 8 previous errors
 
index b4b524786cd7ce01eb8827d1a64a3ba2d134376e..95a2539ed646d1128de79316d0877e4b0922c131 100644 (file)
@@ -34,14 +34,5 @@ error: mod statements in non-mod.rs files are unstable (see issue #44660)
    = help: add #![feature(non_modrs_mods)] to the crate attributes to enable
    = help: on stable builds, rename this file to inner_foors_mod/mod.rs
 
-error: mod statements in non-mod.rs files are unstable (see issue #44660)
-  --> $DIR/some_crazy_attr_mod_dir/arbitrary_name.rs:11:9
-   |
-11 | pub mod inner_modrs_mod;
-   |         ^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(non_modrs_mods)] to the crate attributes to enable
-   = help: on stable builds, rename this file to attr_mod/mod.rs
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs
deleted file mode 100644 (file)
index b61667c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub fn foo() {}
diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs
deleted file mode 100644 (file)
index 77cab97..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub mod innest;
diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs
new file mode 100644 (file)
index 0000000..b61667c
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() {}
diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs
new file mode 100644 (file)
index 0000000..77cab97
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod innest;
index cbf206e6aed5d0529d7930aa924534e0cc887d6a..1bdb47d97d27936c92f585e4ec1f3857e1341b6b 100644 (file)
@@ -2,7 +2,7 @@ error: expected identifier, found `(`
   --> $DIR/pub-restricted-error.rs:16:16
    |
 16 |     pub(crate) () foo: usize, //~ ERROR expected identifier
-   |                ^
+   |                ^ expected identifier
 
 error: aborting due to previous error
 
index b76e87840c6dead09b9c0a537ce07d7755d523a8..e5b13218de1b45b44eb8f2e0a025c8b5fe24e897 100644 (file)
@@ -2,7 +2,7 @@ error: expected identifier, found `.`
   --> $DIR/pub-restricted-non-path.rs:13:6
    |
 13 | pub (.) fn afn() {} //~ ERROR expected identifier
-   |      ^
+   |      ^ expected identifier
 
 error: aborting due to previous error
 
index 078526197656c19012624a1b02200fa1cabe92ce..06f0e6ec228f20489d71f4ab4e1a9b691ad3d8a6 100644 (file)
@@ -6,9 +6,6 @@ error[E0308]: mismatched types
    |
    = note: expected type `usize`
               found type `std::string::String`
-   = help: here are some functions which might fulfill your needs:
-           - .capacity()
-           - .len()
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:19:19
@@ -44,7 +41,10 @@ error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:27:9
    |
 27 |     f = box f;
-   |         ^^^^^ cyclic type of infinite size
+   |         ^^^^^
+   |         |
+   |         cyclic type of infinite size
+   |         help: try using a conversion method: `box f.to_string()`
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:31:9
index 3794d6ba2ded98735d20c1a98c64c7f328f58e89..18860a7456eacb52a4e43f8d47953cdb28cc5848 100644 (file)
@@ -33,8 +33,6 @@ error[E0308]: mismatched types
    |
    = note: expected type `usize`
               found type `&'static str`
-   = help: here are some functions which might fulfill your needs:
-           - .len()
 
 error[E0061]: this function takes 2 parameters but 3 parameters were supplied
   --> $DIR/issue-34264.rs:20:5
diff --git a/src/test/ui/suggestions/conversion-methods.rs b/src/test/ui/suggestions/conversion-methods.rs
new file mode 100644 (file)
index 0000000..8a53bc3
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::path::{Path, PathBuf};
+
+
+fn main() {
+    let _tis_an_instants_play: String = "'Tis a fond Ambush—"; //~ ERROR mismatched types
+    let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
+    //~^ ERROR mismatched types
+
+    let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here
+    //~^ ERROR mismatched types
+
+    let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/conversion-methods.stderr b/src/test/ui/suggestions/conversion-methods.stderr
new file mode 100644 (file)
index 0000000..96fdc29
--- /dev/null
@@ -0,0 +1,50 @@
+error[E0308]: mismatched types
+  --> $DIR/conversion-methods.rs:15:41
+   |
+15 |     let _tis_an_instants_play: String = "'Tis a fond Ambush—"; //~ ERROR mismatched types
+   |                                         ^^^^^^^^^^^^^^^^^^^^^
+   |                                         |
+   |                                         expected struct `std::string::String`, found reference
+   |                                         help: try using a conversion method: `"'Tis a fond Ambush—".to_string()`
+   |
+   = note: expected type `std::string::String`
+              found type `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/conversion-methods.rs:16:40
+   |
+16 |     let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                        |
+   |                                        expected struct `std::path::PathBuf`, found reference
+   |                                        help: try using a conversion method: `Path::new("/ern/her/own/surprise").to_path_buf()`
+   |
+   = note: expected type `std::path::PathBuf`
+              found type `&std::path::Path`
+
+error[E0308]: mismatched types
+  --> $DIR/conversion-methods.rs:19:40
+   |
+19 |     let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here
+   |                                        ^
+   |                                        |
+   |                                        expected struct `std::string::String`, found integral variable
+   |                                        help: try using a conversion method: `2.to_string()`
+   |
+   = note: expected type `std::string::String`
+              found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/conversion-methods.rs:22:47
+   |
+22 |     let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; //~ ERROR mismatched types
+   |                                               ^^^^^^^^^^
+   |                                               |
+   |                                               expected struct `std::vec::Vec`, found reference
+   |                                               help: try using a conversion method: `&[1, 2, 3].to_vec()`
+   |
+   = note: expected type `std::vec::Vec<usize>`
+              found type `&[{integer}; 3]`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/suggestions/issue-45562.rs b/src/test/ui/suggestions/issue-45562.rs
new file mode 100644 (file)
index 0000000..f493df5
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[no_mangle] pub const RAH: usize = 5;
+//~^ ERROR const items should never be #[no_mangle]
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-45562.stderr b/src/test/ui/suggestions/issue-45562.stderr
new file mode 100644 (file)
index 0000000..2f8c4cd
--- /dev/null
@@ -0,0 +1,12 @@
+error: const items should never be #[no_mangle]
+  --> $DIR/issue-45562.rs:11:14
+   |
+11 | #[no_mangle] pub const RAH: usize = 5;
+   |              ---------^^^^^^^^^^^^^^^^
+   |              |
+   |              help: try a static value: `pub static`
+   |
+   = note: #[deny(no_mangle_const_items)] on by default
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
new file mode 100644 (file)
index 0000000..fa5bafa
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let x = 2.0.powi(2);
+    //~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+    let y = 2.0;
+    let x = y.powi(2);
+    //~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+    println!("{:?}", x);
+}
diff --git a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
new file mode 100644 (file)
index 0000000..c2b292c
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+  --> $DIR/method-on-ambiguous-numeric-type.rs:12:17
+   |
+12 |     let x = 2.0.powi(2);
+   |                 ^^^^
+help: you must specify a concrete type for this numeric value, like `f32`
+   |
+12 |     let x = 2.0_f32.powi(2);
+   |             ^^^^^^^
+
+error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+  --> $DIR/method-on-ambiguous-numeric-type.rs:15:15
+   |
+15 |     let x = y.powi(2);
+   |               ^^^^
+help: you must specify a type for this binding, like `f32`
+   |
+14 |     let y: f32 = 2.0;
+   |         ^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/token/issue-15980.rs b/src/test/ui/token/issue-15980.rs
new file mode 100644 (file)
index 0000000..e1b134c
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::io;
+
+fn main(){
+    let x: io::IoResult<()> = Ok(());
+    //~^ ERROR cannot find type `IoResult` in module `io`
+    //~| NOTE did you mean `Result`?
+    match x {
+        Err(ref e) if e.kind == io::EndOfFile {
+            //~^ NOTE while parsing this struct
+            return
+            //~^ ERROR expected identifier, found keyword `return`
+            //~| NOTE expected identifier, found keyword
+        }
+        //~^ NOTE expected one of `.`, `=>`, `?`, or an operator here
+        _ => {}
+        //~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found `_`
+        //~| NOTE unexpected token
+    }
+}
diff --git a/src/test/ui/token/issue-15980.stderr b/src/test/ui/token/issue-15980.stderr
new file mode 100644 (file)
index 0000000..71cd4b2
--- /dev/null
@@ -0,0 +1,26 @@
+error: expected identifier, found keyword `return`
+  --> $DIR/issue-15980.rs:20:13
+   |
+18 |         Err(ref e) if e.kind == io::EndOfFile {
+   |                                 ------------- while parsing this struct
+19 |             //~^ NOTE while parsing this struct
+20 |             return
+   |             ^^^^^^ expected identifier, found keyword
+
+error: expected one of `.`, `=>`, `?`, or an operator, found `_`
+  --> $DIR/issue-15980.rs:25:9
+   |
+23 |         }
+   |          - expected one of `.`, `=>`, `?`, or an operator here
+24 |         //~^ NOTE expected one of `.`, `=>`, `?`, or an operator here
+25 |         _ => {}
+   |         ^ unexpected token
+
+error[E0412]: cannot find type `IoResult` in module `io`
+  --> $DIR/issue-15980.rs:14:16
+   |
+14 |     let x: io::IoResult<()> = Ok(());
+   |                ^^^^^^^^ did you mean `Result`?
+
+error: aborting due to 3 previous errors
+
index fc2759df447482fba908c843103c049366df1b7d..4113f8fd124c7090344189eb1d02176b827d772b 100644 (file)
@@ -67,6 +67,7 @@
     "i386-apple-ios",
     "i586-pc-windows-msvc",
     "i586-unknown-linux-gnu",
+    "i586-unknown-linux-musl",
     "i686-apple-darwin",
     "i686-linux-android",
     "i686-pc-windows-gnu",
index 494c57b161fea13e2ef81c4cda67022376086cbe..725c8e75e6ac44019891fa16a43fe5b3401f0804 100644 (file)
@@ -8,7 +8,7 @@ diff = "0.1.10"
 env_logger = { version = "0.4", default-features = false }
 filetime = "0.1"
 getopts = "0.2"
-log = "0.3"
+log = "0.4"
 regex = "0.2"
 rustc-serialize = "0.3"
 
index dbeee39e606c6e322d15480d3d8f147d424b90ab..efbe5e32fcd277d93fca84de8e8fbaacf93c6c88 100644 (file)
@@ -21,6 +21,7 @@
 use util::logv;
 use regex::Regex;
 
+use std::collections::VecDeque;
 use std::collections::HashMap;
 use std::collections::HashSet;
 use std::env;
@@ -48,6 +49,88 @@ pub fn dylib_env_var() -> &'static str {
     }
 }
 
+#[derive(Debug, PartialEq)]
+pub enum DiffLine {
+    Context(String),
+    Expected(String),
+    Resulting(String),
+}
+
+#[derive(Debug, PartialEq)]
+pub struct Mismatch {
+    pub line_number: u32,
+    pub lines: Vec<DiffLine>,
+}
+
+impl Mismatch {
+    fn new(line_number: u32) -> Mismatch {
+        Mismatch {
+            line_number: line_number,
+            lines: Vec::new(),
+        }
+    }
+}
+
+// Produces a diff between the expected output and actual output.
+pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
+    let mut line_number = 1;
+    let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
+    let mut lines_since_mismatch = context_size + 1;
+    let mut results = Vec::new();
+    let mut mismatch = Mismatch::new(0);
+
+    for result in diff::lines(actual, expected) {
+        match result {
+            diff::Result::Left(str) => {
+                if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
+                    results.push(mismatch);
+                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
+                }
+
+                while let Some(line) = context_queue.pop_front() {
+                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
+                }
+
+                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
+                lines_since_mismatch = 0;
+            }
+            diff::Result::Right(str) => {
+                if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
+                    results.push(mismatch);
+                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
+                }
+
+                while let Some(line) = context_queue.pop_front() {
+                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
+                }
+
+                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
+                line_number += 1;
+                lines_since_mismatch = 0;
+            }
+            diff::Result::Both(str, _) => {
+                if context_queue.len() >= context_size {
+                    let _ = context_queue.pop_front();
+                }
+
+                if lines_since_mismatch < context_size {
+                    mismatch.lines.push(DiffLine::Context(str.to_owned()));
+                } else if context_size > 0 {
+                    context_queue.push_back(str);
+                }
+
+                line_number += 1;
+                lines_since_mismatch += 1;
+            }
+        }
+    }
+
+    results.push(mismatch);
+    results.remove(0);
+
+    results
+}
+
 pub fn run(config: Config, testpaths: &TestPaths) {
     match &*config.target {
         "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => {
@@ -1520,6 +1603,10 @@ fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> C
             rustc.args(&["-Z", "incremental-queries"]);
         }
 
+        if self.config.mode == CodegenUnits {
+            rustc.args(&["-Z", "human_readable_cgu_names"]);
+        }
+
         match self.config.mode {
             CompileFail | ParseFail | Incremental => {
                 // If we are extracting and matching errors in the new
@@ -2716,15 +2803,29 @@ fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
             return 0;
         }
 
-        println!("normalized {}:\n{}\n", kind, actual);
-        println!("expected {}:\n{}\n", kind, expected);
-        println!("diff of {}:\n", kind);
-
-        for diff in diff::lines(expected, actual) {
-            match diff {
-                diff::Result::Left(l) => println!("-{}", l),
-                diff::Result::Both(l, _) => println!(" {}", l),
-                diff::Result::Right(r) => println!("+{}", r),
+        if expected.is_empty() {
+            println!("normalized {}:\n{}\n", kind, actual);
+        } else {
+            println!("diff of {}:\n", kind);
+            let diff_results = make_diff(expected, actual, 3);
+            for result in diff_results {
+                let mut line_number = result.line_number;
+                for line in result.lines {
+                    match line {
+                        DiffLine::Expected(e) => {
+                            println!("-\t{}", e);
+                            line_number += 1;
+                        },
+                        DiffLine::Context(c) => {
+                            println!("{}\t{}", line_number, c);
+                            line_number += 1;
+                        },
+                        DiffLine::Resulting(r) => {
+                            println!("+\t{}", r);
+                        },
+                    }
+                }
+                println!("");
             }
         }
 
@@ -2863,7 +2964,7 @@ fn extend(&mut self, data: &[u8]) {
                     *skipped += data.len();
                     if data.len() <= TAIL_LEN {
                         tail[..data.len()].copy_from_slice(data);
-                        tail.rotate(data.len());
+                        tail.rotate_left(data.len());
                     } else {
                         tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]);
                     }
index ca383b5add011533e4bba7cd61057ac6c68946f1..aedae366c411995038bdfac700ac4eba0e659d10 100644 (file)
@@ -109,7 +109,65 @@ fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
     }
 
     fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
-        write!(output, "</body>\n</html>")?;
+        write!(output, r##"<script>
+function onEach(arr, func) {{
+    if (arr && arr.length > 0 && func) {{
+        for (var i = 0; i < arr.length; i++) {{
+            func(arr[i]);
+        }}
+    }}
+}}
+
+function hasClass(elem, className) {{
+    if (elem && className && elem.className) {{
+        var elemClass = elem.className;
+        var start = elemClass.indexOf(className);
+        if (start === -1) {{
+            return false;
+        }} else if (elemClass.length === className.length) {{
+            return true;
+        }} else {{
+            if (start > 0 && elemClass[start - 1] !== ' ') {{
+                return false;
+            }}
+            var end = start + className.length;
+            if (end < elemClass.length && elemClass[end] !== ' ') {{
+                return false;
+            }}
+            return true;
+        }}
+        if (start > 0 && elemClass[start - 1] !== ' ') {{
+            return false;
+        }}
+        var end = start + className.length;
+        if (end < elemClass.length && elemClass[end] !== ' ') {{
+            return false;
+        }}
+        return true;
+    }}
+    return false;
+}}
+
+onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {{
+    if (hasClass(e, 'compile_fail')) {{
+        e.addEventListener("mouseover", function(event) {{
+            e.previousElementSibling.childNodes[0].style.color = '#f00';
+        }});
+        e.addEventListener("mouseout", function(event) {{
+            e.previousElementSibling.childNodes[0].style.color = '';
+        }});
+    }} else if (hasClass(e, 'ignore')) {{
+        e.addEventListener("mouseover", function(event) {{
+            e.previousElementSibling.childNodes[0].style.color = '#ff9200';
+        }});
+        e.addEventListener("mouseout", function(event) {{
+            e.previousElementSibling.childNodes[0].style.color = '';
+        }});
+    }}
+}});
+</script>
+</body>
+</html>"##)?;
         Ok(())
     }
 }
index 469525ae7386ff1200cea7841e745b2dd769894b..6458ec02669aab24a6263690daab0d6ace254ced 100644 (file)
@@ -158,13 +158,6 @@ fn check(cache: &mut Cache,
        file.ends_with("sync/struct.RwLock.html") {
         return None;
     }
-    // FIXME(#47038)
-    if file.ends_with("deriving/generic/index.html") ||
-       file.ends_with("deriving/generic/macro.vec.html") ||
-       file.ends_with("deriving/custom/macro.panic.html") ||
-       file.ends_with("proc_macro_impl/macro.panic.html") {
-        return None;
-    }
 
     let res = load_file(cache, root, file, SkipRedirect);
     let (pretty_file, contents) = match res {