]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #47277 - tspiteri:log-correctness, r=frewsxcv
authorkennytm <kennytm@gmail.com>
Mon, 15 Jan 2018 08:55:29 +0000 (16:55 +0800)
committerkennytm <kennytm@gmail.com>
Mon, 15 Jan 2018 10:49:32 +0000 (18:49 +0800)
doc: show that `f32::log` and `f64::log` are not correctly rounded

Fixes #47273.

One thing I'm not sure about is whether the "calculated as `self.ln() / base.ln()`" bit is being too specific, maybe we do not want to make this such a strong commitment. I think it's fine, but we should not make commitments in the API documentation by accident.

In case that is removed, the added sentence "`self.log2()` can ... base 10." still makes it amply clear that the `log` methods can be more inaccurate than other methods. If the above clause is removed, this second sentence can be moved to the first paragraph, kind of like the accuracy comment for the [`mul_add`](https://doc.rust-lang.org/std/primitive.f32.html#method.mul_add) method.

347 files changed:
.gitmodules
.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/scripts/musl.sh
src/doc/rust-by-example [new submodule]
src/doc/rust.css
src/liballoc/benches/slice.rs
src/liballoc/lib.rs
src/liballoc/slice.rs
src/liballoc/string.rs
src/liballoc/tests/lib.rs
src/liballoc/tests/slice.rs
src/libarena/lib.rs
src/libcore/fmt/mod.rs
src/libcore/iter/range.rs
src/libcore/marker.rs
src/libcore/slice/mod.rs
src/libcore/tests/iter.rs
src/libcore/tests/lib.rs
src/libcore/tests/num/mod.rs
src/libcore/tests/slice.rs
src/liblibc
src/libproc_macro/lib.rs
src/librustc/dep_graph/dep_node.rs
src/librustc/dep_graph/graph.rs
src/librustc/hir/check_attr.rs
src/librustc/hir/def_id.rs
src/librustc/hir/intravisit.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/def_collector.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/hir/print.rs
src/librustc/ich/fingerprint.rs
src/librustc/ich/impls_hir.rs
src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
src/librustc/infer/error_reporting/nice_region_error/util.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/middle/reachable.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/mir/mono.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/traits/select.rs
src/librustc/ty/item_path.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/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/borrowck/gather_loans/restrictions.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/borrowck/move_data.rs
src/librustc_const_eval/pattern.rs
src/librustc_data_structures/base_n.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_driver/test.rs
src/librustc_errors/emitter.rs
src/librustc_errors/lib.rs
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/bad_style.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_lint/types.rs
src/librustc_llvm/ffi.rs
src/librustc_llvm/lib.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/borrow_check/error_reporting.rs
src/librustc_mir/borrow_check/nll/type_check/liveness.rs
src/librustc_mir/dataflow/graphviz.rs
src/librustc_mir/interpret/const_eval.rs
src/librustc_mir/lib.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/monomorphize/partitioning.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/util/borrowck_errors.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/diagnostics.rs
src/librustc_privacy/lib.rs
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/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_save_analysis/sig.rs
src/librustc_trans/assert_module_sources.rs
src/librustc_trans/attributes.rs
src/librustc_trans/back/bytecode.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/write.rs
src/librustc_trans/callee.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/trans_item.rs
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/coherence/inherent_impls.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/overlap.rs [deleted file]
src/librustc_typeck/coherence/unsafety.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/doctree.rs
src/librustdoc/externalfiles.rs
src/librustdoc/html/item_type.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/librustdoc/passes/mod.rs
src/librustdoc/test.rs
src/librustdoc/visit_ast.rs
src/libserialize/opaque.rs
src/libstd/collections/hash/map.rs
src/libstd/env.rs
src/libstd/ffi/mod.rs
src/libstd/ffi/os_str.rs
src/libstd/fs.rs
src/libstd/io/buffered.rs
src/libstd/io/cursor.rs
src/libstd/io/error.rs
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/net/tcp.rs
src/libstd/net/udp.rs
src/libstd/panic.rs
src/libstd/panicking.rs
src/libstd/path.rs
src/libstd/process.rs
src/libstd/sync/rwlock.rs
src/libstd/sys/cloudabi/abi/bitflags.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/abi/cloudabi.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/abi/mod.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/args.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/backtrace.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/condvar.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/mod.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/mutex.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/os.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/rwlock.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/shims/args.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/shims/env.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/shims/fs.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/shims/mod.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/shims/net.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/shims/os.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/shims/pipe.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/shims/process.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/stack_overflow.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/stdio.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/thread.rs [new file with mode: 0644]
src/libstd/sys/cloudabi/time.rs [new file with mode: 0644]
src/libstd/sys/mod.rs
src/libstd/sys/wasm/mod.rs
src/libstd/sys/windows/c.rs
src/libstd/sys_common/mod.rs
src/libstd/time/duration.rs
src/libsyntax/ast.rs
src/libsyntax/attr.rs
src/libsyntax/codemap.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/tokenstream.rs
src/libsyntax/visit.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_pos/hygiene.rs
src/libtest/lib.rs
src/rtstartup/rsbegin.rs
src/rtstartup/rsend.rs
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.h
src/test/compile-fail/E0198.rs
src/test/compile-fail/auto-impl-future-compat.rs [deleted file]
src/test/compile-fail/auto-trait-validation.rs
src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs
src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs
src/test/compile-fail/coherence-default-trait-impl.rs
src/test/compile-fail/coherence-negative-impls-safe.rs
src/test/compile-fail/directory_ownership/backcompat-warnings.rs [deleted file]
src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs
src/test/compile-fail/issue-16922.rs
src/test/compile-fail/issue-23080-2.rs
src/test/compile-fail/issue-23080.rs
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/issue-45199.rs
src/test/compile-fail/issue-46438.rs [new file with mode: 0644]
src/test/compile-fail/object-lifetime-default-from-box-error.rs
src/test/compile-fail/phantom-oibit.rs
src/test/compile-fail/privacy-sanity.rs
src/test/compile-fail/private-in-public-ill-formed.rs
src/test/compile-fail/region-object-lifetime-in-coercion.rs
src/test/compile-fail/regions-proc-bound-capture.rs
src/test/compile-fail/regions-static-bound.rs
src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs [deleted file]
src/test/compile-fail/specialization/defaultimpl/validation.rs [new file with mode: 0644]
src/test/compile-fail/specialization/specialization-polarity.rs
src/test/compile-fail/static-drop-scope.rs
src/test/compile-fail/syntax-trait-polarity-feature-gate.rs
src/test/compile-fail/syntax-trait-polarity.rs [new file with mode: 0644]
src/test/compile-fail/syntaxt-default-trait-impls.rs [deleted file]
src/test/compile-fail/trait-safety-inherent-impl.rs
src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs
src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs
src/test/compile-fail/typeck-auto-trait-no-supertraits.rs
src/test/compile-fail/typeck-auto-trait-no-typeparams.rs [deleted file]
src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs
src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs
src/test/compile-fail/typeck-default-trait-impl-negation.rs
src/test/compile-fail/typeck-default-trait-impl-precedence.rs
src/test/compile-fail/typeck-negative-impls-builtin.rs
src/test/parse-fail/impl-qpath.rs [new file with mode: 0644]
src/test/parse-fail/issue-32501.rs
src/test/parse-fail/syntax-trait-polarity.rs [deleted file]
src/test/parse-fail/trait-bounds-not-on-impl.rs
src/test/parse-fail/where_with_bound.rs
src/test/run-make/linker-output-non-utf8/Makefile
src/test/run-make/rustdoc-error-lines/Makefile [new file with mode: 0644]
src/test/run-make/rustdoc-error-lines/input.rs [new file with mode: 0644]
src/test/run-make/simd-ffi/simd.rs
src/test/run-make/target-specs/foo.rs
src/test/run-pass/auto-traits.rs
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-25693.rs
src/test/run-pass/issue-29516.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/rustdoc/auxiliary/rustdoc-default-impl.rs
src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs
src/test/rustdoc/impl-parts.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/borrowck/immutable-arg.rs [new file with mode: 0644]
src/test/ui/borrowck/immutable-arg.stderr [new file with mode: 0644]
src/test/ui/deref-suggestion.stderr
src/test/ui/did_you_mean/recursion_limit_deref.stderr
src/test/ui/feature-gate-optin-builtin-traits.rs
src/test/ui/feature-gate-optin-builtin-traits.stderr
src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr
src/test/ui/issue-44406.stderr
src/test/ui/issue-46983.rs [new file with mode: 0644]
src/test/ui/issue-46983.stderr [new file with mode: 0644]
src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs
src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr
src/test/ui/nll/guarantor-issue-46974.rs
src/test/ui/nll/guarantor-issue-46974.stderr
src/test/ui/nll/issue-47022.rs [new file with mode: 0644]
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/obsolete-syntax-impl-for-dotdot.rs [new file with mode: 0644]
src/test/ui/obsolete-syntax-impl-for-dotdot.stderr [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/impl-parsing.rs [new file with mode: 0644]
src/test/ui/span/impl-parsing.stderr [new file with mode: 0644]
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/target-feature-wrong.rs [new file with mode: 0644]
src/test/ui/target-feature-wrong.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/test/ui/typeck-default-trait-impl-outside-crate.rs [deleted file]
src/test/ui/typeck-default-trait-impl-outside-crate.stderr [deleted file]
src/tools/build-manifest/src/main.rs
src/tools/compiletest/src/runtest.rs
src/tools/error_index_generator/main.rs
src/tools/linkchecker/main.rs
src/tools/tidy/src/pal.rs

index 373ca90eca1286e42b7c37739210ee0b09d32556..ffa7b321ba6b6eb8e61fe0e6a17f28c4310d6652 100644 (file)
@@ -48,3 +48,6 @@
 [submodule "src/binaryen"]
        path = src/binaryen
        url = https://github.com/alexcrichton/binaryen.git
+[submodule "src/doc/rust-by-example"]
+       path = src/doc/rust-by-example
+       url = https://github.com/rust-lang/rust-by-example
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 a21ad12700b3b386404a68f942068e52f63e30ac..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,7 +372,7 @@ 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)",
+ "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)",
@@ -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,7 +1711,7 @@ 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)",
+ "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",
@@ -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]]
@@ -2057,7 +2057,7 @@ 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)",
+ "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",
@@ -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)",
 ]
@@ -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..8e35ecc8090c6d82d0321a904670baf78893a300 100644 (file)
@@ -258,7 +258,7 @@ macro_rules! describe {
             Kind::Bench => describe!(check::Crate, check::CrateLibrustc),
             Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
                 doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,
-                doc::Reference, doc::Rustdoc, doc::CargoBook),
+                doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook),
             Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts,
                 dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo,
                 dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign,
@@ -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..d66c01eb4990e040e2e42fff2c5678a9abef7dee 100644 (file)
@@ -12,7 +12,7 @@
 //!
 //! This module implements generation for all bits and pieces of documentation
 //! for the Rust project. This notably includes suites like the rust book, the
-//! nomicon, standalone documentation, etc.
+//! nomicon, rust by example, standalone documentation, etc.
 //!
 //! Everything here is basically just a shim around calling either `rustbook` or
 //! `rustdoc`.
@@ -69,6 +69,7 @@ fn run(self, builder: &Builder) {
     Nomicon, "src/doc/nomicon", "nomicon";
     Reference, "src/doc/reference", "reference";
     Rustdoc, "src/doc/rustdoc", "rustdoc";
+    RustByExample, "src/doc/rust-by-example", "rust-by-example";
 );
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
@@ -616,7 +617,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 c59476f..0000000
+++ /dev/null
@@ -1,49 +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 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 && \
-    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
index b704e37d5929128be514f929b39bd0db551c5334..7a7233216a35f09568db40ed6ab5e740b1eab7fb 100644 (file)
@@ -30,7 +30,7 @@ exit 1
 TAG=$1
 shift
 
-MUSL=musl-1.1.17
+MUSL=musl-1.1.18
 
 # may have been downloaded in a previous run
 if [ ! -d $MUSL ]; then
@@ -39,7 +39,7 @@ fi
 
 cd $MUSL
 ./configure --disable-shared --prefix=/musl-$TAG $@
-if [ "$TAG" = "i686" ]; then
+if [ "$TAG" = "i586" -o "$TAG" = "i686" ]; then
   hide_output make -j$(nproc) AR=ar RANLIB=ranlib
 else
   hide_output make -j$(nproc)
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
new file mode 160000 (submodule)
index 0000000..4ebb816
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 4ebb8169dfe569b3dcbeab560607800bb717978a
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;
 }
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 3cc3ea467966be5a11dc56d4c6b429c00a450e0d..d8ce28695ab6f3049a6ea5e0c5ec7fe6fe8b36de 100644 (file)
 #![feature(unsize)]
 #![feature(allocator_internals)]
 #![feature(on_unimplemented)]
+#![feature(exact_chunks)]
 
 #![cfg_attr(not(test), feature(fused, fn_traits, placement_new_protocol, swap_with_slice, i128))]
 #![cfg_attr(test, feature(test, box_heap))]
index fa73197885be79bf34aa3cc2396bcace33cd6117..861f72bcf88ee42b2e5fcf711a9fc1a1a6c358f4 100644 (file)
 pub use core::slice::{from_ref, from_ref_mut};
 #[unstable(feature = "slice_get_slice", issue = "35729")]
 pub use core::slice::SliceIndex;
+#[unstable(feature = "exact_chunks", issue = "47115")]
+pub use core::slice::{ExactChunks, ExactChunksMut};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Basic slice extension methods
@@ -611,6 +613,9 @@ pub fn windows(&self, size: usize) -> Windows<T> {
     /// not divide the length of the slice, then the last chunk will
     /// not have length `chunk_size`.
     ///
+    /// See [`exact_chunks`] for a variant of this iterator that returns chunks
+    /// of always exactly `chunk_size` elements.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is 0.
@@ -631,11 +636,44 @@ pub fn chunks(&self, chunk_size: usize) -> Chunks<T> {
         core_slice::SliceExt::chunks(self, chunk_size)
     }
 
+    /// Returns an iterator over `chunk_size` elements of the slice at a
+    /// time. The chunks are slices and do not overlap. If `chunk_size` does
+    /// not divide the length of the slice, then the last up to `chunk_size-1`
+    /// elements will be omitted.
+    ///
+    /// Due to each chunk having exactly `chunk_size` elements, the compiler
+    /// can often optimize the resulting code better than in the case of
+    /// [`chunks`].
+    ///
+    /// # Panics
+    ///
+    /// Panics if `chunk_size` is 0.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(exact_chunks)]
+    ///
+    /// let slice = ['l', 'o', 'r', 'e', 'm'];
+    /// let mut iter = slice.exact_chunks(2);
+    /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
+    /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
+    /// assert!(iter.next().is_none());
+    /// ```
+    #[unstable(feature = "exact_chunks", issue = "47115")]
+    #[inline]
+    pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
+        core_slice::SliceExt::exact_chunks(self, chunk_size)
+    }
+
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
     /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
     /// not divide the length of the slice, then the last chunk will not
     /// have length `chunk_size`.
     ///
+    /// See [`exact_chunks_mut`] for a variant of this iterator that returns chunks
+    /// of always exactly `chunk_size` elements.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is 0.
@@ -660,6 +698,42 @@ pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
         core_slice::SliceExt::chunks_mut(self, chunk_size)
     }
 
+    /// Returns an iterator over `chunk_size` elements of the slice at a time.
+    /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
+    /// not divide the length of the slice, then the last up to `chunk_size-1`
+    /// elements will be omitted.
+    ///
+    ///
+    /// Due to each chunk having exactly `chunk_size` elements, the compiler
+    /// can often optimize the resulting code better than in the case of
+    /// [`chunks_mut`].
+    ///
+    /// # Panics
+    ///
+    /// Panics if `chunk_size` is 0.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(exact_chunks)]
+    ///
+    /// let v = &mut [0, 0, 0, 0, 0];
+    /// let mut count = 1;
+    ///
+    /// for chunk in v.exact_chunks_mut(2) {
+    ///     for elem in chunk.iter_mut() {
+    ///         *elem += count;
+    ///     }
+    ///     count += 1;
+    /// }
+    /// assert_eq!(v, &[1, 1, 2, 2, 0]);
+    /// ```
+    #[unstable(feature = "exact_chunks", issue = "47115")]
+    #[inline]
+    pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
+        core_slice::SliceExt::exact_chunks_mut(self, chunk_size)
+    }
+
     /// Divides one slice into two at an index.
     ///
     /// The first will contain all indices from `[0, mid)` (excluding
@@ -1360,24 +1434,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
     ///
-    /// Rotation by `mid` and rotation by `k` are inverse operations.
+    /// 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.
     ///
-    /// [eop]: https://books.google.com/books?id=CO9ULZGINlsC&pg=PA178&q=k-rotation
+    /// # Complexity
+    ///
+    /// Takes linear (in `self.len()`) time.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_rotate)]
+    ///
+    /// 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 +1499,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 +1698,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 f1e95883b38279bddd120fb82cf48974fe76c071..eee229bc6fdfa7aef1d6a908dcfa319a39cb25c1 100644 (file)
@@ -30,6 +30,7 @@
 #![feature(string_retain)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
+#![feature(exact_chunks)]
 
 extern crate alloc_system;
 extern crate std_unicode;
index 85d5ce304b88de2c27556a8414d61e93bb681173..1a9d26fd1a29150b5c18f950d49f0b5deb70aa4b 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);
 }
 
@@ -910,6 +945,30 @@ fn test_chunksator_0() {
     let _it = v.chunks(0);
 }
 
+#[test]
+fn test_exact_chunksator() {
+    let v = &[1, 2, 3, 4, 5];
+
+    assert_eq!(v.exact_chunks(2).len(), 2);
+
+    let chunks: &[&[_]] = &[&[1, 2], &[3, 4]];
+    assert_eq!(v.exact_chunks(2).collect::<Vec<_>>(), chunks);
+    let chunks: &[&[_]] = &[&[1, 2, 3]];
+    assert_eq!(v.exact_chunks(3).collect::<Vec<_>>(), chunks);
+    let chunks: &[&[_]] = &[];
+    assert_eq!(v.exact_chunks(6).collect::<Vec<_>>(), chunks);
+
+    let chunks: &[&[_]] = &[&[3, 4], &[1, 2]];
+    assert_eq!(v.exact_chunks(2).rev().collect::<Vec<_>>(), chunks);
+}
+
+#[test]
+#[should_panic]
+fn test_exact_chunksator_0() {
+    let v = &[1, 2, 3, 4];
+    let _it = v.exact_chunks(0);
+}
+
 #[test]
 fn test_reverse_part() {
     let mut values = [1, 2, 3, 4, 5];
@@ -1124,7 +1183,7 @@ fn test_mut_chunks() {
         }
     }
     let result = [0, 0, 0, 1, 1, 1, 2];
-    assert!(v == result);
+    assert_eq!(v, result);
 }
 
 #[test]
@@ -1136,7 +1195,7 @@ fn test_mut_chunks_rev() {
         }
     }
     let result = [2, 2, 2, 1, 1, 1, 0];
-    assert!(v == result);
+    assert_eq!(v, result);
 }
 
 #[test]
@@ -1146,6 +1205,38 @@ fn test_mut_chunks_0() {
     let _it = v.chunks_mut(0);
 }
 
+#[test]
+fn test_mut_exact_chunks() {
+    let mut v = [0, 1, 2, 3, 4, 5, 6];
+    assert_eq!(v.exact_chunks_mut(2).len(), 3);
+    for (i, chunk) in v.exact_chunks_mut(3).enumerate() {
+        for x in chunk {
+            *x = i as u8;
+        }
+    }
+    let result = [0, 0, 0, 1, 1, 1, 6];
+    assert_eq!(v, result);
+}
+
+#[test]
+fn test_mut_exact_chunks_rev() {
+    let mut v = [0, 1, 2, 3, 4, 5, 6];
+    for (i, chunk) in v.exact_chunks_mut(3).rev().enumerate() {
+        for x in chunk {
+            *x = i as u8;
+        }
+    }
+    let result = [1, 1, 1, 0, 0, 0, 6];
+    assert_eq!(v, result);
+}
+
+#[test]
+#[should_panic]
+fn test_mut_exact_chunks_0() {
+    let mut v = [1, 2, 3, 4];
+    let _it = v.exact_chunks_mut(0);
+}
+
 #[test]
 fn test_mut_last() {
     let mut x = [1, 2, 3, 4, 5];
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 17e77654cf5ef2975ba15a975e54918d7698a7fb..3032fb2de33ada892163d31d5ebcb3ddc64998c3 100644 (file)
 /// [ub]: ../../reference/behavior-considered-undefined.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
-pub unsafe trait Send {
+pub unsafe auto trait Send {
     // empty.
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(unknown_lints)]
-#[allow(auto_impl)]
-unsafe impl Send for .. { }
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !Send for *const T { }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -345,15 +340,10 @@ pub trait Copy : Clone {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
-pub unsafe trait Sync {
+pub unsafe auto trait Sync {
     // Empty
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(unknown_lints)]
-#[allow(auto_impl)]
-unsafe impl Sync for .. { }
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !Sync for *const T { }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -563,11 +553,7 @@ unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
 /// This affects, for example, whether a `static` of that type is
 /// placed in read-only static memory or writable static memory.
 #[lang = "freeze"]
-unsafe trait Freeze {}
-
-#[allow(unknown_lints)]
-#[allow(auto_impl)]
-unsafe impl Freeze for .. {}
+unsafe auto trait Freeze {}
 
 impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
 unsafe impl<T: ?Sized> Freeze for PhantomData<T> {}
index 72036d6d3a248e0cff831c3d5d6e1cd1e3c6f007..48e82666d35151cafa566bf965cddd874cb8b283 100644 (file)
@@ -104,6 +104,9 @@ fn rsplitn<P>(&self,  n: usize, pred: P) -> RSplitN<Self::Item, P>
     #[stable(feature = "core", since = "1.6.0")]
     fn chunks(&self, size: usize) -> Chunks<Self::Item>;
 
+    #[unstable(feature = "exact_chunks", issue = "47115")]
+    fn exact_chunks(&self, size: usize) -> ExactChunks<Self::Item>;
+
     #[stable(feature = "core", since = "1.6.0")]
     fn get<I>(&self, index: I) -> Option<&I::Output>
         where I: SliceIndex<Self>;
@@ -181,6 +184,9 @@ fn rsplitn_mut<P>(&mut self,  n: usize, pred: P) -> RSplitNMut<Self::Item, P>
     #[stable(feature = "core", since = "1.6.0")]
     fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>;
 
+    #[unstable(feature = "exact_chunks", issue = "47115")]
+    fn exact_chunks_mut(&mut self, size: usize) -> ExactChunksMut<Self::Item>;
+
     #[stable(feature = "core", since = "1.6.0")]
     fn swap(&mut self, a: usize, b: usize);
 
@@ -206,7 +212,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;
@@ -353,6 +362,14 @@ fn chunks(&self, chunk_size: usize) -> Chunks<T> {
         Chunks { v: self, chunk_size: chunk_size }
     }
 
+    #[inline]
+    fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
+        assert!(chunk_size != 0);
+        let rem = self.len() % chunk_size;
+        let len = self.len() - rem;
+        ExactChunks { v: &self[..len], chunk_size: chunk_size}
+    }
+
     #[inline]
     fn get<I>(&self, index: I) -> Option<&I::Output>
         where I: SliceIndex<[T]>
@@ -536,6 +553,14 @@ fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
         ChunksMut { v: self, chunk_size: chunk_size }
     }
 
+    #[inline]
+    fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
+        assert!(chunk_size != 0);
+        let rem = self.len() % chunk_size;
+        let len = self.len() - rem;
+        ExactChunksMut { v: &mut self[..len], chunk_size: chunk_size}
+    }
+
     #[inline]
     fn swap(&mut self, a: usize, b: usize) {
         unsafe {
@@ -645,7 +670,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 +680,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(),
@@ -2365,6 +2400,209 @@ unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
     fn may_have_side_effect() -> bool { false }
 }
 
+/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
+/// time).
+///
+/// When the slice len is not evenly divided by the chunk size, the last
+/// up to `chunk_size-1` elements will be omitted.
+///
+/// This struct is created by the [`exact_chunks`] method on [slices].
+///
+/// [`exact_chunks`]: ../../std/primitive.slice.html#method.exact_chunks
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[unstable(feature = "exact_chunks", issue = "47115")]
+pub struct ExactChunks<'a, T:'a> {
+    v: &'a [T],
+    chunk_size: usize
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> Clone for ExactChunks<'a, T> {
+    fn clone(&self) -> ExactChunks<'a, T> {
+        ExactChunks {
+            v: self.v,
+            chunk_size: self.chunk_size,
+        }
+    }
+}
+
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> Iterator for ExactChunks<'a, T> {
+    type Item = &'a [T];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a [T]> {
+        if self.v.len() < self.chunk_size {
+            None
+        } else {
+            let (fst, snd) = self.v.split_at(self.chunk_size);
+            self.v = snd;
+            Some(fst)
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let n = self.v.len() / self.chunk_size;
+        (n, Some(n))
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<Self::Item> {
+        let (start, overflow) = n.overflowing_mul(self.chunk_size);
+        if start >= self.v.len() || overflow {
+            self.v = &[];
+            None
+        } else {
+            let (_, snd) = self.v.split_at(start);
+            self.v = snd;
+            self.next()
+        }
+    }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
+}
+
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> DoubleEndedIterator for ExactChunks<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a [T]> {
+        if self.v.len() < self.chunk_size {
+            None
+        } else {
+            let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
+            self.v = fst;
+            Some(snd)
+        }
+    }
+}
+
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> ExactSizeIterator for ExactChunks<'a, T> {
+    fn is_empty(&self) -> bool {
+        self.v.is_empty()
+    }
+}
+
+#[unstable(feature = "fused", issue = "35602")]
+impl<'a, T> FusedIterator for ExactChunks<'a, T> {}
+
+#[doc(hidden)]
+unsafe impl<'a, T> TrustedRandomAccess for ExactChunks<'a, T> {
+    unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
+        let start = i * self.chunk_size;
+        from_raw_parts(self.v.as_ptr().offset(start as isize), self.chunk_size)
+    }
+    fn may_have_side_effect() -> bool { false }
+}
+
+/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
+/// elements at a time). When the slice len is not evenly divided by the chunk
+/// size, the last up to `chunk_size-1` elements will be omitted.
+///
+/// This struct is created by the [`exact_chunks_mut`] method on [slices].
+///
+/// [`exact_chunks_mut`]: ../../std/primitive.slice.html#method.exact_chunks_mut
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[unstable(feature = "exact_chunks", issue = "47115")]
+pub struct ExactChunksMut<'a, T:'a> {
+    v: &'a mut [T],
+    chunk_size: usize
+}
+
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> Iterator for ExactChunksMut<'a, T> {
+    type Item = &'a mut [T];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a mut [T]> {
+        if self.v.len() < self.chunk_size {
+            None
+        } else {
+            let tmp = mem::replace(&mut self.v, &mut []);
+            let (head, tail) = tmp.split_at_mut(self.chunk_size);
+            self.v = tail;
+            Some(head)
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let n = self.v.len() / self.chunk_size;
+        (n, Some(n))
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
+        let (start, overflow) = n.overflowing_mul(self.chunk_size);
+        if start >= self.v.len() || overflow {
+            self.v = &mut [];
+            None
+        } else {
+            let tmp = mem::replace(&mut self.v, &mut []);
+            let (_, snd) = tmp.split_at_mut(start);
+            self.v = snd;
+            self.next()
+        }
+    }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
+}
+
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> DoubleEndedIterator for ExactChunksMut<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a mut [T]> {
+        if self.v.len() < self.chunk_size {
+            None
+        } else {
+            let tmp = mem::replace(&mut self.v, &mut []);
+            let tmp_len = tmp.len();
+            let (head, tail) = tmp.split_at_mut(tmp_len - self.chunk_size);
+            self.v = head;
+            Some(tail)
+        }
+    }
+}
+
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> ExactSizeIterator for ExactChunksMut<'a, T> {
+    fn is_empty(&self) -> bool {
+        self.v.is_empty()
+    }
+}
+
+#[unstable(feature = "fused", issue = "35602")]
+impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {}
+
+#[doc(hidden)]
+unsafe impl<'a, T> TrustedRandomAccess for ExactChunksMut<'a, T> {
+    unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
+        let start = i * self.chunk_size;
+        from_raw_parts_mut(self.v.as_mut_ptr().offset(start as isize), self.chunk_size)
+    }
+    fn may_have_side_effect() -> bool { false }
+}
+
 //
 // Free functions
 //
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 c4b85b829812c4cb792c5fdd47348b16149f65f7..2c0009569d75d60dccb391fe2a3a79332f96f929 100644 (file)
@@ -42,6 +42,7 @@
 #![feature(try_from)]
 #![feature(try_trait)]
 #![feature(unique)]
+#![feature(exact_chunks)]
 
 extern crate core;
 extern crate test;
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 d6230e93f998d052b2f9aa55d3b6fbec186fedf7..f7a4a71e5cfda4909700cd455c5b762d6a3965cd 100644 (file)
@@ -117,12 +117,12 @@ fn test_chunks_count() {
 fn test_chunks_nth() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5];
     let mut c = v.chunks(2);
-    assert_eq!(c.nth(1).unwrap()[1], 3);
-    assert_eq!(c.next().unwrap()[0], 4);
+    assert_eq!(c.nth(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[4, 5]);
 
     let v2: &[i32] = &[0, 1, 2, 3, 4];
     let mut c2 = v2.chunks(3);
-    assert_eq!(c2.nth(1).unwrap()[1], 4);
+    assert_eq!(c2.nth(1).unwrap(), &[3, 4]);
     assert_eq!(c2.next(), None);
 }
 
@@ -168,12 +168,12 @@ fn test_chunks_mut_count() {
 fn test_chunks_mut_nth() {
     let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
     let mut c = v.chunks_mut(2);
-    assert_eq!(c.nth(1).unwrap()[1], 3);
-    assert_eq!(c.next().unwrap()[0], 4);
+    assert_eq!(c.nth(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[4, 5]);
 
     let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
     let mut c2 = v2.chunks_mut(3);
-    assert_eq!(c2.nth(1).unwrap()[1], 4);
+    assert_eq!(c2.nth(1).unwrap(), &[3, 4]);
     assert_eq!(c2.next(), None);
 }
 
@@ -181,11 +181,11 @@ fn test_chunks_mut_nth() {
 fn test_chunks_mut_last() {
     let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
     let c = v.chunks_mut(2);
-    assert_eq!(c.last().unwrap()[1], 5);
+    assert_eq!(c.last().unwrap(), &[4, 5]);
 
     let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
     let c2 = v2.chunks_mut(2);
-    assert_eq!(c2.last().unwrap()[0], 4);
+    assert_eq!(c2.last().unwrap(), &[4]);
 }
 
 #[test]
@@ -202,6 +202,110 @@ fn test_chunks_mut_zip() {
     assert_eq!(v1, [13, 14, 19, 20, 14]);
 }
 
+#[test]
+fn test_exact_chunks_count() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let c = v.exact_chunks(3);
+    assert_eq!(c.count(), 2);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let c2 = v2.exact_chunks(2);
+    assert_eq!(c2.count(), 2);
+
+    let v3: &[i32] = &[];
+    let c3 = v3.exact_chunks(2);
+    assert_eq!(c3.count(), 0);
+}
+
+#[test]
+fn test_exact_chunks_nth() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let mut c = v.exact_chunks(2);
+    assert_eq!(c.nth(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[4, 5]);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6];
+    let mut c2 = v2.exact_chunks(3);
+    assert_eq!(c2.nth(1).unwrap(), &[3, 4, 5]);
+    assert_eq!(c2.next(), None);
+}
+
+#[test]
+fn test_exact_chunks_last() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let c = v.exact_chunks(2);
+    assert_eq!(c.last().unwrap(), &[4, 5]);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let c2 = v2.exact_chunks(2);
+    assert_eq!(c2.last().unwrap(), &[2, 3]);
+}
+
+#[test]
+fn test_exact_chunks_zip() {
+    let v1: &[i32] = &[0, 1, 2, 3, 4];
+    let v2: &[i32] = &[6, 7, 8, 9, 10];
+
+    let res = v1.exact_chunks(2)
+        .zip(v2.exact_chunks(2))
+        .map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
+        .collect::<Vec<_>>();
+    assert_eq!(res, vec![14, 22]);
+}
+
+#[test]
+fn test_exact_chunks_mut_count() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let c = v.exact_chunks_mut(3);
+    assert_eq!(c.count(), 2);
+
+    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let c2 = v2.exact_chunks_mut(2);
+    assert_eq!(c2.count(), 2);
+
+    let v3: &mut [i32] = &mut [];
+    let c3 = v3.exact_chunks_mut(2);
+    assert_eq!(c3.count(), 0);
+}
+
+#[test]
+fn test_exact_chunks_mut_nth() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let mut c = v.exact_chunks_mut(2);
+    assert_eq!(c.nth(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[4, 5]);
+
+    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4, 5, 6];
+    let mut c2 = v2.exact_chunks_mut(3);
+    assert_eq!(c2.nth(1).unwrap(), &[3, 4, 5]);
+    assert_eq!(c2.next(), None);
+}
+
+#[test]
+fn test_exact_chunks_mut_last() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let c = v.exact_chunks_mut(2);
+    assert_eq!(c.last().unwrap(), &[4, 5]);
+
+    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let c2 = v2.exact_chunks_mut(2);
+    assert_eq!(c2.last().unwrap(), &[2, 3]);
+}
+
+#[test]
+fn test_exact_chunks_mut_zip() {
+    let v1: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let v2: &[i32] = &[6, 7, 8, 9, 10];
+
+    for (a, b) in v1.exact_chunks_mut(2).zip(v2.exact_chunks(2)) {
+        let sum = b.iter().sum::<i32>();
+        for v in a {
+            *v += sum;
+        }
+    }
+    assert_eq!(v1, [13, 14, 19, 20, 4]);
+}
+
 #[test]
 fn test_windows_count() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5];
@@ -329,17 +433,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 ec52c6cf57bf76ca4ff2230de54da685f8ca5342..14f54fbffac2e392c94e74680112c474d16d7b3f 100644 (file)
@@ -496,7 +496,6 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
     [] SuperPredicatesOfItem(DefId),
     [] TraitDefOfItem(DefId),
     [] AdtDefOfItem(DefId),
-    [] IsAutoImpl(DefId),
     [] ImplTraitRef(DefId),
     [] ImplPolarity(DefId),
     [] FnSignature(DefId),
@@ -635,6 +634,10 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
     [] Null,
 
     [] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
+
+    [input] TargetFeaturesWhitelist,
+    [] TargetFeaturesEnabled(DefId),
+
 );
 
 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 7792726006859c58da0b177b040858e0e93bc88f..4b528a0fdc7781c1c55dfa57f6858608bf241b66 100644 (file)
 //! conflicts between multiple such attributes attached to the same
 //! item.
 
-use session::Session;
+use ty::TyCtxt;
 
-use syntax::ast;
-use syntax::visit;
-use syntax::visit::Visitor;
+use hir;
+use hir::intravisit::{self, Visitor, NestedVisitorMap};
 
 #[derive(Copy, Clone, PartialEq)]
 enum Target {
@@ -30,24 +29,26 @@ enum Target {
 }
 
 impl Target {
-    fn from_item(item: &ast::Item) -> Target {
+    fn from_item(item: &hir::Item) -> Target {
         match item.node {
-            ast::ItemKind::Fn(..) => Target::Fn,
-            ast::ItemKind::Struct(..) => Target::Struct,
-            ast::ItemKind::Union(..) => Target::Union,
-            ast::ItemKind::Enum(..) => Target::Enum,
+            hir::ItemFn(..) => Target::Fn,
+            hir::ItemStruct(..) => Target::Struct,
+            hir::ItemUnion(..) => Target::Union,
+            hir::ItemEnum(..) => Target::Enum,
             _ => Target::Other,
         }
     }
 }
 
-struct CheckAttrVisitor<'a> {
-    sess: &'a Session,
+struct CheckAttrVisitor<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
-impl<'a> CheckAttrVisitor<'a> {
+impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
     /// Check any attribute.
-    fn check_attributes(&self, item: &ast::Item, target: Target) {
+    fn check_attributes(&self, item: &hir::Item, target: Target) {
+        self.tcx.target_features_enabled(self.tcx.hir.local_def_id(item.id));
+
         for attr in &item.attrs {
             if let Some(name) = attr.name() {
                 if name == "inline" {
@@ -55,20 +56,24 @@ fn check_attributes(&self, item: &ast::Item, target: Target) {
                 }
             }
         }
+
         self.check_repr(item, target);
     }
 
     /// Check if an `#[inline]` is applied to a function.
-    fn check_inline(&self, attr: &ast::Attribute, item: &ast::Item, target: Target) {
+    fn check_inline(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) {
         if target != Target::Fn {
-            struct_span_err!(self.sess, attr.span, E0518, "attribute should be applied to function")
+            struct_span_err!(self.tcx.sess,
+                             attr.span,
+                             E0518,
+                             "attribute should be applied to function")
                 .span_label(item.span, "not a function")
                 .emit();
         }
     }
 
     /// Check if the `#[repr]` attributes on `item` are valid.
-    fn check_repr(&self, item: &ast::Item, target: Target) {
+    fn check_repr(&self, item: &hir::Item, target: Target) {
         // Extract the names of all repr hints, e.g., [foo, bar, align] for:
         // ```
         // #[repr(foo)]
@@ -144,7 +149,7 @@ fn check_repr(&self, item: &ast::Item, target: Target) {
                 }
                 _ => continue,
             };
-            struct_span_err!(self.sess, hint.span, E0517,
+            struct_span_err!(self.tcx.sess, hint.span, E0517,
                              "attribute should be applied to {}", allowed_targets)
                 .span_label(item.span, format!("not {} {}", article, allowed_targets))
                 .emit();
@@ -154,32 +159,37 @@ fn check_repr(&self, item: &ast::Item, target: Target) {
         if (int_reprs > 1)
            || (is_simd && is_c)
            || (int_reprs == 1 && is_c && is_c_like_enum(item)) {
-            // Just point at all repr hints. This is not ideal, but tracking precisely which ones
-            // are at fault is a huge hassle.
+            // Just point at all repr hints. This is not ideal, but tracking
+            // precisely which ones are at fault is a huge hassle.
             let spans: Vec<_> = hints.iter().map(|hint| hint.span).collect();
-            span_warn!(self.sess, spans, E0566,
+            span_warn!(self.tcx.sess, spans, E0566,
                        "conflicting representation hints");
         }
     }
 }
 
-impl<'a> Visitor<'a> for CheckAttrVisitor<'a> {
-    fn visit_item(&mut self, item: &'a ast::Item) {
+impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
+    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
+        NestedVisitorMap::None
+    }
+
+    fn visit_item(&mut self, item: &'tcx hir::Item) {
         let target = Target::from_item(item);
         self.check_attributes(item, target);
-        visit::walk_item(self, item);
+        intravisit::walk_item(self, item);
     }
 }
 
-pub fn check_crate(sess: &Session, krate: &ast::Crate) {
-    visit::walk_crate(&mut CheckAttrVisitor { sess: sess }, krate);
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    let mut checker = CheckAttrVisitor { tcx };
+    tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
 }
 
-fn is_c_like_enum(item: &ast::Item) -> bool {
-    if let ast::ItemKind::Enum(ref def, _) = item.node {
+fn is_c_like_enum(item: &hir::Item) -> bool {
+    if let hir::ItemEnum(ref def, _) = item.node {
         for variant in &def.variants {
             match variant.node.data {
-                ast::VariantData::Unit(_) => { /* continue */ }
+                hir::VariantData::Unit(_) => { /* continue */ }
                 _ => { return false; }
             }
         }
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 74714edfc86461b8b8a08a8cafe05a3d5f819ca7..ce35e6552ca83f8b3099600002cf8787a58099c8 100644 (file)
@@ -498,10 +498,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             // visit_enum_def() takes care of visiting the Item's NodeId
             visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
         }
-        ItemAutoImpl(_, ref trait_ref) => {
-            visitor.visit_id(item.id);
-            visitor.visit_trait_ref(trait_ref)
-        }
         ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_item_refs) => {
             visitor.visit_id(item.id);
             visitor.visit_generics(type_parameters);
index 059181d2a6a579ba2a42be2a10b27ceda0e5bfda..1af7bd46ad4135bc21be45f9dd2550b35f57d622 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(),
@@ -1502,8 +1502,8 @@ fn lower_fn_decl(&mut self,
                      fn_def_id: Option<DefId>,
                      impl_trait_return_allow: bool)
                      -> P<hir::FnDecl> {
-        // NOTE: The two last paramters here have to do with impl Trait. If fn_def_id is Some,
-        //       then impl Trait arguments are lowered into generic paramters on the given
+        // NOTE: The two last parameters here have to do with impl Trait. If fn_def_id is Some,
+        //       then impl Trait arguments are lowered into generic parameters on the given
         //       fn_def_id, otherwise impl Trait is disallowed. (for now)
         //
         //       Furthermore, if impl_trait_return_allow is true, then impl Trait may be used in
@@ -1952,16 +1952,6 @@ fn lower_item_kind(&mut self,
                 let vdata = self.lower_variant_data(vdata);
                 hir::ItemUnion(vdata, self.lower_generics(generics))
             }
-            ItemKind::AutoImpl(unsafety, ref trait_ref) => {
-                let trait_ref = self.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed);
-
-                if let Def::Trait(def_id) = trait_ref.path.def {
-                    self.trait_auto_impl.insert(def_id, id);
-                }
-
-                hir::ItemAutoImpl(self.lower_unsafety(unsafety),
-                                     trait_ref)
-            }
             ItemKind::Impl(unsafety,
                            polarity,
                            defaultness,
index 002849c0399c30e1a644d948d0ee5e2492ae7285..d68b18dd2f17de4bc599457dd8cc31289b618b9f 100644 (file)
@@ -104,8 +104,7 @@ fn visit_item(&mut self, i: &'a Item) {
         // Pick the def data. This need not be unique, but the more
         // information we encapsulate into
         let def_data = match i.node {
-            ItemKind::AutoImpl(..) | ItemKind::Impl(..) =>
-                DefPathData::Impl,
+            ItemKind::Impl(..) => DefPathData::Impl,
             ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
             ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
             ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
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 b386a0c08b0dade97b1ab35b3c43dc61d630ff48..5feea602d281434271462aa244e74912faf4c2aa 100644 (file)
@@ -1192,7 +1192,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 ItemTrait(..) => "trait",
                 ItemTraitAlias(..) => "trait alias",
                 ItemImpl(..) => "impl",
-                ItemAutoImpl(..) => "default impl",
             };
             format!("{} {}{}", item_str, path_str(), id_str)
         }
index 6bdb60a6a1239672bc39032f9c758a34f3d4d52d..8d43b9b4aa7396878c5d9161eef07fb61ba5f46d 100644 (file)
@@ -1965,10 +1965,6 @@ pub enum Item_ {
     /// Represents a Trait Alias Declaration
     ItemTraitAlias(Generics, TyParamBounds),
 
-    /// Auto trait implementations
-    ///
-    /// `impl Trait for .. {}`
-    ItemAutoImpl(Unsafety, TraitRef),
     /// An implementation, eg `impl<A> Trait for Foo { .. }`
     ItemImpl(Unsafety,
              ImplPolarity,
@@ -1996,8 +1992,7 @@ pub fn descriptive_variant(&self) -> &str {
             ItemUnion(..) => "union",
             ItemTrait(..) => "trait",
             ItemTraitAlias(..) => "trait alias",
-            ItemImpl(..) |
-            ItemAutoImpl(..) => "item",
+            ItemImpl(..) => "item",
         }
     }
 
index 2f9fc70252f8da43b1ccef387875ee1a362ae1d2..a8e55674ae521ceb6420fe58e46520e5a868edee 100644 (file)
@@ -652,18 +652,6 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
                 self.head(&visibility_qualified(&item.vis, "union"))?;
                 self.print_struct(struct_def, generics, item.name, item.span, true)?;
             }
-            hir::ItemAutoImpl(unsafety, ref trait_ref) => {
-                self.head("")?;
-                self.print_visibility(&item.vis)?;
-                self.print_unsafety(unsafety)?;
-                self.word_nbsp("impl")?;
-                self.print_trait_ref(trait_ref)?;
-                self.s.space()?;
-                self.word_space("for")?;
-                self.word_space("..")?;
-                self.bopen()?;
-                self.bclose(item.span)?;
-            }
             hir::ItemImpl(unsafety,
                           polarity,
                           defaultness,
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 125b82ab4d0d4903f18782a1575d5ffd9bc8d6a8..cc1b028480e4d7a715e48f4477c88b37cd001aa2 100644 (file)
@@ -854,7 +854,6 @@ fn hash_stable<W: StableHasherResult>(&self,
     ItemUnion(variant_data, generics),
     ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
     ItemTraitAlias(generics, bounds),
-    ItemAutoImpl(unsafety, trait_ref),
     ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
 });
 
index 9d0ddfd4be04b27733ce2c949a19d4a40c3f1605..5617c7723859743cf3f5cd7468475941a81d27ca 100644 (file)
@@ -118,4 +118,17 @@ pub(super) fn try_report_named_anon_conflict(&self) -> Option<ErrorReported> {
             .emit();
         return Some(ErrorReported);
     }
+
+    // This method returns whether the given Region is Named
+    pub(super) fn is_named_region(&self, region: ty::Region<'tcx>) -> bool {
+        match *region {
+            ty::ReStatic => true,
+            ty::ReFree(ref free_region) => match free_region.bound_region {
+                ty::BrNamed(..) => true,
+                _ => false,
+            },
+            ty::ReEarlyBound(_) => true,
+            _ => false,
+        }
+    }
 }
index f8b6f7d0afa93c5bcf68aa272d26ce1f58192b8b..8aadec64554143e08f7a16b4b24337e9b8c08587 100644 (file)
@@ -198,16 +198,4 @@ pub(super) fn is_bound_region_in_impl_item(
         }
         false
     }
-
-    // This method returns whether the given Region is Named
-    pub(super) fn is_named_region(&self, region: Region<'tcx>) -> bool {
-        match *region {
-            ty::ReFree(ref free_region) => match free_region.bound_region {
-                ty::BrNamed(..) => true,
-                _ => false,
-            },
-            ty::ReEarlyBound(_) => true,
-            _ => false,
-        }
-    }
 }
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..1ff9c7a86291eaea07585d515552c9f2449256fb 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![],
@@ -564,7 +564,6 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
                 hir::ItemTrait(..) |
-                hir::ItemAutoImpl(..) |
                 hir::ItemImpl(..) => self.tcx.sess.codemap().def_span(item.span),
                 _ => item.span,
             };
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 6f457c9d1e1b2960a1dc782f8fe7743c9a901ee3..e11609ea9b7982312fd1350ad251d9c85cf852d3 100644 (file)
@@ -270,8 +270,7 @@ fn propagate_node(&mut self, node: &hir_map::Node<'tcx>,
                     hir::ItemMod(..) | hir::ItemForeignMod(..) |
                     hir::ItemImpl(..) | hir::ItemTrait(..) | hir::ItemTraitAlias(..) |
                     hir::ItemStruct(..) | hir::ItemEnum(..) |
-                    hir::ItemUnion(..) | hir::ItemAutoImpl(..) |
-                    hir::ItemGlobalAsm(..) => {}
+                    hir::ItemUnion(..) |  hir::ItemGlobalAsm(..) => {}
                 }
             }
             hir_map::NodeTraitItem(trait_method) => {
index 8b302dbe67a42ab0cecee0b57915b65e86670b98..935dfd75dd8b7c3579ef8d78d63ca2d02c2e9d47 100644 (file)
@@ -461,10 +461,10 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                                           intravisit::walk_item(this, item);
                 });
             }
+
             hir::ItemExternCrate(_)
             | hir::ItemUse(..)
             | hir::ItemMod(..)
-            | hir::ItemAutoImpl(..)
             | hir::ItemForeignMod(..)
             | hir::ItemGlobalAsm(..) => {
                 // These sorts of items have no lifetime parameters at all.
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 6482ecc7ee16124f8597c8905f5a975f017ba189..51d2bc8701a4e18ac806b1396c6438c79a5b5d77 100644 (file)
@@ -2434,7 +2434,7 @@ fn confirm_builtin_candidate(&mut self,
         VtableBuiltinData { nested: obligations }
     }
 
-    /// This handles the case where a `impl Foo for ..` impl is being used.
+    /// This handles the case where a `auto trait Foo` impl is being used.
     /// The idea is that the impl applies to `X : Foo` if the following conditions are met:
     ///
     /// 1. For each constituent type `Y` in `X`, `Y : Foo` holds
@@ -3276,7 +3276,7 @@ pub fn derived_cause(&self,
         /*!
          * Creates a cause for obligations that are derived from
          * `obligation` by a recursive search (e.g., for a builtin
-         * bound, or eventually a `impl Foo for ..`). If `obligation`
+         * bound, or eventually a `auto trait Foo`). If `obligation`
          * is itself a derived obligation, this is just a clone, but
          * otherwise we create a "derived obligation" cause so as to
          * keep track of the original root obligation for error
index 0fecb5314bf440a640c5f007a2a9ce0f45d32934..0c920a6f13e59514d7f7734d1d8477807b82edbc 100644 (file)
@@ -232,11 +232,11 @@ fn push_impl_path<T>(self,
 
         // Always use types for non-local impls, where types are always
         // available, and filename/line-number is mostly uninteresting.
-        let use_types = !self.is_auto_impl(impl_def_id) && (!impl_def_id.is_local() || {
+        let use_types = !impl_def_id.is_local() || {
             // Otherwise, use filename/line-number if forced.
             let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
             !force_no_types
-        });
+        };
 
         if !use_types {
             return self.push_impl_path_fallback(buffer, impl_def_id);
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 881c59e05aac6268f014ee764e04c53b084e991c..8dedcb24c2fb61a8b50dca7a9d2232ab7941ae98 100644 (file)
@@ -631,6 +631,12 @@ fn describe(tcx: TyCtxt, key: (DefId, &'tcx Substs<'tcx>)) -> String {
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the whitelist of target features")
+    }
+}
+
 macro_rules! impl_disk_cacheable_query(
     ($query_name:ident, |$key:tt| $cond:expr) => {
         impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
index bd8c22aab931624714806dca0fde8bf994154995..e7e92b8a4288f87d73ba58fc98039102968a2f6c 100644 (file)
     /// True if this is a foreign item (i.e., linked via `extern { ... }`).
     [] fn is_foreign_item: IsForeignItem(DefId) -> bool,
 
-    /// True if this is an auto impl (aka impl Foo for ..)
-    [] fn is_auto_impl: IsAutoImpl(DefId) -> bool,
-
     /// Get a map with the variance of every item; use `item_variance`
     /// instead.
     [] fn crate_variances: crate_variances(CrateNum) -> Rc<ty::CrateVariancesMap>,
 
     [] fn substitute_normalize_and_test_predicates:
         substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
+
+    [] fn target_features_whitelist:
+        target_features_whitelist_node(CrateNum) -> Rc<FxHashSet<String>>,
+    [] fn target_features_enabled: TargetFeaturesEnabled(DefId) -> Rc<Vec<String>>,
+
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -508,3 +510,7 @@ fn substitute_normalize_and_test_predicates_node<'tcx>(key: (DefId, &'tcx Substs
                                             -> DepConstructor<'tcx> {
     DepConstructor::SubstituteNormalizeAndTestPredicates { key }
 }
+
+fn target_features_whitelist_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::TargetFeaturesWhitelist
+}
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 dd8b8a2e5da8268f5e74c73a13a757e853ce41dd..d670ecc2691ae2f4a93ca47a4b015938e8259064 100644 (file)
@@ -801,7 +801,6 @@ macro_rules! force {
         DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
         DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
         DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
-        DepKind::IsAutoImpl => { force!(is_auto_impl, def_id!()); }
         DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
         DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
         DepKind::FnSignature => { force!(fn_sig, def_id!()); }
@@ -918,6 +917,9 @@ macro_rules! force {
         }
         DepKind::IsTranslatedFunction => { force!(is_translated_function, def_id!()); }
         DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
+
+        DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
+        DepKind::TargetFeaturesEnabled => { force!(target_features_enabled, def_id!()); }
     }
 
     true
index e5f6ac88530675a762624255e708172d8cdc6241..2b4d2c80c6f9e904bc941939fe1ed66d3bf654f2 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) => {
@@ -1553,11 +1553,6 @@ pub fn new(tcx: TyCtxt, did: DefId) -> ReprOptions {
             }
         }
 
-        // FIXME(eddyb) This is deprecated and should be removed.
-        if tcx.has_attr(did, "simd") {
-            flags.insert(ReprFlags::IS_SIMD);
-        }
-
         // This is here instead of layout because the choice must make it into metadata.
         if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) {
             flags.insert(ReprFlags::IS_LINEAR);
@@ -1691,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]
     }
 
@@ -1733,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)
         }
     }
@@ -2319,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)
         }
@@ -2406,8 +2400,6 @@ pub fn has_attr(self, did: DefId, attr: &str) -> bool {
     }
 
     /// Returns true if this is an `auto trait`.
-    ///
-    /// NB. For a limited time, also returns true if `impl Trait for .. { }` is in the code-base.
     pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
         self.trait_def(trait_def_id).has_auto_impl
     }
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 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 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 58112650c05d00bc5fca5246dabbc9bda9cf3514..4529e4bab752cbb51fe1ce2f3526d796d577ed6b 100644 (file)
@@ -772,11 +772,12 @@ pub fn report_reassigned_immutable_variable(&self,
                                                 &move_data::Assignment) {
         let mut err = self.cannot_reassign_immutable(span,
                                                      &self.loan_path_to_string(lp),
+                                                     false,
                                                      Origin::Ast);
         err.span_label(span, "cannot assign twice to immutable variable");
         if span != assign.span {
             err.span_label(assign.span, format!("first assignment to `{}`",
-                                              self.loan_path_to_string(lp)));
+                                                self.loan_path_to_string(lp)));
         }
         err.emit();
     }
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 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 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 51c61005bdd2c85156d0789673a5340163673c7a..73c1b698087fceb8f80c99e6b38c0dec1dc0db0d 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,
@@ -210,10 +210,6 @@ macro_rules! controller_entry_point {
                                     Ok(()));
         }
 
-        time(sess.time_passes(), "attribute checking", || {
-            hir::check_attr::check_crate(sess, &expanded_crate);
-        });
-
         let opt_crate = if control.keep_ast {
             Some(&expanded_crate)
         } else {
@@ -233,18 +229,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));
@@ -889,10 +885,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)
         }
     };
@@ -1037,6 +1034,10 @@ macro_rules! try_with_f {
         // tcx available.
         rustc_incremental::dep_graph_tcx_init(tcx);
 
+        time(sess.time_passes(), "attribute checking", || {
+            hir::check_attr::check_crate(tcx)
+        });
+
         time(time_passes,
              "stability checking",
              || stability::check_unstable_api_usage(tcx));
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 6765ea5e67a6055d61d0040dcb2fc3dab44ad278..371f0e79a3ad1dc9c8f82639821463a4d195f9da 100644 (file)
@@ -246,8 +246,7 @@ fn search(this: &Env, it: &hir::Item, idx: usize, names: &[String]) -> Option<as
                 hir::ItemUnion(..) |
                 hir::ItemTrait(..) |
                 hir::ItemTraitAlias(..) |
-                hir::ItemImpl(..) |
-                hir::ItemAutoImpl(..) => None,
+                hir::ItemImpl(..) => None,
 
                 hir::ItemMod(ref m) => search_mod(this, m, idx, names),
             };
index af556c576c0350e660805bb88229669d786d1491..1c3d4af9e1888cd19f79915a1de2d21a929e5fc7 100644 (file)
@@ -990,7 +990,7 @@ fn emit_message_default(&mut self,
                     buffer.append(buffer_msg_line_offset,
                                   &format!("{}:{}:{}",
                                            loc.file.name,
-                                           loc.line,
+                                           cm.doctest_offset_line(loc.line),
                                            loc.col.0 + 1),
                                   Style::LineAndColumn);
                     for _ in 0..max_line_num_len {
@@ -1000,7 +1000,7 @@ fn emit_message_default(&mut self,
                     buffer.prepend(0,
                                    &format!("{}:{}:{} - ",
                                             loc.file.name,
-                                            loc.line,
+                                            cm.doctest_offset_line(loc.line),
                                             loc.col.0 + 1),
                                    Style::LineAndColumn);
                 }
index c4db39fae86197965db25448d8211e2a6642bfbf..1fb673815eea328c1f34955e73ba5f7e27e7d5ae 100644 (file)
@@ -103,6 +103,7 @@ pub trait CodeMapper {
     fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span>;
     fn call_span_if_macro(&self, sp: Span) -> Span;
     fn ensure_filemap_source_present(&self, file_map: Rc<FileMap>) -> bool;
+    fn doctest_offset_line(&self, line: usize) -> usize;
 }
 
 impl CodeSuggestion {
@@ -310,9 +311,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 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..c3e283535ec8280fd2ba6da371a02a7f2c4e3e23 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> {
@@ -392,9 +393,6 @@ fn auto_labels(&mut self, item_id: ast::NodeId, attr: &Attribute) -> (&'static s
                     //
                     //HirItem::ItemTrait(..) => ("ItemTrait", LABELS_TRAIT),
 
-                    // `impl Trait for .. {}`
-                    HirItem::ItemAutoImpl(..) => ("ItemAutoImpl", LABELS_IMPL),
-
                     // An implementation, eg `impl<A> Trait for Foo { .. }`
                     HirItem::ItemImpl(..) => ("ItemImpl", LABELS_IMPL),
 
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 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..c5c27c92ab49af2899808a5281155e933f487150 100644 (file)
 // hardwired lints from librustc
 pub use lint::builtin::*;
 
-declare_lint! {
-    pub AUTO_IMPL,
-    Deny,
-    "The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`"
-}
-
-#[derive(Copy, Clone)]
-pub struct AutoImpl;
-
-impl LintPass for AutoImpl {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(AUTO_IMPL)
-    }
-}
-
-impl EarlyLintPass for AutoImpl {
-    fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
-        let msg = "The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`";
-        match item.node {
-            ast::ItemKind::AutoImpl(..) => cx.span_lint(AUTO_IMPL, item.span, msg),
-            _ => ()
-        }
-     }
-}
-
 declare_lint! {
     WHILE_TRUE,
     Warn,
@@ -1214,8 +1189,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 3d7f05afefc1f65c0be2690906a0a1c131391b60..699765dde03ffa50070e8636501c14682dc8295c 100644 (file)
@@ -109,7 +109,6 @@ macro_rules! add_lint_group {
                        AnonymousParameters,
                        IllegalFloatLiteralPattern,
                        UnusedDocComment,
-                       AutoImpl,
                        );
 
     add_early_builtin_with_new!(sess,
@@ -183,10 +182,6 @@ macro_rules! add_lint_group {
     // - Eventually, remove lint
     store.register_future_incompatible(sess,
                                        vec![
-        FutureIncompatibleInfo {
-            id: LintId::of(AUTO_IMPL),
-            reference: "issue #13231 <https://github.com/rust-lang/rust/issues/13231>",
-        },
         FutureIncompatibleInfo {
             id: LintId::of(PRIVATE_IN_PUBLIC),
             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
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 955648208cd8b773c68c6f250642ce370aec29fa..d73e968a827600cc92982d14be97793bf49f67ff 100644 (file)
@@ -143,7 +143,6 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
     inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
     is_const_fn => { cdata.is_const_fn(def_id.index) }
     is_foreign_item => { cdata.is_foreign_item(def_id.index) }
-    is_auto_impl => { cdata.is_auto_impl(def_id.index) }
     describe_def => { cdata.get_def(def_id.index) }
     def_span => { cdata.get_span(def_id.index, &tcx.sess) }
     lookup_stability => {
@@ -463,7 +462,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 91703425017f83ea7a97a5e832371129269b295a..bd63396cd35abd6acaaab4223071abb1eee6333f 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,7 +264,7 @@ 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()?))
     }
 }
 
@@ -330,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]
@@ -398,7 +404,6 @@ fn to_def(&self, did: DefId) -> Option<Def> {
 
             EntryKind::ForeignMod |
             EntryKind::Impl(_) |
-            EntryKind::AutoImpl(_) |
             EntryKind::Field |
             EntryKind::Generator(_) |
             EntryKind::Closure(_) => return None,
@@ -447,7 +452,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))
         }
     }
@@ -628,7 +633,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()
                     );
@@ -684,8 +689,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Sessio
                         }
                         continue;
                     }
-                    EntryKind::Impl(_) |
-                    EntryKind::AutoImpl(_) => continue,
+                    EntryKind::Impl(_) => continue,
 
                     _ => {}
                 }
@@ -1039,13 +1043,6 @@ pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool {
         self.dllimport_foreign_items.contains(&id)
     }
 
-    pub fn is_auto_impl(&self, impl_id: DefIndex) -> bool {
-        match self.entry(impl_id).kind {
-            EntryKind::AutoImpl(_) => true,
-            _ => false,
-        }
-    }
-
     pub fn fn_sig(&self,
                   id: DefIndex,
                   tcx: TyCtxt<'a, 'tcx, 'tcx>)
index a42c8be9c20aada1ace4be23db4731ac25674924..78578ca179c8218505122361f99002f79b147965 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;
@@ -139,7 +140,7 @@ 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())
     }
 }
 
@@ -192,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,
@@ -625,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,
@@ -858,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>])
@@ -935,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
@@ -956,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 {
@@ -966,17 +974,6 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                     ctor_sig: None,
                 }), repr_options)
             }
-            hir::ItemAutoImpl(..) => {
-                let data = ImplData {
-                    polarity: hir::ImplPolarity::Positive,
-                    defaultness: hir::Defaultness::Final,
-                    parent_impl: None,
-                    coerce_unsized_info: None,
-                    trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)),
-                };
-
-                EntryKind::AutoImpl(self.lazy(&data))
-            }
             hir::ItemImpl(_, polarity, defaultness, ..) => {
                 let trait_ref = tcx.impl_trait_ref(def_id);
                 let parent = if let Some(trait_ref) = trait_ref {
@@ -1049,7 +1046,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
                     }))
@@ -1571,7 +1568,6 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
             hir::ItemGlobalAsm(..) |
             hir::ItemExternCrate(..) |
             hir::ItemUse(..) |
-            hir::ItemAutoImpl(..) |
             hir::ItemTy(..) |
             hir::ItemTraitAlias(..) => {
                 // no sub-item recording needed in these cases
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 5510d66b55bfb7a2c9160e44cb64dc7550f22805..c542f65dcecf370609dab3821414dd6f2a43e23b 100644 (file)
@@ -303,7 +303,6 @@ pub enum EntryKind<'tcx> {
     Generator(Lazy<GeneratorData<'tcx>>),
     Trait(Lazy<TraitData<'tcx>>),
     Impl(Lazy<ImplData<'tcx>>),
-    AutoImpl(Lazy<ImplData<'tcx>>),
     Method(Lazy<MethodData<'tcx>>),
     AssociatedType(AssociatedContainer),
     AssociatedConst(AssociatedContainer, u8),
@@ -359,7 +358,6 @@ fn hash_stable<W: StableHasherResult>(&self,
             EntryKind::Trait(ref trait_data) => {
                 trait_data.hash_stable(hcx, hasher);
             }
-            EntryKind::AutoImpl(ref impl_data) |
             EntryKind::Impl(ref impl_data) => {
                 impl_data.hash_stable(hcx, hasher);
             }
index 19bebea7cb8f100794e11e0fb09274111fa0da2e..520febca938f098dcba9d4fd89f259602fe2f415 100644 (file)
@@ -10,7 +10,7 @@
 
 use syntax_pos::Span;
 use rustc::middle::region::ScopeTree;
-use rustc::mir::{BorrowKind, Field, Local, Location, Operand};
+use rustc::mir::{BorrowKind, Field, Local, LocalKind, Location, Operand};
 use rustc::mir::{Place, ProjectionElem, Rvalue, Statement, StatementKind};
 use rustc::ty::{self, RegionKind};
 use rustc_data_structures::indexed_vec::Idx;
@@ -568,19 +568,39 @@ pub(super) fn report_illegal_reassignment(
         (place, span): (&Place<'tcx>, Span),
         assigned_span: Span,
     ) {
+        let is_arg = if let Place::Local(local) = place {
+            if let LocalKind::Arg = self.mir.local_kind(*local) {
+                true
+            } else {
+                false
+            }
+        } else {
+            false
+        };
+
         let mut err = self.tcx.cannot_reassign_immutable(
             span,
             &self.describe_place(place).unwrap_or("_".to_owned()),
+            is_arg,
             Origin::Mir,
         );
-        err.span_label(span, "cannot assign twice to immutable variable");
+        let msg = if is_arg {
+            "cannot assign to immutable argument"
+        } else {
+            "cannot assign twice to immutable variable"
+        };
         if span != assigned_span {
-            let value_msg = match self.describe_place(place) {
-                Some(name) => format!("`{}`", name),
-                None => "value".to_owned(),
-            };
-            err.span_label(assigned_span, format!("first assignment to {}", value_msg));
+            if is_arg {
+                err.span_label(assigned_span, "argument not declared as `mut`");
+            } else {
+                let value_msg = match self.describe_place(place) {
+                    Some(name) => format!("`{}`", name),
+                    None => "value".to_owned(),
+                };
+                err.span_label(assigned_span, format!("first assignment to {}", value_msg));
+            }
         }
+        err.span_label(span, msg);
         err.emit();
     }
 }
@@ -719,7 +739,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 50b38f9b46b618b4b2a03ef43198fee253e71e9d..8a0578ae4d45c302f36c5c4a791c63fa99de9a2c 100644 (file)
@@ -214,6 +214,7 @@ fn add_drop_live_constraint(
             // associated types here and possibly recursively process.
             for ty in dtorck_types {
                 let ty = self.cx.normalize(&ty, location);
+                let ty = self.cx.infcx.resolve_type_and_region_vars_if_possible(&ty);
                 match ty.sty {
                     ty::TyParam(..) | ty::TyProjection(..) | ty::TyAnon(..) => {
                         let cause = Cause::DropVar(dropped_local, location);
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 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..f16187797d4e5127d2f6544683207a8cc244cb5c 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());
@@ -910,7 +910,6 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemUse(..)         |
             hir::ItemForeignMod(..)  |
             hir::ItemTy(..)          |
-            hir::ItemAutoImpl(..) |
             hir::ItemTrait(..)       |
             hir::ItemTraitAlias(..)  |
             hir::ItemMod(..)         => {
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 38227bd713322f19ef213aaa1e635f5440dbbb22..4a7ee397aec00b887fd6382f22c52713e93eb22d 100644 (file)
@@ -269,12 +269,17 @@ fn cannot_move_into_closure(&self, span: Span, desc: &str, o: Origin)
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_reassign_immutable(&self, span: Span, desc: &str, o: Origin)
+    fn cannot_reassign_immutable(&self, span: Span, desc: &str, is_arg: bool, o: Origin)
                                  -> DiagnosticBuilder
     {
+        let msg = if is_arg {
+            "to immutable argument"
+        } else {
+            "twice to immutable variable"
+        };
         let err = struct_span_err!(self, span, E0384,
-                                   "cannot assign twice to immutable variable `{}`{OGN}",
-                                   desc, OGN=o);
+                                   "cannot assign {} `{}`{OGN}",
+                                   msg, desc, OGN=o);
 
         self.cancel_if_wrong_origin(err, o)
     }
index 61f54774163d4772fcc0fcaa52aad5b26fc9c5e0..dd7e6a5c1c8024731fb166094beb33db7c75dec9 100644 (file)
@@ -215,8 +215,16 @@ fn visit_lifetime(&mut self, lifetime: &'a Lifetime) {
 
     fn visit_item(&mut self, item: &'a Item) {
         match item.node {
-            ItemKind::Impl(.., Some(..), _, ref impl_items) => {
+            ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => {
                 self.invalid_visibility(&item.vis, item.span, None);
+                if ty.node == TyKind::Err {
+                    self.err_handler()
+                        .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax")
+                        .help("use `auto trait Trait {}` instead").emit();
+                }
+                if unsafety == Unsafety::Unsafe && polarity == ImplPolarity::Negative {
+                    span_err!(self.session, item.span, E0198, "negative impls cannot be unsafe");
+                }
                 for impl_item in impl_items {
                     self.invalid_visibility(&impl_item.vis, impl_item.span, None);
                     if let ImplItemKind::Method(ref sig, _) = impl_item.node {
@@ -224,13 +232,19 @@ fn visit_item(&mut self, item: &'a Item) {
                     }
                 }
             }
-            ItemKind::Impl(.., None, _, _) => {
+            ItemKind::Impl(unsafety, polarity, defaultness, _, None, _, _) => {
                 self.invalid_visibility(&item.vis,
                                         item.span,
                                         Some("place qualifiers on individual impl items instead"));
-            }
-            ItemKind::AutoImpl(..) => {
-                self.invalid_visibility(&item.vis, item.span, None);
+                if unsafety == Unsafety::Unsafe {
+                    span_err!(self.session, item.span, E0197, "inherent impls cannot be unsafe");
+                }
+                if polarity == ImplPolarity::Negative {
+                    self.err_handler().span_err(item.span, "inherent impls cannot be negative");
+                }
+                if defaultness == Defaultness::Default {
+                    self.err_handler().span_err(item.span, "inherent impls cannot be default");
+                }
             }
             ItemKind::ForeignMod(..) => {
                 self.invalid_visibility(&item.vis,
@@ -250,16 +264,16 @@ fn visit_item(&mut self, item: &'a Item) {
                 if is_auto == IsAuto::Yes {
                     // Auto traits cannot have generics, super traits nor contain items.
                     if generics.is_parameterized() {
-                        self.err_handler().span_err(item.span,
-                                                    "auto traits cannot have generics");
+                        struct_span_err!(self.session, item.span, E0567,
+                                        "auto traits cannot have generic parameters").emit();
                     }
                     if !bounds.is_empty() {
-                        self.err_handler().span_err(item.span,
-                                                    "auto traits cannot have super traits");
+                        struct_span_err!(self.session, item.span, E0568,
+                                        "auto traits cannot have super traits").emit();
                     }
                     if !trait_items.is_empty() {
-                        self.err_handler().span_err(item.span,
-                                                    "auto traits cannot contain items");
+                        struct_span_err!(self.session, item.span, E0380,
+                                "auto traits cannot have methods or associated items").emit();
                     }
                 }
                 self.no_questions_in_bounds(bounds, "supertraits", true);
index 3597a6f18287e62e2e9d41640e2b918f8587b84e..743f7b7326e9e5c2526d4a09949fba928f549544 100644 (file)
@@ -82,6 +82,52 @@ struct SomeStruct {
 ```
 "##,
 
+E0197: r##"
+Inherent implementations (one that do not implement a trait but provide
+methods associated with a type) are always safe because they are not
+implementing an unsafe trait. Removing the `unsafe` keyword from the inherent
+implementation will resolve this error.
+
+```compile_fail,E0197
+struct Foo;
+
+// this will cause this error
+unsafe impl Foo { }
+// converting it to this will fix it
+impl Foo { }
+```
+"##,
+
+E0198: r##"
+A negative implementation is one that excludes a type from implementing a
+particular trait. Not being able to use a trait is always a safe operation,
+so negative implementations are always safe and never need to be marked as
+unsafe.
+
+```compile_fail
+#![feature(optin_builtin_traits)]
+
+struct Foo;
+
+// unsafe is unnecessary
+unsafe impl !Clone for Foo { }
+```
+
+This will compile:
+
+```ignore (ignore auto_trait future compatibility warning)
+#![feature(optin_builtin_traits)]
+
+struct Foo;
+
+auto trait Enterprise {}
+
+impl !Enterprise for Foo { }
+```
+
+Please note that negative impls are only allowed for auto traits.
+"##,
+
 E0265: r##"
 This error indicates that a static or constant references itself.
 All statics and constants need to resolve to a value in an acyclic manner.
@@ -150,6 +196,13 @@ fn some_func() {
 [RFC 911]: https://github.com/rust-lang/rfcs/pull/911
 "##,
 
+E0380: r##"
+Auto traits cannot have methods or associated items.
+For more information see the [opt-in builtin traits RFC][RFC 19].
+
+[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
+"##,
+
 E0449: r##"
 A visibility qualifier was used when it was unnecessary. Erroneous code
 examples:
@@ -264,5 +317,7 @@ fn foo() {}
     E0226, // only a single explicit lifetime bound is permitted
     E0472, // asm! is unsupported on this target
     E0561, // patterns aren't allowed in function pointer types
+    E0567, // auto traits can not have generic parameters
+    E0568, // auto traits can not have super traits
     E0642, // patterns aren't allowed in methods without bodies
 }
index d1dc54e7c3a8ec0ca622a050fe46b34af8939047..b525ab852a7e551c70379a3e24ae0520731ddae4 100644 (file)
@@ -147,10 +147,6 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 let def_id = self.tcx.hir.local_def_id(item.id);
                 cmp::min(self.item_ty_level(def_id), self.impl_trait_level(def_id))
             }
-            hir::ItemAutoImpl(..) => {
-                let def_id = self.tcx.hir.local_def_id(item.id);
-                self.impl_trait_level(def_id)
-            }
             // Foreign mods inherit level from parents
             hir::ItemForeignMod(..) => {
                 self.prev_level
@@ -214,7 +210,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             }
             hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
             hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemMod(..) | hir::ItemTraitAlias(..) |
-            hir::ItemFn(..) | hir::ItemExternCrate(..) | hir::ItemAutoImpl(..) => {}
+            hir::ItemFn(..) | hir::ItemExternCrate(..) => {}
         }
 
         // Mark all items in interfaces of reachable items as reachable
@@ -226,8 +222,6 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             // Reexports are handled in visit_mod
             hir::ItemUse(..) => {}
             // The interface is empty
-            hir::ItemAutoImpl(..) => {}
-            // The interface is empty
             hir::ItemGlobalAsm(..) => {}
             // Visit everything
             hir::ItemConst(..) | hir::ItemStatic(..) |
@@ -1571,8 +1565,6 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                     self.check(field.id, min(item_visibility, field_visibility)).ty();
                 }
             }
-            // The interface is empty
-            hir::ItemAutoImpl(..) => {}
             // An inherent impl is public when its type is public
             // Subitems of inherent impls have their own publicity
             hir::ItemImpl(.., None, _, ref impl_item_refs) => {
index 5866c8f93f094cfe51f122856c6b8d807af1a75b..10bd72ac4a00afb10912d2ef087e07b92f78b93e 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!(),
@@ -400,7 +400,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                 self.insert_field_names(item_def_id, field_names);
             }
 
-            ItemKind::AutoImpl(..) | ItemKind::Impl(..) => {}
+            ItemKind::Impl(..) => {}
 
             ItemKind::Trait(..) => {
                 let def_id = self.definitions.local_def_id(item.id);
index 34e32dc9b640f0e6ce457a91b6c47ce460e70cce..0a29441cef7efdfe7395d53fcc41a47242101c15 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,
         };
@@ -1893,12 +1902,6 @@ fn resolve_item(&mut self, item: &Item) {
                                              |this| visit::walk_item(this, item));
             }
 
-            ItemKind::AutoImpl(_, ref trait_ref) => {
-                self.with_optional_trait_ref(Some(trait_ref), |this, _| {
-                    // Resolve type arguments in trait path
-                    visit::walk_trait_ref(this, trait_ref);
-                });
-            }
             ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
                 self.resolve_implementation(generics,
                                             opt_trait_ref,
@@ -2992,11 +2995,11 @@ 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));
+                    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;
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 98cbb6609085cf34fd4c638d6e85c9d391999121..132119e961bc377459d8af78f84872523c49a127 100644 (file)
@@ -623,7 +623,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
                                          "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 is_extern && !token::Ident(source).is_path_segment_keyword() {
                         let crate_id =
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 9211ddfab671edf292caedbaecdc0dfc848852f9..0c890ce19d0818c605c01e193c06be72d5cf82e6 100644 (file)
@@ -511,17 +511,6 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) ->
 
                 Ok(sig)
             }
-            ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
-                let mut text = String::new();
-                if unsafety == ast::Unsafety::Unsafe {
-                    text.push_str("unsafe ");
-                }
-                text.push_str("impl ");
-                let trait_sig = trait_ref.path.make(offset + text.len(), id, scx)?;
-                text.push_str(&trait_sig.text);
-                text.push_str(" for .. {}");
-                Ok(replace_text(trait_sig, text))
-            }
             ast::ItemKind::Impl(
                 unsafety,
                 polarity,
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 745aa0da82900d1681a7432a9afd6745c4ce5c0b..f3105e03523a3ba657f451d4a0885a9dcc6d7bef 100644 (file)
 //! Set and unset common attributes on LLVM values.
 
 use std::ffi::{CStr, CString};
+use std::rc::Rc;
 
+use rustc::hir::Unsafety;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::session::config::Sanitizer;
+use rustc::ty::TyCtxt;
+use rustc::ty::maps::Providers;
+use rustc_data_structures::fx::FxHashSet;
 
 use llvm::{self, Attribute, ValueRef};
 use llvm::AttributePlace::Function;
+use llvm_util;
 pub use syntax::attr::{self, InlineAttr};
 use syntax::ast;
 use context::CrateContext;
@@ -94,23 +101,16 @@ pub fn set_probestack(ccx: &CrateContext, llfn: ValueRef) {
 
 /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
 /// attributes.
-pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
+pub fn from_fn_attrs(ccx: &CrateContext, llfn: ValueRef, id: DefId) {
     use syntax::attr::*;
-    inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs));
+    let attrs = ccx.tcx().get_attrs(id);
+    inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), &attrs));
 
     set_frame_pointer_elimination(ccx, llfn);
     set_probestack(ccx, llfn);
-    let mut target_features = vec![];
-    for attr in attrs {
-        if attr.check_name("target_feature") {
-            if let Some(val) = attr.value_str() {
-                for feat in val.as_str().split(",").map(|f| f.trim()) {
-                    if !feat.is_empty() && !feat.contains('\0') {
-                        target_features.push(feat.to_string());
-                    }
-                }
-            }
-        } else if attr.check_name("cold") {
+
+    for attr in attrs.iter() {
+        if attr.check_name("cold") {
             Attribute::Cold.apply_llfn(Function, llfn);
         } else if attr.check_name("naked") {
             naked(llfn, true);
@@ -123,6 +123,8 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
             unwind(llfn, false);
         }
     }
+
+    let target_features = ccx.tcx().target_features_enabled(id);
     if !target_features.is_empty() {
         let val = CString::new(target_features.join(",")).unwrap();
         llvm::AddFunctionAttrStringValue(
@@ -134,3 +136,97 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
 fn cstr(s: &'static str) -> &CStr {
     CStr::from_bytes_with_nul(s.as_bytes()).expect("null-terminated string")
 }
+
+pub fn provide(providers: &mut Providers) {
+    providers.target_features_whitelist = |tcx, cnum| {
+        assert_eq!(cnum, LOCAL_CRATE);
+        Rc::new(llvm_util::target_feature_whitelist(tcx.sess)
+            .iter()
+            .map(|c| c.to_str().unwrap().to_string())
+            .collect())
+    };
+
+    providers.target_features_enabled = |tcx, id| {
+        let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
+        let mut target_features = Vec::new();
+        for attr in tcx.get_attrs(id).iter() {
+            if !attr.check_name("target_feature") {
+                continue
+            }
+            if let Some(val) = attr.value_str() {
+                for feat in val.as_str().split(",").map(|f| f.trim()) {
+                    if !feat.is_empty() && !feat.contains('\0') {
+                        target_features.push(feat.to_string());
+                    }
+                }
+                let msg = "#[target_feature = \"..\"] is deprecated and will \
+                           eventually be removed, use \
+                           #[target_feature(enable = \"..\")] instead";
+                tcx.sess.span_warn(attr.span, &msg);
+                continue
+            }
+
+            if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
+                let msg = "#[target_feature(..)] can only be applied to \
+                           `unsafe` function";
+                tcx.sess.span_err(attr.span, msg);
+            }
+            from_target_feature(tcx, attr, &whitelist, &mut target_features);
+        }
+        Rc::new(target_features)
+    };
+}
+
+fn from_target_feature(
+    tcx: TyCtxt,
+    attr: &ast::Attribute,
+    whitelist: &FxHashSet<String>,
+    target_features: &mut Vec<String>,
+) {
+    let list = match attr.meta_item_list() {
+        Some(list) => list,
+        None => {
+            let msg = "#[target_feature] attribute must be of the form \
+                       #[target_feature(..)]";
+            tcx.sess.span_err(attr.span, &msg);
+            return
+        }
+    };
+
+    for item in list {
+        if !item.check_name("enable") {
+            let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
+                       currently";
+            tcx.sess.span_err(item.span, &msg);
+            continue
+        }
+        let value = match item.value_str() {
+            Some(list) => list,
+            None => {
+                let msg = "#[target_feature] attribute must be of the form \
+                           #[target_feature(enable = \"..\")]";
+                tcx.sess.span_err(item.span, &msg);
+                continue
+            }
+        };
+        let value = value.as_str();
+        for feature in value.split(',') {
+            if whitelist.contains(feature) {
+                target_features.push(format!("+{}", feature));
+                continue
+            }
+
+            let msg = format!("the feature named `{}` is not valid for \
+                               this target", feature);
+            let mut err = tcx.sess.struct_span_err(item.span, &msg);
+
+            if feature.starts_with("+") {
+                let valid = whitelist.contains(&feature[1..]);
+                if valid {
+                    err.help("consider removing the leading `+` in the feature name");
+                }
+            }
+            err.emit();
+        }
+    }
+}
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 0a0f2615a1bd162242051521a0a71ae9adface6a..ccbc6620ffe09b0755a488e3e254a1af06da0683 100644 (file)
@@ -99,8 +99,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         if instance.def.is_inline(tcx) {
             attributes::inline(llfn, attributes::InlineAttr::Hint);
         }
-        let attrs = instance.def.attrs(ccx.tcx());
-        attributes::from_fn_attrs(ccx, &attrs, llfn);
+        attributes::from_fn_attrs(ccx, llfn, instance.def.def_id());
 
         let instance_def_id = instance.def_id();
 
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..974c268749b859a5620059aea0f6e6846963aaa7 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;
@@ -166,6 +167,7 @@ fn provide(providers: &mut ty::maps::Providers) {
         back::symbol_names::provide(providers);
         back::symbol_export::provide(providers);
         base::provide(providers);
+        attributes::provide(providers);
     }
 
     fn provide_extern(providers: &mut ty::maps::Providers) {
index a9ea96134faf2aa7f7d2691c8138b5b1c6c65cf2..8112a9eeab1ef4d8d622bd5dcfc5a561eccb153e 100644 (file)
@@ -13,8 +13,8 @@
 use llvm;
 use rustc::session::Session;
 use rustc::session::config::PrintRequest;
-use libc::{c_int, c_char};
-use std::ffi::CString;
+use libc::c_int;
+use std::ffi::{CStr, CString};
 
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::Once;
@@ -97,8 +97,18 @@ unsafe fn configure_llvm(sess: &Session) {
 const MIPS_WHITELIST: &'static [&'static str] = &["msa\0"];
 
 pub fn target_features(sess: &Session) -> Vec<Symbol> {
+    let whitelist = target_feature_whitelist(sess);
     let target_machine = create_target_machine(sess);
+    let mut features = Vec::new();
+    for feat in whitelist {
+        if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr()) } {
+            features.push(Symbol::intern(feat.to_str().unwrap()));
+        }
+    }
+    features
+}
 
+pub fn target_feature_whitelist(sess: &Session) -> Vec<&CStr> {
     let whitelist = match &*sess.target.target.arch {
         "arm" => ARM_WHITELIST,
         "aarch64" => AARCH64_WHITELIST,
@@ -108,15 +118,9 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
         "powerpc" | "powerpc64" => POWERPC_WHITELIST,
         _ => &[],
     };
-
-    let mut features = Vec::new();
-    for feat in whitelist {
-        assert_eq!(feat.chars().last(), Some('\0'));
-        if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
-            features.push(Symbol::intern(&feat[..feat.len() - 1]));
-        }
-    }
-    features
+    whitelist.iter().map(|m| {
+        CStr::from_bytes_with_nul(m.as_bytes()).unwrap()
+    }).collect()
 }
 
 pub fn print_version() {
@@ -140,7 +144,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 31d8e092c4ae49a05486d78c11ad89d3a054cbce..fa6a42e062d9fb5645f755a78b4f4ccc3222e995 100644 (file)
@@ -199,7 +199,7 @@ fn predefine_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     if instance.def.is_inline(ccx.tcx()) {
         attributes::inline(lldecl, attributes::InlineAttr::Hint);
     }
-    attributes::from_fn_attrs(ccx, &attrs, lldecl);
+    attributes::from_fn_attrs(ccx, lldecl, instance.def.def_id());
 
     ccx.instances().borrow_mut().insert(instance, lldecl);
 }
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 15e16e59dd27c3a964f14d8fe94134c6fdb526c1..3f8792aa637a9cb711303f1f064faa86da2250c3 100644 (file)
@@ -289,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 {
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..3668fc46ddc27b0e0fbba290fa762cc4f809f757 100644 (file)
@@ -107,16 +107,21 @@ fn check_item_well_formed(&mut self, item: &hir::Item) {
             //
             // won't be allowed unless there's an *explicit* implementation of `Send`
             // for `T`
-            hir::ItemImpl(_, hir::ImplPolarity::Positive, _, _,
-                          ref trait_ref, ref self_ty, _) => {
-                self.check_impl(item, self_ty, trait_ref);
-            }
-            hir::ItemImpl(_, hir::ImplPolarity::Negative, _, _, Some(_), ..) => {
-                // FIXME(#27579) what amount of WF checking do we need for neg impls?
-
-                let trait_ref = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)).unwrap();
-                if !tcx.trait_is_auto(trait_ref.def_id) {
-                    error_192(tcx, item.span);
+            hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => {
+                let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id))
+                                 .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
+                if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
+                    tcx.sess.span_err(item.span, "impls of auto traits cannot be default");
+                }
+                if polarity == hir::ImplPolarity::Positive {
+                    self.check_impl(item, self_ty, trait_ref);
+                } else {
+                    // FIXME(#27579) what amount of WF checking do we need for neg impls?
+                    if trait_ref.is_some() && !is_auto {
+                        span_err!(tcx.sess, item.span, E0192,
+                                  "negative impls are only allowed for \
+                                   auto traits (e.g., `Send` and `Sync`)")
+                    }
                 }
             }
             hir::ItemFn(..) => {
@@ -130,14 +135,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);
@@ -275,74 +280,8 @@ fn check_type_defn<F>(&mut self, item: &hir::Item, all_sized: bool, mut lookup_f
         });
     }
 
-    fn check_auto_trait(&mut self, trait_def_id: DefId, span: Span) {
-        // We want to ensure:
-        //
-        // 1) that there are no items contained within
-        // the trait definition
-        //
-        // 2) that the definition doesn't violate the no-super trait rule
-        // for auto traits.
-        //
-        // 3) that the trait definition does not have any type parameters
-
-        let predicates = self.tcx.predicates_of(trait_def_id);
-
-        // We must exclude the Self : Trait predicate contained by all
-        // traits.
-        let has_predicates =
-            predicates.predicates.iter().any(|predicate| {
-                match predicate {
-                    &ty::Predicate::Trait(ref poly_trait_ref) => {
-                        let self_ty = poly_trait_ref.0.self_ty();
-                        !(self_ty.is_self() && poly_trait_ref.def_id() == trait_def_id)
-                    },
-                    _ => true,
-                }
-            });
-
-        let has_ty_params = self.tcx.generics_of(trait_def_id).types.len() > 1;
-
-        // We use an if-else here, since the generics will also trigger
-        // an extraneous error message when we find predicates like
-        // `T : Sized` for a trait like: `trait Magic<T>`.
-        //
-        // We also put the check on the number of items here,
-        // as it seems confusing to report an error about
-        // extraneous predicates created by things like
-        // an associated type inside the trait.
-        let mut err = None;
-        if !self.tcx.associated_item_def_ids(trait_def_id).is_empty() {
-            error_380(self.tcx, span);
-        } else if has_ty_params {
-            err = Some(struct_span_err!(self.tcx.sess, span, E0567,
-                "traits with auto impls (`e.g. impl \
-                    Trait for ..`) can not have type parameters"));
-        } else if has_predicates {
-            err = Some(struct_span_err!(self.tcx.sess, span, E0568,
-                "traits with auto impls (`e.g. impl \
-                    Trait for ..`) cannot have predicates"));
-        }
-
-        // Finally if either of the above conditions apply we should add a note
-        // indicating that this error is the result of a recent soundness fix.
-        match err {
-            None => {},
-            Some(mut e) => {
-                e.note("the new auto trait rules are the result of a \
-                          recent soundness fix; see #29859 for more details");
-                e.emit();
-            }
-        }
-    }
-
     fn check_trait(&mut self, item: &hir::Item) {
         let trait_def_id = self.tcx.hir.local_def_id(item.id);
-
-        if self.tcx.trait_is_auto(trait_def_id) {
-            self.check_auto_trait(trait_def_id, item.span);
-        }
-
         self.for_item(item).with_fcx(|fcx, this| {
             let predicates = fcx.tcx.predicates_of(trait_def_id).instantiate_identity(fcx.tcx);
             let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
@@ -689,7 +628,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 +643,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()
     }
 
@@ -727,18 +666,6 @@ fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
     }
 }
 
-fn error_192(tcx: TyCtxt, span: Span) {
-    span_err!(tcx.sess, span, E0192,
-              "negative impls are only allowed for traits with \
-               default impls (e.g., `Send` and `Sync`)")
-}
-
-fn error_380(tcx: TyCtxt, span: Span) {
-    span_err!(tcx.sess, span, E0380,
-              "traits with default impls (`e.g. impl \
-               Trait for ..`) must have no methods or associated items")
-}
-
 fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast::Name)
                        -> DiagnosticBuilder<'tcx> {
     let mut err = struct_span_err!(tcx.sess, span, E0392,
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 4256a1fe12b60a70bfa9a7246123409f4401fbec..2b81c82bc2945f9176dc34fbeea7b551e66eca56 100644 (file)
@@ -93,23 +93,11 @@ struct InherentCollect<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
-        let (unsafety, ty) = match item.node {
-            hir::ItemImpl(unsafety, .., None, ref ty, _) => (unsafety, ty),
+        let ty = match item.node {
+            hir::ItemImpl(.., None, ref ty, _) => ty,
             _ => return
         };
 
-        match unsafety {
-            hir::Unsafety::Normal => {
-                // OK
-            }
-            hir::Unsafety::Unsafe => {
-                span_err!(self.tcx.sess,
-                          item.span,
-                          E0197,
-                          "inherent impls cannot be declared as unsafe");
-            }
-        }
-
         let def_id = self.tcx.hir.local_def_id(item.id);
         let self_ty = self.tcx.type_of(def_id);
         let lang_items = self.tcx.lang_items();
index adf154968c229813a3fea160ff0f6856d72dbdd3..f65d627781f0fb802b848fcc40f5ad5c145d0b3f 100644 (file)
@@ -16,6 +16,7 @@
 // mappings. That mapping code resides here.
 
 use hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::traits;
 use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc::ty::maps::Providers;
 
@@ -25,7 +26,6 @@
 mod inherent_impls;
 mod inherent_impls_overlap;
 mod orphan;
-mod overlap;
 mod unsafety;
 
 fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
@@ -119,7 +119,7 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
         check_impl(tcx, impl_id);
     }
     for &impl_id in impls {
-        overlap::check_impl(tcx, impl_id);
+        check_impl_overlap(tcx, impl_id);
     }
     builtin::check_trait(tcx, def_id);
 }
@@ -131,9 +131,51 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
 
     unsafety::check(tcx);
     orphan::check(tcx);
-    overlap::check_auto_impls(tcx);
 
     // these queries are executed for side-effects (error reporting):
     ty::maps::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
     ty::maps::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE);
 }
+
+/// Overlap: No two impls for the same trait are implemented for the
+/// same type. Likewise, no two inherent impls for a given type
+/// constructor provide a method with the same name.
+fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
+    let impl_def_id = tcx.hir.local_def_id(node_id);
+    let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
+    let trait_def_id = trait_ref.def_id;
+
+    if trait_ref.references_error() {
+        debug!("coherence: skipping impl {:?} with error {:?}",
+               impl_def_id, trait_ref);
+        return
+    }
+
+    // Trigger building the specialization graph for the trait of this impl.
+    // This will detect any overlap errors.
+    tcx.specialization_graph_of(trait_def_id);
+
+    // check for overlap with the automatic `impl Trait for Trait`
+    if let ty::TyDynamic(ref data, ..) = trait_ref.self_ty().sty {
+        // This is something like impl Trait1 for Trait2. Illegal
+        // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
+
+        if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
+            // This is an error, but it will be reported by wfcheck.  Ignore it here.
+            // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
+        } else {
+            let mut supertrait_def_ids =
+                traits::supertrait_def_ids(tcx,
+                                           data.principal().unwrap().def_id());
+            if supertrait_def_ids.any(|d| d == trait_def_id) {
+                span_err!(tcx.sess,
+                          tcx.span_of_impl(impl_def_id).unwrap(),
+                          E0371,
+                          "the object type `{}` automatically \
+                           implements the trait `{}`",
+                          trait_ref.self_ty(),
+                          tcx.item_path_str(trait_def_id));
+            }
+        }
+    }
+}
index 9f183973621894e6ad465893540fd1d92fa3cfc7..c2dfd798a3c4a7d9be89fde45bebedb98b2dc518 100644 (file)
@@ -67,16 +67,15 @@ fn visit_item(&mut self, item: &hir::Item) {
                     }
                 }
 
-                // In addition to the above rules, we restrict impls of defaulted traits
+                // In addition to the above rules, we restrict impls of auto traits
                 // so that they can only be implemented on nominal types, such as structs,
                 // enums or foreign types. To see why this restriction exists, consider the
-                // following example (#22978). Imagine that crate A defines a defaulted trait
+                // following example (#22978). Imagine that crate A defines an auto trait
                 // `Foo` and a fn that operates on pairs of types:
                 //
                 // ```
                 // // Crate A
-                // trait Foo { }
-                // impl Foo for .. { }
+                // auto trait Foo { }
                 // fn two_foos<A:Foo,B:Foo>(..) {
                 //     one_foo::<(A,B)>(..)
                 // }
@@ -142,24 +141,6 @@ fn visit_item(&mut self, item: &hir::Item) {
                     }
                 }
             }
-            hir::ItemAutoImpl(_, ref item_trait_ref) => {
-                // "Trait" impl
-                debug!("coherence2::orphan check: default trait impl {}",
-                       self.tcx.hir.node_to_string(item.id));
-                let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
-                if !trait_ref.def_id.is_local() {
-                    struct_span_err!(self.tcx.sess,
-                                     item_trait_ref.path.span,
-                                     E0318,
-                                     "cannot create default implementations for traits outside \
-                                      the crate they're defined in; define a new trait instead")
-                        .span_label(item_trait_ref.path.span,
-                                    format!("`{}` trait not defined in this crate",
-                            self.tcx.hir.node_to_pretty_string(item_trait_ref.ref_id)))
-                        .emit();
-                    return;
-                }
-            }
             _ => {
                 // Not an impl
             }
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
deleted file mode 100644 (file)
index 5cc6eaa..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Overlap: No two impls for the same trait are implemented for the
-//! same type. Likewise, no two inherent impls for a given type
-//! constructor provide a method with the same name.
-
-use rustc::traits;
-use rustc::ty::{self, TyCtxt, TypeFoldable};
-use syntax::ast;
-use rustc::hir;
-use rustc::hir::itemlikevisit::ItemLikeVisitor;
-
-pub fn check_auto_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let mut overlap = OverlapChecker { tcx };
-
-    // this secondary walk specifically checks for some other cases,
-    // like defaulted traits, for which additional overlap rules exist
-    tcx.hir.krate().visit_all_item_likes(&mut overlap);
-}
-
-pub fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
-    let impl_def_id = tcx.hir.local_def_id(node_id);
-    let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
-    let trait_def_id = trait_ref.def_id;
-
-    if trait_ref.references_error() {
-        debug!("coherence: skipping impl {:?} with error {:?}",
-               impl_def_id, trait_ref);
-        return
-    }
-
-    // Trigger building the specialization graph for the trait of this impl.
-    // This will detect any overlap errors.
-    tcx.specialization_graph_of(trait_def_id);
-
-
-    // check for overlap with the automatic `impl Trait for Trait`
-    if let ty::TyDynamic(ref data, ..) = trait_ref.self_ty().sty {
-        // This is something like impl Trait1 for Trait2. Illegal
-        // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
-
-        if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
-            // This is an error, but it will be reported by wfcheck.  Ignore it here.
-            // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
-        } else {
-            let mut supertrait_def_ids =
-                traits::supertrait_def_ids(tcx,
-                                           data.principal().unwrap().def_id());
-            if supertrait_def_ids.any(|d| d == trait_def_id) {
-                span_err!(tcx.sess,
-                          tcx.span_of_impl(impl_def_id).unwrap(),
-                          E0371,
-                          "the object type `{}` automatically \
-                           implements the trait `{}`",
-                          trait_ref.self_ty(),
-                          tcx.item_path_str(trait_def_id));
-            }
-        }
-    }
-}
-
-struct OverlapChecker<'cx, 'tcx: 'cx> {
-    tcx: TyCtxt<'cx, 'tcx, 'tcx>,
-}
-
-impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &'v hir::Item) {
-        match item.node {
-            hir::ItemAutoImpl(..) => {
-                // look for another auto impl; note that due to the
-                // general orphan/coherence rules, it must always be
-                // in this crate.
-                let impl_def_id = self.tcx.hir.local_def_id(item.id);
-                let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
-
-                let prev_id = self.tcx.hir.trait_auto_impl(trait_ref.def_id).unwrap();
-                if prev_id != item.id {
-                    let mut err = struct_span_err!(self.tcx.sess,
-                                                   self.tcx.span_of_impl(impl_def_id).unwrap(),
-                                                   E0521,
-                                                   "redundant auto implementations of trait \
-                                                    `{}`:",
-                                                   trait_ref);
-                    err.span_note(self.tcx
-                                      .span_of_impl(self.tcx.hir.local_def_id(prev_id))
-                                      .unwrap(),
-                                  "redundant implementation is here:");
-                    err.emit();
-                }
-            }
-            hir::ItemImpl(.., Some(_), _, _) => {
-            }
-            _ => {}
-        }
-    }
-
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
-    }
-
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
-    }
-}
index 280fb04e040011f8af896dd646387652f4a6ab2d..4aa876e85b69a5e2d0e1ee60e2c1f2cc43185fbb 100644 (file)
@@ -37,14 +37,7 @@ fn check_unsafety_coherence(&mut self,
                 let trait_def = self.tcx.trait_def(trait_ref.def_id);
                 let unsafe_attr = impl_generics.and_then(|g| g.carries_unsafe_attr());
                 match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
-                    (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative) => {
-                        span_err!(self.tcx.sess,
-                                  item.span,
-                                  E0198,
-                                  "negative implementations are not unsafe");
-                    }
-
-                    (Unsafety::Normal, None, Unsafety::Unsafe, _) => {
+                    (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
                         span_err!(self.tcx.sess,
                                   item.span,
                                   E0199,
@@ -69,6 +62,10 @@ fn check_unsafety_coherence(&mut self,
                                   g.attr_name());
                     }
 
+                    (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative) => {
+                        // Reported in AST validation
+                        self.tcx.sess.delay_span_bug(item.span, "unsafe negative impl");
+                    }
                     (_, _, Unsafety::Normal, hir::ImplPolarity::Negative) |
                     (Unsafety::Unsafe, _, Unsafety::Unsafe, hir::ImplPolarity::Positive) |
                     (Unsafety::Normal, Some(_), Unsafety::Unsafe, hir::ImplPolarity::Positive) |
@@ -84,9 +81,6 @@ fn check_unsafety_coherence(&mut self,
 impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> {
     fn visit_item(&mut self, item: &'v hir::Item) {
         match item.node {
-            hir::ItemAutoImpl(unsafety, _) => {
-                self.check_unsafety_coherence(item, None, unsafety, hir::ImplPolarity::Positive);
-            }
             hir::ItemImpl(unsafety, polarity, _, ref generics, ..) => {
                 self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
             }
index 0a6d87e5a60b74e4e4b0701e29dac7c3a76afc6c..5485045b7043897f459e02445b8152abde6a1096 100644 (file)
@@ -73,7 +73,6 @@ pub fn provide(providers: &mut Providers) {
         impl_trait_ref,
         impl_polarity,
         is_foreign_item,
-        is_auto_impl,
         ..*providers
     };
 }
@@ -424,9 +423,6 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
             tcx.predicates_of(def_id);
             convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
         },
-        hir::ItemAutoImpl(..) => {
-            tcx.impl_trait_ref(def_id);
-        }
         hir::ItemImpl(..) => {
             tcx.generics_of(def_id);
             tcx.type_of(def_id);
@@ -716,9 +712,9 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
     let item = tcx.hir.expect_item(node_id);
 
-    let unsafety = match item.node {
-        hir::ItemTrait(_, unsafety, ..) => unsafety,
-        hir::ItemTraitAlias(..) => hir::Unsafety::Normal,
+    let (is_auto, unsafety) = match item.node {
+        hir::ItemTrait(is_auto, unsafety, ..) => (is_auto == hir::IsAuto::Yes, unsafety),
+        hir::ItemTraitAlias(..) => (false, hir::Unsafety::Normal),
         _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
     };
 
@@ -735,10 +731,6 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
     let def_path_hash = tcx.def_path_hash(def_id);
-    let is_auto = match item.node {
-        hir::ItemTrait(hir::IsAuto::Yes, ..) => true,
-        _ => tcx.hir.trait_is_auto(def_id),
-    };
     let def = ty::TraitDef::new(def_id,
                                 unsafety,
                                 paren_sugar,
@@ -1109,7 +1101,6 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     let substs = Substs::identity_for_item(tcx, def_id);
                     tcx.mk_adt(def, substs)
                 }
-                ItemAutoImpl(..) |
                 ItemTrait(..) | ItemTraitAlias(..) |
                 ItemMod(..) |
                 ItemForeignMod(..) |
@@ -1278,11 +1269,6 @@ fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
     match tcx.hir.expect_item(node_id).node {
-        hir::ItemAutoImpl(_, ref ast_trait_ref) => {
-            Some(AstConv::instantiate_mono_trait_ref(&icx,
-                                                     ast_trait_ref,
-                                                     tcx.mk_self_type()))
-        }
         hir::ItemImpl(.., ref opt_trait_ref, _, _) => {
             opt_trait_ref.as_ref().map(|ast_trait_ref| {
                 let selfty = tcx.type_of(def_id);
@@ -1728,14 +1714,3 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
     }
 }
-
-fn is_auto_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             def_id: DefId)
-                             -> bool {
-    match tcx.hir.get_if_local(def_id) {
-        Some(hir_map::NodeItem(&hir::Item { node: hir::ItemAutoImpl(..), .. }))
-             => true,
-        Some(_) => false,
-        _ => bug!("is_auto_impl applied to non-local def-id {:?}", def_id)
-    }
-}
index defcbdfe03d053633ef88df88585af1d1529db87..1913b940c08fe2db38d48fbe297c00cb322bca6a 100644 (file)
@@ -1715,7 +1715,7 @@ trait Trait {
 "##,
 
 E0192: r##"
-Negative impls are only allowed for traits with default impls. For more
+Negative impls are only allowed for auto traits. For more
 information see the [opt-in builtin traits RFC][RFC 19].
 
 [RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
@@ -1821,54 +1821,6 @@ fn t<'a,'b:'a>(x: &'a str, y: &'b str) { // ok!
 ```
 "##,
 
-E0197: r##"
-Inherent implementations (one that do not implement a trait but provide
-methods associated with a type) are always safe because they are not
-implementing an unsafe trait. Removing the `unsafe` keyword from the inherent
-implementation will resolve this error.
-
-```compile_fail,E0197
-struct Foo;
-
-// this will cause this error
-unsafe impl Foo { }
-// converting it to this will fix it
-impl Foo { }
-```
-"##,
-
-E0198: r##"
-A negative implementation is one that excludes a type from implementing a
-particular trait. Not being able to use a trait is always a safe operation,
-so negative implementations are always safe and never need to be marked as
-unsafe.
-
-```compile_fail
-#![feature(optin_builtin_traits)]
-
-struct Foo;
-
-// unsafe is unnecessary
-unsafe impl !Clone for Foo { }
-```
-
-This will compile:
-
-```ignore (ignore auto_trait future compatibility warning)
-#![feature(optin_builtin_traits)]
-
-struct Foo;
-
-trait Enterprise {}
-
-impl Enterprise for .. { }
-
-impl !Enterprise for Foo { }
-```
-
-Please note that negative impls are only allowed for traits with default impls.
-"##,
-
 E0199: r##"
 Safe traits should not have unsafe implementations, therefore marking an
 implementation for a safe trait unsafe will cause a compiler error. Removing
@@ -2533,13 +2485,6 @@ struct Bar<S, T> { x: Foo<S, T> }
 ```
 "##,
 
-E0318: r##"
-Default impls for a trait must be located in the same crate where the trait was
-defined. For more information see the [opt-in builtin traits RFC][RFC 19].
-
-[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
-"##,
-
 E0321: r##"
 A cross-crate opt-out trait was implemented on something which wasn't a struct
 or enum type. Erroneous code example:
@@ -3172,13 +3117,6 @@ impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
 struct.
 "##,
 
-E0380: r##"
-Default impls are only allowed for traits with no methods or associated items.
-For more information see the [opt-in builtin traits RFC][RFC 19].
-
-[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
-"##,
-
 E0390: r##"
 You tried to implement methods for a primitive type. Erroneous code example:
 
@@ -4731,13 +4669,10 @@ fn foo<U: Iterator>(&self, _: &U) { } // error method `foo` has incompatible
 //  E0372, // coherence not object safe
     E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
            // between structures with the same definition
-    E0521, // redundant auto implementations of trait
     E0533, // `{}` does not name a unit variant, unit struct or a constant
 //  E0563, // cannot determine a type for this `impl Trait`: {} // removed in 6383de15
     E0564, // only named lifetimes are allowed in `impl Trait`,
            // but `{}` was found in the type `{}`
-    E0567, // auto traits can not have type parameters
-    E0568, // auto-traits can not have predicates,
     E0587, // struct has conflicting packed and align representation hints
     E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
     E0592, // duplicate definitions with name `{}`
index 914365b003e18472a7a909020138e70daca7bd61..496389da7f2f165c8b8a04edc68aa99bdf90e7eb 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,
@@ -300,27 +300,6 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
         }
     }
 
-    // If this is an auto impl, then bail out early here
-    if tcx.is_auto_impl(did) {
-        return ret.push(clean::Item {
-            inner: clean::AutoImplItem(clean::AutoImpl {
-                // FIXME: this should be decoded
-                unsafety: hir::Unsafety::Normal,
-                trait_: match associated_trait.as_ref().unwrap().clean(cx) {
-                    clean::TraitBound(polyt, _) => polyt.trait_,
-                    clean::RegionBound(..) => unreachable!(),
-                },
-            }),
-            source: tcx.def_span(did).clean(cx),
-            name: None,
-            attrs,
-            visibility: Some(clean::Inherited),
-            stability: tcx.lookup_stability(did).clean(cx),
-            deprecation: tcx.lookup_deprecation(did).clean(cx),
-            def_id: did,
-        });
-    }
-
     let for_ = tcx.type_of(did).clean(cx);
 
     // Only inline impl if the implementing type is
index 265114ae826f48d9e86145b602c2da4cf208cbb4..271bc967bc9bc1021d1a0bf1692d5419ae75fb74 100644 (file)
@@ -430,7 +430,6 @@ pub enum ItemEnum {
     PrimitiveItem(PrimitiveType),
     AssociatedConstItem(Type, Option<String>),
     AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
-    AutoImplItem(AutoImpl),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemEnum>),
 }
@@ -481,7 +480,6 @@ fn clean(&self, cx: &DocContext) -> Item {
         items.extend(self.traits.iter().map(|x| x.clean(cx)));
         items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
         items.extend(self.macros.iter().map(|x| x.clean(cx)));
-        items.extend(self.def_traits.iter().map(|x| x.clean(cx)));
 
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
@@ -2941,30 +2939,6 @@ fn build_deref_target_impls(cx: &DocContext,
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct AutoImpl {
-    pub unsafety: hir::Unsafety,
-    pub trait_: Type,
-}
-
-impl Clean<Item> for doctree::AutoImpl {
-    fn clean(&self, cx: &DocContext) -> Item {
-        Item {
-            name: None,
-            attrs: self.attrs.clean(cx),
-            source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
-            visibility: Some(Public),
-            stability: None,
-            deprecation: None,
-            inner: AutoImplItem(AutoImpl {
-                unsafety: self.unsafety,
-                trait_: self.trait_.clean(cx),
-            }),
-        }
-    }
-}
-
 impl Clean<Item> for doctree::ExternCrate {
     fn clean(&self, cx: &DocContext) -> Item {
         Item {
index c21bfd8842f7240efdc7220be531038bbd55920c..776ec7f409c4488910a2187a3be0161cb3e31660 100644 (file)
@@ -44,7 +44,6 @@ pub struct Module {
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub impls: Vec<Impl>,
-    pub def_traits: Vec<AutoImpl>,
     pub foreigns: Vec<hir::ForeignMod>,
     pub macros: Vec<Macro>,
     pub is_crate: bool,
@@ -73,7 +72,6 @@ pub fn new(name: Option<Name>) -> Module {
             constants  : Vec::new(),
             traits     : Vec::new(),
             impls      : Vec::new(),
-            def_traits : Vec::new(),
             foreigns   : Vec::new(),
             macros     : Vec::new(),
             is_crate   : false,
@@ -227,14 +225,6 @@ pub struct Impl {
     pub id: ast::NodeId,
 }
 
-pub struct AutoImpl {
-    pub unsafety: hir::Unsafety,
-    pub trait_: hir::TraitRef,
-    pub id: ast::NodeId,
-    pub attrs: hir::HirVec<ast::Attribute>,
-    pub whence: Span,
-}
-
 // For Macro we store the DefId instead of the NodeId, since we also create
 // these imported macro_rules (which only have a DUMMY_NODE_ID).
 pub struct Macro {
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 c214c15ed4b2be1a0c0b56b736decaf70095fbf4..81087cd412e2c281db1b10af598964147327257b 100644 (file)
@@ -82,7 +82,6 @@ fn from(item: &'a clean::Item) -> ItemType {
             clean::PrimitiveItem(..)       => ItemType::Primitive,
             clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
             clean::AssociatedTypeItem(..)  => ItemType::AssociatedType,
-            clean::AutoImplItem(..)        => ItemType::Impl,
             clean::ForeignTypeItem         => ItemType::ForeignType,
             clean::StrippedItem(..)        => unreachable!(),
         }
index f7a67b1b9c79cca408bc70f88c1f447be12029ca..e66add20376fac9d06983ffc3d6b1e50aba83ca4 100644 (file)
@@ -196,7 +196,7 @@ fn next(&mut self) -> Option<Self::Item> {
                     .map(|l| map_line(l).for_code())
                     .collect::<Vec<&str>>().join("\n");
                 let krate = krate.as_ref().map(|s| &**s);
-                let test = test::make_test(&test, krate, false,
+                let (test, _) = test::make_test(&test, krate, false,
                                            &Default::default());
                 let channel = if test.contains("#![feature(") {
                     "&amp;version=nightly"
@@ -607,7 +607,7 @@ pub fn render(w: &mut fmt::Formatter,
                         .map(|l| map_line(l).for_code())
                         .collect::<Vec<&str>>().join("\n");
                     let krate = krate.as_ref().map(|s| &**s);
-                    let test = test::make_test(&test, krate, false,
+                    let (test, _) = test::make_test(&test, krate, false,
                                                &Default::default());
                     let channel = if test.contains("#![feature(") {
                         "&amp;version=nightly"
index 7449c08fcd290b857c038317b13def01b823db43..6e4980c9e919b5596f4917b27b0be4bd43fa9523 100644 (file)
@@ -866,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"))?;
@@ -1027,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
@@ -1124,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
@@ -1974,12 +1964,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
                item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
     document(w, cx, item)?;
 
-    let mut indices = (0..items.len()).filter(|i| {
-        if let clean::AutoImplItem(..) = items[*i].inner {
-            return false;
-        }
-        !items[*i].is_stripped()
-    }).collect::<Vec<usize>>();
+    let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped())
+                                      .collect::<Vec<usize>>();
 
     // the order of item types in the listing
     fn reorder(ty: ItemType) -> u8 {
@@ -3983,13 +3969,7 @@ fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item,
                    ItemType::Function, ItemType::Typedef, ItemType::Union, ItemType::Impl,
                    ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
                    ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
-        if items.iter().any(|it| {
-            if let clean::AutoImplItem(..) = it.inner {
-                false
-            } else {
-                !it.is_stripped() && it.type_() == myty
-            }
-        }) {
+        if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) {
             let (short, name) = match myty {
                 ItemType::ExternCrate |
                 ItemType::Import          => ("reexports", "Reexports"),
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 3e15d3d3007ac7ef659792d8321b8321c80b9cbb..32f0bcada1d20924414211dcdd462dc7c7bdbe0c 100644 (file)
@@ -116,7 +116,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             // handled in the `strip-priv-imports` pass
             clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
 
-            clean::AutoImplItem(..) | clean::ImplItem(..) => {}
+            clean::ImplItem(..) => {}
 
             // tymethods/macros have no control over privacy
             clean::MacroItem(..) | clean::TyMethodItem(..) => {}
index 8e861f10dd8d4851c4fc2baf24fe37da897ec0b5..5432f5cb6e1656b4c0f8891c4a1d2d007fee0873 100644 (file)
@@ -176,7 +176,8 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
     opts
 }
 
-fn run_test(test: &str, cratename: &str, filename: &FileName, cfgs: Vec<String>, libs: SearchPaths,
+fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
+            cfgs: Vec<String>, libs: SearchPaths,
             externs: Externs,
             should_panic: bool, no_run: bool, as_test_harness: bool,
             compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
@@ -184,7 +185,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, cfgs: Vec<String>,
             linker: Option<PathBuf>) {
     // the test harness wants its own `main` & top level functions, so
     // never wrap the test in `fn main() { ... }`
-    let test = make_test(test, Some(cratename), as_test_harness, opts);
+    let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts);
     // FIXME(#44940): if doctests ever support path remapping, then this filename
     // needs to be the result of CodeMap::span_to_unmapped_path
     let input = config::Input::Str {
@@ -234,7 +235,9 @@ fn drop(&mut self) {
         }
     }
     let data = Arc::new(Mutex::new(Vec::new()));
-    let codemap = Rc::new(CodeMap::new(sessopts.file_path_mapping()));
+    let codemap = Rc::new(CodeMap::new_doctest(
+        sessopts.file_path_mapping(), filename.clone(), line as isize - line_offset as isize
+    ));
     let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()),
                                                       Some(codemap.clone()),
                                                       false);
@@ -326,13 +329,14 @@ fn drop(&mut self) {
     }
 }
 
+/// Makes the test file. Also returns the number of lines before the code begins
 pub fn make_test(s: &str,
                  cratename: Option<&str>,
                  dont_insert_main: bool,
                  opts: &TestOptions)
-                 -> String {
+                 -> (String, usize) {
     let (crate_attrs, everything_else) = partition_source(s);
-
+    let mut line_offset = 0;
     let mut prog = String::new();
 
     if opts.attrs.is_empty() {
@@ -341,11 +345,13 @@ pub fn make_test(s: &str,
         // commonly used to make tests fail in case they trigger warnings, so having this there in
         // that case may cause some tests to pass when they shouldn't have.
         prog.push_str("#![allow(unused)]\n");
+        line_offset += 1;
     }
 
     // Next, any attributes that came from the crate root via #![doc(test(attr(...)))].
     for attr in &opts.attrs {
         prog.push_str(&format!("#![{}]\n", attr));
+        line_offset += 1;
     }
 
     // Now push any outer attributes from the example, assuming they
@@ -358,6 +364,7 @@ pub fn make_test(s: &str,
         if let Some(cratename) = cratename {
             if s.contains(cratename) {
                 prog.push_str(&format!("extern crate {};\n", cratename));
+                line_offset += 1;
             }
         }
     }
@@ -379,6 +386,7 @@ pub fn make_test(s: &str,
         prog.push_str(&everything_else);
     } else {
         prog.push_str("fn main() {\n");
+        line_offset += 1;
         prog.push_str(&everything_else);
         prog = prog.trim().into();
         prog.push_str("\n}");
@@ -386,7 +394,7 @@ pub fn make_test(s: &str,
 
     info!("final test program: {}", prog);
 
-    prog
+    (prog, line_offset)
 }
 
 // FIXME(aburka): use a real parser to deal with multiline attributes
@@ -543,6 +551,7 @@ pub fn add_test(&mut self, test: String,
                         run_test(&test,
                                  &cratename,
                                  &filename,
+                                 line,
                                  cfgs,
                                  libs,
                                  externs,
index be78935cadfbb1897c12a3f4a54cbe5db364ca7a..95531b468f41e24735af46cd1029319f706dcd01 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()`.
@@ -547,19 +548,6 @@ pub fn visit_item(&mut self, item: &hir::Item,
                     om.impls.push(i);
                 }
             },
-            hir::ItemAutoImpl(unsafety, ref trait_ref) => {
-                // See comment above about ItemImpl.
-                if !self.inlining {
-                    let i = AutoImpl {
-                        unsafety,
-                        trait_: trait_ref.clone(),
-                        id: item.id,
-                        attrs: item.attrs.clone(),
-                        whence: item.span,
-                    };
-                    om.def_traits.push(i);
-                }
-            }
         }
     }
 
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 ed34c1204b3a1bd21e4c220c11cdf300b8eac0c4..27bf326631fb0416cf74082a6315bbf931e46a75 100644 (file)
@@ -956,8 +956,7 @@ mod arch {
 mod tests {
     use super::*;
 
-    use ffi::OsStr;
-    use path::{Path, PathBuf};
+    use path::Path;
 
     #[test]
     #[cfg_attr(target_os = "emscripten", ignore)]
@@ -980,6 +979,8 @@ fn test() {
     #[test]
     #[cfg(windows)]
     fn split_paths_windows() {
+        use path::PathBuf;
+
         fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
             split_paths(unparsed).collect::<Vec<_>>() ==
                 parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
@@ -1000,6 +1001,8 @@ fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
     #[test]
     #[cfg(unix)]
     fn split_paths_unix() {
+        use path::PathBuf;
+
         fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
             split_paths(unparsed).collect::<Vec<_>>() ==
                 parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
@@ -1015,6 +1018,8 @@ fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
     #[test]
     #[cfg(unix)]
     fn join_paths_unix() {
+        use ffi::OsStr;
+
         fn test_eq(input: &[&str], output: &str) -> bool {
             &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::new(output)
@@ -1031,6 +1036,8 @@ fn test_eq(input: &[&str], output: &str) -> bool {
     #[test]
     #[cfg(windows)]
     fn join_paths_windows() {
+        use ffi::OsStr;
+
         fn test_eq(input: &[&str], output: &str) -> bool {
             &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::new(output)
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..4e0ff450cabdc84b9622db12b04fa01fd79d08f8 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)
 }
@@ -1981,7 +1989,7 @@ fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
     }
 }
 
-#[cfg(all(test, not(target_os = "emscripten")))]
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
 mod tests {
     use io::prelude::*;
 
index 7001d8e042196c46ac8348b8cd0b50746c06c1f6..16fbf0c6ba69eb03a08945b8da8f3a107154f2cf 100644 (file)
@@ -194,6 +194,31 @@ pub fn is_empty(&self) -> bool {
     pub fn into_inner(self) -> R { self.inner }
 }
 
+impl<R: Seek> BufReader<R> {
+    /// Seeks relative to the current position. If the new position lies within the buffer,
+    /// the buffer will not be flushed, allowing for more efficient seeks.
+    /// This method does not return the location of the underlying reader, so the caller
+    /// must track this information themselves if it is required.
+    #[unstable(feature = "bufreader_seek_relative", issue = "31100")]
+    pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
+        let pos = self.pos as u64;
+        if offset < 0 {
+            if let Some(new_pos) = pos.checked_sub((-offset) as u64) {
+                self.pos = new_pos as usize;
+                return Ok(())
+            }
+        } else {
+            if let Some(new_pos) = pos.checked_add(offset as u64) {
+                if new_pos <= self.cap as u64 {
+                    self.pos = new_pos as usize;
+                    return Ok(())
+                }
+            }
+        }
+        self.seek(SeekFrom::Current(offset)).map(|_|())
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read> Read for BufReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
@@ -260,6 +285,8 @@ impl<R: Seek> Seek for BufReader<R> {
     /// `.into_inner()` immediately after a seek yields the underlying reader
     /// at the same position.
     ///
+    /// To seek without discarding the internal buffer, use [`seek_relative`].
+    ///
     /// See `std::io::Seek` for more details.
     ///
     /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)`
@@ -267,6 +294,8 @@ impl<R: Seek> Seek for BufReader<R> {
     /// seeks will be performed instead of one. If the second seek returns
     /// `Err`, the underlying reader will be left at the same position it would
     /// have if you seeked to `SeekFrom::Current(0)`.
+    ///
+    /// [`seek_relative`]: #method.seek_relative
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         let result: u64;
         if let SeekFrom::Current(n) = pos {
@@ -953,6 +982,23 @@ fn test_buffered_reader_seek() {
         assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
     }
 
+    #[test]
+    fn test_buffered_reader_seek_relative() {
+        let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
+        let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
+
+        assert!(reader.seek_relative(3).is_ok());
+        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
+        assert!(reader.seek_relative(0).is_ok());
+        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
+        assert!(reader.seek_relative(1).is_ok());
+        assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
+        assert!(reader.seek_relative(-1).is_ok());
+        assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
+        assert!(reader.seek_relative(2).is_ok());
+        assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
+    }
+
     #[test]
     fn test_buffered_reader_seek_underflow() {
         // gimmick reader that yields its position modulo 256 for each byte
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 bb9383d3d6e02cb668740581d6c66393a8f6a6d6..f0b41f30251e09d10209422ea9cd23eb139588ad 100644 (file)
 /// [`Write`]: ../io/trait.Write.html
 /// [`Seek`]: ../io/trait.Seek.html
 /// [`ErrorKind`]: enum.ErrorKind.html
-#[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Error {
     repr: Repr,
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&self.repr, f)
+    }
+}
+
 enum Repr {
     Os(i32),
     Simple(ErrorKind),
@@ -511,10 +517,12 @@ pub fn kind(&self) -> ErrorKind {
 impl fmt::Debug for Repr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match *self {
-            Repr::Os(ref code) =>
-                fmt.debug_struct("Os").field("code", code)
-                   .field("message", &sys::os::error_string(*code)).finish(),
-            Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(),
+            Repr::Os(code) =>
+                fmt.debug_struct("Os")
+                    .field("code", &code)
+                    .field("kind", &sys::decode_error_kind(code))
+                    .field("message", &sys::os::error_string(code)).finish(),
+            Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
             Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
         }
     }
@@ -559,17 +567,36 @@ fn _is_sync_send<T: Sync+Send>() {}
 
 #[cfg(test)]
 mod test {
-    use super::{Error, ErrorKind};
+    use super::{Error, ErrorKind, Repr, Custom};
     use error;
     use fmt;
     use sys::os::error_string;
+    use sys::decode_error_kind;
 
     #[test]
     fn test_debug_error() {
         let code = 6;
         let msg = error_string(code);
-        let err = Error { repr: super::Repr::Os(code) };
-        let expected = format!("Error {{ repr: Os {{ code: {:?}, message: {:?} }} }}", code, msg);
+        let kind = decode_error_kind(code);
+        let err = Error {
+            repr: Repr::Custom(box Custom {
+                kind: ErrorKind::InvalidInput,
+                error: box Error {
+                    repr: super::Repr::Os(code)
+                },
+            })
+        };
+        let expected = format!(
+            "Custom {{ \
+                kind: InvalidInput, \
+                error: Os {{ \
+                    code: {:?}, \
+                    kind: {:?}, \
+                    message: {:?} \
+                }} \
+            }}",
+            code, kind, msg
+        );
         assert_eq!(format!("{:?}", err), expected);
     }
 
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 539ff1df1876f052bb00188edce8504c289e52e3..78235ea1b4b5f31b886d7fb95deb7a1f4b2a5215 100644 (file)
@@ -885,7 +885,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(all(test, not(target_os = "emscripten")))]
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
 mod tests {
     use io::ErrorKind;
     use io::prelude::*;
index 84ceaa659510f0790bed3217c0c95dc4806d94e8..fc7f9205d06ff6f72d57e6289b8d4dd9a4cfccde 100644 (file)
@@ -786,7 +786,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(all(test, not(target_os = "emscripten")))]
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
 mod tests {
     use io::ErrorKind;
     use net::*;
index 219e55d6c12062baf44552036ca1eac14d2a450a..53c2211745c328dda26a9d50025525b6c2ee6e19 100644 (file)
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 #[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
                             across an unwind boundary"]
-pub trait UnwindSafe {}
+pub auto trait UnwindSafe {}
 
 /// A marker trait representing types where a shared reference is considered
 /// unwind safe.
@@ -115,7 +115,7 @@ pub trait UnwindSafe {}
 #[rustc_on_unimplemented = "the type {Self} may contain interior mutability \
                             and a reference may not be safely transferrable \
                             across a catch_unwind boundary"]
-pub trait RefUnwindSafe {}
+pub auto trait RefUnwindSafe {}
 
 /// A simple wrapper around a type to assert that it is unwind safe.
 ///
@@ -187,10 +187,7 @@ pub struct AssertUnwindSafe<T>(
 // * Unique, an owning pointer, lifts an implementation
 // * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
 // * Our custom AssertUnwindSafe wrapper is indeed unwind safe
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-#[allow(unknown_lints)]
-#[allow(auto_impl)]
-impl UnwindSafe for .. {}
+
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
@@ -219,14 +216,10 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
 impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
 
 // Pretty simple implementations for the `RefUnwindSafe` marker trait,
-// basically just saying that this is a marker trait and `UnsafeCell` is the
+// basically just saying that `UnsafeCell` is the
 // only thing which doesn't implement it (which then transitively applies to
 // everything else).
 #[stable(feature = "catch_unwind", since = "1.9.0")]
-#[allow(unknown_lints)]
-#[allow(auto_impl)]
-impl RefUnwindSafe for .. {}
-#[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
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 33e8a87a0b62c801d87b8ac0db569463e50269a0..5c66ac6ddded8efc2049c03fd12e8a766f8ca745 100644 (file)
@@ -1392,7 +1392,7 @@ pub fn id() -> u32 {
     ::sys::os::getpid()
 }
 
-#[cfg(all(test, not(target_os = "emscripten")))]
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
 mod tests {
     use io::prelude::*;
 
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
 ///
diff --git a/src/libstd/sys/cloudabi/abi/bitflags.rs b/src/libstd/sys/cloudabi/abi/bitflags.rs
new file mode 100644 (file)
index 0000000..f764cc1
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (c) 2018 Nuxi (https://nuxi.nl/) and contributors.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+// Appease Rust's tidy.
+// ignore-license
+
+#[cfg(feature = "bitflags")]
+#[macro_use]
+extern crate bitflags;
+
+// Minimal implementation of bitflags! in case we can't depend on the bitflags
+// crate. Only implements `bits()` and a `from_bits_truncate()` that doesn't
+// actually truncate.
+#[cfg(not(feature = "bitflags"))]
+macro_rules! bitflags {
+  (
+    $(#[$attr:meta])*
+    pub struct $name:ident: $type:ty {
+      $($(#[$const_attr:meta])* const $const:ident = $val:expr;)*
+    }
+  ) => {
+    $(#[$attr])*
+    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+    pub struct $name { bits: $type }
+    impl $name {
+      $($(#[$const_attr])* pub const $const: $name = $name{ bits: $val };)*
+      pub fn bits(&self) -> $type { self.bits }
+      pub fn from_bits_truncate(bits: $type) -> Self { $name{ bits } }
+    }
+  }
+}
diff --git a/src/libstd/sys/cloudabi/abi/cloudabi.rs b/src/libstd/sys/cloudabi/abi/cloudabi.rs
new file mode 100644 (file)
index 0000000..2909db5
--- /dev/null
@@ -0,0 +1,2847 @@
+// Copyright (c) 2016-2017 Nuxi (https://nuxi.nl/) and contributors.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+// This file is automatically generated. Do not edit.
+//
+// Source: https://github.com/NuxiNL/cloudabi
+
+// Appease Rust's tidy.
+// ignore-license
+// ignore-tidy-linelength
+
+//! **PLEASE NOTE: This entire crate including this
+//! documentation is automatically generated from
+//! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt)**
+//!
+//! # Nuxi CloudABI
+//!
+//! CloudABI is what you get if you take POSIX, add capability-based
+//! security, and remove everything that's incompatible with that. The
+//! result is a minimal ABI consisting of only 49 syscalls.
+//!
+//! CloudABI doesn't have its own kernel, but instead is implemented in existing
+//! kernels: FreeBSD has CloudABI support for x86-64 and arm64, and [a patch-set
+//! for NetBSD](https://github.com/NuxiNL/netbsd) and [a patch-set for
+//! Linux](https://github.com/NuxiNL/linux) are available as well. This means that
+//! CloudABI binaries can be executed on different operating systems, without any
+//! modification.
+//!
+//! ## Capability-Based Security
+//!
+//! Capability-based security means that processes can only perform
+//! actions that have no global impact. Processes cannot open files by
+//! their absolute path, cannot open network connections, and cannot
+//! observe global system state such as the process table.
+//!
+//! The capabilities of a process are fully determined by its set of open
+//! file descriptors (fds). For example, files can only be opened if the
+//! process already has a file descriptor to a directory the file is in.
+//!
+//! Unlike in POSIX, where processes are normally started with file
+//! descriptors 0, 1, and 2 reserved for standard input, output, and
+//! error, CloudABI does not reserve any file descriptor numbers for
+//! specific purposes.
+//!
+//! In CloudABI, a process depends on its parent process to launch it with
+//! the right set of resources, since the process will not be able to open
+//! any new resources. For example, a simple static web server would need
+//! to be started with a file descriptor to a [TCP
+//! listener](https://github.com/NuxiNL/flower), and a file descriptor to
+//! the directory for which to serve files. The web server will then be
+//! unable to do anything other than reading files in that directory, and
+//! process incoming network connections.
+//!
+//! So, unknown CloudABI binaries can safely be executed without the need
+//! for containers, virtual machines, or other sandboxing technologies.
+//!
+//! Watch [Ed Schouten's Talk at
+//! 32C3](https://www.youtube.com/watch?v=3N29vrPoDv8) for more
+//! information about what capability-based security for UNIX means.
+//!
+//! ## Cloudlibc
+//!
+//! [Cloudlibc](https://github.com/NuxiNL/cloudlibc) is an implementation
+//! of the C standard library, without all CloudABI-incompatible
+//! functions. For example, Cloudlibc does not have `printf`, but does
+//! have `fprintf`. It does not have `open`, but does have `openat`.
+//!
+//! ## CloudABI-Ports
+//!
+//! [CloudABI-Ports](https://github.com/NuxiNL/cloudabi-ports) is a
+//! collection of ports of commonly used libraries and applications to
+//! CloudABI. It contains software such as `zlib`, `libpng`, `boost`,
+//! `memcached`, and much more. The software is patched to not depend on
+//! any global state, such as files in `/etc` or `/dev`, using `open()`,
+//! etc.
+//!
+//! ## Using CloudABI
+//!
+//! Instructions for using CloudABI (including kernel modules/patches,
+//! toolchain, and ports) are available for several operating systems:
+//!
+//! - [Arch Linux](https://nuxi.nl/cloudabi/archlinux/)
+//! - [Debian, Ubuntu, and other Debian derivatives](https://nuxi.nl/cloudabi/debian/)
+//! - [FreeBSD, PC-BSD and DragonFly BSD](https://nuxi.nl/cloudabi/freebsd/)
+//! - [Mac OS X](https://nuxi.nl/cloudabi/mac/)
+//! - [NetBSD](https://nuxi.nl/cloudabi/netbsd/)
+//!
+//! ## Specification of the ABI
+//!
+//! The entire ABI is specified in a a file called
+//! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt),
+//! from which all
+//! [headers](https://github.com/NuxiNL/cloudabi/tree/master/headers)
+//! and documentation (including the one you're reading now) is generated.
+
+#![no_std]
+#![allow(non_camel_case_types)]
+
+include!("bitflags.rs");
+
+/// File or memory access pattern advisory information.
+#[repr(u8)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum advice {
+  /// The application expects that it will not access the
+  /// specified data in the near future.
+  DONTNEED   = 1,
+  /// The application expects to access the specified data
+  /// once and then not reuse it thereafter.
+  NOREUSE    = 2,
+  /// The application has no advice to give on its behavior
+  /// with respect to the specified data.
+  NORMAL     = 3,
+  /// The application expects to access the specified data
+  /// in a random order.
+  RANDOM     = 4,
+  /// The application expects to access the specified data
+  /// sequentially from lower offsets to higher offsets.
+  SEQUENTIAL = 5,
+  /// The application expects to access the specified data
+  /// in the near future.
+  WILLNEED   = 6,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
+}
+
+/// Enumeration describing the kind of value stored in [`auxv`](struct.auxv.html).
+#[repr(u32)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum auxtype {
+  /// Base address of the binary argument data provided to
+  /// [`proc_exec()`](fn.proc_exec.html).
+  ARGDATA      = 256,
+  /// Length of the binary argument data provided to
+  /// [`proc_exec()`](fn.proc_exec.html).
+  ARGDATALEN   = 257,
+  /// Base address at which the executable is placed in
+  /// memory.
+  BASE         =   7,
+  /// Base address of a buffer of random data that may be
+  /// used for non-cryptographic purposes, for example as a
+  /// canary for stack smashing protection.
+  CANARY       = 258,
+  /// Length of a buffer of random data that may be used
+  /// for non-cryptographic purposes, for example as a
+  /// canary for stack smashing protection.
+  CANARYLEN    = 259,
+  /// Number of CPUs that the system this process is running
+  /// on has.
+  NCPUS        = 260,
+  /// Terminator of the auxiliary vector.
+  NULL         =   0,
+  /// Smallest memory object size for which individual
+  /// memory protection controls can be configured.
+  PAGESZ       =   6,
+  /// Address of the first ELF program header of the
+  /// executable.
+  PHDR         =   3,
+  /// Number of ELF program headers of the executable.
+  PHNUM        =   4,
+  /// Identifier of the process.
+  ///
+  /// This environment does not provide any simple numerical
+  /// process identifiers, for the reason that these are not
+  /// useful in distributed contexts. Instead, processes are
+  /// identified by a UUID.
+  ///
+  /// This record should point to sixteen bytes of binary
+  /// data, containing a version 4 UUID (fully random).
+  PID          = 263,
+  /// Address of the ELF header of the vDSO.
+  ///
+  /// The vDSO is a shared library that is mapped in the
+  /// address space of the process. It provides entry points
+  /// for every system call supported by the environment,
+  /// all having a corresponding symbol that is prefixed
+  /// with `cloudabi_sys_`. System calls should be invoked
+  /// through these entry points.
+  ///
+  /// The first advantage of letting processes call into a
+  /// vDSO to perform system calls instead of raising
+  /// hardware traps is that it allows for easy emulation of
+  /// executables on top of existing operating systems. The
+  /// second advantage is that in cases where an operating
+  /// system provides native support for CloudABI executables,
+  /// it may still implement partial userspace
+  /// implementations of these system calls to improve
+  /// performance (e.g., [`clock_time_get()`](fn.clock_time_get.html)). It also provides
+  /// a more dynamic way of adding, removing or replacing
+  /// system calls.
+  SYSINFO_EHDR = 262,
+  /// Thread ID of the initial thread of the process.
+  TID          = 261,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u32,
+}
+
+/// Identifiers for clocks.
+#[repr(u32)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum clockid {
+  /// The system-wide monotonic clock, which is defined as a
+  /// clock measuring real time, whose value cannot be
+  /// adjusted and which cannot have negative clock jumps.
+  ///
+  /// The epoch of this clock is undefined. The absolute
+  /// time value of this clock therefore has no meaning.
+  MONOTONIC          = 1,
+  /// The CPU-time clock associated with the current
+  /// process.
+  PROCESS_CPUTIME_ID = 2,
+  /// The system-wide clock measuring real time. Time value
+  /// zero corresponds with 1970-01-01T00:00:00Z.
+  REALTIME           = 3,
+  /// The CPU-time clock associated with the current thread.
+  THREAD_CPUTIME_ID  = 4,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u32,
+}
+
+/// A userspace condition variable.
+#[repr(C)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub struct condvar(pub u32);
+/// The condition variable is in its initial state. There
+/// are no threads waiting to be woken up. If the
+/// condition variable has any other value, the kernel
+/// must be called to wake up any sleeping threads.
+pub const CONDVAR_HAS_NO_WAITERS: condvar = condvar(0);
+
+/// Identifier for a device containing a file system. Can be used
+/// in combination with [`inode`](struct.inode.html) to uniquely identify a file on the
+/// local system.
+#[repr(C)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub struct device(pub u64);
+
+/// A reference to the offset of a directory entry.
+#[repr(C)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub struct dircookie(pub u64);
+/// Permanent reference to the first directory entry
+/// within a directory.
+pub const DIRCOOKIE_START: dircookie = dircookie(0);
+
+/// Error codes returned by system calls.
+///
+/// Not all of these error codes are returned by the system calls
+/// provided by this environment, but are either used in userspace
+/// exclusively or merely provided for alignment with POSIX.
+#[repr(u16)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum errno {
+  /// No error occurred. System call completed successfully.
+  SUCCESS        =  0,
+  /// Argument list too long.
+  TOOBIG         =  1,
+  /// Permission denied.
+  ACCES          =  2,
+  /// Address in use.
+  ADDRINUSE      =  3,
+  /// Address not available.
+  ADDRNOTAVAIL   =  4,
+  /// Address family not supported.
+  AFNOSUPPORT    =  5,
+  /// Resource unavailable, or operation would block.
+  AGAIN          =  6,
+  /// Connection already in progress.
+  ALREADY        =  7,
+  /// Bad file descriptor.
+  BADF           =  8,
+  /// Bad message.
+  BADMSG         =  9,
+  /// Device or resource busy.
+  BUSY           = 10,
+  /// Operation canceled.
+  CANCELED       = 11,
+  /// No child processes.
+  CHILD          = 12,
+  /// Connection aborted.
+  CONNABORTED    = 13,
+  /// Connection refused.
+  CONNREFUSED    = 14,
+  /// Connection reset.
+  CONNRESET      = 15,
+  /// Resource deadlock would occur.
+  DEADLK         = 16,
+  /// Destination address required.
+  DESTADDRREQ    = 17,
+  /// Mathematics argument out of domain of function.
+  DOM            = 18,
+  /// Reserved.
+  DQUOT          = 19,
+  /// File exists.
+  EXIST          = 20,
+  /// Bad address.
+  FAULT          = 21,
+  /// File too large.
+  FBIG           = 22,
+  /// Host is unreachable.
+  HOSTUNREACH    = 23,
+  /// Identifier removed.
+  IDRM           = 24,
+  /// Illegal byte sequence.
+  ILSEQ          = 25,
+  /// Operation in progress.
+  INPROGRESS     = 26,
+  /// Interrupted function.
+  INTR           = 27,
+  /// Invalid argument.
+  INVAL          = 28,
+  /// I/O error.
+  IO             = 29,
+  /// Socket is connected.
+  ISCONN         = 30,
+  /// Is a directory.
+  ISDIR          = 31,
+  /// Too many levels of symbolic links.
+  LOOP           = 32,
+  /// File descriptor value too large.
+  MFILE          = 33,
+  /// Too many links.
+  MLINK          = 34,
+  /// Message too large.
+  MSGSIZE        = 35,
+  /// Reserved.
+  MULTIHOP       = 36,
+  /// Filename too long.
+  NAMETOOLONG    = 37,
+  /// Network is down.
+  NETDOWN        = 38,
+  /// Connection aborted by network.
+  NETRESET       = 39,
+  /// Network unreachable.
+  NETUNREACH     = 40,
+  /// Too many files open in system.
+  NFILE          = 41,
+  /// No buffer space available.
+  NOBUFS         = 42,
+  /// No such device.
+  NODEV          = 43,
+  /// No such file or directory.
+  NOENT          = 44,
+  /// Executable file format error.
+  NOEXEC         = 45,
+  /// No locks available.
+  NOLCK          = 46,
+  /// Reserved.
+  NOLINK         = 47,
+  /// Not enough space.
+  NOMEM          = 48,
+  /// No message of the desired type.
+  NOMSG          = 49,
+  /// Protocol not available.
+  NOPROTOOPT     = 50,
+  /// No space left on device.
+  NOSPC          = 51,
+  /// Function not supported.
+  NOSYS          = 52,
+  /// The socket is not connected.
+  NOTCONN        = 53,
+  /// Not a directory or a symbolic link to a directory.
+  NOTDIR         = 54,
+  /// Directory not empty.
+  NOTEMPTY       = 55,
+  /// State not recoverable.
+  NOTRECOVERABLE = 56,
+  /// Not a socket.
+  NOTSOCK        = 57,
+  /// Not supported, or operation not supported on socket.
+  NOTSUP         = 58,
+  /// Inappropriate I/O control operation.
+  NOTTY          = 59,
+  /// No such device or address.
+  NXIO           = 60,
+  /// Value too large to be stored in data type.
+  OVERFLOW       = 61,
+  /// Previous owner died.
+  OWNERDEAD      = 62,
+  /// Operation not permitted.
+  PERM           = 63,
+  /// Broken pipe.
+  PIPE           = 64,
+  /// Protocol error.
+  PROTO          = 65,
+  /// Protocol not supported.
+  PROTONOSUPPORT = 66,
+  /// Protocol wrong type for socket.
+  PROTOTYPE      = 67,
+  /// Result too large.
+  RANGE          = 68,
+  /// Read-only file system.
+  ROFS           = 69,
+  /// Invalid seek.
+  SPIPE          = 70,
+  /// No such process.
+  SRCH           = 71,
+  /// Reserved.
+  STALE          = 72,
+  /// Connection timed out.
+  TIMEDOUT       = 73,
+  /// Text file busy.
+  TXTBSY         = 74,
+  /// Cross-device link.
+  XDEV           = 75,
+  /// Extension: Capabilities insufficient.
+  NOTCAPABLE     = 76,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u16,
+}
+
+bitflags! {
+  /// The state of the file descriptor subscribed to with
+  /// [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
+  #[repr(C)]
+  pub struct eventrwflags: u16 {
+    /// The peer of this socket has closed or disconnected.
+    const HANGUP = 0x0001;
+  }
+}
+
+/// Type of a subscription to an event or its occurrence.
+#[repr(u8)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum eventtype {
+  /// The time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id)
+  /// has reached timestamp [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout).
+  CLOCK          = 1,
+  /// Condition variable [`subscription.union.condvar.condvar`](struct.subscription_condvar.html#structfield.condvar) has
+  /// been woken up and [`subscription.union.condvar.lock`](struct.subscription_condvar.html#structfield.lock) has been
+  /// acquired for writing.
+  CONDVAR        = 2,
+  /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
+  /// data available for reading. This event always triggers
+  /// for regular files.
+  FD_READ        = 3,
+  /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
+  /// capacity available for writing. This event always
+  /// triggers for regular files.
+  FD_WRITE       = 4,
+  /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
+  /// reading.
+  LOCK_RDLOCK    = 5,
+  /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
+  /// writing.
+  LOCK_WRLOCK    = 6,
+  /// The process associated with process descriptor
+  /// [`subscription.union.proc_terminate.fd`](struct.subscription_proc_terminate.html#structfield.fd) has terminated.
+  PROC_TERMINATE = 7,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
+}
+
+/// Exit code generated by a process when exiting.
+pub type exitcode = u32;
+
+/// A file descriptor number.
+///
+/// Unlike on POSIX-compliant systems, none of the file descriptor
+/// numbers are reserved for a purpose (e.g., stdin, stdout,
+/// stderr). Operating systems are not required to allocate new
+/// file descriptors in ascending order.
+#[repr(C)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub struct fd(pub u32);
+/// Returned to the child process by [`proc_fork()`](fn.proc_fork.html).
+pub const PROCESS_CHILD: fd = fd(0xffffffff);
+/// Passed to [`mem_map()`](fn.mem_map.html) when creating a mapping to
+/// anonymous memory.
+pub const MAP_ANON_FD  : fd = fd(0xffffffff);
+
+bitflags! {
+  /// File descriptor flags.
+  #[repr(C)]
+  pub struct fdflags: u16 {
+    /// Append mode: Data written to the file is always
+    /// appended to the file's end.
+    const APPEND   = 0x0001;
+    /// Write according to synchronized I/O data integrity
+    /// completion. Only the data stored in the file is
+    /// synchronized.
+    const DSYNC    = 0x0002;
+    /// Non-blocking mode.
+    const NONBLOCK = 0x0004;
+    /// Synchronized read I/O operations.
+    const RSYNC    = 0x0008;
+    /// Write according to synchronized I/O file integrity
+    /// completion. In addition to synchronizing the data
+    /// stored in the file, the system may also synchronously
+    /// update the file's metadata.
+    const SYNC     = 0x0010;
+  }
+}
+
+bitflags! {
+  /// Which file descriptor attributes to adjust.
+  #[repr(C)]
+  pub struct fdsflags: u16 {
+    /// Adjust the file descriptor flags stored in
+    /// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags).
+    const FLAGS  = 0x0001;
+    /// Restrict the rights of the file descriptor to the
+    /// rights stored in [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
+    /// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting).
+    const RIGHTS = 0x0002;
+  }
+}
+
+/// Relative offset within a file.
+pub type filedelta = i64;
+
+/// Non-negative file size or length of a region within a file.
+pub type filesize = u64;
+
+/// The type of a file descriptor or file.
+#[repr(u8)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum filetype {
+  /// The type of the file descriptor or file is unknown or
+  /// is different from any of the other types specified.
+  UNKNOWN          =   0,
+  /// The file descriptor or file refers to a block device
+  /// inode.
+  BLOCK_DEVICE     =  16,
+  /// The file descriptor or file refers to a character
+  /// device inode.
+  CHARACTER_DEVICE =  17,
+  /// The file descriptor or file refers to a directory
+  /// inode.
+  DIRECTORY        =  32,
+  /// The file descriptor refers to a process handle.
+  PROCESS          =  80,
+  /// The file descriptor or file refers to a regular file
+  /// inode.
+  REGULAR_FILE     =  96,
+  /// The file descriptor refers to a shared memory object.
+  SHARED_MEMORY    = 112,
+  /// The file descriptor or file refers to a datagram
+  /// socket.
+  SOCKET_DGRAM     = 128,
+  /// The file descriptor or file refers to a byte-stream
+  /// socket.
+  SOCKET_STREAM    = 130,
+  /// The file refers to a symbolic link inode.
+  SYMBOLIC_LINK    = 144,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
+}
+
+bitflags! {
+  /// Which file attributes to adjust.
+  #[repr(C)]
+  pub struct fsflags: u16 {
+    /// Adjust the last data access timestamp to the value
+    /// stored in [`filestat.st_atim`](struct.filestat.html#structfield.st_atim).
+    const ATIM     = 0x0001;
+    /// Adjust the last data access timestamp to the time
+    /// of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
+    const ATIM_NOW = 0x0002;
+    /// Adjust the last data modification timestamp to the
+    /// value stored in [`filestat.st_mtim`](struct.filestat.html#structfield.st_mtim).
+    const MTIM     = 0x0004;
+    /// Adjust the last data modification timestamp to the
+    /// time of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
+    const MTIM_NOW = 0x0008;
+    /// Truncate or extend the file to the size stored in
+    /// [`filestat.st_size`](struct.filestat.html#structfield.st_size).
+    const SIZE     = 0x0010;
+  }
+}
+
+/// File serial number that is unique within its file system.
+#[repr(C)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub struct inode(pub u64);
+
+/// Number of hard links to an inode.
+pub type linkcount = u32;
+
+/// A userspace read-recursive readers-writer lock, similar to a
+/// Linux futex or a FreeBSD umtx.
+#[repr(C)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub struct lock(pub u32);
+/// Value indicating that the lock is in its initial
+/// unlocked state.
+pub const LOCK_UNLOCKED      : lock = lock(0x00000000);
+/// Bitmask indicating that the lock is write-locked. If
+/// set, the lower 30 bits of the lock contain the
+/// identifier of the thread that owns the write lock.
+/// Otherwise, the lower 30 bits of the lock contain the
+/// number of acquired read locks.
+pub const LOCK_WRLOCKED      : lock = lock(0x40000000);
+/// Bitmask indicating that the lock is either read locked
+/// or write locked, and that one or more threads have
+/// their execution suspended, waiting to acquire the
+/// lock. The last owner of the lock must call the
+/// kernel to unlock.
+///
+/// When the lock is acquired for reading and this bit is
+/// set, it means that one or more threads are attempting
+/// to acquire this lock for writing. In that case, other
+/// threads should only acquire additional read locks if
+/// suspending execution would cause a deadlock. It is
+/// preferred to suspend execution, as this prevents
+/// starvation of writers.
+pub const LOCK_KERNEL_MANAGED: lock = lock(0x80000000);
+/// Value indicating that the lock is in an incorrect
+/// state. A lock cannot be in its initial unlocked state,
+/// while also managed by the kernel.
+pub const LOCK_BOGUS         : lock = lock(0x80000000);
+
+bitflags! {
+  /// Flags determining the method of how paths are resolved.
+  #[repr(C)]
+  pub struct lookupflags: u32 {
+    /// As long as the resolved path corresponds to a symbolic
+    /// link, it is expanded.
+    const SYMLINK_FOLLOW = 0x00000001;
+  }
+}
+
+bitflags! {
+  /// Memory mapping flags.
+  #[repr(C)]
+  pub struct mflags: u8 {
+    /// Instead of mapping the contents of the file provided,
+    /// create a mapping to anonymous memory. The file
+    /// descriptor argument must be set to [`MAP_ANON_FD`](constant.MAP_ANON_FD.html),
+    /// and the offset must be set to zero.
+    const ANON    = 0x01;
+    /// Require that the mapping is performed at the base
+    /// address provided.
+    const FIXED   = 0x02;
+    /// Changes are private.
+    const PRIVATE = 0x04;
+    /// Changes are shared.
+    const SHARED  = 0x08;
+  }
+}
+
+bitflags! {
+  /// Memory page protection options.
+  ///
+  /// This implementation enforces the `W^X` property: Pages cannot be
+  /// mapped for execution while also mapped for writing.
+  #[repr(C)]
+  pub struct mprot: u8 {
+    /// Page can be executed.
+    const EXEC  = 0x01;
+    /// Page can be written.
+    const WRITE = 0x02;
+    /// Page can be read.
+    const READ  = 0x04;
+  }
+}
+
+bitflags! {
+  /// Methods of synchronizing memory with physical storage.
+  #[repr(C)]
+  pub struct msflags: u8 {
+    /// Perform asynchronous writes.
+    const ASYNC      = 0x01;
+    /// Invalidate cached data.
+    const INVALIDATE = 0x02;
+    /// Perform synchronous writes.
+    const SYNC       = 0x04;
+  }
+}
+
+/// Specifies the number of threads sleeping on a condition
+/// variable that should be woken up.
+pub type nthreads = u32;
+
+bitflags! {
+  /// Open flags used by [`file_open()`](fn.file_open.html).
+  #[repr(C)]
+  pub struct oflags: u16 {
+    /// Create file if it does not exist.
+    const CREAT     = 0x0001;
+    /// Fail if not a directory.
+    const DIRECTORY = 0x0002;
+    /// Fail if file already exists.
+    const EXCL      = 0x0004;
+    /// Truncate file to size 0.
+    const TRUNC     = 0x0008;
+  }
+}
+
+bitflags! {
+  /// Flags provided to [`sock_recv()`](fn.sock_recv.html).
+  #[repr(C)]
+  pub struct riflags: u16 {
+    /// Returns the message without removing it from the
+    /// socket's receive queue.
+    const PEEK    = 0x0004;
+    /// On byte-stream sockets, block until the full amount
+    /// of data can be returned.
+    const WAITALL = 0x0010;
+  }
+}
+
+bitflags! {
+  /// File descriptor rights, determining which actions may be
+  /// performed.
+  #[repr(C)]
+  pub struct rights: u64 {
+    /// The right to invoke [`fd_datasync()`](fn.fd_datasync.html).
+    ///
+    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
+    /// invoke [`file_open()`](fn.file_open.html) with [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
+    const FD_DATASYNC           = 0x0000000000000001;
+    /// The right to invoke [`fd_read()`](fn.fd_read.html) and [`sock_recv()`](fn.sock_recv.html).
+    ///
+    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
+    /// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
+    /// [`READ`](struct.mprot.html#associatedconstant.READ).
+    ///
+    /// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to invoke
+    /// [`fd_pread()`](fn.fd_pread.html).
+    const FD_READ               = 0x0000000000000002;
+    /// The right to invoke [`fd_seek()`](fn.fd_seek.html). This flag implies
+    /// [`FD_TELL`](struct.rights.html#associatedconstant.FD_TELL).
+    const FD_SEEK               = 0x0000000000000004;
+    /// The right to invoke [`fd_stat_put()`](fn.fd_stat_put.html) with
+    /// [`FLAGS`](struct.fdsflags.html#associatedconstant.FLAGS).
+    const FD_STAT_PUT_FLAGS     = 0x0000000000000008;
+    /// The right to invoke [`fd_sync()`](fn.fd_sync.html).
+    ///
+    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
+    /// invoke [`file_open()`](fn.file_open.html) with [`RSYNC`](struct.fdflags.html#associatedconstant.RSYNC) and
+    /// [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
+    const FD_SYNC               = 0x0000000000000010;
+    /// The right to invoke [`fd_seek()`](fn.fd_seek.html) in such a way that the
+    /// file offset remains unaltered (i.e., [`CUR`](enum.whence.html#variant.CUR) with
+    /// offset zero).
+    const FD_TELL               = 0x0000000000000020;
+    /// The right to invoke [`fd_write()`](fn.fd_write.html) and [`sock_send()`](fn.sock_send.html).
+    ///
+    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
+    /// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
+    /// [`WRITE`](struct.mprot.html#associatedconstant.WRITE).
+    ///
+    /// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to
+    /// invoke [`fd_pwrite()`](fn.fd_pwrite.html).
+    const FD_WRITE              = 0x0000000000000040;
+    /// The right to invoke [`file_advise()`](fn.file_advise.html).
+    const FILE_ADVISE           = 0x0000000000000080;
+    /// The right to invoke [`file_allocate()`](fn.file_allocate.html).
+    const FILE_ALLOCATE         = 0x0000000000000100;
+    /// The right to invoke [`file_create()`](fn.file_create.html) with
+    /// [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY).
+    const FILE_CREATE_DIRECTORY = 0x0000000000000200;
+    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, the right to invoke
+    /// [`file_open()`](fn.file_open.html) with [`CREAT`](struct.oflags.html#associatedconstant.CREAT).
+    const FILE_CREATE_FILE      = 0x0000000000000400;
+    /// The right to invoke [`file_link()`](fn.file_link.html) with the file
+    /// descriptor as the source directory.
+    const FILE_LINK_SOURCE      = 0x0000000000001000;
+    /// The right to invoke [`file_link()`](fn.file_link.html) with the file
+    /// descriptor as the target directory.
+    const FILE_LINK_TARGET      = 0x0000000000002000;
+    /// The right to invoke [`file_open()`](fn.file_open.html).
+    const FILE_OPEN             = 0x0000000000004000;
+    /// The right to invoke [`file_readdir()`](fn.file_readdir.html).
+    const FILE_READDIR          = 0x0000000000008000;
+    /// The right to invoke [`file_readlink()`](fn.file_readlink.html).
+    const FILE_READLINK         = 0x0000000000010000;
+    /// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
+    /// descriptor as the source directory.
+    const FILE_RENAME_SOURCE    = 0x0000000000020000;
+    /// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
+    /// descriptor as the target directory.
+    const FILE_RENAME_TARGET    = 0x0000000000040000;
+    /// The right to invoke [`file_stat_fget()`](fn.file_stat_fget.html).
+    const FILE_STAT_FGET        = 0x0000000000080000;
+    /// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
+    /// [`SIZE`](struct.fsflags.html#associatedconstant.SIZE).
+    ///
+    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
+    /// invoke [`file_open()`](fn.file_open.html) with [`TRUNC`](struct.oflags.html#associatedconstant.TRUNC).
+    const FILE_STAT_FPUT_SIZE   = 0x0000000000100000;
+    /// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
+    /// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
+    /// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
+    const FILE_STAT_FPUT_TIMES  = 0x0000000000200000;
+    /// The right to invoke [`file_stat_get()`](fn.file_stat_get.html).
+    const FILE_STAT_GET         = 0x0000000000400000;
+    /// The right to invoke [`file_stat_put()`](fn.file_stat_put.html) with
+    /// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
+    /// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
+    const FILE_STAT_PUT_TIMES   = 0x0000000000800000;
+    /// The right to invoke [`file_symlink()`](fn.file_symlink.html).
+    const FILE_SYMLINK          = 0x0000000001000000;
+    /// The right to invoke [`file_unlink()`](fn.file_unlink.html).
+    const FILE_UNLINK           = 0x0000000002000000;
+    /// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`](struct.mprot.html) set to
+    /// zero.
+    const MEM_MAP               = 0x0000000004000000;
+    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, the right to invoke
+    /// [`mem_map()`](fn.mem_map.html) with [`EXEC`](struct.mprot.html#associatedconstant.EXEC).
+    const MEM_MAP_EXEC          = 0x0000000008000000;
+    /// If [`FD_READ`](struct.rights.html#associatedconstant.FD_READ) is set, includes the right to
+    /// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_READ`](enum.eventtype.html#variant.FD_READ).
+    ///
+    /// If [`FD_WRITE`](struct.rights.html#associatedconstant.FD_WRITE) is set, includes the right to
+    /// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
+    const POLL_FD_READWRITE     = 0x0000000010000000;
+    /// The right to invoke [`poll()`](fn.poll.html) to subscribe to
+    /// [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
+    const POLL_PROC_TERMINATE   = 0x0000000040000000;
+    /// The right to invoke [`proc_exec()`](fn.proc_exec.html).
+    const PROC_EXEC             = 0x0000000100000000;
+    /// The right to invoke [`sock_shutdown()`](fn.sock_shutdown.html).
+    const SOCK_SHUTDOWN         = 0x0000008000000000;
+  }
+}
+
+bitflags! {
+  /// Flags returned by [`sock_recv()`](fn.sock_recv.html).
+  #[repr(C)]
+  pub struct roflags: u16 {
+    /// Returned by [`sock_recv()`](fn.sock_recv.html): List of file descriptors
+    /// has been truncated.
+    const FDS_TRUNCATED  = 0x0001;
+    /// Returned by [`sock_recv()`](fn.sock_recv.html): Message data has been
+    /// truncated.
+    const DATA_TRUNCATED = 0x0008;
+  }
+}
+
+/// Indicates whether an object is stored in private or shared
+/// memory.
+#[repr(u8)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum scope {
+  /// The object is stored in private memory.
+  PRIVATE = 4,
+  /// The object is stored in shared memory.
+  SHARED  = 8,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
+}
+
+bitflags! {
+  /// Which channels on a socket need to be shut down.
+  #[repr(C)]
+  pub struct sdflags: u8 {
+    /// Disables further receive operations.
+    const RD = 0x01;
+    /// Disables further send operations.
+    const WR = 0x02;
+  }
+}
+
+bitflags! {
+  /// Flags provided to [`sock_send()`](fn.sock_send.html). As there are currently no flags
+  /// defined, it must be set to zero.
+  #[repr(C)]
+  pub struct siflags: u16 {
+    const DEFAULT = 0;
+  }
+}
+
+/// Signal condition.
+#[repr(u8)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum signal {
+  /// Process abort signal.
+  ///
+  /// Action: Terminates the process.
+  ABRT   =  1,
+  /// Alarm clock.
+  ///
+  /// Action: Terminates the process.
+  ALRM   =  2,
+  /// Access to an undefined portion of a memory object.
+  ///
+  /// Action: Terminates the process.
+  BUS    =  3,
+  /// Child process terminated, stopped, or continued.
+  ///
+  /// Action: Ignored.
+  CHLD   =  4,
+  /// Continue executing, if stopped.
+  ///
+  /// Action: Continues executing, if stopped.
+  CONT   =  5,
+  /// Erroneous arithmetic operation.
+  ///
+  /// Action: Terminates the process.
+  FPE    =  6,
+  /// Hangup.
+  ///
+  /// Action: Terminates the process.
+  HUP    =  7,
+  /// Illegal instruction.
+  ///
+  /// Action: Terminates the process.
+  ILL    =  8,
+  /// Terminate interrupt signal.
+  ///
+  /// Action: Terminates the process.
+  INT    =  9,
+  /// Kill.
+  ///
+  /// Action: Terminates the process.
+  KILL   = 10,
+  /// Write on a pipe with no one to read it.
+  ///
+  /// Action: Ignored.
+  PIPE   = 11,
+  /// Terminal quit signal.
+  ///
+  /// Action: Terminates the process.
+  QUIT   = 12,
+  /// Invalid memory reference.
+  ///
+  /// Action: Terminates the process.
+  SEGV   = 13,
+  /// Stop executing.
+  ///
+  /// Action: Stops executing.
+  STOP   = 14,
+  /// Bad system call.
+  ///
+  /// Action: Terminates the process.
+  SYS    = 15,
+  /// Termination signal.
+  ///
+  /// Action: Terminates the process.
+  TERM   = 16,
+  /// Trace/breakpoint trap.
+  ///
+  /// Action: Terminates the process.
+  TRAP   = 17,
+  /// Terminal stop signal.
+  ///
+  /// Action: Stops executing.
+  TSTP   = 18,
+  /// Background process attempting read.
+  ///
+  /// Action: Stops executing.
+  TTIN   = 19,
+  /// Background process attempting write.
+  ///
+  /// Action: Stops executing.
+  TTOU   = 20,
+  /// High bandwidth data is available at a socket.
+  ///
+  /// Action: Ignored.
+  URG    = 21,
+  /// User-defined signal 1.
+  ///
+  /// Action: Terminates the process.
+  USR1   = 22,
+  /// User-defined signal 2.
+  ///
+  /// Action: Terminates the process.
+  USR2   = 23,
+  /// Virtual timer expired.
+  ///
+  /// Action: Terminates the process.
+  VTALRM = 24,
+  /// CPU time limit exceeded.
+  ///
+  /// Action: Terminates the process.
+  XCPU   = 25,
+  /// File size limit exceeded.
+  ///
+  /// Action: Terminates the process.
+  XFSZ   = 26,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
+}
+
+bitflags! {
+  /// Flags determining how the timestamp provided in
+  /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) should be interpreted.
+  #[repr(C)]
+  pub struct subclockflags: u16 {
+    /// If set, treat the timestamp provided in
+    /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) as an absolute timestamp
+    /// of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
+    ///
+    /// If clear, treat the timestamp provided in
+    /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) relative to the current
+    /// time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
+    const ABSTIME = 0x0001;
+  }
+}
+
+bitflags! {
+  /// Flags influencing the method of polling for read or writing on
+  /// a file descriptor.
+  #[repr(C)]
+  pub struct subrwflags: u16 {
+    /// Deprecated. Must be set by callers and ignored by
+    /// implementations.
+    const POLL = 0x0001;
+  }
+}
+
+/// Unique system-local identifier of a thread. This identifier is
+/// only valid during the lifetime of the thread.
+///
+/// Threads must be aware of their thread identifier, as it is
+/// written it into locks when acquiring them for writing. It is
+/// not advised to use these identifiers for any other purpose.
+///
+/// As the thread identifier is also stored in [`lock`](struct.lock.html) when
+/// [`LOCK_WRLOCKED`](constant.LOCK_WRLOCKED.html) is set, the top two bits of the thread
+/// must always be set to zero.
+#[repr(C)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub struct tid(pub u32);
+
+/// Timestamp in nanoseconds.
+pub type timestamp = u64;
+
+bitflags! {
+  /// Specifies whether files are unlinked or directories are
+  /// removed.
+  #[repr(C)]
+  pub struct ulflags: u8 {
+    /// If set, removes a directory. Otherwise, unlinks any
+    /// non-directory file.
+    const REMOVEDIR = 0x01;
+  }
+}
+
+/// User-provided value that can be attached to objects that is
+/// retained when extracted from the kernel.
+pub type userdata = u64;
+
+/// Relative to which position the offset of the file descriptor
+/// should be set.
+#[repr(u8)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum whence {
+  /// Seek relative to current position.
+  CUR = 1,
+  /// Seek relative to end-of-file.
+  END = 2,
+  /// Seek relative to start-of-file.
+  SET = 3,
+  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
+}
+
+/// Auxiliary vector entry.
+///
+/// The auxiliary vector is a list of key-value pairs that is
+/// provided to the process on startup. Unlike structures, it is
+/// extensible, as it is possible to add new records later on.
+/// The auxiliary vector is always terminated by an entry having
+/// type [`NULL`](enum.auxtype.html#variant.NULL).
+///
+/// The auxiliary vector is part of the x86-64 ABI, but is used by
+/// this environment on all architectures.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct auxv {
+  /// The type of the auxiliary vector entry.
+  pub a_type: auxtype,
+  pub union: auxv_union
+}
+/// A union inside `auxv`.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union auxv_union {
+  /// Used when `a_type` is [`ARGDATALEN`](enum.auxtype.html#variant.ARGDATALEN), [`CANARYLEN`](enum.auxtype.html#variant.CANARYLEN), [`NCPUS`](enum.auxtype.html#variant.NCPUS), [`PAGESZ`](enum.auxtype.html#variant.PAGESZ), [`PHNUM`](enum.auxtype.html#variant.PHNUM), or [`TID`](enum.auxtype.html#variant.TID).
+/// A numerical value.
+  pub a_val: usize,
+  /// Used when `a_type` is [`ARGDATA`](enum.auxtype.html#variant.ARGDATA), [`BASE`](enum.auxtype.html#variant.BASE), [`CANARY`](enum.auxtype.html#variant.CANARY), [`PHDR`](enum.auxtype.html#variant.PHDR), [`PID`](enum.auxtype.html#variant.PID), or [`SYSINFO_EHDR`](enum.auxtype.html#variant.SYSINFO_EHDR).
+/// A pointer value.
+  pub a_ptr: *mut (),
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn auxv_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<auxv>(), 8);
+  assert_eq!(::core::mem::align_of::<auxv>(), 4);
+  unsafe {
+    let obj: auxv = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.a_type as *const _ as usize - base, 0);
+    assert_eq!(&obj.union.a_val as *const _ as usize - base, 4);
+    assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 4);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn auxv_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<auxv>(), 16);
+  assert_eq!(::core::mem::align_of::<auxv>(), 8);
+  unsafe {
+    let obj: auxv = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.a_type as *const _ as usize - base, 0);
+    assert_eq!(&obj.union.a_val as *const _ as usize - base, 8);
+    assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 8);
+  }
+}
+
+/// A region of memory for scatter/gather writes.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct ciovec {
+  /// The address and length of the buffer to be written.
+  pub buf: (*const (), usize),
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn ciovec_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<ciovec>(), 8);
+  assert_eq!(::core::mem::align_of::<ciovec>(), 4);
+  unsafe {
+    let obj: ciovec = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
+    assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn ciovec_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<ciovec>(), 16);
+  assert_eq!(::core::mem::align_of::<ciovec>(), 8);
+  unsafe {
+    let obj: ciovec = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
+    assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
+  }
+}
+
+/// A directory entry.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct dirent {
+  /// The offset of the next directory entry stored in this
+  /// directory.
+  pub d_next: dircookie,
+  /// The serial number of the file referred to by this
+  /// directory entry.
+  pub d_ino: inode,
+  /// The length of the name of the directory entry.
+  pub d_namlen: u32,
+  /// The type of the file referred to by this directory
+  /// entry.
+  pub d_type: filetype,
+}
+#[test]
+fn dirent_layout_test() {
+  assert_eq!(::core::mem::size_of::<dirent>(), 24);
+  assert_eq!(::core::mem::align_of::<dirent>(), 8);
+  unsafe {
+    let obj: dirent = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.d_next as *const _ as usize - base, 0);
+    assert_eq!(&obj.d_ino as *const _ as usize - base, 8);
+    assert_eq!(&obj.d_namlen as *const _ as usize - base, 16);
+    assert_eq!(&obj.d_type as *const _ as usize - base, 20);
+  }
+}
+
+/// An event that occurred.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct event {
+  /// User-provided value that got attached to
+  /// [`subscription.userdata`](struct.subscription.html#structfield.userdata).
+  pub userdata: userdata,
+  /// If non-zero, an error that occurred while processing
+  /// the subscription request.
+  pub error: errno,
+  /// The type of the event that occurred.
+  pub type_: eventtype,
+  pub union: event_union
+}
+/// A union inside `event`.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union event_union {
+  /// Used when `type_` is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
+  pub fd_readwrite: event_fd_readwrite,
+  /// Used when `type_` is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
+  pub proc_terminate: event_proc_terminate,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct event_fd_readwrite {
+  /// The number of bytes available
+  /// for reading or writing.
+  pub nbytes: filesize,
+  /// Obsolete.
+  pub unused: [u8; 4],
+  /// The state of the file
+  /// descriptor.
+  pub flags: eventrwflags,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct event_proc_terminate {
+  /// Obsolete.
+  pub unused: [u8; 4],
+  /// If zero, the process has
+  /// exited.
+  /// Otherwise, the signal
+  /// condition causing it to
+  /// terminated.
+  pub signal: signal,
+  /// If exited, the exit code of
+  /// the process.
+  pub exitcode: exitcode,
+}
+#[test]
+fn event_layout_test() {
+  assert_eq!(::core::mem::size_of::<event>(), 32);
+  assert_eq!(::core::mem::align_of::<event>(), 8);
+  unsafe {
+    let obj: event = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.userdata as *const _ as usize - base, 0);
+    assert_eq!(&obj.error as *const _ as usize - base, 8);
+    assert_eq!(&obj.type_ as *const _ as usize - base, 10);
+    assert_eq!(&obj.union.fd_readwrite.nbytes as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.fd_readwrite.unused as *const _ as usize - base, 24);
+    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 28);
+    assert_eq!(&obj.union.proc_terminate.unused as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.proc_terminate.signal as *const _ as usize - base, 20);
+    assert_eq!(&obj.union.proc_terminate.exitcode as *const _ as usize - base, 24);
+  }
+}
+
+/// File descriptor attributes.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct fdstat {
+  /// File type.
+  pub fs_filetype: filetype,
+  /// File descriptor flags.
+  pub fs_flags: fdflags,
+  /// Rights that apply to this file descriptor.
+  pub fs_rights_base: rights,
+  /// Maximum set of rights that can be installed on new
+  /// file descriptors that are created through this file
+  /// descriptor, e.g., through [`file_open()`](fn.file_open.html).
+  pub fs_rights_inheriting: rights,
+}
+#[test]
+fn fdstat_layout_test() {
+  assert_eq!(::core::mem::size_of::<fdstat>(), 24);
+  assert_eq!(::core::mem::align_of::<fdstat>(), 8);
+  unsafe {
+    let obj: fdstat = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.fs_filetype as *const _ as usize - base, 0);
+    assert_eq!(&obj.fs_flags as *const _ as usize - base, 2);
+    assert_eq!(&obj.fs_rights_base as *const _ as usize - base, 8);
+    assert_eq!(&obj.fs_rights_inheriting as *const _ as usize - base, 16);
+  }
+}
+
+/// File attributes.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct filestat {
+  /// Device ID of device containing the file.
+  pub st_dev: device,
+  /// File serial number.
+  pub st_ino: inode,
+  /// File type.
+  pub st_filetype: filetype,
+  /// Number of hard links to the file.
+  pub st_nlink: linkcount,
+  /// For regular files, the file size in bytes. For
+  /// symbolic links, the length in bytes of the pathname
+  /// contained in the symbolic link.
+  pub st_size: filesize,
+  /// Last data access timestamp.
+  pub st_atim: timestamp,
+  /// Last data modification timestamp.
+  pub st_mtim: timestamp,
+  /// Last file status change timestamp.
+  pub st_ctim: timestamp,
+}
+#[test]
+fn filestat_layout_test() {
+  assert_eq!(::core::mem::size_of::<filestat>(), 56);
+  assert_eq!(::core::mem::align_of::<filestat>(), 8);
+  unsafe {
+    let obj: filestat = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.st_dev as *const _ as usize - base, 0);
+    assert_eq!(&obj.st_ino as *const _ as usize - base, 8);
+    assert_eq!(&obj.st_filetype as *const _ as usize - base, 16);
+    assert_eq!(&obj.st_nlink as *const _ as usize - base, 20);
+    assert_eq!(&obj.st_size as *const _ as usize - base, 24);
+    assert_eq!(&obj.st_atim as *const _ as usize - base, 32);
+    assert_eq!(&obj.st_mtim as *const _ as usize - base, 40);
+    assert_eq!(&obj.st_ctim as *const _ as usize - base, 48);
+  }
+}
+
+/// A region of memory for scatter/gather reads.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct iovec {
+  /// The address and length of the buffer to be filled.
+  pub buf: (*mut (), usize),
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn iovec_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<iovec>(), 8);
+  assert_eq!(::core::mem::align_of::<iovec>(), 4);
+  unsafe {
+    let obj: iovec = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
+    assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn iovec_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<iovec>(), 16);
+  assert_eq!(::core::mem::align_of::<iovec>(), 8);
+  unsafe {
+    let obj: iovec = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
+    assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
+  }
+}
+
+/// Path lookup properties.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct lookup {
+  /// The working directory at which the resolution of the
+  /// path starts.
+  pub fd: fd,
+  /// Flags determining the method of how the path is
+  /// resolved.
+  pub flags: lookupflags,
+}
+#[test]
+fn lookup_layout_test() {
+  assert_eq!(::core::mem::size_of::<lookup>(), 8);
+  assert_eq!(::core::mem::align_of::<lookup>(), 4);
+  unsafe {
+    let obj: lookup = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.fd as *const _ as usize - base, 0);
+    assert_eq!(&obj.flags as *const _ as usize - base, 4);
+  }
+}
+
+/// Entry point for a process (`_start`).
+///
+/// **auxv**:
+/// The auxiliary vector. See [`auxv`](struct.auxv.html).
+pub type processentry = unsafe extern "C" fn(
+  auxv: *const auxv,
+) -> ();
+
+/// Arguments of [`sock_recv()`](fn.sock_recv.html).
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct recv_in {
+  /// List of scatter/gather vectors where message data
+  /// should be stored.
+  pub ri_data: (*const iovec, usize),
+  /// Buffer where numbers of incoming file descriptors
+  /// should be stored.
+  pub ri_fds: (*mut fd, usize),
+  /// Message flags.
+  pub ri_flags: riflags,
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn recv_in_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<recv_in>(), 20);
+  assert_eq!(::core::mem::align_of::<recv_in>(), 4);
+  unsafe {
+    let obj: recv_in = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
+    assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 4);
+    assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 8);
+    assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 12);
+    assert_eq!(&obj.ri_flags as *const _ as usize - base, 16);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn recv_in_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<recv_in>(), 40);
+  assert_eq!(::core::mem::align_of::<recv_in>(), 8);
+  unsafe {
+    let obj: recv_in = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
+    assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 8);
+    assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 16);
+    assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 24);
+    assert_eq!(&obj.ri_flags as *const _ as usize - base, 32);
+  }
+}
+
+/// Results of [`sock_recv()`](fn.sock_recv.html).
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct recv_out {
+  /// Number of bytes stored in [`recv_in.ri_data`](struct.recv_in.html#structfield.ri_data).
+  pub ro_datalen: usize,
+  /// Number of file descriptors stored in [`recv_in.ri_fds`](struct.recv_in.html#structfield.ri_fds).
+  pub ro_fdslen: usize,
+  /// Fields that were used by previous implementations.
+  pub ro_unused: [u8; 40],
+  /// Message flags.
+  pub ro_flags: roflags,
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn recv_out_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<recv_out>(), 52);
+  assert_eq!(::core::mem::align_of::<recv_out>(), 4);
+  unsafe {
+    let obj: recv_out = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
+    assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 4);
+    assert_eq!(&obj.ro_unused as *const _ as usize - base, 8);
+    assert_eq!(&obj.ro_flags as *const _ as usize - base, 48);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn recv_out_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<recv_out>(), 64);
+  assert_eq!(::core::mem::align_of::<recv_out>(), 8);
+  unsafe {
+    let obj: recv_out = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
+    assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 8);
+    assert_eq!(&obj.ro_unused as *const _ as usize - base, 16);
+    assert_eq!(&obj.ro_flags as *const _ as usize - base, 56);
+  }
+}
+
+/// Arguments of [`sock_send()`](fn.sock_send.html).
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct send_in {
+  /// List of scatter/gather vectors where message data
+  /// should be retrieved.
+  pub si_data: (*const ciovec, usize),
+  /// File descriptors that need to be attached to the
+  /// message.
+  pub si_fds: (*const fd, usize),
+  /// Message flags.
+  pub si_flags: siflags,
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn send_in_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<send_in>(), 20);
+  assert_eq!(::core::mem::align_of::<send_in>(), 4);
+  unsafe {
+    let obj: send_in = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
+    assert_eq!(&obj.si_data.1 as *const _ as usize - base, 4);
+    assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 8);
+    assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 12);
+    assert_eq!(&obj.si_flags as *const _ as usize - base, 16);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn send_in_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<send_in>(), 40);
+  assert_eq!(::core::mem::align_of::<send_in>(), 8);
+  unsafe {
+    let obj: send_in = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
+    assert_eq!(&obj.si_data.1 as *const _ as usize - base, 8);
+    assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 16);
+    assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 24);
+    assert_eq!(&obj.si_flags as *const _ as usize - base, 32);
+  }
+}
+
+/// Results of [`sock_send()`](fn.sock_send.html).
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct send_out {
+  /// Number of bytes transmitted.
+  pub so_datalen: usize,
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn send_out_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<send_out>(), 4);
+  assert_eq!(::core::mem::align_of::<send_out>(), 4);
+  unsafe {
+    let obj: send_out = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn send_out_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<send_out>(), 8);
+  assert_eq!(::core::mem::align_of::<send_out>(), 8);
+  unsafe {
+    let obj: send_out = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
+  }
+}
+
+/// Subscription to an event.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct subscription {
+  /// User-provided value that is attached to the
+  /// subscription in the kernel and returned through
+  /// [`event.userdata`](struct.event.html#structfield.userdata).
+  pub userdata: userdata,
+  /// Used by previous implementations. Ignored.
+  pub unused: u16,
+  /// The type of the event to which to subscribe.
+  ///
+  /// Currently, [`CONDVAR`](enum.eventtype.html#variant.CONDVAR),
+  /// [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK), and [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK)
+  /// must be provided as the first subscription and may
+  /// only be followed by up to one other subscription,
+  /// having type [`CLOCK`](enum.eventtype.html#variant.CLOCK).
+  pub type_: eventtype,
+  pub union: subscription_union
+}
+/// A union inside `subscription`.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union subscription_union {
+  /// Used when `type_` is [`CLOCK`](enum.eventtype.html#variant.CLOCK).
+  pub clock: subscription_clock,
+  /// Used when `type_` is [`CONDVAR`](enum.eventtype.html#variant.CONDVAR).
+  pub condvar: subscription_condvar,
+  /// Used when `type_` is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
+  pub fd_readwrite: subscription_fd_readwrite,
+  /// Used when `type_` is [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK) or [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK).
+  pub lock: subscription_lock,
+  /// Used when `type_` is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
+  pub proc_terminate: subscription_proc_terminate,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct subscription_clock {
+  /// The user-defined unique
+  /// identifier of the clock.
+  pub identifier: userdata,
+  /// The clock against which the
+  /// timestamp should be compared.
+  pub clock_id: clockid,
+  /// The absolute or relative
+  /// timestamp.
+  pub timeout: timestamp,
+  /// The amount of time that the
+  /// kernel may wait additionally
+  /// to coalesce with other events.
+  pub precision: timestamp,
+  /// Flags specifying whether the
+  /// timeout is absolute or
+  /// relative.
+  pub flags: subclockflags,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct subscription_condvar {
+  /// The condition variable on
+  /// which to wait to be woken up.
+  pub condvar: *mut condvar,
+  /// The lock that will be
+  /// released while waiting.
+  ///
+  /// The lock will be reacquired
+  /// for writing when the condition
+  /// variable triggers.
+  pub lock: *mut lock,
+  /// Whether the condition variable
+  /// is stored in private or shared
+  /// memory.
+  pub condvar_scope: scope,
+  /// Whether the lock is stored in
+  /// private or shared memory.
+  pub lock_scope: scope,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct subscription_fd_readwrite {
+  /// The file descriptor on which
+  /// to wait for it to become ready
+  /// for reading or writing.
+  pub fd: fd,
+  /// Under which conditions to
+  /// trigger.
+  pub flags: subrwflags,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct subscription_lock {
+  /// The lock that will be acquired
+  /// for reading or writing.
+  pub lock: *mut lock,
+  /// Whether the lock is stored in
+  /// private or shared memory.
+  pub lock_scope: scope,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct subscription_proc_terminate {
+  /// The process descriptor on
+  /// which to wait for process
+  /// termination.
+  pub fd: fd,
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn subscription_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<subscription>(), 56);
+  assert_eq!(::core::mem::align_of::<subscription>(), 8);
+  unsafe {
+    let obj: subscription = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.userdata as *const _ as usize - base, 0);
+    assert_eq!(&obj.unused as *const _ as usize - base, 8);
+    assert_eq!(&obj.type_ as *const _ as usize - base, 10);
+    assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
+    assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
+    assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
+    assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
+    assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 20);
+    assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 24);
+    assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 25);
+    assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
+    assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 20);
+    assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn subscription_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<subscription>(), 56);
+  assert_eq!(::core::mem::align_of::<subscription>(), 8);
+  unsafe {
+    let obj: subscription = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.userdata as *const _ as usize - base, 0);
+    assert_eq!(&obj.unused as *const _ as usize - base, 8);
+    assert_eq!(&obj.type_ as *const _ as usize - base, 10);
+    assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
+    assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
+    assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
+    assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
+    assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 24);
+    assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 32);
+    assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 33);
+    assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
+    assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
+    assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 24);
+    assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
+  }
+}
+
+/// The Thread Control Block (TCB).
+///
+/// After a thread begins execution (at program startup or when
+/// created through [`thread_create()`](fn.thread_create.html)), the CPU's registers
+/// controlling Thread-Local Storage (TLS) will already be
+/// initialized. They will point to an area only containing the
+/// TCB.
+///
+/// If the thread needs space for storing thread-specific
+/// variables, the thread may allocate a larger area and adjust
+/// the CPU's registers to point to that area instead. However, it
+/// does need to make sure that the TCB is copied over to the new
+/// TLS area.
+///
+/// The purpose of the TCB is that it allows light-weight
+/// emulators to store information related to individual threads.
+/// For example, it may be used to store a copy of the CPU
+/// registers prior emulation, so that TLS for the host system
+/// can be restored if needed.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct tcb {
+  /// Pointer that may be freely assigned by the system. Its
+  /// value cannot be interpreted by the application.
+  pub parent: *mut (),
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn tcb_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<tcb>(), 4);
+  assert_eq!(::core::mem::align_of::<tcb>(), 4);
+  unsafe {
+    let obj: tcb = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.parent as *const _ as usize - base, 0);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn tcb_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<tcb>(), 8);
+  assert_eq!(::core::mem::align_of::<tcb>(), 8);
+  unsafe {
+    let obj: tcb = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.parent as *const _ as usize - base, 0);
+  }
+}
+
+/// Entry point for additionally created threads.
+///
+/// **tid**:
+/// Thread ID of the current thread.
+///
+/// **aux**:
+/// Copy of the value stored in
+/// [`threadattr.argument`](struct.threadattr.html#structfield.argument).
+pub type threadentry = unsafe extern "C" fn(
+  tid: tid,
+  aux: *mut (),
+) -> ();
+
+/// Attributes for thread creation.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct threadattr {
+  /// Initial program counter value.
+  pub entry_point: threadentry,
+  /// Region allocated to serve as stack space.
+  pub stack: (*mut (), usize),
+  /// Argument to be forwarded to the entry point function.
+  pub argument: *mut (),
+}
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn threadattr_layout_test_32() {
+  assert_eq!(::core::mem::size_of::<threadattr>(), 16);
+  assert_eq!(::core::mem::align_of::<threadattr>(), 4);
+  unsafe {
+    let obj: threadattr = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
+    assert_eq!(&obj.stack.0 as *const _ as usize - base, 4);
+    assert_eq!(&obj.stack.1 as *const _ as usize - base, 8);
+    assert_eq!(&obj.argument as *const _ as usize - base, 12);
+  }
+}
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn threadattr_layout_test_64() {
+  assert_eq!(::core::mem::size_of::<threadattr>(), 32);
+  assert_eq!(::core::mem::align_of::<threadattr>(), 8);
+  unsafe {
+    let obj: threadattr = ::core::mem::uninitialized();
+    let base = &obj as *const _ as usize;
+    assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
+    assert_eq!(&obj.stack.0 as *const _ as usize - base, 8);
+    assert_eq!(&obj.stack.1 as *const _ as usize - base, 16);
+    assert_eq!(&obj.argument as *const _ as usize - base, 24);
+  }
+}
+
+/// The table with pointers to all syscall implementations.
+#[allow(improper_ctypes)]
+extern "C" {
+  fn cloudabi_sys_clock_res_get(_: clockid, _: *mut timestamp) -> errno;
+  fn cloudabi_sys_clock_time_get(_: clockid, _: timestamp, _: *mut timestamp) -> errno;
+  fn cloudabi_sys_condvar_signal(_: *mut condvar, _: scope, _: nthreads) -> errno;
+  fn cloudabi_sys_fd_close(_: fd) -> errno;
+  fn cloudabi_sys_fd_create1(_: filetype, _: *mut fd) -> errno;
+  fn cloudabi_sys_fd_create2(_: filetype, _: *mut fd, _: *mut fd) -> errno;
+  fn cloudabi_sys_fd_datasync(_: fd) -> errno;
+  fn cloudabi_sys_fd_dup(_: fd, _: *mut fd) -> errno;
+  fn cloudabi_sys_fd_pread(_: fd, _: *const iovec, _: usize, _: filesize, _: *mut usize) -> errno;
+  fn cloudabi_sys_fd_pwrite(_: fd, _: *const ciovec, _: usize, _: filesize, _: *mut usize) -> errno;
+  fn cloudabi_sys_fd_read(_: fd, _: *const iovec, _: usize, _: *mut usize) -> errno;
+  fn cloudabi_sys_fd_replace(_: fd, _: fd) -> errno;
+  fn cloudabi_sys_fd_seek(_: fd, _: filedelta, _: whence, _: *mut filesize) -> errno;
+  fn cloudabi_sys_fd_stat_get(_: fd, _: *mut fdstat) -> errno;
+  fn cloudabi_sys_fd_stat_put(_: fd, _: *const fdstat, _: fdsflags) -> errno;
+  fn cloudabi_sys_fd_sync(_: fd) -> errno;
+  fn cloudabi_sys_fd_write(_: fd, _: *const ciovec, _: usize, _: *mut usize) -> errno;
+  fn cloudabi_sys_file_advise(_: fd, _: filesize, _: filesize, _: advice) -> errno;
+  fn cloudabi_sys_file_allocate(_: fd, _: filesize, _: filesize) -> errno;
+  fn cloudabi_sys_file_create(_: fd, _: *const u8, _: usize, _: filetype) -> errno;
+  fn cloudabi_sys_file_link(_: lookup, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
+  fn cloudabi_sys_file_open(_: lookup, _: *const u8, _: usize, _: oflags, _: *const fdstat, _: *mut fd) -> errno;
+  fn cloudabi_sys_file_readdir(_: fd, _: *mut (), _: usize, _: dircookie, _: *mut usize) -> errno;
+  fn cloudabi_sys_file_readlink(_: fd, _: *const u8, _: usize, _: *mut u8, _: usize, _: *mut usize) -> errno;
+  fn cloudabi_sys_file_rename(_: fd, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
+  fn cloudabi_sys_file_stat_fget(_: fd, _: *mut filestat) -> errno;
+  fn cloudabi_sys_file_stat_fput(_: fd, _: *const filestat, _: fsflags) -> errno;
+  fn cloudabi_sys_file_stat_get(_: lookup, _: *const u8, _: usize, _: *mut filestat) -> errno;
+  fn cloudabi_sys_file_stat_put(_: lookup, _: *const u8, _: usize, _: *const filestat, _: fsflags) -> errno;
+  fn cloudabi_sys_file_symlink(_: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
+  fn cloudabi_sys_file_unlink(_: fd, _: *const u8, _: usize, _: ulflags) -> errno;
+  fn cloudabi_sys_lock_unlock(_: *mut lock, _: scope) -> errno;
+  fn cloudabi_sys_mem_advise(_: *mut (), _: usize, _: advice) -> errno;
+  fn cloudabi_sys_mem_map(_: *mut (), _: usize, _: mprot, _: mflags, _: fd, _: filesize, _: *mut *mut ()) -> errno;
+  fn cloudabi_sys_mem_protect(_: *mut (), _: usize, _: mprot) -> errno;
+  fn cloudabi_sys_mem_sync(_: *mut (), _: usize, _: msflags) -> errno;
+  fn cloudabi_sys_mem_unmap(_: *mut (), _: usize) -> errno;
+  fn cloudabi_sys_poll(_: *const subscription, _: *mut event, _: usize, _: *mut usize) -> errno;
+  fn cloudabi_sys_proc_exec(_: fd, _: *const (), _: usize, _: *const fd, _: usize) -> errno;
+  fn cloudabi_sys_proc_exit(_: exitcode) -> !;
+  fn cloudabi_sys_proc_fork(_: *mut fd, _: *mut tid) -> errno;
+  fn cloudabi_sys_proc_raise(_: signal) -> errno;
+  fn cloudabi_sys_random_get(_: *mut (), _: usize) -> errno;
+  fn cloudabi_sys_sock_recv(_: fd, _: *const recv_in, _: *mut recv_out) -> errno;
+  fn cloudabi_sys_sock_send(_: fd, _: *const send_in, _: *mut send_out) -> errno;
+  fn cloudabi_sys_sock_shutdown(_: fd, _: sdflags) -> errno;
+  fn cloudabi_sys_thread_create(_: *mut threadattr, _: *mut tid) -> errno;
+  fn cloudabi_sys_thread_exit(_: *mut lock, _: scope) -> !;
+  fn cloudabi_sys_thread_yield() -> errno;
+}
+
+/// Obtains the resolution of a clock.
+///
+/// ## Parameters
+///
+/// **clock_id**:
+/// The clock for which the resolution needs to be
+/// returned.
+///
+/// **resolution**:
+/// The resolution of the clock.
+#[inline]
+pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) -> errno {
+  cloudabi_sys_clock_res_get(clock_id_, resolution_)
+}
+
+/// Obtains the time value of a clock.
+///
+/// ## Parameters
+///
+/// **clock_id**:
+/// The clock for which the time needs to be
+/// returned.
+///
+/// **precision**:
+/// The maximum lag (exclusive) that the returned
+/// time value may have, compared to its actual
+/// value.
+///
+/// **time**:
+/// The time value of the clock.
+#[inline]
+pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: &mut timestamp) -> errno {
+  cloudabi_sys_clock_time_get(clock_id_, precision_, time_)
+}
+
+/// Wakes up threads waiting on a userspace condition variable.
+///
+/// If an invocation of this system call causes all waiting
+/// threads to be woken up, the value of the condition variable
+/// is set to [`CONDVAR_HAS_NO_WAITERS`](constant.CONDVAR_HAS_NO_WAITERS.html). As long as the condition
+/// variable is set to this value, it is not needed to invoke this
+/// system call.
+///
+/// ## Parameters
+///
+/// **condvar**:
+/// The userspace condition variable that has
+/// waiting threads.
+///
+/// **scope**:
+/// Whether the condition variable is stored in
+/// private or shared memory.
+///
+/// **nwaiters**:
+/// The number of threads that need to be woken
+/// up. If it exceeds the number of waiting
+/// threads, all threads are woken up.
+#[inline]
+pub unsafe fn condvar_signal(condvar_: *mut condvar, scope_: scope, nwaiters_: nthreads) -> errno {
+  cloudabi_sys_condvar_signal(condvar_, scope_, nwaiters_)
+}
+
+/// Closes a file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor that needs to be closed.
+#[inline]
+pub unsafe fn fd_close(fd_: fd) -> errno {
+  cloudabi_sys_fd_close(fd_)
+}
+
+/// Creates a file descriptor.
+///
+/// ## Parameters
+///
+/// **type**:
+/// Possible values:
+///
+///   - [`SHARED_MEMORY`](enum.filetype.html#variant.SHARED_MEMORY):
+///     Creates an anonymous shared memory
+///     object.
+///
+/// **fd**:
+/// The file descriptor that has been created.
+#[inline]
+pub unsafe fn fd_create1(type_: filetype, fd_: &mut fd) -> errno {
+  cloudabi_sys_fd_create1(type_, fd_)
+}
+
+/// Creates a pair of file descriptors.
+///
+/// ## Parameters
+///
+/// **type**:
+/// Possible values:
+///
+///   - [`SOCKET_DGRAM`](enum.filetype.html#variant.SOCKET_DGRAM):
+///     Creates a UNIX datagram socket pair.
+///   - [`SOCKET_STREAM`](enum.filetype.html#variant.SOCKET_STREAM):
+///     Creates a UNIX byte-stream socket
+///     pair.
+///
+/// **fd1**:
+/// The first file descriptor of the pair.
+///
+/// **fd2**:
+/// The second file descriptor of the pair.
+#[inline]
+pub unsafe fn fd_create2(type_: filetype, fd1_: &mut fd, fd2_: &mut fd) -> errno {
+  cloudabi_sys_fd_create2(type_, fd1_, fd2_)
+}
+
+/// Synchronizes the data of a file to disk.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor of the file whose data
+/// needs to be synchronized to disk.
+#[inline]
+pub unsafe fn fd_datasync(fd_: fd) -> errno {
+  cloudabi_sys_fd_datasync(fd_)
+}
+
+/// Duplicates a file descriptor.
+///
+/// ## Parameters
+///
+/// **from**:
+/// The file descriptor that needs to be
+/// duplicated.
+///
+/// **fd**:
+/// The new file descriptor.
+#[inline]
+pub unsafe fn fd_dup(from_: fd, fd_: &mut fd) -> errno {
+  cloudabi_sys_fd_dup(from_, fd_)
+}
+
+/// Reads from a file descriptor, without using and updating the
+/// file descriptor's offset.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor from which data should be
+/// read.
+///
+/// **iovs**:
+/// List of scatter/gather vectors where data
+/// should be stored.
+///
+/// **offset**:
+/// The offset within the file at which reading
+/// should start.
+///
+/// **nread**:
+/// The number of bytes read.
+#[inline]
+pub unsafe fn fd_pread(fd_: fd, iovs_: &[iovec], offset_: filesize, nread_: &mut usize) -> errno {
+  cloudabi_sys_fd_pread(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nread_)
+}
+
+/// Writes to a file descriptor, without using and updating the
+/// file descriptor's offset.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor to which data should be
+/// written.
+///
+/// **iovs**:
+/// List of scatter/gather vectors where data
+/// should be retrieved.
+///
+/// **offset**:
+/// The offset within the file at which writing
+/// should start.
+///
+/// **nwritten**:
+/// The number of bytes written.
+#[inline]
+pub unsafe fn fd_pwrite(fd_: fd, iovs_: &[ciovec], offset_: filesize, nwritten_: &mut usize) -> errno {
+  cloudabi_sys_fd_pwrite(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nwritten_)
+}
+
+/// Reads from a file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor from which data should be
+/// read.
+///
+/// **iovs**:
+/// List of scatter/gather vectors where data
+/// should be stored.
+///
+/// **nread**:
+/// The number of bytes read.
+#[inline]
+pub unsafe fn fd_read(fd_: fd, iovs_: &[iovec], nread_: &mut usize) -> errno {
+  cloudabi_sys_fd_read(fd_, iovs_.as_ptr(), iovs_.len(), nread_)
+}
+
+/// Atomically replaces a file descriptor by a copy of another
+/// file descriptor.
+///
+/// Due to the strong focus on thread safety, this environment
+/// does not provide a mechanism to duplicate a file descriptor to
+/// an arbitrary number, like dup2(). This would be prone to race
+/// conditions, as an actual file descriptor with the same number
+/// could be allocated by a different thread at the same time.
+///
+/// This system call provides a way to atomically replace file
+/// descriptors, which would disappear if dup2() were to be
+/// removed entirely.
+///
+/// ## Parameters
+///
+/// **from**:
+/// The file descriptor that needs to be copied.
+///
+/// **to**:
+/// The file descriptor that needs to be
+/// overwritten.
+#[inline]
+pub unsafe fn fd_replace(from_: fd, to_: fd) -> errno {
+  cloudabi_sys_fd_replace(from_, to_)
+}
+
+/// Moves the offset of the file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor whose offset has to be
+/// moved.
+///
+/// **offset**:
+/// The number of bytes to move.
+///
+/// **whence**:
+/// Relative to which position the move should
+/// take place.
+///
+/// **newoffset**:
+/// The new offset of the file descriptor,
+/// relative to the start of the file.
+#[inline]
+pub unsafe fn fd_seek(fd_: fd, offset_: filedelta, whence_: whence, newoffset_: &mut filesize) -> errno {
+  cloudabi_sys_fd_seek(fd_, offset_, whence_, newoffset_)
+}
+
+/// Gets attributes of a file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor whose attributes have to
+/// be obtained.
+///
+/// **buf**:
+/// The buffer where the file descriptor's
+/// attributes are stored.
+#[inline]
+pub unsafe fn fd_stat_get(fd_: fd, buf_: *mut fdstat) -> errno {
+  cloudabi_sys_fd_stat_get(fd_, buf_)
+}
+
+/// Adjusts attributes of a file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor whose attributes have to
+/// be adjusted.
+///
+/// **buf**:
+/// The desired values of the file descriptor
+/// attributes that are adjusted.
+///
+/// **flags**:
+/// A bitmask indicating which attributes have to
+/// be adjusted.
+#[inline]
+pub unsafe fn fd_stat_put(fd_: fd, buf_: *const fdstat, flags_: fdsflags) -> errno {
+  cloudabi_sys_fd_stat_put(fd_, buf_, flags_)
+}
+
+/// Synchronizes the data and metadata of a file to disk.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor of the file whose data
+/// and metadata needs to be synchronized to disk.
+#[inline]
+pub unsafe fn fd_sync(fd_: fd) -> errno {
+  cloudabi_sys_fd_sync(fd_)
+}
+
+/// Writes to a file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor to which data should be
+/// written.
+///
+/// **iovs**:
+/// List of scatter/gather vectors where data
+/// should be retrieved.
+///
+/// **nwritten**:
+/// The number of bytes written.
+#[inline]
+pub unsafe fn fd_write(fd_: fd, iovs_: &[ciovec], nwritten_: &mut usize) -> errno {
+  cloudabi_sys_fd_write(fd_, iovs_.as_ptr(), iovs_.len(), nwritten_)
+}
+
+/// Provides file advisory information on a file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor for which to provide file
+/// advisory information.
+///
+/// **offset**:
+/// The offset within the file to which the
+/// advisory applies.
+///
+/// **len**:
+/// The length of the region to which the advisory
+/// applies.
+///
+/// **advice**:
+/// The advice.
+#[inline]
+pub unsafe fn file_advise(fd_: fd, offset_: filesize, len_: filesize, advice_: advice) -> errno {
+  cloudabi_sys_file_advise(fd_, offset_, len_, advice_)
+}
+
+/// Forces the allocation of space in a file.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file in which the space should be
+/// allocated.
+///
+/// **offset**:
+/// The offset at which the allocation should
+/// start.
+///
+/// **len**:
+/// The length of the area that is allocated.
+#[inline]
+pub unsafe fn file_allocate(fd_: fd, offset_: filesize, len_: filesize) -> errno {
+  cloudabi_sys_file_allocate(fd_, offset_, len_)
+}
+
+/// Creates a file of a specified type.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The working directory at which the resolution
+/// of the file to be created starts.
+///
+/// **path**:
+/// The path at which the file should be created.
+///
+/// **type**:
+/// Possible values:
+///
+///   - [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY):
+///     Creates a directory.
+#[inline]
+pub unsafe fn file_create(fd_: fd, path_: &[u8], type_: filetype) -> errno {
+  cloudabi_sys_file_create(fd_, path_.as_ptr(), path_.len(), type_)
+}
+
+/// Creates a hard link.
+///
+/// ## Parameters
+///
+/// **fd1**:
+/// The working directory at which the resolution
+/// of the source path starts.
+///
+/// **path1**:
+/// The source path of the file that should be
+/// hard linked.
+///
+/// **fd2**:
+/// The working directory at which the resolution
+/// of the destination path starts.
+///
+/// **path2**:
+/// The destination path at which the hard link
+/// should be created.
+#[inline]
+pub unsafe fn file_link(fd1_: lookup, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
+  cloudabi_sys_file_link(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
+}
+
+/// Opens a file.
+///
+/// ## Parameters
+///
+/// **dirfd**:
+/// The working directory at which the resolution
+/// of the file to be opened starts.
+///
+/// **path**:
+/// The path of the file that should be opened.
+///
+/// **oflags**:
+/// The method at which the file should be opened.
+///
+/// **fds**:
+/// [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
+/// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting) specify the
+/// initial rights of the newly created file
+/// descriptor. The operating system is allowed to
+/// return a file descriptor with fewer rights
+/// than specified, if and only if those rights do
+/// not apply to the type of file being opened.
+///
+/// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags) specifies the initial flags
+/// of the file descriptor.
+///
+/// [`fdstat.fs_filetype`](struct.fdstat.html#structfield.fs_filetype) is ignored.
+///
+/// **fd**:
+/// The file descriptor of the file that has been
+/// opened.
+#[inline]
+pub unsafe fn file_open(dirfd_: lookup, path_: &[u8], oflags_: oflags, fds_: *const fdstat, fd_: &mut fd) -> errno {
+  cloudabi_sys_file_open(dirfd_, path_.as_ptr(), path_.len(), oflags_, fds_, fd_)
+}
+
+/// Reads directory entries from a directory.
+///
+/// When successful, the contents of the output buffer consist of
+/// a sequence of directory entries. Each directory entry consists
+/// of a [`dirent`](struct.dirent.html) object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes
+/// holding the name of the directory entry.
+///
+/// This system call fills the output buffer as much as possible,
+/// potentially truncating the last directory entry. This allows
+/// the caller to grow its read buffer size in case it's too small
+/// to fit a single large directory entry, or skip the oversized
+/// directory entry.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The directory from which to read the directory
+/// entries.
+///
+/// **buf**:
+/// The buffer where directory entries are stored.
+///
+/// **cookie**:
+/// The location within the directory to start
+/// reading.
+///
+/// **bufused**:
+/// The number of bytes stored in the read buffer.
+/// If less than the size of the read buffer, the
+/// end of the directory has been reached.
+#[inline]
+pub unsafe fn file_readdir(fd_: fd, buf_: &mut [u8], cookie_: dircookie, bufused_: &mut usize) -> errno {
+  cloudabi_sys_file_readdir(fd_, buf_.as_mut_ptr() as *mut (), buf_.len(), cookie_, bufused_)
+}
+
+/// Reads the contents of a symbolic link.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The working directory at which the resolution
+/// of the path of the symbolic starts.
+///
+/// **path**:
+/// The path of the symbolic link whose contents
+/// should be read.
+///
+/// **buf**:
+/// The buffer where the contents of the symbolic
+/// link should be stored.
+///
+/// **bufused**:
+/// The number of bytes placed in the buffer.
+#[inline]
+pub unsafe fn file_readlink(fd_: fd, path_: &[u8], buf_: &mut [u8], bufused_: &mut usize) -> errno {
+  cloudabi_sys_file_readlink(fd_, path_.as_ptr(), path_.len(), buf_.as_mut_ptr(), buf_.len(), bufused_)
+}
+
+/// Renames a file.
+///
+/// ## Parameters
+///
+/// **fd1**:
+/// The working directory at which the resolution
+/// of the source path starts.
+///
+/// **path1**:
+/// The source path of the file that should be
+/// renamed.
+///
+/// **fd2**:
+/// The working directory at which the resolution
+/// of the destination path starts.
+///
+/// **path2**:
+/// The destination path to which the file should
+/// be renamed.
+#[inline]
+pub unsafe fn file_rename(fd1_: fd, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
+  cloudabi_sys_file_rename(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
+}
+
+/// Gets attributes of a file by file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor whose attributes have to
+/// be obtained.
+///
+/// **buf**:
+/// The buffer where the file's attributes are
+/// stored.
+#[inline]
+pub unsafe fn file_stat_fget(fd_: fd, buf_: *mut filestat) -> errno {
+  cloudabi_sys_file_stat_fget(fd_, buf_)
+}
+
+/// Adjusts attributes of a file by file descriptor.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The file descriptor whose attributes have to
+/// be adjusted.
+///
+/// **buf**:
+/// The desired values of the file attributes that
+/// are adjusted.
+///
+/// **flags**:
+/// A bitmask indicating which attributes have to
+/// be adjusted.
+#[inline]
+pub unsafe fn file_stat_fput(fd_: fd, buf_: *const filestat, flags_: fsflags) -> errno {
+  cloudabi_sys_file_stat_fput(fd_, buf_, flags_)
+}
+
+/// Gets attributes of a file by path.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The working directory at which the resolution
+/// of the path whose attributes have to be
+/// obtained starts.
+///
+/// **path**:
+/// The path of the file whose attributes have to
+/// be obtained.
+///
+/// **buf**:
+/// The buffer where the file's attributes are
+/// stored.
+#[inline]
+pub unsafe fn file_stat_get(fd_: lookup, path_: &[u8], buf_: *mut filestat) -> errno {
+  cloudabi_sys_file_stat_get(fd_, path_.as_ptr(), path_.len(), buf_)
+}
+
+/// Adjusts attributes of a file by path.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The working directory at which the resolution
+/// of the path whose attributes have to be
+/// adjusted starts.
+///
+/// **path**:
+/// The path of the file whose attributes have to
+/// be adjusted.
+///
+/// **buf**:
+/// The desired values of the file attributes that
+/// are adjusted.
+///
+/// **flags**:
+/// A bitmask indicating which attributes have to
+/// be adjusted.
+#[inline]
+pub unsafe fn file_stat_put(fd_: lookup, path_: &[u8], buf_: *const filestat, flags_: fsflags) -> errno {
+  cloudabi_sys_file_stat_put(fd_, path_.as_ptr(), path_.len(), buf_, flags_)
+}
+
+/// Creates a symbolic link.
+///
+/// ## Parameters
+///
+/// **path1**:
+/// The contents of the symbolic link.
+///
+/// **fd**:
+/// The working directory at which the resolution
+/// of the destination path starts.
+///
+/// **path2**:
+/// The destination path at which the symbolic
+/// link should be created.
+#[inline]
+pub unsafe fn file_symlink(path1_: &[u8], fd_: fd, path2_: &[u8]) -> errno {
+  cloudabi_sys_file_symlink(path1_.as_ptr(), path1_.len(), fd_, path2_.as_ptr(), path2_.len())
+}
+
+/// Unlinks a file, or removes a directory.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// The working directory at which the resolution
+/// of the path starts.
+///
+/// **path**:
+/// The path that needs to be unlinked or removed.
+///
+/// **flags**:
+/// Possible values:
+///
+///   - [`REMOVEDIR`](struct.ulflags.html#associatedconstant.REMOVEDIR):
+///     If set, attempt to remove a directory.
+///     Otherwise, unlink a file.
+#[inline]
+pub unsafe fn file_unlink(fd_: fd, path_: &[u8], flags_: ulflags) -> errno {
+  cloudabi_sys_file_unlink(fd_, path_.as_ptr(), path_.len(), flags_)
+}
+
+/// Unlocks a write-locked userspace lock.
+///
+/// If a userspace lock is unlocked while having its
+/// [`LOCK_KERNEL_MANAGED`](constant.LOCK_KERNEL_MANAGED.html) flag set, the lock cannot be unlocked in
+/// userspace directly. This system call needs to be performed
+/// instead, so that any waiting threads can be woken up.
+///
+/// To prevent spurious invocations of this system call, the lock
+/// must be locked for writing. This prevents other threads from
+/// acquiring additional read locks while the system call is in
+/// progress. If the lock is acquired for reading, it must first
+/// be upgraded to a write lock.
+///
+/// ## Parameters
+///
+/// **lock**:
+/// The userspace lock that is locked for writing
+/// by the calling thread.
+///
+/// **scope**:
+/// Whether the lock is stored in private or
+/// shared memory.
+#[inline]
+pub unsafe fn lock_unlock(lock_: *mut lock, scope_: scope) -> errno {
+  cloudabi_sys_lock_unlock(lock_, scope_)
+}
+
+/// Provides memory advisory information on a region of memory.
+///
+/// ## Parameters
+///
+/// **mapping**:
+/// The pages for which to provide memory advisory
+/// information.
+///
+/// **advice**:
+/// The advice.
+#[inline]
+pub unsafe fn mem_advise(mapping_: &mut [u8], advice_: advice) -> errno {
+  cloudabi_sys_mem_advise(mapping_.as_mut_ptr() as *mut (), mapping_.len(), advice_)
+}
+
+/// Creates a memory mapping, making the contents of a file
+/// accessible through memory.
+///
+/// ## Parameters
+///
+/// **addr**:
+/// If [`FIXED`](struct.mflags.html#associatedconstant.FIXED) is set, specifies to which
+/// address the file region is mapped. Otherwise,
+/// the mapping is performed at an unused
+/// location.
+///
+/// **len**:
+/// The length of the memory mapping to be
+/// created.
+///
+/// **prot**:
+/// Initial memory protection options for the
+/// memory mapping.
+///
+/// **flags**:
+/// Memory mapping flags.
+///
+/// **fd**:
+/// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
+/// [`MAP_ANON_FD`](constant.MAP_ANON_FD.html). Otherwise, this argument
+/// specifies the file whose contents need to be
+/// mapped.
+///
+/// **off**:
+/// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
+/// zero. Otherwise, this argument specifies the
+/// offset within the file at which the mapping
+/// starts.
+///
+/// **mem**:
+/// The starting address of the memory mapping.
+#[inline]
+pub unsafe fn mem_map(addr_: *mut (), len_: usize, prot_: mprot, flags_: mflags, fd_: fd, off_: filesize, mem_: &mut *mut ()) -> errno {
+  cloudabi_sys_mem_map(addr_, len_, prot_, flags_, fd_, off_, mem_)
+}
+
+/// Change the protection of a memory mapping.
+///
+/// ## Parameters
+///
+/// **mapping**:
+/// The pages that need their protection changed.
+///
+/// **prot**:
+/// New protection options.
+#[inline]
+pub unsafe fn mem_protect(mapping_: &mut [u8], prot_: mprot) -> errno {
+  cloudabi_sys_mem_protect(mapping_.as_mut_ptr() as *mut (), mapping_.len(), prot_)
+}
+
+/// Synchronize a region of memory with its physical storage.
+///
+/// ## Parameters
+///
+/// **mapping**:
+/// The pages that need to be synchronized.
+///
+/// **flags**:
+/// The method of synchronization.
+#[inline]
+pub unsafe fn mem_sync(mapping_: &mut [u8], flags_: msflags) -> errno {
+  cloudabi_sys_mem_sync(mapping_.as_mut_ptr() as *mut (), mapping_.len(), flags_)
+}
+
+/// Unmaps a region of memory.
+///
+/// ## Parameters
+///
+/// **mapping**:
+/// The pages that needs to be unmapped.
+#[inline]
+pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno {
+  cloudabi_sys_mem_unmap(mapping_.as_mut_ptr() as *mut (), mapping_.len())
+}
+
+/// Concurrently polls for the occurrence of a set of events.
+///
+/// ## Parameters
+///
+/// **in**:
+/// The events to which to subscribe.
+///
+/// **out**:
+/// The events that have occurred.
+///
+/// **nsubscriptions**:
+/// Both the number of subscriptions and events.
+///
+/// **nevents**:
+/// The number of events stored.
+#[inline]
+pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: &mut usize) -> errno {
+  cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_)
+}
+
+/// Replaces the process by a new executable.
+///
+/// Process execution in CloudABI differs from POSIX in two ways:
+/// handling of arguments and inheritance of file descriptors.
+///
+/// CloudABI does not use string command line arguments. Instead,
+/// a buffer with binary data is copied into the address space of
+/// the new executable. The kernel does not enforce any specific
+/// structure to this data, although CloudABI's C library uses it
+/// to store a tree structure that is semantically identical to
+/// YAML.
+///
+/// Due to the strong focus on thread safety, file descriptors
+/// aren't inherited through close-on-exec flags. An explicit
+/// list of file descriptors that need to be retained needs to be
+/// provided. After execution, file descriptors are placed in the
+/// order in which they are stored in the array. This not only
+/// makes the execution process deterministic. It also prevents
+/// potential information disclosures about the layout of the
+/// original process.
+///
+/// ## Parameters
+///
+/// **fd**:
+/// A file descriptor of the new executable.
+///
+/// **data**:
+/// Binary argument data that is passed on to the
+/// new executable.
+///
+/// **fds**:
+/// The layout of the file descriptor table after
+/// execution.
+#[inline]
+pub unsafe fn proc_exec(fd_: fd, data_: &[u8], fds_: &[fd]) -> errno {
+  cloudabi_sys_proc_exec(fd_, data_.as_ptr() as *const (), data_.len(), fds_.as_ptr(), fds_.len())
+}
+
+/// Terminates the process normally.
+///
+/// ## Parameters
+///
+/// **rval**:
+/// The exit code returned by the process. The
+/// exit code can be obtained by other processes
+/// through [`event.union.proc_terminate.exitcode`](struct.event_proc_terminate.html#structfield.exitcode).
+#[inline]
+pub unsafe fn proc_exit(rval_: exitcode) -> ! {
+  cloudabi_sys_proc_exit(rval_)
+}
+
+/// Forks the process of the calling thread.
+///
+/// After forking, a new process shall be created, having only a
+/// copy of the calling thread. The parent process will obtain a
+/// process descriptor. When closed, the child process is
+/// automatically signaled with [`KILL`](enum.signal.html#variant.KILL).
+///
+/// ## Parameters
+///
+/// **fd**:
+/// In the parent process: the file descriptor
+/// number of the process descriptor.
+///
+/// In the child process: [`PROCESS_CHILD`](constant.PROCESS_CHILD.html).
+///
+/// **tid**:
+/// In the parent process: undefined.
+///
+/// In the child process: the thread ID of the
+/// initial thread of the child process.
+#[inline]
+pub unsafe fn proc_fork(fd_: &mut fd, tid_: &mut tid) -> errno {
+  cloudabi_sys_proc_fork(fd_, tid_)
+}
+
+/// Sends a signal to the process of the calling thread.
+///
+/// ## Parameters
+///
+/// **sig**:
+/// The signal condition that should be triggered.
+/// If the signal causes the process to terminate,
+/// its condition can be obtained by other
+/// processes through
+/// [`event.union.proc_terminate.signal`](struct.event_proc_terminate.html#structfield.signal).
+#[inline]
+pub unsafe fn proc_raise(sig_: signal) -> errno {
+  cloudabi_sys_proc_raise(sig_)
+}
+
+/// Obtains random data from the kernel random number generator.
+///
+/// As this interface is not guaranteed to be fast, it is advised
+/// that the random data obtained through this system call is used
+/// as the seed for a userspace pseudo-random number generator.
+///
+/// ## Parameters
+///
+/// **buf**:
+/// The buffer that needs to be filled with random
+/// data.
+#[inline]
+pub unsafe fn random_get(buf_: &mut [u8]) -> errno {
+  cloudabi_sys_random_get(buf_.as_mut_ptr() as *mut (), buf_.len())
+}
+
+/// Receives a message on a socket.
+///
+/// ## Parameters
+///
+/// **sock**:
+/// The socket on which a message should be
+/// received.
+///
+/// **in**:
+/// Input parameters.
+///
+/// **out**:
+/// Output parameters.
+#[inline]
+pub unsafe fn sock_recv(sock_: fd, in_: *const recv_in, out_: *mut recv_out) -> errno {
+  cloudabi_sys_sock_recv(sock_, in_, out_)
+}
+
+/// Sends a message on a socket.
+///
+/// ## Parameters
+///
+/// **sock**:
+/// The socket on which a message should be sent.
+///
+/// **in**:
+/// Input parameters.
+///
+/// **out**:
+/// Output parameters.
+#[inline]
+pub unsafe fn sock_send(sock_: fd, in_: *const send_in, out_: *mut send_out) -> errno {
+  cloudabi_sys_sock_send(sock_, in_, out_)
+}
+
+/// Shuts down socket send and receive channels.
+///
+/// ## Parameters
+///
+/// **sock**:
+/// The socket that needs its channels shut down.
+///
+/// **how**:
+/// Which channels on the socket need to be shut
+/// down.
+#[inline]
+pub unsafe fn sock_shutdown(sock_: fd, how_: sdflags) -> errno {
+  cloudabi_sys_sock_shutdown(sock_, how_)
+}
+
+/// Creates a new thread within the current process.
+///
+/// ## Parameters
+///
+/// **attr**:
+/// The desired attributes of the new thread.
+///
+/// **tid**:
+/// The thread ID of the new thread.
+#[inline]
+pub unsafe fn thread_create(attr_: *mut threadattr, tid_: &mut tid) -> errno {
+  cloudabi_sys_thread_create(attr_, tid_)
+}
+
+/// Terminates the calling thread.
+///
+/// This system call can also unlock a single userspace lock
+/// after termination, which can be used to implement thread
+/// joining.
+///
+/// ## Parameters
+///
+/// **lock**:
+/// Userspace lock that is locked for writing by
+/// the calling thread.
+///
+/// **scope**:
+/// Whether the lock is stored in private or
+/// shared memory.
+#[inline]
+pub unsafe fn thread_exit(lock_: *mut lock, scope_: scope) -> ! {
+  cloudabi_sys_thread_exit(lock_, scope_)
+}
+
+/// Temporarily yields execution of the calling thread.
+#[inline]
+pub unsafe fn thread_yield() -> errno {
+  cloudabi_sys_thread_yield()
+}
diff --git a/src/libstd/sys/cloudabi/abi/mod.rs b/src/libstd/sys/cloudabi/abi/mod.rs
new file mode 100644 (file)
index 0000000..81a4d29
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+#[allow(warnings)]
+mod cloudabi;
+pub use self::cloudabi::*;
diff --git a/src/libstd/sys/cloudabi/args.rs b/src/libstd/sys/cloudabi/args.rs
new file mode 100644 (file)
index 0000000..7b62cc6
--- /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.
+
+pub use sys::cloudabi::shims::args::*;
+
+#[allow(dead_code)]
+pub fn init(_: isize, _: *const *const u8) {}
+
+#[allow(dead_code)]
+pub fn cleanup() {}
diff --git a/src/libstd/sys/cloudabi/backtrace.rs b/src/libstd/sys/cloudabi/backtrace.rs
new file mode 100644 (file)
index 0000000..33d9317
--- /dev/null
@@ -0,0 +1,121 @@
+// Copyright 2014-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 error::Error;
+use ffi::CStr;
+use intrinsics;
+use io;
+use libc;
+use sys_common::backtrace::Frame;
+use unwind as uw;
+
+pub struct BacktraceContext;
+
+struct Context<'a> {
+    idx: usize,
+    frames: &'a mut [Frame],
+}
+
+#[derive(Debug)]
+struct UnwindError(uw::_Unwind_Reason_Code);
+
+impl Error for UnwindError {
+    fn description(&self) -> &'static str {
+        "unexpected return value while unwinding"
+    }
+}
+
+impl ::fmt::Display for UnwindError {
+    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+        write!(f, "{}: {:?}", self.description(), self.0)
+    }
+}
+
+#[inline(never)] // if we know this is a function call, we can skip it when
+                 // tracing
+pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
+    let mut cx = Context { idx: 0, frames };
+    let result_unwind =
+        unsafe { uw::_Unwind_Backtrace(trace_fn, &mut cx as *mut Context as *mut libc::c_void) };
+    // See libunwind:src/unwind/Backtrace.c for the return values.
+    // No, there is no doc.
+    match result_unwind {
+        // These return codes seem to be benign and need to be ignored for backtraces
+        // to show up properly on all tested platforms.
+        uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
+            Ok((cx.idx, BacktraceContext))
+        }
+        _ => Err(io::Error::new(
+            io::ErrorKind::Other,
+            UnwindError(result_unwind),
+        )),
+    }
+}
+
+extern "C" fn trace_fn(
+    ctx: *mut uw::_Unwind_Context,
+    arg: *mut libc::c_void,
+) -> uw::_Unwind_Reason_Code {
+    let cx = unsafe { &mut *(arg as *mut Context) };
+    let mut ip_before_insn = 0;
+    let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void };
+    if !ip.is_null() && ip_before_insn == 0 {
+        // this is a non-signaling frame, so `ip` refers to the address
+        // after the calling instruction. account for that.
+        ip = (ip as usize - 1) as *mut _;
+    }
+
+    let symaddr = unsafe { uw::_Unwind_FindEnclosingFunction(ip) };
+    if cx.idx < cx.frames.len() {
+        cx.frames[cx.idx] = Frame {
+            symbol_addr: symaddr as *mut u8,
+            exact_position: ip as *mut u8,
+        };
+        cx.idx += 1;
+    }
+
+    uw::_URC_NO_REASON
+}
+
+pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
+where
+    F: FnMut(&[u8], u32) -> io::Result<()>,
+{
+    // No way to obtain this information on CloudABI.
+    Ok(false)
+}
+
+pub fn resolve_symname<F>(frame: Frame, callback: F, _: &BacktraceContext) -> io::Result<()>
+where
+    F: FnOnce(Option<&str>) -> io::Result<()>,
+{
+    unsafe {
+        let mut info: Dl_info = intrinsics::init();
+        let symname =
+            if dladdr(frame.exact_position as *mut _, &mut info) == 0 || info.dli_sname.is_null() {
+                None
+            } else {
+                CStr::from_ptr(info.dli_sname).to_str().ok()
+            };
+        callback(symname)
+    }
+}
+
+#[repr(C)]
+struct Dl_info {
+    dli_fname: *const libc::c_char,
+    dli_fbase: *mut libc::c_void,
+    dli_sname: *const libc::c_char,
+    dli_saddr: *mut libc::c_void,
+}
+
+extern "C" {
+    fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
+}
diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs
new file mode 100644 (file)
index 0000000..c05c837
--- /dev/null
@@ -0,0 +1,169 @@
+// 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 cell::UnsafeCell;
+use mem;
+use sync::atomic::{AtomicU32, Ordering};
+use sys::cloudabi::abi;
+use sys::mutex::{self, Mutex};
+use sys::time::dur2intervals;
+use time::Duration;
+
+extern "C" {
+    #[thread_local]
+    static __pthread_thread_id: abi::tid;
+}
+
+pub struct Condvar {
+    condvar: UnsafeCell<AtomicU32>,
+}
+
+unsafe impl Send for Condvar {}
+unsafe impl Sync for Condvar {}
+
+impl Condvar {
+    pub const fn new() -> Condvar {
+        Condvar {
+            condvar: UnsafeCell::new(AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0)),
+        }
+    }
+
+    pub unsafe fn init(&mut self) {}
+
+    pub unsafe fn notify_one(&self) {
+        let condvar = self.condvar.get();
+        if (*condvar).load(Ordering::Relaxed) != abi::CONDVAR_HAS_NO_WAITERS.0 {
+            let ret = abi::condvar_signal(condvar as *mut abi::condvar, abi::scope::PRIVATE, 1);
+            assert_eq!(
+                ret,
+                abi::errno::SUCCESS,
+                "Failed to signal on condition variable"
+            );
+        }
+    }
+
+    pub unsafe fn notify_all(&self) {
+        let condvar = self.condvar.get();
+        if (*condvar).load(Ordering::Relaxed) != abi::CONDVAR_HAS_NO_WAITERS.0 {
+            let ret = abi::condvar_signal(
+                condvar as *mut abi::condvar,
+                abi::scope::PRIVATE,
+                abi::nthreads::max_value(),
+            );
+            assert_eq!(
+                ret,
+                abi::errno::SUCCESS,
+                "Failed to broadcast on condition variable"
+            );
+        }
+    }
+
+    pub unsafe fn wait(&self, mutex: &Mutex) {
+        let mutex = mutex::raw(mutex);
+        assert_eq!(
+            (*mutex).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
+            __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+            "This lock is not write-locked by this thread"
+        );
+
+        // Call into the kernel to wait on the condition variable.
+        let condvar = self.condvar.get();
+        let subscription = abi::subscription {
+            type_: abi::eventtype::CONDVAR,
+            union: abi::subscription_union {
+                condvar: abi::subscription_condvar {
+                    condvar: condvar as *mut abi::condvar,
+                    condvar_scope: abi::scope::PRIVATE,
+                    lock: mutex as *mut abi::lock,
+                    lock_scope: abi::scope::PRIVATE,
+                },
+            },
+            ..mem::zeroed()
+        };
+        let mut event: abi::event = mem::uninitialized();
+        let mut nevents: usize = mem::uninitialized();
+        let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+        assert_eq!(
+            ret,
+            abi::errno::SUCCESS,
+            "Failed to wait on condition variable"
+        );
+        assert_eq!(
+            event.error,
+            abi::errno::SUCCESS,
+            "Failed to wait on condition variable"
+        );
+    }
+
+    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
+        let mutex = mutex::raw(mutex);
+        assert_eq!(
+            (*mutex).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
+            __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+            "This lock is not write-locked by this thread"
+        );
+
+        // Call into the kernel to wait on the condition variable.
+        let condvar = self.condvar.get();
+        let subscriptions = [
+            abi::subscription {
+                type_: abi::eventtype::CONDVAR,
+                union: abi::subscription_union {
+                    condvar: abi::subscription_condvar {
+                        condvar: condvar as *mut abi::condvar,
+                        condvar_scope: abi::scope::PRIVATE,
+                        lock: mutex as *mut abi::lock,
+                        lock_scope: abi::scope::PRIVATE,
+                    },
+                },
+                ..mem::zeroed()
+            },
+            abi::subscription {
+                type_: abi::eventtype::CLOCK,
+                union: abi::subscription_union {
+                    clock: abi::subscription_clock {
+                        clock_id: abi::clockid::MONOTONIC,
+                        timeout: dur2intervals(&dur),
+                        ..mem::zeroed()
+                    },
+                },
+                ..mem::zeroed()
+            },
+        ];
+        let mut events: [abi::event; 2] = mem::uninitialized();
+        let mut nevents: usize = mem::uninitialized();
+        let ret = abi::poll(subscriptions.as_ptr(), events.as_mut_ptr(), 2, &mut nevents);
+        assert_eq!(
+            ret,
+            abi::errno::SUCCESS,
+            "Failed to wait on condition variable"
+        );
+        for i in 0..nevents {
+            assert_eq!(
+                events[i].error,
+                abi::errno::SUCCESS,
+                "Failed to wait on condition variable"
+            );
+            if events[i].type_ == abi::eventtype::CONDVAR {
+                return true;
+            }
+        }
+        false
+    }
+
+    pub unsafe fn destroy(&self) {
+        let condvar = self.condvar.get();
+        assert_eq!(
+            (*condvar).load(Ordering::Relaxed),
+            abi::CONDVAR_HAS_NO_WAITERS.0,
+            "Attempted to destroy a condition variable with blocked threads"
+        );
+    }
+}
diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs
new file mode 100644 (file)
index 0000000..9e943c1
--- /dev/null
@@ -0,0 +1,76 @@
+// 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 io;
+use libc;
+use mem;
+
+pub mod args;
+#[cfg(feature = "backtrace")]
+pub mod backtrace;
+#[path = "../unix/cmath.rs"]
+pub mod cmath;
+pub mod condvar;
+#[path = "../unix/memchr.rs"]
+pub mod memchr;
+pub mod mutex;
+pub mod os;
+#[path = "../unix/os_str.rs"]
+pub mod os_str;
+pub mod rwlock;
+pub mod stack_overflow;
+pub mod stdio;
+pub mod thread;
+#[path = "../unix/thread_local.rs"]
+pub mod thread_local;
+pub mod time;
+
+mod abi;
+
+mod shims;
+pub use self::shims::*;
+
+#[allow(dead_code)]
+pub fn init() {}
+
+pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
+    match errno {
+        x if x == abi::errno::ACCES as i32 => io::ErrorKind::PermissionDenied,
+        x if x == abi::errno::ADDRINUSE as i32 => io::ErrorKind::AddrInUse,
+        x if x == abi::errno::ADDRNOTAVAIL as i32 => io::ErrorKind::AddrNotAvailable,
+        x if x == abi::errno::AGAIN as i32 => io::ErrorKind::WouldBlock,
+        x if x == abi::errno::CONNABORTED as i32 => io::ErrorKind::ConnectionAborted,
+        x if x == abi::errno::CONNREFUSED as i32 => io::ErrorKind::ConnectionRefused,
+        x if x == abi::errno::CONNRESET as i32 => io::ErrorKind::ConnectionReset,
+        x if x == abi::errno::EXIST as i32 => io::ErrorKind::AlreadyExists,
+        x if x == abi::errno::INTR as i32 => io::ErrorKind::Interrupted,
+        x if x == abi::errno::INVAL as i32 => io::ErrorKind::InvalidInput,
+        x if x == abi::errno::NOENT as i32 => io::ErrorKind::NotFound,
+        x if x == abi::errno::NOTCONN as i32 => io::ErrorKind::NotConnected,
+        x if x == abi::errno::PERM as i32 => io::ErrorKind::PermissionDenied,
+        x if x == abi::errno::PIPE as i32 => io::ErrorKind::BrokenPipe,
+        x if x == abi::errno::TIMEDOUT as i32 => io::ErrorKind::TimedOut,
+        _ => io::ErrorKind::Other,
+    }
+}
+
+pub unsafe fn abort_internal() -> ! {
+    ::core::intrinsics::abort();
+}
+
+pub use libc::strlen;
+
+pub fn hashmap_random_keys() -> (u64, u64) {
+    unsafe {
+        let mut v = mem::uninitialized();
+        libc::arc4random_buf(&mut v as *mut _ as *mut libc::c_void, mem::size_of_val(&v));
+        v
+    }
+}
diff --git a/src/libstd/sys/cloudabi/mutex.rs b/src/libstd/sys/cloudabi/mutex.rs
new file mode 100644 (file)
index 0000000..d4ba6bc
--- /dev/null
@@ -0,0 +1,158 @@
+// 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 cell::UnsafeCell;
+use mem;
+use sync::atomic::{AtomicU32, Ordering};
+use sys::cloudabi::abi;
+use sys::rwlock::{self, RWLock};
+
+extern "C" {
+    #[thread_local]
+    static __pthread_thread_id: abi::tid;
+}
+
+// Implement Mutex using an RWLock. This doesn't introduce any
+// performance overhead in this environment, as the operations would be
+// implemented identically.
+pub struct Mutex(RWLock);
+
+pub unsafe fn raw(m: &Mutex) -> *mut AtomicU32 {
+    rwlock::raw(&m.0)
+}
+
+impl Mutex {
+    pub const fn new() -> Mutex {
+        Mutex(RWLock::new())
+    }
+
+    pub unsafe fn init(&mut self) {
+        // This function should normally reinitialize the mutex after
+        // moving it to a different memory address. This implementation
+        // does not require adjustments after moving.
+    }
+
+    pub unsafe fn try_lock(&self) -> bool {
+        self.0.try_write()
+    }
+
+    pub unsafe fn lock(&self) {
+        self.0.write()
+    }
+
+    pub unsafe fn unlock(&self) {
+        self.0.write_unlock()
+    }
+
+    pub unsafe fn destroy(&self) {
+        self.0.destroy()
+    }
+}
+
+pub struct ReentrantMutex {
+    lock: UnsafeCell<AtomicU32>,
+    recursion: UnsafeCell<u32>,
+}
+
+impl ReentrantMutex {
+    pub unsafe fn uninitialized() -> ReentrantMutex {
+        mem::uninitialized()
+    }
+
+    pub unsafe fn init(&mut self) {
+        self.lock = UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0));
+        self.recursion = UnsafeCell::new(0);
+    }
+
+    pub unsafe fn try_lock(&self) -> bool {
+        // Attempt to acquire the lock.
+        let lock = self.lock.get();
+        let recursion = self.recursion.get();
+        if let Err(old) = (*lock).compare_exchange(
+            abi::LOCK_UNLOCKED.0,
+            __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+            Ordering::Acquire,
+            Ordering::Relaxed,
+        ) {
+            // If we fail to acquire the lock, it may be the case
+            // that we've already acquired it and may need to recurse.
+            if old & !abi::LOCK_KERNEL_MANAGED.0 == __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0 {
+                *recursion += 1;
+                true
+            } else {
+                false
+            }
+        } else {
+            // Success.
+            assert_eq!(*recursion, 0, "Mutex has invalid recursion count");
+            true
+        }
+    }
+
+    pub unsafe fn lock(&self) {
+        if !self.try_lock() {
+            // Call into the kernel to acquire a write lock.
+            let lock = self.lock.get();
+            let subscription = abi::subscription {
+                type_: abi::eventtype::LOCK_WRLOCK,
+                union: abi::subscription_union {
+                    lock: abi::subscription_lock {
+                        lock: lock as *mut abi::lock,
+                        lock_scope: abi::scope::PRIVATE,
+                    },
+                },
+                ..mem::zeroed()
+            };
+            let mut event: abi::event = mem::uninitialized();
+            let mut nevents: usize = mem::uninitialized();
+            let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+            assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire mutex");
+            assert_eq!(event.error, abi::errno::SUCCESS, "Failed to acquire mutex");
+        }
+    }
+
+    pub unsafe fn unlock(&self) {
+        let lock = self.lock.get();
+        let recursion = self.recursion.get();
+        assert_eq!(
+            (*lock).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
+            __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+            "This mutex is locked by a different thread"
+        );
+
+        if *recursion > 0 {
+            *recursion -= 1;
+        } else if !(*lock)
+            .compare_exchange(
+                __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+                abi::LOCK_UNLOCKED.0,
+                Ordering::Release,
+                Ordering::Relaxed,
+            )
+            .is_ok()
+        {
+            // Lock is managed by kernelspace. Call into the kernel
+            // to unblock waiting threads.
+            let ret = abi::lock_unlock(lock as *mut abi::lock, abi::scope::PRIVATE);
+            assert_eq!(ret, abi::errno::SUCCESS, "Failed to unlock a mutex");
+        }
+    }
+
+    pub unsafe fn destroy(&self) {
+        let lock = self.lock.get();
+        let recursion = self.recursion.get();
+        assert_eq!(
+            (*lock).load(Ordering::Relaxed),
+            abi::LOCK_UNLOCKED.0,
+            "Attempted to destroy locked mutex"
+        );
+        assert_eq!(*recursion, 0, "Recursion counter invalid");
+    }
+}
diff --git a/src/libstd/sys/cloudabi/os.rs b/src/libstd/sys/cloudabi/os.rs
new file mode 100644 (file)
index 0000000..7e506b8
--- /dev/null
@@ -0,0 +1,37 @@
+// 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 ffi::CStr;
+use libc::{self, c_int};
+use str;
+
+pub use sys::cloudabi::shims::os::*;
+
+pub fn errno() -> i32 {
+    extern "C" {
+        #[thread_local]
+        static errno: c_int;
+    }
+
+    unsafe { errno as i32 }
+}
+
+/// Gets a detailed string description for the given error number.
+pub fn error_string(errno: i32) -> String {
+    // cloudlibc's strerror() is guaranteed to be thread-safe. There is
+    // thus no need to use strerror_r().
+    str::from_utf8(unsafe { CStr::from_ptr(libc::strerror(errno)) }.to_bytes())
+        .unwrap()
+        .to_owned()
+}
+
+pub fn exit(code: i32) -> ! {
+    unsafe { libc::exit(code as c_int) }
+}
diff --git a/src/libstd/sys/cloudabi/rwlock.rs b/src/libstd/sys/cloudabi/rwlock.rs
new file mode 100644 (file)
index 0000000..8539aec
--- /dev/null
@@ -0,0 +1,237 @@
+// 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 cell::UnsafeCell;
+use mem;
+use sync::atomic::{AtomicU32, Ordering};
+use sys::cloudabi::abi;
+
+extern "C" {
+    #[thread_local]
+    static __pthread_thread_id: abi::tid;
+}
+
+#[thread_local]
+static mut RDLOCKS_ACQUIRED: u32 = 0;
+
+pub struct RWLock {
+    lock: UnsafeCell<AtomicU32>,
+}
+
+pub unsafe fn raw(r: &RWLock) -> *mut AtomicU32 {
+    r.lock.get()
+}
+
+unsafe impl Send for RWLock {}
+unsafe impl Sync for RWLock {}
+
+impl RWLock {
+    pub const fn new() -> RWLock {
+        RWLock {
+            lock: UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)),
+        }
+    }
+
+    pub unsafe fn try_read(&self) -> bool {
+        let lock = self.lock.get();
+        let mut old = abi::LOCK_UNLOCKED.0;
+        while let Err(cur) =
+            (*lock).compare_exchange_weak(old, old + 1, Ordering::Acquire, Ordering::Relaxed)
+        {
+            if (cur & abi::LOCK_WRLOCKED.0) != 0 {
+                // Another thread already has a write lock.
+                assert_ne!(
+                    old & !abi::LOCK_KERNEL_MANAGED.0,
+                    __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+                    "Attempted to acquire a read lock while holding a write lock"
+                );
+                return false;
+            } else if (old & abi::LOCK_KERNEL_MANAGED.0) != 0 && RDLOCKS_ACQUIRED == 0 {
+                // Lock has threads waiting for the lock. Only acquire
+                // the lock if we have already acquired read locks. In
+                // that case, it is justified to acquire this lock to
+                // prevent a deadlock.
+                return false;
+            }
+            old = cur;
+        }
+
+        RDLOCKS_ACQUIRED += 1;
+        true
+    }
+
+    pub unsafe fn read(&self) {
+        if !self.try_read() {
+            // Call into the kernel to acquire a read lock.
+            let lock = self.lock.get();
+            let subscription = abi::subscription {
+                type_: abi::eventtype::LOCK_RDLOCK,
+                union: abi::subscription_union {
+                    lock: abi::subscription_lock {
+                        lock: lock as *mut abi::lock,
+                        lock_scope: abi::scope::PRIVATE,
+                    },
+                },
+                ..mem::zeroed()
+            };
+            let mut event: abi::event = mem::uninitialized();
+            let mut nevents: usize = mem::uninitialized();
+            let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+            assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire read lock");
+            assert_eq!(
+                event.error,
+                abi::errno::SUCCESS,
+                "Failed to acquire read lock"
+            );
+
+            RDLOCKS_ACQUIRED += 1;
+        }
+    }
+
+    pub unsafe fn read_unlock(&self) {
+        // Perform a read unlock. We can do this in userspace, except when
+        // other threads are blocked and we are performing the last unlock.
+        // In that case, call into the kernel.
+        //
+        // Other threads may attempt to increment the read lock count,
+        // meaning that the call into the kernel could be spurious. To
+        // prevent this from happening, upgrade to a write lock first. This
+        // allows us to call into the kernel, having the guarantee that the
+        // lock value will not change in the meantime.
+        assert!(RDLOCKS_ACQUIRED > 0, "Bad lock count");
+        let mut old = 1;
+        loop {
+            let lock = self.lock.get();
+            if old == 1 | abi::LOCK_KERNEL_MANAGED.0 {
+                // Last read lock while threads are waiting. Attempt to upgrade
+                // to a write lock before calling into the kernel to unlock.
+                if let Err(cur) = (*lock).compare_exchange_weak(
+                    old,
+                    __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0 | abi::LOCK_KERNEL_MANAGED.0,
+                    Ordering::Acquire,
+                    Ordering::Relaxed,
+                ) {
+                    old = cur;
+                } else {
+                    // Call into the kernel to unlock.
+                    let ret = abi::lock_unlock(lock as *mut abi::lock, abi::scope::PRIVATE);
+                    assert_eq!(ret, abi::errno::SUCCESS, "Failed to write unlock a rwlock");
+                    break;
+                }
+            } else {
+                // No threads waiting or not the last read lock. Just decrement
+                // the read lock count.
+                assert_ne!(
+                    old & !abi::LOCK_KERNEL_MANAGED.0,
+                    0,
+                    "This rwlock is not locked"
+                );
+                assert_eq!(
+                    old & abi::LOCK_WRLOCKED.0,
+                    0,
+                    "Attempted to read-unlock a write-locked rwlock"
+                );
+                if let Err(cur) = (*lock).compare_exchange_weak(
+                    old,
+                    old - 1,
+                    Ordering::Acquire,
+                    Ordering::Relaxed,
+                ) {
+                    old = cur;
+                } else {
+                    break;
+                }
+            }
+        }
+
+        RDLOCKS_ACQUIRED -= 1;
+    }
+
+    pub unsafe fn try_write(&self) -> bool {
+        // Attempt to acquire the lock.
+        let lock = self.lock.get();
+        if let Err(old) = (*lock).compare_exchange(
+            abi::LOCK_UNLOCKED.0,
+            __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+            Ordering::Acquire,
+            Ordering::Relaxed,
+        ) {
+            // Failure. Crash upon recursive acquisition.
+            assert_ne!(
+                old & !abi::LOCK_KERNEL_MANAGED.0,
+                __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+                "Attempted to recursive write-lock a rwlock",
+            );
+            false
+        } else {
+            // Success.
+            true
+        }
+    }
+
+    pub unsafe fn write(&self) {
+        if !self.try_write() {
+            // Call into the kernel to acquire a write lock.
+            let lock = self.lock.get();
+            let subscription = abi::subscription {
+                type_: abi::eventtype::LOCK_WRLOCK,
+                union: abi::subscription_union {
+                    lock: abi::subscription_lock {
+                        lock: lock as *mut abi::lock,
+                        lock_scope: abi::scope::PRIVATE,
+                    },
+                },
+                ..mem::zeroed()
+            };
+            let mut event: abi::event = mem::uninitialized();
+            let mut nevents: usize = mem::uninitialized();
+            let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+            assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire write lock");
+            assert_eq!(
+                event.error,
+                abi::errno::SUCCESS,
+                "Failed to acquire write lock"
+            );
+        }
+    }
+
+    pub unsafe fn write_unlock(&self) {
+        let lock = self.lock.get();
+        assert_eq!(
+            (*lock).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
+            __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+            "This rwlock is not write-locked by this thread"
+        );
+
+        if !(*lock)
+            .compare_exchange(
+                __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
+                abi::LOCK_UNLOCKED.0,
+                Ordering::Release,
+                Ordering::Relaxed,
+            )
+            .is_ok()
+        {
+            // Lock is managed by kernelspace. Call into the kernel
+            // to unblock waiting threads.
+            let ret = abi::lock_unlock(lock as *mut abi::lock, abi::scope::PRIVATE);
+            assert_eq!(ret, abi::errno::SUCCESS, "Failed to write unlock a rwlock");
+        }
+    }
+
+    pub unsafe fn destroy(&self) {
+        let lock = self.lock.get();
+        assert_eq!(
+            (*lock).load(Ordering::Relaxed),
+            abi::LOCK_UNLOCKED.0,
+            "Attempted to destroy locked rwlock"
+        );
+    }
+}
diff --git a/src/libstd/sys/cloudabi/shims/args.rs b/src/libstd/sys/cloudabi/shims/args.rs
new file mode 100644 (file)
index 0000000..1b5785a
--- /dev/null
@@ -0,0 +1,45 @@
+// 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 ffi::OsString;
+
+pub struct Args(());
+
+impl Args {
+    pub fn inner_debug(&self) -> &[OsString] {
+        &[]
+    }
+}
+
+impl Iterator for Args {
+    type Item = OsString;
+    fn next(&mut self) -> Option<OsString> {
+        None
+    }
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (0, Some(0))
+    }
+}
+
+impl ExactSizeIterator for Args {
+    fn len(&self) -> usize {
+        0
+    }
+}
+
+impl DoubleEndedIterator for Args {
+    fn next_back(&mut self) -> Option<OsString> {
+        None
+    }
+}
+
+pub fn args() -> Args {
+    Args(())
+}
diff --git a/src/libstd/sys/cloudabi/shims/env.rs b/src/libstd/sys/cloudabi/shims/env.rs
new file mode 100644 (file)
index 0000000..31777aa
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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 os {
+    pub const FAMILY: &'static str = "cloudabi";
+    pub const OS: &'static str = "cloudabi";
+    pub const DLL_PREFIX: &'static str = "lib";
+    pub const DLL_SUFFIX: &'static str = ".so";
+    pub const DLL_EXTENSION: &'static str = "so";
+    pub const EXE_SUFFIX: &'static str = "";
+    pub const EXE_EXTENSION: &'static str = "";
+}
diff --git a/src/libstd/sys/cloudabi/shims/fs.rs b/src/libstd/sys/cloudabi/shims/fs.rs
new file mode 100644 (file)
index 0000000..d3da0fb
--- /dev/null
@@ -0,0 +1,302 @@
+// 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 ffi::OsString;
+use fmt;
+use hash::{Hash, Hasher};
+use io::{self, SeekFrom};
+use path::{Path, PathBuf};
+use sys::time::SystemTime;
+use sys::{unsupported, Void};
+
+pub struct File(Void);
+
+pub struct FileAttr(Void);
+
+pub struct ReadDir(Void);
+
+pub struct DirEntry(Void);
+
+#[derive(Clone, Debug)]
+pub struct OpenOptions {}
+
+pub struct FilePermissions(Void);
+
+pub struct FileType(Void);
+
+#[derive(Debug)]
+pub struct DirBuilder {}
+
+impl FileAttr {
+    pub fn size(&self) -> u64 {
+        match self.0 {}
+    }
+
+    pub fn perm(&self) -> FilePermissions {
+        match self.0 {}
+    }
+
+    pub fn file_type(&self) -> FileType {
+        match self.0 {}
+    }
+
+    pub fn modified(&self) -> io::Result<SystemTime> {
+        match self.0 {}
+    }
+
+    pub fn accessed(&self) -> io::Result<SystemTime> {
+        match self.0 {}
+    }
+
+    pub fn created(&self) -> io::Result<SystemTime> {
+        match self.0 {}
+    }
+}
+
+impl Clone for FileAttr {
+    fn clone(&self) -> FileAttr {
+        match self.0 {}
+    }
+}
+
+impl FilePermissions {
+    pub fn readonly(&self) -> bool {
+        match self.0 {}
+    }
+
+    pub fn set_readonly(&mut self, _readonly: bool) {
+        match self.0 {}
+    }
+}
+
+impl Clone for FilePermissions {
+    fn clone(&self) -> FilePermissions {
+        match self.0 {}
+    }
+}
+
+impl PartialEq for FilePermissions {
+    fn eq(&self, _other: &FilePermissions) -> bool {
+        match self.0 {}
+    }
+}
+
+impl Eq for FilePermissions {}
+
+impl fmt::Debug for FilePermissions {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+impl FileType {
+    pub fn is_dir(&self) -> bool {
+        match self.0 {}
+    }
+
+    pub fn is_file(&self) -> bool {
+        match self.0 {}
+    }
+
+    pub fn is_symlink(&self) -> bool {
+        match self.0 {}
+    }
+}
+
+impl Clone for FileType {
+    fn clone(&self) -> FileType {
+        match self.0 {}
+    }
+}
+
+impl Copy for FileType {}
+
+impl PartialEq for FileType {
+    fn eq(&self, _other: &FileType) -> bool {
+        match self.0 {}
+    }
+}
+
+impl Eq for FileType {}
+
+impl Hash for FileType {
+    fn hash<H: Hasher>(&self, _h: &mut H) {
+        match self.0 {}
+    }
+}
+
+impl fmt::Debug for FileType {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+impl fmt::Debug for ReadDir {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+impl Iterator for ReadDir {
+    type Item = io::Result<DirEntry>;
+
+    fn next(&mut self) -> Option<io::Result<DirEntry>> {
+        match self.0 {}
+    }
+}
+
+impl DirEntry {
+    pub fn path(&self) -> PathBuf {
+        match self.0 {}
+    }
+
+    pub fn file_name(&self) -> OsString {
+        match self.0 {}
+    }
+
+    pub fn metadata(&self) -> io::Result<FileAttr> {
+        match self.0 {}
+    }
+
+    pub fn file_type(&self) -> io::Result<FileType> {
+        match self.0 {}
+    }
+}
+
+impl OpenOptions {
+    pub fn new() -> OpenOptions {
+        OpenOptions {}
+    }
+
+    pub fn read(&mut self, _read: bool) {}
+    pub fn write(&mut self, _write: bool) {}
+    pub fn append(&mut self, _append: bool) {}
+    pub fn truncate(&mut self, _truncate: bool) {}
+    pub fn create(&mut self, _create: bool) {}
+    pub fn create_new(&mut self, _create_new: bool) {}
+}
+
+impl File {
+    pub fn open(_path: &Path, _opts: &OpenOptions) -> io::Result<File> {
+        unsupported()
+    }
+
+    pub fn file_attr(&self) -> io::Result<FileAttr> {
+        match self.0 {}
+    }
+
+    pub fn fsync(&self) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn datasync(&self) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn truncate(&self, _size: u64) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn flush(&self) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn seek(&self, _pos: SeekFrom) -> io::Result<u64> {
+        match self.0 {}
+    }
+
+    pub fn duplicate(&self) -> io::Result<File> {
+        match self.0 {}
+    }
+
+    pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn diverge(&self) -> ! {
+        match self.0 {}
+    }
+}
+
+impl DirBuilder {
+    pub fn new() -> DirBuilder {
+        DirBuilder {}
+    }
+
+    pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
+        unsupported()
+    }
+}
+
+impl fmt::Debug for File {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
+    unsupported()
+}
+
+pub fn unlink(_p: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> {
+    match perm.0 {}
+}
+
+pub fn rmdir(_p: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn remove_dir_all(_path: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn readlink(_p: &Path) -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn symlink(_src: &Path, _dst: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn stat(_p: &Path) -> io::Result<FileAttr> {
+    unsupported()
+}
+
+pub fn lstat(_p: &Path) -> io::Result<FileAttr> {
+    unsupported()
+}
+
+pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {
+    unsupported()
+}
diff --git a/src/libstd/sys/cloudabi/shims/mod.rs b/src/libstd/sys/cloudabi/shims/mod.rs
new file mode 100644 (file)
index 0000000..407c2b9
--- /dev/null
@@ -0,0 +1,32 @@
+// 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 io;
+
+pub mod args;
+pub mod env;
+pub mod fs;
+pub mod net;
+#[path = "../../unix/path.rs"]
+pub mod path;
+pub mod pipe;
+pub mod process;
+pub mod os;
+
+// This enum is used as the storage for a bunch of types which can't actually exist.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub enum Void {}
+
+pub fn unsupported<T>() -> io::Result<T> {
+    Err(io::Error::new(
+        io::ErrorKind::Other,
+        "This function is not available on CloudABI.",
+    ))
+}
diff --git a/src/libstd/sys/cloudabi/shims/net.rs b/src/libstd/sys/cloudabi/shims/net.rs
new file mode 100644 (file)
index 0000000..93eaf6a
--- /dev/null
@@ -0,0 +1,296 @@
+// 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 fmt;
+use io;
+use net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
+use time::Duration;
+use sys::{unsupported, Void};
+
+pub extern crate libc as netc;
+
+pub struct TcpStream(Void);
+
+impl TcpStream {
+    pub fn connect(_: &SocketAddr) -> io::Result<TcpStream> {
+        unsupported()
+    }
+
+    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
+        unsupported()
+    }
+
+    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        match self.0 {}
+    }
+
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        match self.0 {}
+    }
+
+    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        match self.0 {}
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        match self.0 {}
+    }
+
+    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn duplicate(&self) -> io::Result<TcpStream> {
+        match self.0 {}
+    }
+
+    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn nodelay(&self) -> io::Result<bool> {
+        match self.0 {}
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        match self.0 {}
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        match self.0 {}
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+}
+
+impl fmt::Debug for TcpStream {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+pub struct TcpListener(Void);
+
+impl TcpListener {
+    pub fn bind(_: &SocketAddr) -> io::Result<TcpListener> {
+        unsupported()
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        match self.0 {}
+    }
+
+    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
+        match self.0 {}
+    }
+
+    pub fn duplicate(&self) -> io::Result<TcpListener> {
+        match self.0 {}
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        match self.0 {}
+    }
+
+    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn only_v6(&self) -> io::Result<bool> {
+        match self.0 {}
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        match self.0 {}
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+}
+
+impl fmt::Debug for TcpListener {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+pub struct UdpSocket(Void);
+
+impl UdpSocket {
+    pub fn bind(_: &SocketAddr) -> io::Result<UdpSocket> {
+        unsupported()
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        match self.0 {}
+    }
+
+    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        match self.0 {}
+    }
+
+    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        match self.0 {}
+    }
+
+    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn duplicate(&self) -> io::Result<UdpSocket> {
+        match self.0 {}
+    }
+
+    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        match self.0 {}
+    }
+
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        match self.0 {}
+    }
+
+    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn broadcast(&self) -> io::Result<bool> {
+        match self.0 {}
+    }
+
+    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
+        match self.0 {}
+    }
+
+    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
+        match self.0 {}
+    }
+
+    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
+        match self.0 {}
+    }
+
+    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        match self.0 {}
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        match self.0 {}
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn connect(&self, _: &SocketAddr) -> io::Result<()> {
+        match self.0 {}
+    }
+}
+
+impl fmt::Debug for UdpSocket {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+pub struct LookupHost(Void);
+
+impl Iterator for LookupHost {
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> {
+        match self.0 {}
+    }
+}
+
+pub fn lookup_host(_: &str) -> io::Result<LookupHost> {
+    unsupported()
+}
diff --git a/src/libstd/sys/cloudabi/shims/os.rs b/src/libstd/sys/cloudabi/shims/os.rs
new file mode 100644 (file)
index 0000000..1e355d9
--- /dev/null
@@ -0,0 +1,95 @@
+// 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 error::Error as StdError;
+use ffi::{OsStr, OsString};
+use fmt;
+use io;
+use iter;
+use path::{self, PathBuf};
+use sys::{unsupported, Void};
+
+pub fn getcwd() -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn chdir(_: &path::Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub type Env = iter::Empty<(OsString, OsString)>;
+
+pub fn env() -> Env {
+    iter::empty()
+}
+
+pub fn getenv(_: &OsStr) -> io::Result<Option<OsString>> {
+    Ok(None)
+}
+
+pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn unsetenv(_: &OsStr) -> io::Result<()> {
+    unsupported()
+}
+
+pub struct SplitPaths<'a>(&'a Void);
+
+pub fn split_paths(_unparsed: &OsStr) -> SplitPaths {
+    panic!("unsupported")
+}
+
+impl<'a> Iterator for SplitPaths<'a> {
+    type Item = PathBuf;
+    fn next(&mut self) -> Option<PathBuf> {
+        match *self.0 {}
+    }
+}
+
+#[derive(Debug)]
+pub struct JoinPathsError;
+
+pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
+where
+    I: Iterator<Item = T>,
+    T: AsRef<OsStr>,
+{
+    Err(JoinPathsError)
+}
+
+impl fmt::Display for JoinPathsError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "not supported on CloudABI yet".fmt(f)
+    }
+}
+
+impl StdError for JoinPathsError {
+    fn description(&self) -> &str {
+        "not supported on CloudABI yet"
+    }
+}
+
+pub fn home_dir() -> Option<PathBuf> {
+    None
+}
+
+pub fn temp_dir() -> PathBuf {
+    PathBuf::from("/tmp")
+}
+
+pub fn current_exe() -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn getpid() -> u32 {
+    1
+}
diff --git a/src/libstd/sys/cloudabi/shims/pipe.rs b/src/libstd/sys/cloudabi/shims/pipe.rs
new file mode 100644 (file)
index 0000000..77a9cd6
--- /dev/null
@@ -0,0 +1,32 @@
+// 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 io;
+use sys::Void;
+
+pub struct AnonPipe(Void);
+
+impl AnonPipe {
+    pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn diverge(&self) -> ! {
+        match self.0 {}
+    }
+}
+
+pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> {
+    match p1.0 {}
+}
diff --git a/src/libstd/sys/cloudabi/shims/process.rs b/src/libstd/sys/cloudabi/shims/process.rs
new file mode 100644 (file)
index 0000000..52e8c82
--- /dev/null
@@ -0,0 +1,147 @@
+// 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 ffi::OsStr;
+use fmt;
+use io;
+use sys::fs::File;
+use sys::pipe::AnonPipe;
+use sys::{unsupported, Void};
+use sys_common::process::{CommandEnv, DefaultEnvKey};
+
+////////////////////////////////////////////////////////////////////////////////
+// Command
+////////////////////////////////////////////////////////////////////////////////
+
+pub struct Command {
+    env: CommandEnv<DefaultEnvKey>,
+}
+
+// passed back to std::process with the pipes connected to the child, if any
+// were requested
+pub struct StdioPipes {
+    pub stdin: Option<AnonPipe>,
+    pub stdout: Option<AnonPipe>,
+    pub stderr: Option<AnonPipe>,
+}
+
+pub enum Stdio {
+    Inherit,
+    Null,
+    MakePipe,
+}
+
+impl Command {
+    pub fn new(_program: &OsStr) -> Command {
+        Command {
+            env: Default::default(),
+        }
+    }
+
+    pub fn arg(&mut self, _arg: &OsStr) {}
+
+    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+        &mut self.env
+    }
+
+    pub fn cwd(&mut self, _dir: &OsStr) {}
+
+    pub fn stdin(&mut self, _stdin: Stdio) {}
+
+    pub fn stdout(&mut self, _stdout: Stdio) {}
+
+    pub fn stderr(&mut self, _stderr: Stdio) {}
+
+    pub fn spawn(
+        &mut self,
+        _default: Stdio,
+        _needs_stdin: bool,
+    ) -> io::Result<(Process, StdioPipes)> {
+        unsupported()
+    }
+}
+
+impl From<AnonPipe> for Stdio {
+    fn from(pipe: AnonPipe) -> Stdio {
+        pipe.diverge()
+    }
+}
+
+impl From<File> for Stdio {
+    fn from(file: File) -> Stdio {
+        file.diverge()
+    }
+}
+
+impl fmt::Debug for Command {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        Ok(())
+    }
+}
+
+pub struct ExitStatus(Void);
+
+impl ExitStatus {
+    pub fn success(&self) -> bool {
+        match self.0 {}
+    }
+
+    pub fn code(&self) -> Option<i32> {
+        match self.0 {}
+    }
+}
+
+impl Clone for ExitStatus {
+    fn clone(&self) -> ExitStatus {
+        match self.0 {}
+    }
+}
+
+impl Copy for ExitStatus {}
+
+impl PartialEq for ExitStatus {
+    fn eq(&self, _other: &ExitStatus) -> bool {
+        match self.0 {}
+    }
+}
+
+impl Eq for ExitStatus {}
+
+impl fmt::Debug for ExitStatus {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+impl fmt::Display for ExitStatus {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+pub struct Process(Void);
+
+impl Process {
+    pub fn id(&self) -> u32 {
+        match self.0 {}
+    }
+
+    pub fn kill(&mut self) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn wait(&mut self) -> io::Result<ExitStatus> {
+        match self.0 {}
+    }
+
+    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
+        match self.0 {}
+    }
+}
diff --git a/src/libstd/sys/cloudabi/stack_overflow.rs b/src/libstd/sys/cloudabi/stack_overflow.rs
new file mode 100644 (file)
index 0000000..5c0b1e5
--- /dev/null
@@ -0,0 +1,23 @@
+// 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.
+
+#![cfg_attr(test, allow(dead_code))]
+
+pub struct Handler;
+
+impl Handler {
+    pub unsafe fn new() -> Handler {
+        Handler
+    }
+}
+
+pub unsafe fn init() {}
+
+pub unsafe fn cleanup() {}
diff --git a/src/libstd/sys/cloudabi/stdio.rs b/src/libstd/sys/cloudabi/stdio.rs
new file mode 100644 (file)
index 0000000..9519a92
--- /dev/null
@@ -0,0 +1,79 @@
+// 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 io;
+use sys::cloudabi::abi;
+
+pub struct Stdin(());
+pub struct Stdout(());
+pub struct Stderr(());
+
+impl Stdin {
+    pub fn new() -> io::Result<Stdin> {
+        Ok(Stdin(()))
+    }
+
+    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
+        Ok(0)
+    }
+}
+
+impl Stdout {
+    pub fn new() -> io::Result<Stdout> {
+        Ok(Stdout(()))
+    }
+
+    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
+        Err(io::Error::new(
+            io::ErrorKind::BrokenPipe,
+            "Stdout is not connected to any output in this environment",
+        ))
+    }
+
+    pub fn flush(&self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl Stderr {
+    pub fn new() -> io::Result<Stderr> {
+        Ok(Stderr(()))
+    }
+
+    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
+        Err(io::Error::new(
+            io::ErrorKind::BrokenPipe,
+            "Stderr is not connected to any output in this environment",
+        ))
+    }
+
+    pub fn flush(&self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+// FIXME: right now this raw stderr handle is used in a few places because
+//        std::io::stderr_raw isn't exposed, but once that's exposed this impl
+//        should go away
+impl io::Write for Stderr {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        Stderr::write(self, data)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Stderr::flush(self)
+    }
+}
+
+pub fn is_ebadf(err: &io::Error) -> bool {
+    err.raw_os_error() == Some(abi::errno::BADF as i32)
+}
+
+pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
new file mode 100644 (file)
index 0000000..c980ae7
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright 2014-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 alloc::boxed::FnBox;
+use cmp;
+use ffi::CStr;
+use io;
+use libc;
+use mem;
+use ptr;
+use sys::cloudabi::abi;
+use sys::time::dur2intervals;
+use sys_common::thread::*;
+use time::Duration;
+
+pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
+
+pub struct Thread {
+    id: libc::pthread_t,
+}
+
+// CloudABI has pthread_t as a pointer in which case we still want
+// a thread to be Send/Sync
+unsafe impl Send for Thread {}
+unsafe impl Sync for Thread {}
+
+impl Thread {
+    pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>) -> io::Result<Thread> {
+        let p = box p;
+        let mut native: libc::pthread_t = mem::zeroed();
+        let mut attr: libc::pthread_attr_t = mem::zeroed();
+        assert_eq!(libc::pthread_attr_init(&mut attr), 0);
+
+        let stack_size = cmp::max(stack, min_stack_size(&attr));
+        assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
+
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+
+        return if ret != 0 {
+            Err(io::Error::from_raw_os_error(ret))
+        } else {
+            mem::forget(p); // ownership passed to pthread_create
+            Ok(Thread { id: native })
+        };
+
+        extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
+            unsafe {
+                start_thread(main as *mut u8);
+            }
+            ptr::null_mut()
+        }
+    }
+
+    pub fn yield_now() {
+        let ret = unsafe { abi::thread_yield() };
+        debug_assert_eq!(ret, abi::errno::SUCCESS);
+    }
+
+    pub fn set_name(_name: &CStr) {
+        // CloudABI has no way to set a thread name.
+    }
+
+    pub fn sleep(dur: Duration) {
+        unsafe {
+            let subscription = abi::subscription {
+                type_: abi::eventtype::CLOCK,
+                union: abi::subscription_union {
+                    clock: abi::subscription_clock {
+                        clock_id: abi::clockid::MONOTONIC,
+                        timeout: dur2intervals(&dur),
+                        ..mem::zeroed()
+                    },
+                },
+                ..mem::zeroed()
+            };
+            let mut event: abi::event = mem::uninitialized();
+            let mut nevents: usize = mem::uninitialized();
+            let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+            assert_eq!(ret, abi::errno::SUCCESS);
+            assert_eq!(event.error, abi::errno::SUCCESS);
+        }
+    }
+
+    pub fn join(self) {
+        unsafe {
+            let ret = libc::pthread_join(self.id, ptr::null_mut());
+            mem::forget(self);
+            assert!(
+                ret == 0,
+                "failed to join thread: {}",
+                io::Error::from_raw_os_error(ret)
+            );
+        }
+    }
+}
+
+impl Drop for Thread {
+    fn drop(&mut self) {
+        let ret = unsafe { libc::pthread_detach(self.id) };
+        debug_assert_eq!(ret, 0);
+    }
+}
+
+#[cfg_attr(test, allow(dead_code))]
+pub mod guard {
+    pub unsafe fn current() -> Option<usize> {
+        None
+    }
+    pub unsafe fn init() -> Option<usize> {
+        None
+    }
+}
+
+fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
+    libc::PTHREAD_STACK_MIN
+}
diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs
new file mode 100644 (file)
index 0000000..ee12731
--- /dev/null
@@ -0,0 +1,111 @@
+// 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 mem;
+use sys::cloudabi::abi;
+use time::Duration;
+
+const NSEC_PER_SEC: abi::timestamp = 1_000_000_000;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub struct Instant {
+    t: abi::timestamp,
+}
+
+pub fn dur2intervals(dur: &Duration) -> abi::timestamp {
+    dur.as_secs()
+        .checked_mul(NSEC_PER_SEC)
+        .and_then(|nanos| nanos.checked_add(dur.subsec_nanos() as abi::timestamp))
+        .expect("overflow converting duration to nanoseconds")
+}
+
+impl Instant {
+    pub fn now() -> Instant {
+        unsafe {
+            let mut t = mem::uninitialized();
+            let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, &mut t);
+            assert_eq!(ret, abi::errno::SUCCESS);
+            Instant { t: t }
+        }
+    }
+
+    pub fn sub_instant(&self, other: &Instant) -> Duration {
+        let diff = self.t
+            .checked_sub(other.t)
+            .expect("second instant is later than self");
+        Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32)
+    }
+
+    pub fn add_duration(&self, other: &Duration) -> Instant {
+        Instant {
+            t: self.t
+                .checked_add(dur2intervals(other))
+                .expect("overflow when adding duration to instant"),
+        }
+    }
+
+    pub fn sub_duration(&self, other: &Duration) -> Instant {
+        Instant {
+            t: self.t
+                .checked_sub(dur2intervals(other))
+                .expect("overflow when subtracting duration from instant"),
+        }
+    }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub struct SystemTime {
+    t: abi::timestamp,
+}
+
+impl SystemTime {
+    pub fn now() -> SystemTime {
+        unsafe {
+            let mut t = mem::uninitialized();
+            let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, &mut t);
+            assert_eq!(ret, abi::errno::SUCCESS);
+            SystemTime { t: t }
+        }
+    }
+
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        if self.t >= other.t {
+            let diff = self.t - other.t;
+            Ok(Duration::new(
+                diff / NSEC_PER_SEC,
+                (diff % NSEC_PER_SEC) as u32,
+            ))
+        } else {
+            let diff = other.t - self.t;
+            Err(Duration::new(
+                diff / NSEC_PER_SEC,
+                (diff % NSEC_PER_SEC) as u32,
+            ))
+        }
+    }
+
+    pub fn add_duration(&self, other: &Duration) -> SystemTime {
+        SystemTime {
+            t: self.t
+                .checked_add(dur2intervals(other))
+                .expect("overflow when adding duration to instant"),
+        }
+    }
+
+    pub fn sub_duration(&self, other: &Duration) -> SystemTime {
+        SystemTime {
+            t: self.t
+                .checked_sub(dur2intervals(other))
+                .expect("overflow when subtracting duration from instant"),
+        }
+    }
+}
+
+pub const UNIX_EPOCH: SystemTime = SystemTime { t: 0 };
index be8cb88416bb6561f5fed45ae0a696973df73cc5..1231898ed7eba0051edc90b95fd0babf9ee7aece 100644 (file)
@@ -39,6 +39,9 @@
     } else if #[cfg(windows)] {
         mod windows;
         pub use self::windows::*;
+    } else if #[cfg(target_os = "cloudabi")] {
+        mod cloudabi;
+        pub use self::cloudabi::*;
     } else if #[cfg(target_os = "redox")] {
         mod redox;
         pub use self::redox::*;
     if #[cfg(any(unix, target_os = "redox"))] {
         // On unix we'll document what's already available
         pub use self::ext as unix_ext;
-    } else if #[cfg(target_arch = "wasm32")] {
-        // On wasm right now the module below doesn't compile (missing things
-        // in `libc` which is empty) so just omit everything with an empty module
+    } else if #[cfg(any(target_os = "cloudabi", target_arch = "wasm32"))] {
+        // On CloudABI and wasm right now the module below doesn't compile
+        // (missing things in `libc` which is empty) so just omit everything
+        // with an empty module
         #[unstable(issue = "0", feature = "std_internals")]
         pub mod unix_ext {}
     } else {
@@ -77,8 +81,9 @@ pub mod unix_ext {}
     if #[cfg(windows)] {
         // On windows we'll just be documenting what's already available
         pub use self::ext as windows_ext;
-    } else if #[cfg(target_arch = "wasm32")] {
-        // On wasm right now the shim below doesn't compile, so just omit it
+    } else if #[cfg(any(target_os = "cloudabi", target_arch = "wasm32"))] {
+        // On CloudABI and wasm right now the shim below doesn't compile, so
+        // just omit it
         #[unstable(issue = "0", feature = "std_internals")]
         pub mod windows_ext {}
     } else {
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 938e8656808068b7dd6e9b7e9857769acd05fa4e..27504d374ddbfaba19cb09ea52ba382aae13919b 100644 (file)
@@ -46,7 +46,7 @@
 pub mod process;
 
 cfg_if! {
-    if #[cfg(any(target_os = "redox", target_os = "l4re"))] {
+    if #[cfg(any(target_os = "cloudabi", target_os = "l4re", target_os = "redox"))] {
         pub use sys::net;
     } else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
         pub use sys::net;
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 e08a2cbfd0846792d6a159ef6c589f33f200b24b..9c0622e7bef9740a16b7112debd5d5ef6be14753 100644 (file)
@@ -2022,10 +2022,6 @@ pub enum ItemKind {
     ///
     /// E.g. `trait Foo = Bar + Quux;`
     TraitAlias(Generics, TyParamBounds),
-    /// Auto trait implementation.
-    ///
-    /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
-    AutoImpl(Unsafety, TraitRef),
     /// An implementation.
     ///
     /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
@@ -2064,8 +2060,7 @@ pub fn descriptive_variant(&self) -> &str {
             ItemKind::TraitAlias(..) => "trait alias",
             ItemKind::Mac(..) |
             ItemKind::MacroDef(..) |
-            ItemKind::Impl(..) |
-            ItemKind::AutoImpl(..) => "item"
+            ItemKind::Impl(..) => "item"
         }
     }
 }
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 129defd20932499e1773d6457f4f588a75b237c0..a58a61c36361b4d82f0dd548a1f08464e1344d04 100644 (file)
@@ -131,6 +131,9 @@ pub struct CodeMap {
     // -Zremap-path-prefix to all FileMaps allocated within this CodeMap.
     path_mapping: FilePathMapping,
     stable_id_to_filemap: RefCell<FxHashMap<StableFilemapId, Rc<FileMap>>>,
+    /// In case we are in a doctest, replace all file names with the PathBuf,
+    /// and add the given offsets to the line info
+    doctest_offset: Option<(FileName, isize)>,
 }
 
 impl CodeMap {
@@ -140,9 +143,19 @@ pub fn new(path_mapping: FilePathMapping) -> CodeMap {
             file_loader: Box::new(RealFileLoader),
             path_mapping,
             stable_id_to_filemap: RefCell::new(FxHashMap()),
+            doctest_offset: None,
         }
     }
 
+    pub fn new_doctest(path_mapping: FilePathMapping,
+                       file: FileName, line: isize) -> CodeMap {
+        CodeMap {
+            doctest_offset: Some((file, line)),
+            ..CodeMap::new(path_mapping)
+        }
+
+    }
+
     pub fn with_file_loader(file_loader: Box<FileLoader>,
                             path_mapping: FilePathMapping)
                             -> CodeMap {
@@ -151,6 +164,7 @@ pub fn with_file_loader(file_loader: Box<FileLoader>,
             file_loader,
             path_mapping,
             stable_id_to_filemap: RefCell::new(FxHashMap()),
+            doctest_offset: None,
         }
     }
 
@@ -164,7 +178,12 @@ pub fn file_exists(&self, path: &Path) -> bool {
 
     pub fn load_file(&self, path: &Path) -> io::Result<Rc<FileMap>> {
         let src = self.file_loader.read_file(path)?;
-        Ok(self.new_filemap(path.to_owned().into(), src))
+        let filename = if let Some((ref name, _)) = self.doctest_offset {
+            name.clone()
+        } else {
+            path.to_owned().into()
+        };
+        Ok(self.new_filemap(filename, src))
     }
 
     pub fn files(&self) -> Ref<Vec<Rc<FileMap>>> {
@@ -303,6 +322,18 @@ pub fn mk_substr_filename(&self, sp: Span) -> String {
                  pos.col.to_usize() + 1)).to_string()
     }
 
+    // If there is a doctest_offset, apply it to the line
+    pub fn doctest_offset_line(&self, mut orig: usize) -> usize {
+        if let Some((_, line)) = self.doctest_offset {
+            if line >= 0 {
+                orig = orig + line as usize;
+            } else {
+                orig = orig - (-line) as usize;
+            }
+        }
+        orig
+    }
+
     /// Lookup source information about a BytePos
     pub fn lookup_char_pos(&self, pos: BytePos) -> Loc {
         let chpos = self.bytepos_to_file_charpos(pos);
@@ -681,6 +712,9 @@ fn ensure_filemap_source_present(&self, file_map: Rc<FileMap>) -> bool {
             }
         )
     }
+    fn doctest_offset_line(&self, line: usize) -> usize {
+        self.doctest_offset_line(line)
+    }
 }
 
 #[derive(Clone)]
index 08eec0f9117f8723ec32864fa81ce00a1d72db36..c3bf5dbff5c586351d780a22f70589a8de9318c1 100644 (file)
@@ -131,7 +131,6 @@ pub fn new() -> Features {
     (active, link_llvm_intrinsics, "1.0.0", Some(29602)),
     (active, linkage, "1.0.0", Some(29603)),
     (active, quote, "1.0.0", Some(29601)),
-    (active, simd, "1.0.0", Some(27731)),
 
 
     // rustc internal
@@ -473,6 +472,8 @@ pub fn new() -> Features {
     (removed, unmarked_api, "1.0.0", None),
     (removed, pushpop_unsafe, "1.2.0", None),
     (removed, allocator, "1.0.0", None),
+    // Allows the `#[simd]` attribute -- removed in favor of `#[repr(simd)]`
+    (removed, simd, "1.0.0", Some(27731)),
 );
 
 declare_features! (
@@ -636,7 +637,6 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
     ("start", Normal, Ungated),
     ("test", Normal, Ungated),
     ("bench", Normal, Ungated),
-    ("simd", Normal, Ungated),
     ("repr", Normal, Ungated),
     ("path", Normal, Ungated),
     ("abi", Normal, Ungated),
@@ -969,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",
@@ -1504,14 +1511,6 @@ fn visit_item(&mut self, i: &'a ast::Item) {
             }
 
             ast::ItemKind::Struct(..) => {
-                if let Some(attr) = attr::find_by_name(&i.attrs[..], "simd") {
-                    gate_feature_post!(&self, simd, attr.span,
-                                       "SIMD types are experimental and possibly buggy");
-                    self.context.parse_sess.span_diagnostic.span_warn(attr.span,
-                                                                      "the `#[simd]` attribute \
-                                                                       is deprecated, use \
-                                                                       `#[repr(simd)]` instead");
-                }
                 if let Some(attr) = attr::find_by_name(&i.attrs[..], "repr") {
                     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
                         if item.check_name("simd") {
@@ -1533,13 +1532,6 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                                    "trait aliases are not yet fully implemented");
             }
 
-            ast::ItemKind::AutoImpl(..) => {
-                gate_feature_post!(&self, optin_builtin_traits,
-                                   i.span,
-                                   "auto trait implementations are experimental \
-                                    and possibly buggy");
-            }
-
             ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, ref impl_items) => {
                 if polarity == ast::ImplPolarity::Negative {
                     gate_feature_post!(&self, optin_builtin_traits,
index 6682a3439f1b959819cb6167db6ac72e682fcd55..c304e3a9f50525c86e8bc4f40df8b5671e78503d 100644 (file)
@@ -911,9 +911,6 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
             let generics = folder.fold_generics(generics);
             ItemKind::Union(folder.fold_variant_data(struct_def), generics)
         }
-        ItemKind::AutoImpl(unsafety, ref trait_ref) => {
-            ItemKind::AutoImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
-        }
         ItemKind::Impl(unsafety,
                        polarity,
                        defaultness,
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 b61c39d589bb166038b84e8b15f6feb0131b07f1..e7565d357397cbce0f1a91eed9bb00d6db582e9a 100644 (file)
@@ -71,7 +71,7 @@ pub struct Restrictions: u8 {
     }
 }
 
-type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute> >);
+type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>);
 
 /// How to parse a path.
 #[derive(Copy, Clone, PartialEq)]
@@ -151,10 +151,9 @@ macro_rules! maybe_whole {
     };
 }
 
-fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
-                -> Vec<Attribute> {
-    if let Some(ref attrs) = rhs {
-        lhs.extend(attrs.iter().cloned())
+fn maybe_append(mut lhs: Vec<Attribute>, mut rhs: Option<Vec<Attribute>>) -> Vec<Attribute> {
+    if let Some(ref mut rhs) = rhs {
+        lhs.append(rhs);
     }
     lhs
 }
@@ -609,14 +608,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 +758,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 +789,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");
                         }
@@ -1318,7 +1346,7 @@ pub fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>)
         Function Style
         */
 
-        let unsafety = self.parse_unsafety()?;
+        let unsafety = self.parse_unsafety();
         let abi = if self.eat_keyword(keywords::Extern) {
             self.parse_opt_abi()?.unwrap_or(Abi::C)
         } else {
@@ -1341,11 +1369,12 @@ pub fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>)
         })))
     }
 
-    pub fn parse_unsafety(&mut self) -> PResult<'a, Unsafety> {
+    /// Parse unsafety: `unsafe` or nothing.
+    fn parse_unsafety(&mut self) -> Unsafety {
         if self.eat_keyword(keywords::Unsafe) {
-            return Ok(Unsafety::Unsafe);
+            Unsafety::Unsafe
         } else {
-            return Ok(Unsafety::Normal);
+            Unsafety::Normal
         }
     }
 
@@ -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;
@@ -4053,36 +4084,14 @@ 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))
-        {
-            self.eat_keyword(keywords::Auto) && self.eat_keyword(keywords::Trait)
-        } else {
-            false
-        }
-    }
-
-    fn is_defaultness(&self) -> bool {
-        // `pub` is included for better error messages
-        self.token.is_keyword(keywords::Default) &&
-        self.look_ahead(1, |t| t.is_keyword(keywords::Impl) ||
-                        t.is_keyword(keywords::Const) ||
-                        t.is_keyword(keywords::Fn) ||
-                        t.is_keyword(keywords::Unsafe) ||
-                        t.is_keyword(keywords::Extern) ||
-                        t.is_keyword(keywords::Type) ||
-                        t.is_keyword(keywords::Pub))
-    }
-
-    fn eat_defaultness(&mut self) -> bool {
-        let is_defaultness = self.is_defaultness();
-        if is_defaultness {
-            self.bump()
-        } else {
-            self.expected_tokens.push(TokenType::Keyword(keywords::Default));
-        }
-        is_defaultness
+    fn is_auto_trait_item(&mut self) -> bool {
+        // auto trait
+        (self.token.is_keyword(keywords::Auto)
+            && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
+        || // unsafe auto trait
+        (self.token.is_keyword(keywords::Unsafe) &&
+         self.look_ahead(1, |t| t.is_keyword(keywords::Auto)) &&
+         self.look_ahead(2, |t| t.is_keyword(keywords::Trait)))
     }
 
     fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span)
@@ -4163,7 +4172,8 @@ fn parse_stmt_without_recovery(&mut self,
                 node: StmtKind::Item(macro_def),
                 span: lo.to(self.prev_span),
             }
-        // Starts like a simple path, but not a union item or item with `crate` visibility.
+        // Starts like a simple path, being careful to avoid contextual keywords
+        // such as a union items, item with `crate` visibility or auto trait items.
         // Our goal here is to parse an arbitrary path `a::b::c` but not something that starts
         // like a path (1 token), but it fact not a path.
         // `union::b::c` - path, `union U { ... }` - not a path.
@@ -4173,7 +4183,8 @@ fn parse_stmt_without_recovery(&mut self,
                   !self.token.is_qpath_start() &&
                   !self.is_union_item() &&
                   !self.is_crate_vis() &&
-                  !self.is_extern_non_path() {
+                  !self.is_extern_non_path() &&
+                  !self.is_auto_trait_item() {
             let pth = self.parse_path(PathStyle::Expr)?;
 
             if !self.eat(&token::Not) {
@@ -4761,21 +4772,13 @@ pub fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
         }
         let lo = self.prev_span;
 
-        // This is a temporary future proofing.
-        //
         // We are considering adding generics to the `where` keyword as an alternative higher-rank
         // parameter syntax (as in `where<'a>` or `where<T>`. To avoid that being a breaking
-        // change, for now we refuse to parse `where < (ident | lifetime) (> | , | :)`.
-        if token::Lt == self.token {
-            let ident_or_lifetime = self.look_ahead(1, |t| t.is_ident() || t.is_lifetime());
-            if ident_or_lifetime {
-                let gt_comma_or_colon = self.look_ahead(2, |t| {
-                    *t == token::Gt || *t == token::Comma || *t == token::Colon
-                });
-                if gt_comma_or_colon {
-                    self.span_err(self.span, "syntax `where<T>` is reserved for future use");
-                }
-            }
+        // change we parse those generics now, but report an error.
+        if self.choose_generics_over_qpath() {
+            let generics = self.parse_generics()?;
+            self.span_err(generics.span,
+                          "generic parameters on `where` clauses are reserved for future use");
         }
 
         loop {
@@ -5093,7 +5096,7 @@ fn mk_item(&mut self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
     fn parse_item_fn(&mut self,
                      unsafety: Unsafety,
                      constness: Spanned<Constness>,
-                     abi: abi::Abi)
+                     abi: Abi)
                      -> PResult<'a, ItemInfo> {
         let (ident, mut generics) = self.parse_fn_header()?;
         let decl = self.parse_fn_decl(false)?;
@@ -5117,13 +5120,10 @@ pub fn is_const_item(&mut self) -> bool {
     /// - `const unsafe fn`
     /// - `extern fn`
     /// - etc
-    pub fn parse_fn_front_matter(&mut self)
-                                 -> PResult<'a, (Spanned<ast::Constness>,
-                                                ast::Unsafety,
-                                                abi::Abi)> {
+    pub fn parse_fn_front_matter(&mut self) -> PResult<'a, (Spanned<Constness>, Unsafety, Abi)> {
         let is_const_fn = self.eat_keyword(keywords::Const);
         let const_span = self.prev_span;
-        let unsafety = self.parse_unsafety()?;
+        let unsafety = self.parse_unsafety();
         let (constness, unsafety, abi) = if is_const_fn {
             (respan(const_span, Constness::Const), unsafety, Abi::Rust)
         } else {
@@ -5158,7 +5158,7 @@ fn parse_impl_item_(&mut self,
                         mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> {
         let lo = self.span;
         let vis = self.parse_visibility(false)?;
-        let defaultness = self.parse_defaultness()?;
+        let defaultness = self.parse_defaultness();
         let (name, node, generics) = if self.eat_keyword(keywords::Type) {
             // This parses the grammar:
             //     ImplItemAssocTy = Ident ["<"...">"] ["where" ...] "=" Ty ";"
@@ -5251,7 +5251,7 @@ fn missing_assoc_item_kind_err(&mut self, item_type: &str, prev_span: Span)
 
     /// Parse a method or a macro invocation in a trait impl.
     fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
-                         -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::Generics,
+                         -> PResult<'a, (Ident, Vec<Attribute>, ast::Generics,
                              ast::ImplItemKind)> {
         // code copied from parse_macro_use_or_failure... abstraction!
         if self.token.is_path_start() && !self.is_extern_non_path() {
@@ -5340,98 +5340,123 @@ fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'
         }
     }
 
-    /// Parses items implementations variants
-    ///    impl<T> Foo { ... }
-    ///    impl<T> ToString for &'static T { ... }
-    ///    impl Send for .. {}
-    fn parse_item_impl(&mut self,
-                       unsafety: ast::Unsafety,
-                       defaultness: Defaultness) -> PResult<'a, ItemInfo> {
-        let impl_span = self.span;
+    fn choose_generics_over_qpath(&self) -> bool {
+        // There's an ambiguity between generic parameters and qualified paths in impls.
+        // If we see `<` it may start both, so we have to inspect some following tokens.
+        // The following combinations can only start generics,
+        // but not qualified paths (with one exception):
+        //     `<` `>` - empty generic parameters
+        //     `<` `#` - generic parameters with attributes
+        //     `<` (LIFETIME|IDENT) `>` - single generic parameter
+        //     `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
+        //     `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
+        //     `<` (LIFETIME|IDENT) `=` - generic parameter with a default
+        // The only truly ambiguous case is
+        //     `<` IDENT `>` `::` IDENT ...
+        // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
+        // because this is what almost always expected in practice, qualified paths in impls
+        // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
+        self.token == token::Lt &&
+            (self.look_ahead(1, |t| t == &token::Pound || t == &token::Gt) ||
+             self.look_ahead(1, |t| t.is_lifetime() || t.is_ident()) &&
+                self.look_ahead(2, |t| t == &token::Gt || t == &token::Comma ||
+                                       t == &token::Colon || t == &token::Eq))
+    }
+
+    fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
+        self.expect(&token::OpenDelim(token::Brace))?;
+        let attrs = self.parse_inner_attributes()?;
 
-        // First, parse type parameters if necessary.
-        let mut generics = self.parse_generics()?;
+        let mut impl_items = Vec::new();
+        while !self.eat(&token::CloseDelim(token::Brace)) {
+            let mut at_end = false;
+            match self.parse_impl_item(&mut at_end) {
+                Ok(impl_item) => impl_items.push(impl_item),
+                Err(mut err) => {
+                    err.emit();
+                    if !at_end {
+                        self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
+                    }
+                }
+            }
+        }
+        Ok((impl_items, attrs))
+    }
 
-        // Special case: if the next identifier that follows is '(', don't
-        // allow this to be parsed as a trait.
-        let could_be_trait = self.token != token::OpenDelim(token::Paren);
+    /// Parses an implementation item, `impl` keyword is already parsed.
+    ///    impl<'a, T> TYPE { /* impl items */ }
+    ///    impl<'a, T> TRAIT for TYPE { /* impl items */ }
+    ///    impl<'a, T> !TRAIT for TYPE { /* impl items */ }
+    /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
+    ///     `impl` GENERICS `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}`
+    ///     `impl` GENERICS `!`? TYPE (`where` PREDICATES)? `{` BODY `}`
+    fn parse_item_impl(&mut self, unsafety: Unsafety, defaultness: Defaultness)
+                       -> PResult<'a, ItemInfo> {
+        // First, parse generic parameters if necessary.
+        let mut generics = if self.choose_generics_over_qpath() {
+            self.parse_generics()?
+        } else {
+            ast::Generics::default()
+        };
 
-        let neg_span = self.span;
-        let polarity = if self.eat(&token::Not) {
+        // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
+        let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
+            self.bump(); // `!`
             ast::ImplPolarity::Negative
         } else {
             ast::ImplPolarity::Positive
         };
 
-        // Parse the trait.
-        let mut ty = self.parse_ty()?;
-
-        // Parse traits, if necessary.
-        let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
-            // New-style trait. Reinterpret the type as a trait.
-            match ty.node {
-                TyKind::Path(None, ref path) => {
-                    Some(TraitRef {
-                        path: (*path).clone(),
-                        ref_id: ty.id,
-                    })
-                }
-                _ => {
-                    self.span_err(ty.span, "not a trait");
-                    None
-                }
-            }
+        // Parse both types and traits as a type, then reinterpret if necessary.
+        let ty_first = self.parse_ty()?;
+
+        // If `for` is missing we try to recover.
+        let has_for = self.eat_keyword(keywords::For);
+        let missing_for_span = self.prev_span.between(self.span);
+
+        let ty_second = if self.token == token::DotDot {
+            // We need to report this error after `cfg` expansion for compatibility reasons
+            self.bump(); // `..`, do not add it to expected tokens
+            Some(P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID }))
+        } else if has_for || self.token.can_begin_type() {
+            Some(self.parse_ty()?)
         } else {
-            if polarity == ast::ImplPolarity::Negative {
-                // This is a negated type implementation
-                // `impl !MyType {}`, which is not allowed.
-                self.span_err(neg_span, "inherent implementation can't be negated");
-            }
             None
         };
 
-        if opt_trait.is_some() && self.eat(&token::DotDot) {
-            if generics.is_parameterized() {
-                self.span_err(impl_span, "auto trait implementations are not \
-                                          allowed to have generics");
-            }
+        generics.where_clause = self.parse_where_clause()?;
 
-            if let ast::Defaultness::Default = defaultness {
-                self.span_err(impl_span, "`default impl` is not allowed for \
-                                         auto trait implementations");
-            }
+        let (impl_items, attrs) = self.parse_impl_body()?;
 
-            self.expect(&token::OpenDelim(token::Brace))?;
-            self.expect(&token::CloseDelim(token::Brace))?;
-            Ok((keywords::Invalid.ident(),
-             ItemKind::AutoImpl(unsafety, opt_trait.unwrap()), None))
-        } else {
-            if opt_trait.is_some() {
-                ty = self.parse_ty()?;
-            }
-            generics.where_clause = self.parse_where_clause()?;
-
-            self.expect(&token::OpenDelim(token::Brace))?;
-            let attrs = self.parse_inner_attributes()?;
+        let item_kind = match ty_second {
+            Some(ty_second) => {
+                // impl Trait for Type
+                if !has_for {
+                    self.span_err(missing_for_span, "missing `for` in a trait impl");
+                }
 
-            let mut impl_items = vec![];
-            while !self.eat(&token::CloseDelim(token::Brace)) {
-                let mut at_end = false;
-                match self.parse_impl_item(&mut at_end) {
-                    Ok(item) => impl_items.push(item),
-                    Err(mut e) => {
-                        e.emit();
-                        if !at_end {
-                            self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
-                        }
+                let ty_first = ty_first.into_inner();
+                let path = match ty_first.node {
+                    // This notably includes paths passed through `ty` macro fragments (#46438).
+                    TyKind::Path(None, path) => path,
+                    _ => {
+                        self.span_err(ty_first.span, "expected a trait, found type");
+                        ast::Path::from_ident(ty_first.span, keywords::Invalid.ident())
                     }
-                }
+                };
+                let trait_ref = TraitRef { path, ref_id: ty_first.id };
+
+                ItemKind::Impl(unsafety, polarity, defaultness,
+                               generics, Some(trait_ref), ty_second, impl_items)
             }
+            None => {
+                // impl Type
+                ItemKind::Impl(unsafety, polarity, defaultness,
+                               generics, None, ty_first, impl_items)
+            }
+        };
 
-            Ok((keywords::Invalid.ident(),
-             ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
-             Some(attrs)))
-        }
+        Ok((keywords::Invalid.ident(), item_kind, Some(attrs)))
     }
 
     fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
@@ -5704,12 +5729,21 @@ pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibili
         Ok(Visibility::Public)
     }
 
-    /// Parse defaultness: DEFAULT or nothing
-    fn parse_defaultness(&mut self) -> PResult<'a, Defaultness> {
-        if self.eat_defaultness() {
-            Ok(Defaultness::Default)
+    /// Parse defaultness: `default` or nothing.
+    fn parse_defaultness(&mut self) -> Defaultness {
+        // `pub` is included for better error messages
+        if self.check_keyword(keywords::Default) &&
+           self.look_ahead(1, |t| t.is_keyword(keywords::Impl) ||
+                                  t.is_keyword(keywords::Const) ||
+                                  t.is_keyword(keywords::Fn) ||
+                                  t.is_keyword(keywords::Unsafe) ||
+                                  t.is_keyword(keywords::Extern) ||
+                                  t.is_keyword(keywords::Type) ||
+                                  t.is_keyword(keywords::Pub)) {
+            self.bump(); // `default`
+            Defaultness::Default
         } else {
-            Ok(Defaultness::Final)
+            Defaultness::Final
         }
     }
 
@@ -5779,7 +5813,7 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
                 let (module, mut attrs) =
                     self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
                 if warn {
-                    let attr = ast::Attribute {
+                    let attr = Attribute {
                         id: attr::mk_attr_id(),
                         style: ast::AttrStyle::Outer,
                         path: ast::Path::from_ident(syntax_pos::DUMMY_SP,
@@ -5819,7 +5853,7 @@ fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
         }
     }
 
-    pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> {
+    pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
         attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&d.as_str()))
     }
 
@@ -5888,16 +5922,20 @@ pub fn default_submod_path(
 
     fn submod_path(&mut self,
                    id: ast::Ident,
-                   outer_attrs: &[ast::Attribute],
+                   outer_attrs: &[Attribute],
                    id_sp: Span)
                    -> PResult<'a, ModulePathSuccess> {
         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,
@@ -5977,7 +6015,7 @@ fn eval_src_mod(&mut self,
                     directory_ownership: DirectoryOwnership,
                     name: String,
                     id_sp: Span)
-                    -> PResult<'a, (ast::ItemKind, Vec<ast::Attribute> )> {
+                    -> PResult<'a, (ast::ItemKind, Vec<Attribute> )> {
         let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
         if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
             let mut err = String::from("circular modules: ");
@@ -6100,7 +6138,7 @@ fn parse_item_extern_crate(&mut self,
     /// extern {}
     fn parse_item_foreign_mod(&mut self,
                               lo: Span,
-                              opt_abi: Option<abi::Abi>,
+                              opt_abi: Option<Abi>,
                               visibility: Visibility,
                               mut attrs: Vec<Attribute>)
                               -> PResult<'a, P<Item>> {
@@ -6203,7 +6241,7 @@ fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
 
     /// Parses a string as an ABI spec on an extern type or module. Consumes
     /// the `extern` keyword, if one is found.
-    fn parse_opt_abi(&mut self) -> PResult<'a, Option<abi::Abi>> {
+    fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
         match self.token {
             token::Literal(token::Str_(s), suf) | token::Literal(token::StrRaw(s, _), suf) => {
                 let sp = self.span;
@@ -6308,11 +6346,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
                 || (self.check_keyword(keywords::Unsafe)
                     && self.look_ahead(1, |t| t.is_keyword(keywords::Fn))) {
                 // CONST FUNCTION ITEM
-                let unsafety = if self.eat_keyword(keywords::Unsafe) {
-                    Unsafety::Unsafe
-                } else {
-                    Unsafety::Normal
-                };
+                let unsafety = self.parse_unsafety();
                 self.bump();
                 let (ident, item_, extra_attrs) =
                     self.parse_item_fn(unsafety,
@@ -6348,15 +6382,16 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             self.look_ahead(1, |t| t.is_keyword(keywords::Auto)))
         {
             // UNSAFE TRAIT ITEM
-            self.expect_keyword(keywords::Unsafe)?;
+            self.bump(); // `unsafe`
             let is_auto = if self.eat_keyword(keywords::Trait) {
                 IsAuto::No
             } else {
-                self.eat_auto_trait();
+                self.expect_keyword(keywords::Auto)?;
+                self.expect_keyword(keywords::Trait)?;
                 IsAuto::Yes
             };
             let (ident, item_, extra_attrs) =
-                self.parse_item_trait(is_auto, ast::Unsafety::Unsafe)?;
+                self.parse_item_trait(is_auto, Unsafety::Unsafe)?;
             let prev_span = self.prev_span;
             let item = self.mk_item(lo.to(prev_span),
                                     ident,
@@ -6365,26 +6400,21 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
                                     maybe_append(attrs, extra_attrs));
             return Ok(Some(item));
         }
-        if (self.check_keyword(keywords::Unsafe) &&
-            self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) ||
-           (self.check_keyword(keywords::Default) &&
-            self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) &&
-            self.look_ahead(2, |t| t.is_keyword(keywords::Impl)))
-        {
+        if self.check_keyword(keywords::Impl) ||
+           self.check_keyword(keywords::Unsafe) &&
+                self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) ||
+           self.check_keyword(keywords::Default) &&
+                self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) ||
+           self.check_keyword(keywords::Default) &&
+                self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) {
             // IMPL ITEM
-            let defaultness = self.parse_defaultness()?;
-            self.expect_keyword(keywords::Unsafe)?;
+            let defaultness = self.parse_defaultness();
+            let unsafety = self.parse_unsafety();
             self.expect_keyword(keywords::Impl)?;
-            let (ident,
-                 item_,
-                 extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe, defaultness)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let (ident, item, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?;
+            let span = lo.to(self.prev_span);
+            return Ok(Some(self.mk_item(span, ident, item, visibility,
+                                        maybe_append(attrs, extra_attrs))));
         }
         if self.check_keyword(keywords::Fn) {
             // FUNCTION ITEM
@@ -6405,7 +6435,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
         if self.check_keyword(keywords::Unsafe)
             && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
             // UNSAFE FUNCTION ITEM
-            self.bump();
+            self.bump(); // `unsafe`
             let abi = if self.eat_keyword(keywords::Extern) {
                 self.parse_opt_abi()?.unwrap_or(Abi::C)
             } else {
@@ -6466,30 +6496,13 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             let is_auto = if self.eat_keyword(keywords::Trait) {
                 IsAuto::No
             } else {
-                self.eat_auto_trait();
+                self.expect_keyword(keywords::Auto)?;
+                self.expect_keyword(keywords::Trait)?;
                 IsAuto::Yes
             };
             // TRAIT ITEM
             let (ident, item_, extra_attrs) =
-                self.parse_item_trait(is_auto, ast::Unsafety::Normal)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
-        }
-        if (self.check_keyword(keywords::Impl)) ||
-           (self.check_keyword(keywords::Default) &&
-            self.look_ahead(1, |t| t.is_keyword(keywords::Impl)))
-        {
-            // IMPL ITEM
-            let defaultness = self.parse_defaultness()?;
-            self.expect_keyword(keywords::Impl)?;
-            let (ident,
-                 item_,
-                 extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal, defaultness)?;
+                self.parse_item_trait(is_auto, Unsafety::Normal)?;
             let prev_span = self.prev_span;
             let item = self.mk_item(lo.to(prev_span),
                                     ident,
index dd343a2384b1f475f1ee52c15a698febeb576d01..5374bf180f49a1172228dc1ac3d52b883638b438 100644 (file)
@@ -1294,18 +1294,6 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                 self.head(&visibility_qualified(&item.vis, "union"))?;
                 self.print_struct(struct_def, generics, item.ident, item.span, true)?;
             }
-            ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
-                self.head("")?;
-                self.print_visibility(&item.vis)?;
-                self.print_unsafety(unsafety)?;
-                self.word_nbsp("impl")?;
-                self.print_trait_ref(trait_ref)?;
-                self.s.space()?;
-                self.word_space("for")?;
-                self.word_space("..")?;
-                self.bopen()?;
-                self.bclose(item.span)?;
-            }
             ast::ItemKind::Impl(unsafety,
                           polarity,
                           defaultness,
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 bd68d7cf8f5d88c94eaf0eab12eb508969ff4efa..b5fc9236ad39a895b97f9d4215546e943f1eca3f 100644 (file)
@@ -259,9 +259,6 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_generics(type_parameters);
             visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
         }
-        ItemKind::AutoImpl(_, ref trait_ref) => {
-            visitor.visit_trait_ref(trait_ref)
-        }
         ItemKind::Impl(_, _, _,
                  ref type_parameters,
                  ref opt_trait_reference,
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 d33b52486296f8b3c7fe27e68ec99b9baeb97ab9..7d5581bb774b03132b384146479f6004ac46b417 100644 (file)
 #[lang = "sized"]
 trait Sized {}
 #[lang = "sync"]
-trait Sync {}
-#[allow(unknown_lints)]
-#[allow(auto_impl)]
-impl Sync for .. {}
+auto trait Sync {}
 #[lang = "copy"]
 trait Copy {}
 #[lang = "freeze"]
-trait Freeze {}
-#[allow(unknown_lints)]
-#[allow(auto_impl)]
-impl Freeze for .. {}
+auto trait Freeze {}
 
 #[lang = "drop_in_place"]
 #[inline]
index 410366d0d7ff50f87039c0df29593afe67bff5da..f487f1d410e03874ea65cadac68c1824f28f2bbb 100644 (file)
@@ -22,10 +22,7 @@ impl<T> Sync for T {}
 #[lang = "copy"]
 trait Copy {}
 #[lang = "freeze"]
-trait Freeze {}
-#[allow(unknown_lints)]
-#[allow(auto_impl)]
-impl Freeze for .. {}
+auto trait Freeze {}
 
 #[lang = "drop_in_place"]
 #[inline]
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);
index 892989cc6a080132c0dbdbc64e2f32c4f1ec6f9f..1a779a41e66604615838974c937c5641b3205102 100644 (file)
@@ -12,7 +12,7 @@
 
 struct Foo;
 
-unsafe impl !Clone for Foo { } //~ ERROR negative implementations are not unsafe [E0198]
+unsafe impl !Send for Foo { } //~ ERROR E0198
 
 fn main() {
 }
diff --git a/src/test/compile-fail/auto-impl-future-compat.rs b/src/test/compile-fail/auto-impl-future-compat.rs
deleted file mode 100644 (file)
index 5c32a75..0000000
+++ /dev/null
@@ -1,16 +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.
-
-#![feature(optin_builtin_traits)]
-
-trait Foo {}
-impl Foo for .. {}
-//~^ ERROR The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`
-//~^^ WARN this was previously accepted by the compiler
index b28b776d9c2a656d9ff05ef63aad076275695b14..92b222e1322b8b5e13442a973daa68bd0a38ba80 100644 (file)
 #![feature(optin_builtin_traits)]
 
 auto trait Generic<T> {}
-//~^ ERROR auto traits cannot have generics
-//~^^ traits with auto impls (`e.g. impl Trait for ..`) can not have type parameters
+//~^ auto traits cannot have generic parameters [E0567]
 auto trait Bound : Copy {}
-//~^ ERROR auto traits cannot have super traits
-//~^^ traits with auto impls (`e.g. impl Trait for ..`) cannot have predicates
+//~^ auto traits cannot have super traits [E0568]
 auto trait MyTrait { fn foo() {} }
-//~^ ERROR auto traits cannot contain items
-//~^^ traits with default impls (`e.g. impl Trait for ..`) must have no methods or associated items
+//~^ auto traits cannot have methods or associated items [E0380]
 fn main() {}
index 1e1c55de87e17aa1ecb57b6fb16c6a796633e8b0..f6f7a250174ba5b2c2b7ded7bd6cea7f506c5eef 100644 (file)
@@ -11,8 +11,6 @@
 #![feature(optin_builtin_traits, core)]
 #![crate_type = "rlib"]
 
-pub trait DefaultedTrait { }
-#[allow(auto_impl)]
-impl DefaultedTrait for .. { }
+pub auto trait DefaultedTrait { }
 
 pub struct Something<T> { t: T }
index 513a17e2ef2f4e1a1218da12ccadcddc65b5f5f9..1ffba68263a9a4faceab7cb075c04e4ffceef7e7 100644 (file)
@@ -13,7 +13,7 @@ fn bar<F>(blk: F) where F: FnOnce() + 'static {
 
 fn foo(x: &()) {
     bar(|| {
-        //~^ ERROR does not fulfill
+        //~^ ERROR explicit lifetime required in the type of `x` [E0621]
         let _ = x;
     })
 }
index 9c26b8b05f259ce1e8c3aa03b62bce48a1a06ff5..751d0a14c57ee12ce6d511bbd88ba903311b1a2d 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-trait MyTrait { fn foo() {} }
+auto trait MySafeTrait {}
 
-#[allow(auto_impl)]
-impl MyTrait for .. {}
-//~^ ERROR redundant auto implementations of trait `MyTrait`
+struct Foo;
 
-#[allow(auto_impl)]
-impl MyTrait for .. {}
-
-trait MySafeTrait {}
-
-#[allow(auto_impl)]
-unsafe impl MySafeTrait for .. {}
+unsafe impl MySafeTrait for Foo {}
 //~^ ERROR implementing the trait `MySafeTrait` is not unsafe
 
-unsafe trait MyUnsafeTrait {}
+unsafe auto trait MyUnsafeTrait {}
 
-#[allow(auto_impl)]
-impl MyUnsafeTrait for .. {}
+impl MyUnsafeTrait for Foo {}
 //~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
 
 fn main() {}
index 3b335d586f39184c0922de71aa196fac8263e653..1ae07b646855737c716ff85751d07ac9eb6e807f 100644 (file)
@@ -15,6 +15,6 @@
 struct TestType;
 
 unsafe impl !Send for TestType {}
-//~^ ERROR negative implementations are not unsafe
+//~^ ERROR negative impls cannot be unsafe
 
 fn main() {}
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 837160bc2fcd99d9221d3d13b86da6ba937f9359..0eb99ca0fc3f1b1f8db492fcb556baa5958c28f5 100644 (file)
@@ -13,7 +13,7 @@
 use std::fmt::Debug;
 
 fn elided(x: &i32) -> impl Copy { x }
-//~^ ERROR cannot infer an appropriate lifetime
+//~^ ERROR explicit lifetime required in the type of `x` [E0621]
 
 fn explicit<'a>(x: &'a i32) -> impl Copy { x }
 //~^ ERROR cannot infer an appropriate lifetime
index b525d5f64fc9a9d9237671479d313ff72727f030..1768c834cb39161334dc38fa7cb12f0a18790954 100644 (file)
@@ -12,7 +12,7 @@
 
 fn foo<T: Any>(value: &T) -> Box<Any> {
     Box::new(value) as Box<Any>
-    //~^ ERROR: cannot infer an appropriate lifetime
+    //~^ ERROR explicit lifetime required in the type of `value` [E0621]
 }
 
 fn main() {
index bf44cd53f67dc45bda84c3d1bbd7c25692315da3..2aa87f8424b9584498dcbd54fe594fe9345d9bc3 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-unsafe trait Trait {
+unsafe auto trait Trait {
 //~^ ERROR E0380
     type Output;
 }
 
-#[allow(auto_impl)]
-unsafe impl Trait for .. {}
-
 fn call_method<T: Trait>(x: T) {}
 
 fn main() {
     // ICE
     call_method(());
+    //~^ ERROR
 }
index 1fb63391d5608df43db2846b69917f97cbccff97..153b6fd07e6d1832cfcebee72ddb08550cf81e41 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-unsafe trait Trait {
+unsafe auto trait Trait {
 //~^ ERROR E0380
     fn method(&self) {
         println!("Hello");
     }
 }
 
-#[allow(auto_impl)]
-unsafe impl Trait for .. {}
-
 fn call_method<T: Trait>(x: T) {
     x.method();
 }
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!(),
+    }
+}
index af8f7dce60875bd9c96faaa9b2e6b6a9e56f21e4..ecddb4c101fdf7f89d26008f9ff4768dc2e513fd 100644 (file)
@@ -31,11 +31,11 @@ fn test_call() {
 }
 
 fn test_args(b: Box<i32>) {  //[ast]~ NOTE first assignment
-                                //[mir]~^ NOTE first assignment
+                                //[mir]~^ NOTE argument not declared as `mut`
     b = Box::new(2);            //[ast]~ ERROR cannot assign twice to immutable variable
-                                //[mir]~^ ERROR cannot assign twice to immutable variable `b`
+                                //[mir]~^ ERROR cannot assign to immutable argument `b`
                                 //[ast]~| NOTE cannot assign twice to immutable
-                                //[mir]~| NOTE cannot assign twice to immutable
+                                //[mir]~| NOTE cannot assign to immutable argument
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-46438.rs b/src/test/compile-fail/issue-46438.rs
new file mode 100644 (file)
index 0000000..d84b581
--- /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.
+
+macro_rules! m {
+    ($my_type: ty) => {
+        impl $my_type for u8 {}
+    }
+}
+
+trait Trait {}
+
+m!(Tr);
+
+m!(&'static u8); //~ ERROR expected a trait, found type
+
+fn main() {}
index c50f425b2c01d744cb41256a10fd0f726010c8bf..b253612bc327b1ff24f9cb334198a7205098e8f2 100644 (file)
@@ -25,7 +25,7 @@ fn load(ss: &mut SomeStruct) -> Box<SomeTrait> {
     // `Box<SomeTrait>` defaults to a `'static` bound, so this return
     // is illegal.
 
-    ss.r //~ ERROR cannot infer an appropriate lifetime
+    ss.r //~ ERROR explicit lifetime required in the type of `ss` [E0621]
 }
 
 fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) {
index 1c1cb396a54f200e8a50eaa296dd3c30efd6c4c9..e36c4835ca1c9390fd2fcfe3a29725aa1f32c12c 100644 (file)
@@ -9,17 +9,13 @@
 // except according to those terms.
 
 // Ensure that OIBIT checks `T` when it encounters a `PhantomData<T>` field, instead of checking
-// the `PhantomData<T>` type itself (which almost always implements a "default" trait
-// (`impl Trait for ..`))
+// the `PhantomData<T>` type itself (which almost always implements an auto trait)
 
 #![feature(optin_builtin_traits)]
 
 use std::marker::{PhantomData};
 
-unsafe trait Zen {}
-
-#[allow(auto_impl)]
-unsafe impl Zen for .. {}
+unsafe auto trait Zen {}
 
 unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
 
index 34082adb8f9a563a82c674d5fbb723f0e849a676..f245b7cef29b9e56f5003408162cd769195d4b5e 100644 (file)
@@ -10,7 +10,6 @@
 
 #![feature(optin_builtin_traits)]
 
-trait MarkerTr {}
 pub trait Tr {
     fn f();
     const C: u8;
@@ -21,8 +20,6 @@ pub struct S {
 }
 struct Ts(pub u8);
 
-#[allow(auto_impl)]
-pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
 pub impl Tr for S {  //~ ERROR unnecessary visibility qualifier
     pub fn f() {} //~ ERROR unnecessary visibility qualifier
     pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier
@@ -39,7 +36,6 @@ pub fn f() {}
 }
 
 const MAIN: u8 = {
-    trait MarkerTr {}
     pub trait Tr {
         fn f();
         const C: u8;
@@ -50,8 +46,6 @@ pub struct S {
     }
     struct Ts(pub u8);
 
-    #[allow(auto_impl)]
-    pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
     pub impl Tr for S {  //~ ERROR unnecessary visibility qualifier
         pub fn f() {} //~ ERROR unnecessary visibility qualifier
         pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier
@@ -71,7 +65,6 @@ pub fn f() {}
 };
 
 fn main() {
-    trait MarkerTr {}
     pub trait Tr {
         fn f();
         const C: u8;
@@ -82,8 +75,6 @@ pub struct S {
     }
     struct Ts(pub u8);
 
-    #[allow(auto_impl)]
-    pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
     pub impl Tr for S {  //~ ERROR unnecessary visibility qualifier
         pub fn f() {} //~ ERROR unnecessary visibility qualifier
         pub const C: u8 = 0; //~ ERROR unnecessary visibility qualifier
index 4e10614bf62c6b274fce6a581e4928f7d1ad5b7a..480406054adb52d11b2ec3cf75472604b48f384c 100644 (file)
@@ -21,7 +21,7 @@ impl PrivTr for Priv {
         type AssocAlias = m::Pub3;
     }
 
-    impl (<Priv as PrivTr>::AssocAlias) { //~ ERROR no base type found for inherent implementation
+    impl <Priv as PrivTr>::AssocAlias { //~ ERROR no base type found for inherent implementation
         pub fn f(arg: Priv) {} // private type `aliases_pub::Priv` in public interface
     }
 }
@@ -37,7 +37,7 @@ impl PrivTr for Priv {
         type AssocAlias = Priv3;
     }
 
-    impl (<Priv as PrivTr>::AssocAlias) { //~ ERROR no base type found for inherent implementation
+    impl <Priv as PrivTr>::AssocAlias { //~ ERROR no base type found for inherent implementation
         pub fn f(arg: Priv) {} // OK
     }
 }
index 687b2c344a3b755d42f6baa392b31ddc18b1741a..5bf397ab3838ce747441d5fe4992b1d3cd675567 100644 (file)
@@ -16,20 +16,20 @@ impl<'a> Foo for &'a [u8] {}
 
 fn a(v: &[u8]) -> Box<Foo + 'static> {
     let x: Box<Foo + 'static> = Box::new(v);
-    //~^ ERROR cannot infer an appropriate lifetime due to conflicting
+    //~^ ERROR explicit lifetime required in the type of `v` [E0621]
     x
 }
 
 fn b(v: &[u8]) -> Box<Foo + 'static> {
     Box::new(v)
-        //~^ ERROR cannot infer an appropriate lifetime due to conflicting
+        //~^ ERROR explicit lifetime required in the type of `v` [E0621]
 }
 
 fn c(v: &[u8]) -> Box<Foo> {
     // same as previous case due to RFC 599
 
     Box::new(v)
-        //~^ ERROR cannot infer an appropriate lifetime due to conflicting
+        //~^ ERROR explicit lifetime required in the type of `v` [E0621]
 }
 
 fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
index 17fd55b031b61463513dc077928a330bb5ffe6ac..dd7b2bf96357525a8a111e4e7903c346ce5a1dba 100644 (file)
@@ -16,7 +16,7 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box<FnMut()->(isize) + 'a> {
 
 fn static_proc(x: &isize) -> Box<FnMut()->(isize) + 'static> {
     // This is illegal, because the region bound on `proc` is 'static.
-    Box::new(move|| { *x }) //~ ERROR cannot infer an appropriate lifetime
+    Box::new(move|| { *x }) //~ ERROR explicit lifetime required in the type of `x` [E0621]
 }
 
 fn main() { }
index a217cc9ebfa527a70f768f5ca954cf0c16177065..13f93090fbbb4fae5260fe6296d19cca0a8ca8bb 100644 (file)
@@ -22,12 +22,12 @@ fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
 }
 
 fn error(u: &(), v: &()) {
-    static_id(&u); //[ll]~ ERROR cannot infer an appropriate lifetime
+    static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
     //[nll]~^ WARNING not reporting region error due to -Znll
-    //[nll]~| ERROR free region `` does not outlive free region `'static`
-    static_id_indirect(&v); //[ll]~ ERROR cannot infer an appropriate lifetime
+    //[nll]~| ERROR explicit lifetime required in the type of `u` [E0621]
+    static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
     //[nll]~^ WARNING not reporting region error due to -Znll
-    //[nll]~| ERROR free region `` does not outlive free region `'static`
+    //[nll]~| ERROR explicit lifetime required in the type of `v` [E0621]
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs
deleted file mode 100644 (file)
index cad43ff..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(specialization)]
-#![feature(optin_builtin_traits)]
-
-trait Foo {}
-
-#[allow(auto_impl)]
-default impl Foo for .. {}
-//~^ ERROR `default impl` is not allowed for auto trait implementations
-
-fn main() {}
diff --git a/src/test/compile-fail/specialization/defaultimpl/validation.rs b/src/test/compile-fail/specialization/defaultimpl/validation.rs
new file mode 100644 (file)
index 0000000..26b8b73
--- /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.
+
+#![feature(optin_builtin_traits)]
+#![feature(specialization)]
+
+struct S;
+struct Z;
+
+default impl S {} //~ ERROR inherent impls cannot be default
+
+default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
+default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
+
+trait Tr {}
+default impl !Tr for S {} //~ ERROR negative impls are only allowed for auto traits
index c97cb3f6bb70b6c47a6d019ae2e21255a7f8137f..b28a63c8293aed1103a399cc9a539c47a73e1f7a 100644 (file)
 #![feature(optin_builtin_traits)]
 #![feature(specialization)]
 
-trait Foo {}
-
-#[allow(auto_impl)]
-impl Foo for .. {}
+auto trait Foo {}
 
 impl<T> Foo for T {}
 impl !Foo for u8 {} //~ ERROR E0119
 
-trait Bar {}
-
-#[allow(auto_impl)]
-impl Bar for .. {}
+auto trait Bar {}
 
 impl<T> !Bar for T {}
 impl Bar for u8 {} //~ ERROR E0119
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 a7ca5e3bf093a02046a0f4d30e44e4e65d7ddf65..8d5e89cc66f753d408025a57e4e6900407804067 100644 (file)
@@ -14,7 +14,7 @@
 
 trait TestTrait {}
 
-unsafe impl !Send for TestType {}
+impl !Send for TestType {}
 //~^ ERROR negative trait bounds
 
 fn main() {}
diff --git a/src/test/compile-fail/syntax-trait-polarity.rs b/src/test/compile-fail/syntax-trait-polarity.rs
new file mode 100644 (file)
index 0000000..1a5d058
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::Send;
+
+struct TestType;
+
+impl !TestType {}
+//~^ ERROR inherent impls cannot be negative
+
+trait TestTrait {}
+
+unsafe impl !Send for TestType {}
+//~^ ERROR negative impls cannot be unsafe
+impl !TestTrait for TestType {}
+//~^ ERROR negative impls are only allowed for auto traits
+
+struct TestType2<T>(T);
+
+impl<T> !TestType2<T> {}
+//~^ ERROR inherent impls cannot be negative
+
+unsafe impl<T> !Send for TestType2<T> {}
+//~^ ERROR negative impls cannot be unsafe
+impl<T> !TestTrait for TestType2<T> {}
+//~^ ERROR negative impls are only allowed for auto traits
+
+fn main() {}
diff --git a/src/test/compile-fail/syntaxt-default-trait-impls.rs b/src/test/compile-fail/syntaxt-default-trait-impls.rs
deleted file mode 100644 (file)
index 45303cb..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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(optin_builtin_traits)]
-
-trait MyAutoImpl {}
-
-#[allow(auto_impl)]
-impl<T> MyAutoImpl for .. {}
-//~^ ERROR auto trait implementations are not allowed to have generics
-
-fn main() {}
index 285d4c1ba8d14a312e55c7667e3fb3825830b765..059fdc100c94407d2df29e8d7bdb380744f55582 100644 (file)
@@ -12,7 +12,7 @@
 
 struct SomeStruct;
 
-unsafe impl SomeStruct { //~ ERROR inherent impls cannot be declared as unsafe
+unsafe impl SomeStruct { //~ ERROR inherent impls cannot be unsafe
     fn foo(self) { }
 }
 
index 6c7928f13f8941f3052c74189e808490d1ca110b..59d5dc6c58b47821071dfbdc75a70d981f9b451f 100644 (file)
@@ -14,9 +14,7 @@
 
 #![feature(optin_builtin_traits)]
 
-trait Magic: Copy {} //~ ERROR E0568
-#[allow(auto_impl)]
-impl Magic for .. {}
+auto trait Magic: Copy {} //~ ERROR E0568
 
 fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
 
@@ -24,6 +22,6 @@ fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
 struct NoClone;
 
 fn main() {
-    let (a, b) = copy(NoClone);
+    let (a, b) = copy(NoClone); //~ ERROR
     println!("{:?} {:?}", a, b);
 }
index 173582ed22fdc2523f74fbef0296694abf7c5c2b..fa63088d00088028a6e5ae86f7f70f13e892dc42 100644 (file)
@@ -10,9 +10,7 @@
 
 #![feature(optin_builtin_traits)]
 
-trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
-#[allow(auto_impl)]
-impl Magic for .. {}
+auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
 impl<T:Magic> Magic for T {}
 
 fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
index 6802f72504b7d65adc1457fc8112254c89948f37..c8cf96f52fcf1775f4c3d419ee4d14cc9ee233ee 100644 (file)
@@ -34,9 +34,7 @@
 
 #![feature(optin_builtin_traits)]
 
-trait Magic: Copy {} //~ ERROR E0568
-#[allow(auto_impl)]
-impl Magic for .. {}
+auto trait Magic: Copy {} //~ ERROR E0568
 impl<T:Magic> Magic for T {}
 
 fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
diff --git a/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs b/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs
deleted file mode 100644 (file)
index 3c409d1..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(optin_builtin_traits)]
-
-trait Magic<T> {} //~ ERROR E0567
-#[allow(auto_impl)]
-impl Magic<isize> for .. {}
index a837d8c9ca74eccf2d989c134f7a5d7ce8a155dd..6e7c9afb6749a8e10fe801a13f38842e96cbeee0 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-trait MyTrait {}
-
-#[allow(auto_impl)]
-impl MyTrait for .. {}
+auto trait MyTrait {}
 
 struct MyS;
 
index bed184eb4ccca9e70f57e35bae9ccd28692ada6a..4660ecf4fb4b424a11d9dab70381898a59073699 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-trait MyTrait {}
+auto trait MyTrait {}
 
-#[allow(auto_impl)]
-impl MyTrait for .. {}
 impl<T> !MyTrait for *mut T {}
 
 struct MyS;
index f3a6d8a342e221c7153bc70f7255270f406de7a1..b28cdd8aa2450c74c2b3e14ac1e089a552142851 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-trait MyTrait {}
+auto trait MyTrait {}
 
-#[allow(auto_impl)]
-impl MyTrait for .. {}
-
-unsafe trait MyUnsafeTrait {}
-
-#[allow(auto_impl)]
-unsafe impl MyUnsafeTrait for .. {}
+unsafe auto trait MyUnsafeTrait {}
 
 struct ThisImplsTrait;
 
index bdd6487b86d74ea65de8026a350697aac56717b3..d63d70bad2204e9db7dbcc71b3116c360b697b26 100644 (file)
 
 // Test that declaring that `&T` is `Defaulted` if `T:Signed` implies
 // that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In
-// other words, the `..` impl only applies if there are no existing
+// other words, the auto impl only applies if there are no existing
 // impls whose types unify.
 
 #![feature(optin_builtin_traits)]
 
-trait Defaulted { }
-#[allow(auto_impl)]
-impl Defaulted for .. { }
+auto trait Defaulted { }
 impl<'a,T:Signed> Defaulted for &'a T { }
 impl<'a,T:Signed> Defaulted for &'a mut T { }
 fn is_defaulted<T:Defaulted>() { }
index 57a394dc7f1ec746847641673a6ac0ef8fcf126c..d6d8fb6235d386f8aed71342f5a01b980158db36 100644 (file)
@@ -17,6 +17,6 @@ fn dummy(&self) { }
 }
 
 impl !TestTrait for TestType {}
-//~^ ERROR negative impls are only allowed for traits with default impls (e.g., `Send` and `Sync`)
+//~^ ERROR negative impls are only allowed for auto traits (e.g., `Send` and `Sync`)
 
 fn main() {}
diff --git a/src/test/parse-fail/impl-qpath.rs b/src/test/parse-fail/impl-qpath.rs
new file mode 100644 (file)
index 0000000..48dd888
--- /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.
+
+// compile-flags: -Z parse-only
+
+impl <*const u8>::AssocTy {} // OK
+impl <Type as Trait>::AssocTy {} // OK
+impl <'a + Trait>::AssocTy {} // OK
+impl <<Type>::AssocTy>::AssocTy {} // OK
+
+FAIL //~ ERROR
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/syntax-trait-polarity.rs b/src/test/parse-fail/syntax-trait-polarity.rs
deleted file mode 100644 (file)
index 1971ffe..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -Z parse-only -Z continue-parse-after-error
-
-#![feature(optin_builtin_traits)]
-
-use std::marker::Send;
-
-struct TestType;
-
-impl !TestType {}
-//~^ ERROR inherent implementation can't be negated
-
-trait TestTrait {}
-
-unsafe impl !Send for TestType {}
-impl !TestTrait for TestType {}
-
-struct TestType2<T>;
-
-impl<T> !TestType2<T> {}
-//~^ ERROR inherent implementation can't be negated
-
-unsafe impl<T> !Send for TestType2<T> {}
-impl<T> !TestTrait for TestType2<T> {}
-
-fn main() {}
index b7dcc8a8b3bc1a5774ebd4ce41e22dcf37bb254c..7cd2774fe39b2ce78ef16f8ecf3c670288daefc0 100644 (file)
@@ -15,9 +15,7 @@ trait Foo {
 
 struct Bar;
 
-impl Foo + Owned for Bar {
-//~^ ERROR not a trait
-//~^^ ERROR expected one of `where` or `{`, found `Bar`
+impl Foo + Owned for Bar { //~ ERROR expected a trait, found type
 }
 
 fn main() { }
index cb57500df797eae06475148616c6e092409471cc..2948619ccd07dce770b2837074a565c22b74d557 100644 (file)
@@ -11,6 +11,6 @@
 // compile-flags: -Z parse-only
 
 fn foo<T>() where <T>::Item: ToString, T: Iterator { }
-               //~^ syntax `where<T>` is reserved for future use
+//~^ ERROR generic parameters on `where` clauses are reserved for future use
 
 fn main() {}
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-make/rustdoc-error-lines/Makefile b/src/test/run-make/rustdoc-error-lines/Makefile
new file mode 100644 (file)
index 0000000..0019e5e
--- /dev/null
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+# Test that hir-tree output doens't crash and includes
+# the string constant we would expect to see.
+
+all:
+       $(RUSTDOC) --test input.rs > $(TMPDIR)/output || true
+       $(CGREP) 'input.rs:17:15' < $(TMPDIR)/output
diff --git a/src/test/run-make/rustdoc-error-lines/input.rs b/src/test/run-make/rustdoc-error-lines/input.rs
new file mode 100644 (file)
index 0000000..6dc7060
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test for #45868
+
+// random #![feature] to ensure that crate attrs
+// do not offset things
+/// ```rust
+/// #![feature(nll)]
+/// let x: char = 1;
+/// ```
+pub fn foo() {
+
+}
index 185476fb704f7fe4176766abe11d54c7c3e2025d..94b91c711cce0d9c7bebb69ef8b7a7c5383d3276 100644 (file)
@@ -80,6 +80,4 @@ pub mod marker {
 }
 
 #[lang = "freeze"]
-trait Freeze {}
-#[allow(auto_impl)]
-impl Freeze for .. {}
+auto trait Freeze {}
index a0feb72702834e74eed0166eaeab601f322cbfd3..bbd1c5d900fafbc99088c7294106583a57f979aa 100644 (file)
@@ -18,9 +18,7 @@ trait Copy { }
 trait Sized { }
 
 #[lang = "freeze"]
-trait Freeze {}
-#[allow(auto_impl)]
-impl Freeze for .. {}
+auto trait Freeze {}
 
 #[lang="start"]
 fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize { 0 }
index e42aca9ccbd1378c29cff2e7c80765e2237b5e88..2a18b402bc64d4c70575ce67caf6707ed0af0178 100644 (file)
 #![feature(optin_builtin_traits)]
 
 auto trait Auto {}
-// Redundant but accepted until we remove it.
-#[allow(auto_impl)]
-impl Auto for .. {}
-
 unsafe auto trait AutoUnsafe {}
 
 impl !Auto for bool {}
@@ -29,6 +25,10 @@ fn take_auto<T: Auto>(_: T) {}
 fn take_auto_unsafe<T: AutoUnsafe>(_: T) {}
 
 fn main() {
+    // Parse inside functions.
+    auto trait AutoInner {}
+    unsafe auto trait AutoUnsafeInner {}
+
     take_auto(0);
     take_auto(AutoBool(true));
     take_auto_unsafe(0);
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
     }
 }
index aee89befda8f9ed7a95eefb484d4d3bdf852888f..0d9dc3cf60556aabfc95630d3229ff5b3f24b136 100644 (file)
@@ -8,16 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Paramters { type SelfRef; }
+pub trait Parameters { type SelfRef; }
 
 struct RP<'a> { _marker: std::marker::PhantomData<&'a ()> }
 struct BP;
 
-impl<'a> Paramters for RP<'a> { type SelfRef = &'a X<RP<'a>>; }
-impl Paramters for BP { type SelfRef = Box<X<BP>>; }
+impl<'a> Parameters for RP<'a> { type SelfRef = &'a X<RP<'a>>; }
+impl Parameters for BP { type SelfRef = Box<X<BP>>; }
 
 pub struct Y;
-pub enum X<P: Paramters> {
+pub enum X<P: Parameters> {
     Nothing,
     SameAgain(P::SelfRef, Y)
 }
index 5fa0a002a10db9071c31f3f4418bda4ffccbc959..465986583b15560d3edb575faddfb31ebaf19592 100644 (file)
@@ -10,9 +10,8 @@
 
 #![feature(optin_builtin_traits)]
 
-trait NotSame {}
-#[allow(auto_impl)]
-impl NotSame for .. {}
+auto trait NotSame {}
+
 impl<A> !NotSame for (A, A) {}
 
 trait OneOfEach {}
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;
index 4fd55bd482cd998029fb89eb2dcd477d999414c3..34a1331353dca96d1259937dd9d06caaf520ecc7 100644 (file)
 pub mod bar {
     use std::marker;
 
-    pub trait Bar {}
-
-    #[allow(auto_impl)]
-    impl Bar for .. {}
+    pub auto trait Bar {}
 
     pub trait Foo {
         fn foo(&self) {}
index d886778278dfd3dd86a35bc16c5096961eaca876..977d98ca87b10b4cb9fcde1692edd9f3c7e0af79 100644 (file)
@@ -10,7 +10,4 @@
 
 #![feature(optin_builtin_traits)]
 
-pub trait AnOibit {}
-
-#[allow(auto_impl)]
-impl AnOibit for .. {}
+pub auto trait AnOibit {}
index f74f66ce7290551849082781c0f7184313d6e956..6e472da379c592546b392de66a2917f113cbb4fd 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-pub trait AnOibit {}
-
-#[allow(auto_impl)]
-impl AnOibit for .. {}
+pub auto trait AnOibit {}
 
 pub struct Foo<T> { field: 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() {}
diff --git a/src/test/ui/borrowck/immutable-arg.rs b/src/test/ui/borrowck/immutable-arg.rs
new file mode 100644 (file)
index 0000000..7c387ed
--- /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.
+
+//compile-flags: -Z emit-end-regions -Z borrowck=compare
+
+fn foo(_x: u32) {
+    _x = 4;
+    //~^ ERROR cannot assign to immutable argument `_x` (Mir)
+    //~^^ ERROR cannot assign twice to immutable variable `_x` (Ast)
+}
+
+fn main() {}
+
diff --git a/src/test/ui/borrowck/immutable-arg.stderr b/src/test/ui/borrowck/immutable-arg.stderr
new file mode 100644 (file)
index 0000000..40e1878
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0384]: cannot assign twice to immutable variable `_x` (Ast)
+  --> $DIR/immutable-arg.rs:14:5
+   |
+13 | fn foo(_x: u32) {
+   |        -- first assignment to `_x`
+14 |     _x = 4;
+   |     ^^^^^^ cannot assign twice to immutable variable
+
+error[E0384]: cannot assign to immutable argument `_x` (Mir)
+  --> $DIR/immutable-arg.rs:14:5
+   |
+13 | fn foo(_x: u32) {
+   |        -- argument not declared as `mut`
+14 |     _x = 4;
+   |     ^^^^^^ cannot assign to immutable argument
+
+error: aborting due to 2 previous errors
+
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
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
index 4c5502cec18a851ff4c7d25cb6e07c17dab1f9ea..ab3313af16d5d6b325a70539cfbeb82899d3aad3 100644 (file)
@@ -20,10 +20,6 @@ fn dummy(&self) {}
 auto trait AutoDummyTrait {}
 //~^ ERROR auto traits are experimental and possibly buggy
 
-#[allow(auto_impl)]
-impl DummyTrait for .. {}
-//~^ ERROR auto trait implementations are experimental and possibly buggy
-
 impl !DummyTrait for DummyStruct {}
 //~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now
 
index c5e9614c29ad7239257e864bf921f1380bf38297..d66da1224f8b950d0fd8dcc460ff8ecd8d2b18b0 100644 (file)
@@ -6,21 +6,13 @@ error: auto traits are experimental and possibly buggy (see issue #13231)
    |
    = help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
 
-error: auto trait implementations are experimental and possibly buggy (see issue #13231)
-  --> $DIR/feature-gate-optin-builtin-traits.rs:24:1
-   |
-24 | impl DummyTrait for .. {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
-
 error: negative trait bounds are not yet fully implemented; use marker types for now (see issue #13231)
-  --> $DIR/feature-gate-optin-builtin-traits.rs:27:1
+  --> $DIR/feature-gate-optin-builtin-traits.rs:23:1
    |
-27 | impl !DummyTrait for DummyStruct {}
+23 | impl !DummyTrait for DummyStruct {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(optin_builtin_traits)] to the crate attributes to enable
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
index ab2fe02bb147667a75677d1846e049b5d29b9f8f..029949b26047b28c1317d337f6186f0f9904388c 100644 (file)
@@ -60,7 +60,6 @@
 #![start                     = "x4300"] //~ WARN unused attribute
 // see issue-43106-gating-of-test.rs for crate-level; but non crate-level is below at "4200"
 // see issue-43106-gating-of-bench.rs for crate-level; but non crate-level is below at "4100"
-#![simd                       = "4000"] //~ WARN unused attribute
 #![repr                       = "3900"] //~ WARN unused attribute
 #![path                       = "3800"] //~ WARN unused attribute
 #![abi                        = "3700"] //~ WARN unused attribute
@@ -328,24 +327,6 @@ mod inner { #![bench="4100"] }
     impl S { }
 }
 
-#[simd = "4000"]
-//~^ WARN unused attribute
-mod simd {
-    mod inner { #![simd="4000"] }
-    //~^ WARN unused attribute
-
-    #[simd = "4000"] fn f() { }
-    //~^ WARN unused attribute
-
-    struct S; // for `struct S` case, see feature-gate-repr-simd.rs
-
-    #[simd = "4000"] type T = S;
-    //~^ WARN unused attribute
-
-    #[simd = "4000"] impl S { }
-    //~^ WARN unused attribute
-}
-
 #[repr = "3900"]
 //~^ WARN unused attribute
 mod repr {
index be340b1ab9aee14f1e3c6e1e16a922543b887b09..df831ded9a74d2392872086eff4f2a622dcca2c7 100644 (file)
@@ -1,21 +1,21 @@
 warning: macro_escape is a deprecated synonym for macro_use
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:513:1
     |
-532 | #[macro_escape]
+513 | #[macro_escape]
     | ^^^^^^^^^^^^^^^
 
 warning: macro_escape is a deprecated synonym for macro_use
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
     |
-535 |     mod inner { #![macro_escape] }
+516 |     mod inner { #![macro_escape] }
     |                 ^^^^^^^^^^^^^^^^
     |
     = help: consider an outer attribute, #[macro_use] mod ...
 
 warning: `#[must_use]` on functions is experimental (see issue #43302)
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5
     |
-682 |     #[must_use = "1400"] fn f() { }
+663 |     #[must_use = "1400"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^
     |
     = help: add #![feature(fn_must_use)] to the crate attributes to enable
@@ -51,153 +51,153 @@ warning: unknown lint: `x5100`
    |                                 ^^^^^
 
 warning: unknown lint: `x5400`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:114:8
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:113:8
     |
-114 | #[warn(x5400)]
+113 | #[warn(x5400)]
     |        ^^^^^
 
 warning: unknown lint: `x5400`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:117:25
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:116:25
     |
-117 |     mod inner { #![warn(x5400)] }
+116 |     mod inner { #![warn(x5400)] }
     |                         ^^^^^
 
 warning: unknown lint: `x5400`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:120:12
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:119:12
     |
-120 |     #[warn(x5400)] fn f() { }
+119 |     #[warn(x5400)] fn f() { }
     |            ^^^^^
 
 warning: unknown lint: `x5400`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:123:12
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:122:12
     |
-123 |     #[warn(x5400)] struct S;
+122 |     #[warn(x5400)] struct S;
     |            ^^^^^
 
 warning: unknown lint: `x5400`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:126:12
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:125:12
     |
-126 |     #[warn(x5400)] type T = S;
+125 |     #[warn(x5400)] type T = S;
     |            ^^^^^
 
 warning: unknown lint: `x5400`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:129:12
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:128:12
     |
-129 |     #[warn(x5400)] impl S { }
+128 |     #[warn(x5400)] impl S { }
     |            ^^^^^
 
 warning: unknown lint: `x5300`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:133:9
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:132:9
     |
-133 | #[allow(x5300)]
+132 | #[allow(x5300)]
     |         ^^^^^
 
 warning: unknown lint: `x5300`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:136:26
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:135:26
     |
-136 |     mod inner { #![allow(x5300)] }
+135 |     mod inner { #![allow(x5300)] }
     |                          ^^^^^
 
 warning: unknown lint: `x5300`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:139:13
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:138:13
     |
-139 |     #[allow(x5300)] fn f() { }
+138 |     #[allow(x5300)] fn f() { }
     |             ^^^^^
 
 warning: unknown lint: `x5300`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:142:13
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:141:13
     |
-142 |     #[allow(x5300)] struct S;
+141 |     #[allow(x5300)] struct S;
     |             ^^^^^
 
 warning: unknown lint: `x5300`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:145:13
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:144:13
     |
-145 |     #[allow(x5300)] type T = S;
+144 |     #[allow(x5300)] type T = S;
     |             ^^^^^
 
 warning: unknown lint: `x5300`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:148:13
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:147:13
     |
-148 |     #[allow(x5300)] impl S { }
+147 |     #[allow(x5300)] impl S { }
     |             ^^^^^
 
 warning: unknown lint: `x5200`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:152:10
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:151:10
     |
-152 | #[forbid(x5200)]
+151 | #[forbid(x5200)]
     |          ^^^^^
 
 warning: unknown lint: `x5200`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:155:27
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:154:27
     |
-155 |     mod inner { #![forbid(x5200)] }
+154 |     mod inner { #![forbid(x5200)] }
     |                           ^^^^^
 
 warning: unknown lint: `x5200`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:158:14
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:157:14
     |
-158 |     #[forbid(x5200)] fn f() { }
+157 |     #[forbid(x5200)] fn f() { }
     |              ^^^^^
 
 warning: unknown lint: `x5200`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:161:14
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:160:14
     |
-161 |     #[forbid(x5200)] struct S;
+160 |     #[forbid(x5200)] struct S;
     |              ^^^^^
 
 warning: unknown lint: `x5200`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:164:14
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:163:14
     |
-164 |     #[forbid(x5200)] type T = S;
+163 |     #[forbid(x5200)] type T = S;
     |              ^^^^^
 
 warning: unknown lint: `x5200`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:167:14
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:166:14
     |
-167 |     #[forbid(x5200)] impl S { }
+166 |     #[forbid(x5200)] impl S { }
     |              ^^^^^
 
 warning: unknown lint: `x5100`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:171:8
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:170:8
     |
-171 | #[deny(x5100)]
+170 | #[deny(x5100)]
     |        ^^^^^
 
 warning: unknown lint: `x5100`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:174:25
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:173:25
     |
-174 |     mod inner { #![deny(x5100)] }
+173 |     mod inner { #![deny(x5100)] }
     |                         ^^^^^
 
 warning: unknown lint: `x5100`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:177:12
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:12
     |
-177 |     #[deny(x5100)] fn f() { }
+176 |     #[deny(x5100)] fn f() { }
     |            ^^^^^
 
 warning: unknown lint: `x5100`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:180:12
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:179:12
     |
-180 |     #[deny(x5100)] struct S;
+179 |     #[deny(x5100)] struct S;
     |            ^^^^^
 
 warning: unknown lint: `x5100`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:183:12
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:182:12
     |
-183 |     #[deny(x5100)] type T = S;
+182 |     #[deny(x5100)] type T = S;
     |            ^^^^^
 
 warning: unknown lint: `x5100`
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:186:12
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:185:12
     |
-186 |     #[deny(x5100)] impl S { }
+185 |     #[deny(x5100)] impl S { }
     |            ^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:193:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:17
     |
-193 |     mod inner { #![macro_reexport="5000"] }
+192 |     mod inner { #![macro_reexport="5000"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
     |
 note: lint level defined here
@@ -207,345 +207,315 @@ note: lint level defined here
     |         ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:196:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:195:5
     |
-196 |     #[macro_reexport = "5000"] fn f() { }
+195 |     #[macro_reexport = "5000"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:199:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:5
     |
-199 |     #[macro_reexport = "5000"] struct S;
+198 |     #[macro_reexport = "5000"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:202:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5
     |
-202 |     #[macro_reexport = "5000"] type T = S;
+201 |     #[macro_reexport = "5000"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:5
     |
-205 |     #[macro_reexport = "5000"] impl S { }
+204 |     #[macro_reexport = "5000"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:190:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:189:1
     |
-190 | #[macro_reexport = "5000"]
+189 | #[macro_reexport = "5000"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:213:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:212:5
     |
-213 |     #[macro_use] fn f() { }
+212 |     #[macro_use] fn f() { }
     |     ^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:215:5
     |
-216 |     #[macro_use] struct S;
+215 |     #[macro_use] struct S;
     |     ^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:219:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:218:5
     |
-219 |     #[macro_use] type T = S;
+218 |     #[macro_use] type T = S;
     |     ^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:222:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:5
     |
-222 |     #[macro_use] impl S { }
+221 |     #[macro_use] impl S { }
     |     ^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:229:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:17
     |
-229 |     mod inner { #![macro_export="4800"] }
+228 |     mod inner { #![macro_export="4800"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:232:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:231:5
     |
-232 |     #[macro_export = "4800"] fn f() { }
+231 |     #[macro_export = "4800"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:234:5
     |
-235 |     #[macro_export = "4800"] struct S;
+234 |     #[macro_export = "4800"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:238:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:237:5
     |
-238 |     #[macro_export = "4800"] type T = S;
+237 |     #[macro_export = "4800"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:241:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:240:5
     |
-241 |     #[macro_export = "4800"] impl S { }
+240 |     #[macro_export = "4800"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:226:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:225:1
     |
-226 | #[macro_export = "4800"]
+225 | #[macro_export = "4800"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:248:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:247:17
     |
-248 |     mod inner { #![plugin_registrar="4700"] }
+247 |     mod inner { #![plugin_registrar="4700"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:253:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:252:5
     |
-253 |     #[plugin_registrar = "4700"] struct S;
+252 |     #[plugin_registrar = "4700"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:256:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:255:5
     |
-256 |     #[plugin_registrar = "4700"] type T = S;
+255 |     #[plugin_registrar = "4700"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:259:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:258:5
     |
-259 |     #[plugin_registrar = "4700"] impl S { }
+258 |     #[plugin_registrar = "4700"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:244:1
     |
-245 | #[plugin_registrar = "4700"]
+244 | #[plugin_registrar = "4700"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:266:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:265:17
     |
-266 |     mod inner { #![main="4300"] }
+265 |     mod inner { #![main="4300"] }
     |                 ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:271:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:270:5
     |
-271 |     #[main = "4400"] struct S;
+270 |     #[main = "4400"] struct S;
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:274:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:273:5
     |
-274 |     #[main = "4400"] type T = S;
+273 |     #[main = "4400"] type T = S;
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:277:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:276:5
     |
-277 |     #[main = "4400"] impl S { }
+276 |     #[main = "4400"] impl S { }
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:262:1
     |
-263 | #[main = "4400"]
+262 | #[main = "4400"]
     | ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:284:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:283:17
     |
-284 |     mod inner { #![start="4300"] }
+283 |     mod inner { #![start="4300"] }
     |                 ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:289:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:288:5
     |
-289 |     #[start = "4300"] struct S;
+288 |     #[start = "4300"] struct S;
     |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:292:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:291:5
     |
-292 |     #[start = "4300"] type T = S;
+291 |     #[start = "4300"] type T = S;
     |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:295:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:294:5
     |
-295 |     #[start = "4300"] impl S { }
+294 |     #[start = "4300"] impl S { }
     |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:281:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:280:1
     |
-281 | #[start = "4300"]
+280 | #[start = "4300"]
     | ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:334:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:17
     |
-334 |     mod inner { #![simd="4000"] }
+333 |     mod inner { #![repr="3900"] }
     |                 ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:337:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:336:5
     |
-337 |     #[simd = "4000"] fn f() { }
+336 |     #[repr = "3900"] fn f() { }
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:342:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5
     |
-342 |     #[simd = "4000"] type T = S;
+341 |     #[repr = "3900"] type T = S;
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:344:5
     |
-345 |     #[simd = "4000"] impl S { }
+344 |     #[repr = "3900"] impl S { }
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:331:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:1
     |
-331 | #[simd = "4000"]
+330 | #[repr = "3900"]
     | ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:352:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:352:5
     |
-352 |     mod inner { #![repr="3900"] }
-    |                 ^^^^^^^^^^^^^^^
-
-warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:5
-    |
-355 |     #[repr = "3900"] fn f() { }
+352 |     #[path = "3800"] fn f() { }
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:360:5
-    |
-360 |     #[repr = "3900"] type T = S;
-    |     ^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:363:5
-    |
-363 |     #[repr = "3900"] impl S { }
-    |     ^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:349:1
-    |
-349 | #[repr = "3900"]
-    | ^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:5
-    |
-371 |     #[path = "3800"] fn f() { }
-    |     ^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:5
     |
-374 |     #[path = "3800"]  struct S;
+355 |     #[path = "3800"]  struct S;
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:358:5
     |
-377 |     #[path = "3800"] type T = S;
+358 |     #[path = "3800"] type T = S;
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5
     |
-380 |     #[path = "3800"] impl S { }
+361 |     #[path = "3800"] impl S { }
     |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:368:17
     |
-387 |     mod inner { #![abi="3700"] }
+368 |     mod inner { #![abi="3700"] }
     |                 ^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:390:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:5
     |
-390 |     #[abi = "3700"] fn f() { }
+371 |     #[abi = "3700"] fn f() { }
     |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:393:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:5
     |
-393 |     #[abi = "3700"] struct S;
+374 |     #[abi = "3700"] struct S;
     |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:396:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:5
     |
-396 |     #[abi = "3700"] type T = S;
+377 |     #[abi = "3700"] type T = S;
     |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5
     |
-399 |     #[abi = "3700"] impl S { }
+380 |     #[abi = "3700"] impl S { }
     |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:365:1
     |
-384 | #[abi = "3700"]
+365 | #[abi = "3700"]
     | ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:406:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:17
     |
-406 |     mod inner { #![automatically_derived="3600"] }
+387 |     mod inner { #![automatically_derived="3600"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:409:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:390:5
     |
-409 |     #[automatically_derived = "3600"] fn f() { }
+390 |     #[automatically_derived = "3600"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:412:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:393:5
     |
-412 |     #[automatically_derived = "3600"] struct S;
+393 |     #[automatically_derived = "3600"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:415:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:396:5
     |
-415 |     #[automatically_derived = "3600"] type T = S;
+396 |     #[automatically_derived = "3600"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:418:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:5
     |
-418 |     #[automatically_derived = "3600"] impl S { }
+399 |     #[automatically_derived = "3600"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:403:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:1
     |
-403 | #[automatically_derived = "3600"]
+384 | #[automatically_derived = "3600"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: function is marked #[no_mangle], but not exported
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:27
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:27
     |
-426 |     #[no_mangle = "3500"] fn f() { }
+407 |     #[no_mangle = "3500"] fn f() { }
     |                           -^^^^^^^^^
     |                           |
     |                           help: try making it public: `pub`
@@ -553,711 +523,711 @@ warning: function is marked #[no_mangle], but not exported
     = note: #[warn(private_no_mangle_fns)] on by default
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:439:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:17
     |
-439 |     mod inner { #![no_link="3400"] }
+420 |     mod inner { #![no_link="3400"] }
     |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5
     |
-442 |     #[no_link = "3400"] fn f() { }
+423 |     #[no_link = "3400"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:5
     |
-445 |     #[no_link = "3400"] struct S;
+426 |     #[no_link = "3400"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5
     |
-448 |     #[no_link = "3400"]type T = S;
+429 |     #[no_link = "3400"]type T = S;
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5
     |
-451 |     #[no_link = "3400"] impl S { }
+432 |     #[no_link = "3400"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:1
     |
-436 | #[no_link = "3400"]
+417 | #[no_link = "3400"]
     | ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:439:17
     |
-458 |     mod inner { #![should_panic="3200"] }
+439 |     mod inner { #![should_panic="3200"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:5
     |
-461 |     #[should_panic = "3200"] fn f() { }
+442 |     #[should_panic = "3200"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:464:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:5
     |
-464 |     #[should_panic = "3200"] struct S;
+445 |     #[should_panic = "3200"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:467:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5
     |
-467 |     #[should_panic = "3200"] type T = S;
+448 |     #[should_panic = "3200"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5
     |
-470 |     #[should_panic = "3200"] impl S { }
+451 |     #[should_panic = "3200"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:455:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:1
     |
-455 | #[should_panic = "3200"]
+436 | #[should_panic = "3200"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:477:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:17
     |
-477 |     mod inner { #![ignore="3100"] }
+458 |     mod inner { #![ignore="3100"] }
     |                 ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:5
     |
-480 |     #[ignore = "3100"] fn f() { }
+461 |     #[ignore = "3100"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:464:5
     |
-483 |     #[ignore = "3100"] struct S;
+464 |     #[ignore = "3100"] struct S;
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:467:5
     |
-486 |     #[ignore = "3100"] type T = S;
+467 |     #[ignore = "3100"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5
     |
-489 |     #[ignore = "3100"] impl S { }
+470 |     #[ignore = "3100"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:455:1
     |
-474 | #[ignore = "3100"]
+455 | #[ignore = "3100"]
     | ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:477:17
     |
-496 |     mod inner { #![no_implicit_prelude="3000"] }
+477 |     mod inner { #![no_implicit_prelude="3000"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:5
     |
-499 |     #[no_implicit_prelude = "3000"] fn f() { }
+480 |     #[no_implicit_prelude = "3000"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5
     |
-502 |     #[no_implicit_prelude = "3000"] struct S;
+483 |     #[no_implicit_prelude = "3000"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5
     |
-505 |     #[no_implicit_prelude = "3000"] type T = S;
+486 |     #[no_implicit_prelude = "3000"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5
     |
-508 |     #[no_implicit_prelude = "3000"] impl S { }
+489 |     #[no_implicit_prelude = "3000"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:1
     |
-493 | #[no_implicit_prelude = "3000"]
+474 | #[no_implicit_prelude = "3000"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:515:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17
     |
-515 |     mod inner { #![reexport_test_harness_main="2900"] }
+496 |     mod inner { #![reexport_test_harness_main="2900"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:518:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:5
     |
-518 |     #[reexport_test_harness_main = "2900"] fn f() { }
+499 |     #[reexport_test_harness_main = "2900"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:521:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5
     |
-521 |     #[reexport_test_harness_main = "2900"] struct S;
+502 |     #[reexport_test_harness_main = "2900"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5
     |
-524 |     #[reexport_test_harness_main = "2900"] type T = S;
+505 |     #[reexport_test_harness_main = "2900"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:527:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5
     |
-527 |     #[reexport_test_harness_main = "2900"] impl S { }
+508 |     #[reexport_test_harness_main = "2900"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:1
     |
-512 | #[reexport_test_harness_main = "2900"]
+493 | #[reexport_test_harness_main = "2900"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:538:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:5
     |
-538 |     #[macro_escape] fn f() { }
+519 |     #[macro_escape] fn f() { }
     |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:541:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:522:5
     |
-541 |     #[macro_escape] struct S;
+522 |     #[macro_escape] struct S;
     |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:5
     |
-544 |     #[macro_escape] type T = S;
+525 |     #[macro_escape] type T = S;
     |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
     |
-547 |     #[macro_escape] impl S { }
+528 |     #[macro_escape] impl S { }
     |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:17
     |
-555 |     mod inner { #![no_std="2600"] }
+536 |     mod inner { #![no_std="2600"] }
     |                 ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:17
     |
-555 |     mod inner { #![no_std="2600"] }
+536 |     mod inner { #![no_std="2600"] }
     |                 ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:5
     |
-559 |     #[no_std = "2600"] fn f() { }
+540 |     #[no_std = "2600"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:5
     |
-559 |     #[no_std = "2600"] fn f() { }
+540 |     #[no_std = "2600"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:563:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:5
     |
-563 |     #[no_std = "2600"] struct S;
+544 |     #[no_std = "2600"] struct S;
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:563:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:5
     |
-563 |     #[no_std = "2600"] struct S;
+544 |     #[no_std = "2600"] struct S;
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:567:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:548:5
     |
-567 |     #[no_std = "2600"] type T = S;
+548 |     #[no_std = "2600"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:567:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:548:5
     |
-567 |     #[no_std = "2600"] type T = S;
+548 |     #[no_std = "2600"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:571:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:552:5
     |
-571 |     #[no_std = "2600"] impl S { }
+552 |     #[no_std = "2600"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:571:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:552:5
     |
-571 |     #[no_std = "2600"] impl S { }
+552 |     #[no_std = "2600"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:1
     |
-551 | #[no_std = "2600"]
+532 | #[no_std = "2600"]
     | ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:1
     |
-551 | #[no_std = "2600"]
+532 | #[no_std = "2600"]
     | ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:17
     |
-711 |     mod inner { #![crate_name="0900"] }
+692 |     mod inner { #![crate_name="0900"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:17
     |
-711 |     mod inner { #![crate_name="0900"] }
+692 |     mod inner { #![crate_name="0900"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5
     |
-715 |     #[crate_name = "0900"] fn f() { }
+696 |     #[crate_name = "0900"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5
     |
-715 |     #[crate_name = "0900"] fn f() { }
+696 |     #[crate_name = "0900"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
     |
-719 |     #[crate_name = "0900"] struct S;
+700 |     #[crate_name = "0900"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
     |
-719 |     #[crate_name = "0900"] struct S;
+700 |     #[crate_name = "0900"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:723:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
     |
-723 |     #[crate_name = "0900"] type T = S;
+704 |     #[crate_name = "0900"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:723:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
     |
-723 |     #[crate_name = "0900"] type T = S;
+704 |     #[crate_name = "0900"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
     |
-727 |     #[crate_name = "0900"] impl S { }
+708 |     #[crate_name = "0900"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
     |
-727 |     #[crate_name = "0900"] impl S { }
+708 |     #[crate_name = "0900"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:1
     |
-707 | #[crate_name = "0900"]
+688 | #[crate_name = "0900"]
     | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:1
     |
-707 | #[crate_name = "0900"]
+688 | #[crate_name = "0900"]
     | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:17
     |
-736 |     mod inner { #![crate_type="0800"] }
+717 |     mod inner { #![crate_type="0800"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:17
     |
-736 |     mod inner { #![crate_type="0800"] }
+717 |     mod inner { #![crate_type="0800"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
     |
-740 |     #[crate_type = "0800"] fn f() { }
+721 |     #[crate_type = "0800"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
     |
-740 |     #[crate_type = "0800"] fn f() { }
+721 |     #[crate_type = "0800"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
     |
-744 |     #[crate_type = "0800"] struct S;
+725 |     #[crate_type = "0800"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
     |
-744 |     #[crate_type = "0800"] struct S;
+725 |     #[crate_type = "0800"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:748:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
     |
-748 |     #[crate_type = "0800"] type T = S;
+729 |     #[crate_type = "0800"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:748:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
     |
-748 |     #[crate_type = "0800"] type T = S;
+729 |     #[crate_type = "0800"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:752:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
     |
-752 |     #[crate_type = "0800"] impl S { }
+733 |     #[crate_type = "0800"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:752:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
     |
-752 |     #[crate_type = "0800"] impl S { }
+733 |     #[crate_type = "0800"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:1
     |
-732 | #[crate_type = "0800"]
+713 | #[crate_type = "0800"]
     | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:1
     |
-732 | #[crate_type = "0800"]
+713 | #[crate_type = "0800"]
     | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:17
     |
-761 |     mod inner { #![feature(x0600)] }
+742 |     mod inner { #![feature(x0600)] }
     |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:17
     |
-761 |     mod inner { #![feature(x0600)] }
+742 |     mod inner { #![feature(x0600)] }
     |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
     |
-765 |     #[feature(x0600)] fn f() { }
+746 |     #[feature(x0600)] fn f() { }
     |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
     |
-765 |     #[feature(x0600)] fn f() { }
+746 |     #[feature(x0600)] fn f() { }
     |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:769:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5
     |
-769 |     #[feature(x0600)] struct S;
+750 |     #[feature(x0600)] struct S;
     |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:769:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5
     |
-769 |     #[feature(x0600)] struct S;
+750 |     #[feature(x0600)] struct S;
     |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5
     |
-773 |     #[feature(x0600)] type T = S;
+754 |     #[feature(x0600)] type T = S;
     |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5
     |
-773 |     #[feature(x0600)] type T = S;
+754 |     #[feature(x0600)] type T = S;
     |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:777:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
     |
-777 |     #[feature(x0600)] impl S { }
+758 |     #[feature(x0600)] impl S { }
     |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:777:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
     |
-777 |     #[feature(x0600)] impl S { }
+758 |     #[feature(x0600)] impl S { }
     |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:1
     |
-757 | #[feature(x0600)]
+738 | #[feature(x0600)]
     | ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:1
     |
-757 | #[feature(x0600)]
+738 | #[feature(x0600)]
     | ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:787:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:17
     |
-787 |     mod inner { #![no_main="0400"] }
+768 |     mod inner { #![no_main="0400"] }
     |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:787:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:768:17
     |
-787 |     mod inner { #![no_main="0400"] }
+768 |     mod inner { #![no_main="0400"] }
     |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:791:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:5
     |
-791 |     #[no_main = "0400"] fn f() { }
+772 |     #[no_main = "0400"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:791:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:5
     |
-791 |     #[no_main = "0400"] fn f() { }
+772 |     #[no_main = "0400"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:795:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5
     |
-795 |     #[no_main = "0400"] struct S;
+776 |     #[no_main = "0400"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:795:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5
     |
-795 |     #[no_main = "0400"] struct S;
+776 |     #[no_main = "0400"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:799:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5
     |
-799 |     #[no_main = "0400"] type T = S;
+780 |     #[no_main = "0400"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:799:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5
     |
-799 |     #[no_main = "0400"] type T = S;
+780 |     #[no_main = "0400"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:803:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5
     |
-803 |     #[no_main = "0400"] impl S { }
+784 |     #[no_main = "0400"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:803:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5
     |
-803 |     #[no_main = "0400"] impl S { }
+784 |     #[no_main = "0400"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:783:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:1
     |
-783 | #[no_main = "0400"]
+764 | #[no_main = "0400"]
     | ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:783:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:1
     |
-783 | #[no_main = "0400"]
+764 | #[no_main = "0400"]
     | ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:825:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:17
     |
-825 |     mod inner { #![recursion_limit="0200"] }
+806 |     mod inner { #![recursion_limit="0200"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:825:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:17
     |
-825 |     mod inner { #![recursion_limit="0200"] }
+806 |     mod inner { #![recursion_limit="0200"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:829:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5
     |
-829 |     #[recursion_limit="0200"] fn f() { }
+810 |     #[recursion_limit="0200"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:829:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5
     |
-829 |     #[recursion_limit="0200"] fn f() { }
+810 |     #[recursion_limit="0200"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:833:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
     |
-833 |     #[recursion_limit="0200"] struct S;
+814 |     #[recursion_limit="0200"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:833:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
     |
-833 |     #[recursion_limit="0200"] struct S;
+814 |     #[recursion_limit="0200"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:837:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
     |
-837 |     #[recursion_limit="0200"] type T = S;
+818 |     #[recursion_limit="0200"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:837:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
     |
-837 |     #[recursion_limit="0200"] type T = S;
+818 |     #[recursion_limit="0200"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:841:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
     |
-841 |     #[recursion_limit="0200"] impl S { }
+822 |     #[recursion_limit="0200"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:841:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
     |
-841 |     #[recursion_limit="0200"] impl S { }
+822 |     #[recursion_limit="0200"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:821:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:1
     |
-821 | #[recursion_limit="0200"]
+802 | #[recursion_limit="0200"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:821:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:1
     |
-821 | #[recursion_limit="0200"]
+802 | #[recursion_limit="0200"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:850:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:17
     |
-850 |     mod inner { #![type_length_limit="0100"] }
+831 |     mod inner { #![type_length_limit="0100"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:850:17
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:17
     |
-850 |     mod inner { #![type_length_limit="0100"] }
+831 |     mod inner { #![type_length_limit="0100"] }
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:854:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:835:5
     |
-854 |     #[type_length_limit="0100"] fn f() { }
+835 |     #[type_length_limit="0100"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:854:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:835:5
     |
-854 |     #[type_length_limit="0100"] fn f() { }
+835 |     #[type_length_limit="0100"] fn f() { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:858:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5
     |
-858 |     #[type_length_limit="0100"] struct S;
+839 |     #[type_length_limit="0100"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:858:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5
     |
-858 |     #[type_length_limit="0100"] struct S;
+839 |     #[type_length_limit="0100"] struct S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:862:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5
     |
-862 |     #[type_length_limit="0100"] type T = S;
+843 |     #[type_length_limit="0100"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:862:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5
     |
-862 |     #[type_length_limit="0100"] type T = S;
+843 |     #[type_length_limit="0100"] type T = S;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:866:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
     |
-866 |     #[type_length_limit="0100"] impl S { }
+847 |     #[type_length_limit="0100"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:866:5
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
     |
-866 |     #[type_length_limit="0100"] impl S { }
+847 |     #[type_length_limit="0100"] impl S { }
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:846:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:1
     |
-846 | #[type_length_limit="0100"]
+827 | #[type_length_limit="0100"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:846:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:1
     |
-846 | #[type_length_limit="0100"]
+827 | #[type_length_limit="0100"]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
@@ -1293,62 +1263,56 @@ warning: unused attribute
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:1
    |
-63 | #![simd                       = "4000"] //~ WARN unused attribute
+63 | #![repr                       = "3900"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
    |
-64 | #![repr                       = "3900"] //~ WARN unused attribute
+64 | #![path                       = "3800"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1
    |
-65 | #![path                       = "3800"] //~ WARN unused attribute
+65 | #![abi                        = "3700"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
    |
-66 | #![abi                        = "3700"] //~ WARN unused attribute
+66 | #![automatically_derived      = "3600"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:68:1
    |
-67 | #![automatically_derived      = "3600"] //~ WARN unused attribute
+68 | #![no_link                    = "3400"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:70:1
    |
-69 | #![no_link                    = "3400"] //~ WARN unused attribute
+70 | #![should_panic               = "3200"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:71:1
    |
-71 | #![should_panic               = "3200"] //~ WARN unused attribute
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
-   |
-72 | #![ignore                     = "3100"] //~ WARN unused attribute
+71 | #![ignore                     = "3100"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:78:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:77:1
    |
-78 | #![proc_macro_derive          = "2500"] //~ WARN unused attribute
+77 | #![proc_macro_derive          = "2500"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: compilation successful
-   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:877:1
+   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:858:1
     |
-877 | / fn main() { //~ ERROR compilation successful
-878 | |     println!("Hello World");
-879 | | }
+858 | / fn main() { //~ ERROR compilation successful
+859 | |     println!("Hello World");
+860 | | }
     | |_^
 
index 92bda4d0446d9490455942f8f8302d967574190c..444c4176994c593a1eeee61592294e373f289a0c 100644 (file)
@@ -1,3 +1,5 @@
+error[E0601]: main function not found
+
 error[E0518]: attribute should be applied to function
   --> $DIR/issue-43106-gating-of-inline.rs:21:1
    |
@@ -37,7 +39,5 @@ error[E0518]: attribute should be applied to function
 35 |     #[inline = "2100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^ ---------- not a function
 
-error[E0601]: main function not found
-
 error: aborting due to 6 previous errors
 
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
diff --git a/src/test/ui/issue-46983.rs b/src/test/ui/issue-46983.rs
new file mode 100644 (file)
index 0000000..ebbd474
--- /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.
+
+#![feature(nll)]
+
+fn foo(x: &u32) -> &'static u32 {
+    &*x
+    //~^ ERROR explicit lifetime required in the type of `x` [E0621]
+}
+
+fn main() {}
diff --git a/src/test/ui/issue-46983.stderr b/src/test/ui/issue-46983.stderr
new file mode 100644 (file)
index 0000000..ac8417a
--- /dev/null
@@ -0,0 +1,10 @@
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/issue-46983.rs:14:5
+   |
+13 | fn foo(x: &u32) -> &'static u32 {
+   |        - consider changing the type of `x` to `&'static u32`
+14 |     &*x
+   |     ^^^ lifetime `'static` required
+
+error: aborting due to previous error
+
index 3f56dfe5af48dbe9cfd2cc9ecc3c08eeb3d24f4c..ac21fe25bd112e5a9183bb737012f15b9d06704c 100644 (file)
@@ -18,7 +18,7 @@
 fn foo(x: &u32) -> &'static u32 {
     &*x
         //~^ WARN not reporting region error due to -Znll
-        //~| ERROR does not outlive free region
+        //~| ERROR explicit lifetime required in the type of `x`
 }
 
 fn main() { }
index 6648e38e7dea8c44f21f746feca5a2e298db305c..2a1122cbda7a947ed7dbbac945128018d8f5a237 100644 (file)
@@ -4,11 +4,13 @@ warning: not reporting region error due to -Znll
 19 |     &*x
    |     ^^^
 
-error: free region `ReFree(DefId(0/0:3 ~ region_lbr_anon_does_not_outlive_static[317d]::foo[0]), BrAnon(0))` does not outlive free region `ReStatic`
+error[E0621]: explicit lifetime required in the type of `x`
   --> $DIR/region-lbr-anon-does-not-outlive-static.rs:19:5
    |
+18 | fn foo(x: &u32) -> &'static u32 {
+   |        - consider changing the type of `x` to `&ReStatic u32`
 19 |     &*x
-   |     ^^^
+   |     ^^^ lifetime `ReStatic` required
 
 error: aborting due to previous error
 
index 57ecddb80ab3db250266a36a38ca64c29266b1a1..09ce42ce1b5519899cdab30e1589a87fb081fddd 100644 (file)
@@ -22,7 +22,7 @@ fn foo(s: &mut (i32,)) -> i32 {
 
 fn bar(s: &Box<(i32,)>) -> &'static i32 {
     // FIXME(#46983): error message should be better
-    &s.0 //~ ERROR free region `` does not outlive free region `'static`
+    &s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621]
 }
 
 fn main() {
index 68cc87ef4073418317d90baff9b9216f2e92c903..4f0bd88f988ae3e370c6c1e71e9bab31d572b303 100644 (file)
@@ -7,11 +7,14 @@ error[E0506]: cannot assign to `*s` because it is borrowed
 19 |     *s = (2,); //~ ERROR cannot assign to `*s`
    |     ^^^^^^^^^ assignment to borrowed `*s` occurs here
 
-error: free region `` does not outlive free region `'static`
+error[E0621]: explicit lifetime required in the type of `s`
   --> $DIR/guarantor-issue-46974.rs:25:5
    |
-25 |     &s.0 //~ ERROR free region `` does not outlive free region `'static`
-   |     ^^^^
+23 | fn bar(s: &Box<(i32,)>) -> &'static i32 {
+   |        - consider changing the type of `s` to `&'static std::boxed::Box<(i32,)>`
+24 |     // FIXME(#46983): error message should be better
+25 |     &s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621]
+   |     ^^^^ lifetime `'static` required
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/issue-47022.rs b/src/test/ui/nll/issue-47022.rs
new file mode 100644 (file)
index 0000000..a7362c3
--- /dev/null
@@ -0,0 +1,47 @@
+// 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.
+
+// must-compile-successfully
+
+#![allow(warnings)]
+#![feature(nll)]
+
+struct LoadedObject {
+    bodies: Vec<Body>,
+    color: Color,
+}
+
+struct Body;
+
+#[derive(Clone)]
+struct Color;
+
+struct Graphic {
+    color: Color,
+}
+
+fn convert(objects: Vec<LoadedObject>) -> (Vec<Body>, Vec<Graphic>) {
+    objects
+        .into_iter()
+        .flat_map(|LoadedObject { bodies, color, .. }| {
+            bodies.into_iter().map(move |body| {
+                (
+                    body,
+                    Graphic {
+                        color: color.clone(),
+                    },
+                )
+            })
+        })
+        .unzip()
+}
+
+fn main() {}
+
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;
diff --git a/src/test/ui/obsolete-syntax-impl-for-dotdot.rs b/src/test/ui/obsolete-syntax-impl-for-dotdot.rs
new file mode 100644 (file)
index 0000000..914621a
--- /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.
+
+trait Trait1 {}
+trait Trait2 {}
+
+#[cfg(not_enabled)]
+impl Trait1 for .. {}
+
+impl Trait2 for .. {} //~ ERROR `impl Trait for .. {}` is an obsolete syntax
+
+fn main() {}
diff --git a/src/test/ui/obsolete-syntax-impl-for-dotdot.stderr b/src/test/ui/obsolete-syntax-impl-for-dotdot.stderr
new file mode 100644 (file)
index 0000000..aa0af84
--- /dev/null
@@ -0,0 +1,10 @@
+error: `impl Trait for .. {}` is an obsolete syntax
+  --> $DIR/obsolete-syntax-impl-for-dotdot.rs:17:1
+   |
+17 | impl Trait2 for .. {} //~ ERROR `impl Trait for .. {}` is an obsolete syntax
+   | ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `auto trait Trait {}` instead
+
+error: aborting due to previous error
+
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
diff --git a/src/test/ui/span/impl-parsing.rs b/src/test/ui/span/impl-parsing.rs
new file mode 100644 (file)
index 0000000..064e3c3
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -Z parse-only -Z continue-parse-after-error
+
+impl ! {} // OK
+impl ! where u8: Copy {} // OK
+
+impl Trait Type {} //~ ERROR missing `for` in a trait impl
+impl Trait .. {} //~ ERROR missing `for` in a trait impl
+impl ?Sized for Type {} //~ ERROR expected a trait, found type
+impl ?Sized for .. {} //~ ERROR expected a trait, found type
+
+default unsafe FAIL //~ ERROR expected `impl`, found `FAIL`
diff --git a/src/test/ui/span/impl-parsing.stderr b/src/test/ui/span/impl-parsing.stderr
new file mode 100644 (file)
index 0000000..9126384
--- /dev/null
@@ -0,0 +1,32 @@
+error: missing `for` in a trait impl
+  --> $DIR/impl-parsing.rs:16:11
+   |
+16 | impl Trait Type {} //~ ERROR missing `for` in a trait impl
+   |           ^
+
+error: missing `for` in a trait impl
+  --> $DIR/impl-parsing.rs:17:11
+   |
+17 | impl Trait .. {} //~ ERROR missing `for` in a trait impl
+   |           ^
+
+error: expected a trait, found type
+  --> $DIR/impl-parsing.rs:18:6
+   |
+18 | impl ?Sized for Type {} //~ ERROR expected a trait, found type
+   |      ^^^^^^
+
+error: expected a trait, found type
+  --> $DIR/impl-parsing.rs:19:6
+   |
+19 | impl ?Sized for .. {} //~ ERROR expected a trait, found type
+   |      ^^^^^^
+
+error: expected `impl`, found `FAIL`
+  --> $DIR/impl-parsing.rs:21:16
+   |
+21 | default unsafe FAIL //~ ERROR expected `impl`, found `FAIL`
+   |                ^^^^ expected `impl` here
+
+error: aborting due to 5 previous errors
+
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/target-feature-wrong.rs b/src/test/ui/target-feature-wrong.rs
new file mode 100644 (file)
index 0000000..e70d549
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-arm
+// ignore-aarch64
+// ignore-wasm
+// ignore-emscripten
+
+#![feature(target_feature)]
+
+#[target_feature = "+sse2"]
+//~^ WARN: deprecated
+#[target_feature(enable = "foo")]
+//~^ ERROR: not valid for this target
+#[target_feature(bar)]
+//~^ ERROR: only accepts sub-keys
+#[target_feature(disable = "baz")]
+//~^ ERROR: only accepts sub-keys
+unsafe fn foo() {}
+
+#[target_feature(enable = "sse2")]
+//~^ ERROR: can only be applied to `unsafe` function
+fn bar() {}
+
+fn main() {
+    unsafe {
+        foo();
+        bar();
+    }
+}
diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr
new file mode 100644 (file)
index 0000000..c5534bf
--- /dev/null
@@ -0,0 +1,32 @@
+warning: #[target_feature = ".."] is deprecated and will eventually be removed, use #[target_feature(enable = "..")] instead
+  --> $DIR/target-feature-wrong.rs:18:1
+   |
+18 | #[target_feature = "+sse2"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the feature named `foo` is not valid for this target
+  --> $DIR/target-feature-wrong.rs:20:18
+   |
+20 | #[target_feature(enable = "foo")]
+   |                  ^^^^^^^^^^^^^^
+
+error: #[target_feature(..)] only accepts sub-keys of `enable` currently
+  --> $DIR/target-feature-wrong.rs:22:18
+   |
+22 | #[target_feature(bar)]
+   |                  ^^^
+
+error: #[target_feature(..)] only accepts sub-keys of `enable` currently
+  --> $DIR/target-feature-wrong.rs:24:18
+   |
+24 | #[target_feature(disable = "baz")]
+   |                  ^^^^^^^^^^^^^^^
+
+error: #[target_feature(..)] can only be applied to `unsafe` function
+  --> $DIR/target-feature-wrong.rs:28:1
+   |
+28 | #[target_feature(enable = "sse2")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 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
+
diff --git a/src/test/ui/typeck-default-trait-impl-outside-crate.rs b/src/test/ui/typeck-default-trait-impl-outside-crate.rs
deleted file mode 100644 (file)
index ff0446e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(optin_builtin_traits)]
-
-#[allow(auto_impl)]
-impl Copy for .. {} //~ ERROR E0318
-fn main() {}
diff --git a/src/test/ui/typeck-default-trait-impl-outside-crate.stderr b/src/test/ui/typeck-default-trait-impl-outside-crate.stderr
deleted file mode 100644 (file)
index 6b50fde..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0318]: cannot create default implementations for traits outside the crate they're defined in; define a new trait instead
-  --> $DIR/typeck-default-trait-impl-outside-crate.rs:14:6
-   |
-14 | impl Copy for .. {} //~ ERROR E0318
-   |      ^^^^ `Copy` trait not defined in this crate
-
-error: aborting due to previous error
-
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 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 {
index fdbcfd10bde7cc2377be9925e63636de7ad98f30..8071f07d811959975e8d409d06a674c82102dd7a 100644 (file)
@@ -168,8 +168,8 @@ fn find_test_mod(contents: &str) -> usize {
         let prev_newline_idx = contents[..prev_newline_idx].rfind('\n');
         if let Some(nl) = prev_newline_idx {
             let prev_line = &contents[nl + 1 .. mod_tests_idx];
-            let emcc_cfg = "cfg(all(test, not(target_os";
-            if prev_line.contains(emcc_cfg) {
+            if prev_line.contains("cfg(all(test, not(target_os")
+                || prev_line.contains("cfg(all(test, not(any(target_os") {
                 nl
             } else {
                 mod_tests_idx