]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #42236 - citizen428:docs/unchecked-indexing-slicing, r=GuillaumeGomez
authorCorey Farwell <coreyf@rwell.org>
Fri, 26 May 2017 14:20:29 +0000 (10:20 -0400)
committerGitHub <noreply@github.com>
Fri, 26 May 2017 14:20:29 +0000 (10:20 -0400)
Update documentation for indexing/slicing methods

See #39911

r? @steveklabnik

380 files changed:
src/Cargo.lock
src/bootstrap/bootstrap.py
src/bootstrap/dist.rs
src/ci/docker/dist-i686-linux/build-openssl.sh
src/ci/docker/dist-x86_64-linux/build-openssl.sh
src/ci/init_repo.sh
src/doc/unstable-book/src/SUMMARY.md
src/doc/unstable-book/src/language-features/abi-thiscall.md [new file with mode: 0644]
src/doc/unstable-book/src/language-features/decl-macro.md [new file with mode: 0644]
src/doc/unstable-book/src/language-features/relaxed-adts.md [deleted file]
src/doc/unstable-book/src/library-features/step-trait.md
src/etc/make-win-dist.py [deleted file]
src/libcollections/range.rs
src/libcollections/str.rs
src/libcore/iter/mod.rs
src/libcore/iter/range.rs
src/libcore/marker.rs
src/libcore/ops.rs
src/libcore/slice/mod.rs
src/libcore/str/mod.rs
src/libcore/tests/lib.rs
src/libcore/tests/ops.rs
src/librustc/hir/def.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/def_collector.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/ich/impls_hir.rs
src/librustc/ich/impls_syntax.rs
src/librustc/lib.rs
src/librustc/lint/context.rs
src/librustc/middle/effect.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/ty/mod.rs
src/librustc_back/target/arm_base.rs
src/librustc_const_eval/check_match.rs
src/librustc_driver/lib.rs
src/librustc_errors/lib.rs
src/librustc_llvm/Cargo.lock [deleted file]
src/librustc_llvm/ffi.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/schema.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/consts.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/lib.rs
src/librustc_trans/abi.rs
src/librustc_trans/mir/block.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustdoc/clean/inline.rs
src/librustdoc/lib.rs
src/librustdoc/visit_ast.rs
src/libstd/ffi/os_str.rs
src/libstd/rt.rs
src/libstd/sync/mpsc/mpsc_queue.rs
src/libstd/sync/mpsc/spsc_queue.rs
src/libstd/sys/redox/thread_local.rs
src/libstd/thread/mod.rs
src/libsyntax/abi.rs
src/libsyntax/ast.rs
src/libsyntax/attr.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/lexer/unicode_chars.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/std_inject.rs
src/libsyntax/test.rs
src/libsyntax/tokenstream.rs
src/libsyntax/visit.rs
src/libsyntax_ext/deriving/generic/ty.rs
src/libsyntax_ext/deriving/mod.rs
src/libsyntax_ext/env.rs
src/libsyntax_ext/format.rs
src/libsyntax_ext/proc_macro_registrar.rs
src/libsyntax_pos/hygiene.rs
src/libsyntax_pos/symbol.rs
src/test/compile-fail-fulldeps/proc-macro/feature-gate-proc_macro.rs
src/test/compile-fail/E0229.rs
src/test/compile-fail/feature-gate-abi.rs
src/test/compile-fail/feature-gate-decl_macro.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-global_asm.rs
src/test/compile-fail/hygiene/globs.rs [new file with mode: 0644]
src/test/compile-fail/hygiene/nested_macro_privacy.rs [new file with mode: 0644]
src/test/compile-fail/hygiene/no_implicit_prelude.rs [new file with mode: 0644]
src/test/compile-fail/hygiene/privacy.rs [new file with mode: 0644]
src/test/compile-fail/hygiene/trait_items.rs [new file with mode: 0644]
src/test/compile-fail/issue-23543.rs
src/test/compile-fail/issue-23544.rs
src/test/compile-fail/issue-36379.rs [new file with mode: 0644]
src/test/compile-fail/issue-37550.rs [new file with mode: 0644]
src/test/compile-fail/issue-37665.rs [new file with mode: 0644]
src/test/compile-fail/issue-38160.rs [new file with mode: 0644]
src/test/compile-fail/issue-38954.rs [new file with mode: 0644]
src/test/compile-fail/issue-39362.rs [new file with mode: 0644]
src/test/compile-fail/numeric-fields-feature-gate.rs [deleted file]
src/test/compile-fail/numeric-fields.rs
src/test/compile-fail/union/union-unsafe.rs
src/test/parse-fail/unicode-chars.rs
src/test/run-pass/auxiliary/issue_42007_s.rs [new file with mode: 0644]
src/test/run-pass/extern-thiscall.rs [new file with mode: 0644]
src/test/run-pass/hygiene/arguments.rs [new file with mode: 0644]
src/test/run-pass/hygiene/auxiliary/intercrate.rs [new file with mode: 0644]
src/test/run-pass/hygiene/fields.rs [new file with mode: 0644]
src/test/run-pass/hygiene/impl_items.rs [new file with mode: 0644]
src/test/run-pass/hygiene/intercrate.rs [new file with mode: 0644]
src/test/run-pass/hygiene/items.rs [new file with mode: 0644]
src/test/run-pass/hygiene/lexical.rs [new file with mode: 0644]
src/test/run-pass/hygiene/trait_items.rs [new file with mode: 0644]
src/test/run-pass/hygiene/ty_params.rs [new file with mode: 0644]
src/test/run-pass/issue-16671.rs
src/test/run-pass/issue-42007.rs [new file with mode: 0644]
src/test/run-pass/numeric-fields.rs
src/test/run-pass/range_inclusive.rs
src/test/ui/borrowck/borrowck-in-static.stderr
src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
src/test/ui/check_match/issue-35609.stderr
src/test/ui/codemap_tests/bad-format-args.stderr
src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr
src/test/ui/codemap_tests/empty_span.stderr
src/test/ui/codemap_tests/huge_multispan_highlight.stderr
src/test/ui/codemap_tests/issue-11715.stderr
src/test/ui/codemap_tests/issue-28308.stderr
src/test/ui/codemap_tests/one_line.stderr
src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
src/test/ui/codemap_tests/overlapping_spans.stderr
src/test/ui/codemap_tests/tab.stderr
src/test/ui/codemap_tests/unicode.stderr
src/test/ui/coercion-missing-tail-expected-type.stderr
src/test/ui/compare-method/proj-outlives-region.stderr
src/test/ui/compare-method/region-extra-2.stderr
src/test/ui/compare-method/region-extra.stderr
src/test/ui/compare-method/region-unrelated.stderr
src/test/ui/compare-method/reordered-type-param.stderr
src/test/ui/compare-method/trait-bound-on-type-parameter.stderr
src/test/ui/compare-method/traits-misc-mismatch-1.stderr
src/test/ui/compare-method/traits-misc-mismatch-2.stderr
src/test/ui/cross-crate-macro-backtrace/main.stderr
src/test/ui/did_you_mean/E0178.stderr
src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
src/test/ui/did_you_mean/issue-31424.stderr
src/test/ui/did_you_mean/issue-34126.stderr
src/test/ui/did_you_mean/issue-34337.stderr
src/test/ui/did_you_mean/issue-35937.stderr
src/test/ui/did_you_mean/issue-36798.stderr
src/test/ui/did_you_mean/issue-36798_unknown_field.stderr
src/test/ui/did_you_mean/issue-37139.stderr
src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr
src/test/ui/did_you_mean/issue-38147-1.stderr
src/test/ui/did_you_mean/issue-38147-2.stderr
src/test/ui/did_you_mean/issue-38147-3.stderr
src/test/ui/did_you_mean/issue-38147-4.stderr
src/test/ui/did_you_mean/issue-39544.stderr
src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
src/test/ui/did_you_mean/issue-40006.stderr
src/test/ui/did_you_mean/issue-40396.stderr
src/test/ui/did_you_mean/issue-40823.stderr
src/test/ui/did_you_mean/issue-41679.stderr
src/test/ui/did_you_mean/recursion_limit.stderr
src/test/ui/did_you_mean/recursion_limit_deref.stderr
src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr
src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr
src/test/ui/dropck/dropck-eyepatch-reorder.stderr
src/test/ui/dropck/dropck-eyepatch.stderr
src/test/ui/fmt/format-string-error.stderr
src/test/ui/fn_once-moved.stderr
src/test/ui/impl-trait/equality.stderr
src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
src/test/ui/issue-37311-type-length-limit/issue-37311.stderr
src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr
src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr
src/test/ui/issue-41652/issue_41652.stderr
src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr
src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr
src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr
src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr
src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr
src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr
src/test/ui/lifetimes/borrowck-let-suggestion.stderr
src/test/ui/lint/command-line-lint-group-deny.stderr
src/test/ui/lint/command-line-lint-group-forbid.stderr
src/test/ui/lint/lint-group-style.stderr
src/test/ui/loop-break-value-no-repeat.stderr
src/test/ui/macros/bad_hello.stderr
src/test/ui/macros/format-foreign.stderr
src/test/ui/macros/macro-backtrace-invalid-internals.stderr
src/test/ui/macros/macro-backtrace-nested.stderr
src/test/ui/macros/macro-backtrace-println.stderr
src/test/ui/mismatched_types/E0053.stderr
src/test/ui/mismatched_types/E0281.stderr
src/test/ui/mismatched_types/E0409.stderr
src/test/ui/mismatched_types/abridged.stderr
src/test/ui/mismatched_types/binops.stderr
src/test/ui/mismatched_types/cast-rfc0401.stderr
src/test/ui/mismatched_types/closure-arg-count.stderr
src/test/ui/mismatched_types/closure-mismatch.stderr
src/test/ui/mismatched_types/const-fn-in-trait.stderr
src/test/ui/mismatched_types/fn-variance-1.stderr
src/test/ui/mismatched_types/issue-19109.stderr
src/test/ui/mismatched_types/issue-26480.stderr
src/test/ui/mismatched_types/issue-35030.stderr
src/test/ui/mismatched_types/issue-36053-2.stderr
src/test/ui/mismatched_types/issue-38371.stderr
src/test/ui/mismatched_types/main.stderr
src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
src/test/ui/mismatched_types/overloaded-calls-bad.stderr
src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
src/test/ui/missing-items/issue-40221.stderr
src/test/ui/missing-items/m2.stderr
src/test/ui/missing-items/missing-type-parameter.stderr
src/test/ui/pub/pub-restricted-error-fn.stderr
src/test/ui/pub/pub-restricted-error.stderr
src/test/ui/pub/pub-restricted-non-path.stderr
src/test/ui/pub/pub-restricted.stderr
src/test/ui/reachable/expr_add.stderr
src/test/ui/reachable/expr_again.stderr
src/test/ui/reachable/expr_array.stderr
src/test/ui/reachable/expr_assign.stderr
src/test/ui/reachable/expr_block.stderr
src/test/ui/reachable/expr_box.stderr
src/test/ui/reachable/expr_call.stderr
src/test/ui/reachable/expr_cast.stderr
src/test/ui/reachable/expr_if.stderr
src/test/ui/reachable/expr_loop.stderr
src/test/ui/reachable/expr_match.stderr
src/test/ui/reachable/expr_method.stderr
src/test/ui/reachable/expr_repeat.stderr
src/test/ui/reachable/expr_return.stderr
src/test/ui/reachable/expr_struct.stderr
src/test/ui/reachable/expr_tup.stderr
src/test/ui/reachable/expr_type.stderr
src/test/ui/reachable/expr_unary.stderr
src/test/ui/reachable/expr_while.stderr
src/test/ui/regions-fn-subtyping-return-static.stderr
src/test/ui/resolve/enums-are-namespaced-xc.stderr
src/test/ui/resolve/issue-14254.stderr
src/test/ui/resolve/issue-16058.stderr
src/test/ui/resolve/issue-17518.stderr
src/test/ui/resolve/issue-18252.stderr
src/test/ui/resolve/issue-19452.stderr
src/test/ui/resolve/issue-23305.stderr
src/test/ui/resolve/issue-2356.stderr
src/test/ui/resolve/issue-24968.stderr
src/test/ui/resolve/issue-33876.stderr
src/test/ui/resolve/issue-3907-2.stderr
src/test/ui/resolve/issue-39226.stderr
src/test/ui/resolve/issue-5035-2.stderr
src/test/ui/resolve/issue-6702.stderr
src/test/ui/resolve/levenshtein.stderr
src/test/ui/resolve/privacy-struct-ctor.stderr
src/test/ui/resolve/resolve-assoc-suggestions.stderr
src/test/ui/resolve/resolve-hint-macro.stderr
src/test/ui/resolve/resolve-speculative-adjustment.stderr
src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
src/test/ui/resolve/token-error-correct-2.stderr
src/test/ui/resolve/token-error-correct-3.stderr
src/test/ui/resolve/token-error-correct.stderr
src/test/ui/resolve/tuple-struct-alias.stderr
src/test/ui/resolve/unresolved_static_type_field.stderr
src/test/ui/span/E0046.stderr
src/test/ui/span/E0057.stderr
src/test/ui/span/E0072.stderr
src/test/ui/span/E0204.stderr
src/test/ui/span/E0493.stderr
src/test/ui/span/E0535.stderr
src/test/ui/span/E0536.stderr
src/test/ui/span/E0537.stderr
src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr
src/test/ui/span/borrowck-fn-in-const-b.stderr
src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
src/test/ui/span/borrowck-object-mutability.stderr
src/test/ui/span/borrowck-ref-into-rvalue.stderr
src/test/ui/span/coerce-suggestions.stderr
src/test/ui/span/destructor-restrictions.stderr
src/test/ui/span/dropck-object-cycle.stderr
src/test/ui/span/dropck_arr_cycle_checked.stderr
src/test/ui/span/dropck_direct_cycle_with_drop.stderr
src/test/ui/span/dropck_misc_variants.stderr
src/test/ui/span/dropck_vec_cycle_checked.stderr
src/test/ui/span/impl-wrong-item-for-trait.stderr
src/test/ui/span/issue-11925.stderr
src/test/ui/span/issue-15480.stderr
src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
src/test/ui/span/issue-23729.stderr
src/test/ui/span/issue-23827.stderr
src/test/ui/span/issue-24356.stderr
src/test/ui/span/issue-24690.stderr
src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
src/test/ui/span/issue-24805-dropck-trait-has-items.stderr
src/test/ui/span/issue-24895-copy-clone-dropck.stderr
src/test/ui/span/issue-25199.stderr
src/test/ui/span/issue-26656.stderr
src/test/ui/span/issue-27522.stderr
src/test/ui/span/issue-29106.stderr
src/test/ui/span/issue-29595.stderr
src/test/ui/span/issue-33884.stderr
src/test/ui/span/issue-34264.stderr
src/test/ui/span/issue-36530.stderr
src/test/ui/span/issue-36537.stderr
src/test/ui/span/issue-37767.stderr
src/test/ui/span/issue-39018.stderr
src/test/ui/span/issue-39698.stderr
src/test/ui/span/issue-40157.stderr
src/test/ui/span/issue-7575.stderr
src/test/ui/span/issue28498-reject-ex1.stderr
src/test/ui/span/issue28498-reject-lifetime-param.stderr
src/test/ui/span/issue28498-reject-passed-to-fn.stderr
src/test/ui/span/issue28498-reject-trait-bound.stderr
src/test/ui/span/lint-unused-unsafe.stderr
src/test/ui/span/loan-extend.stderr
src/test/ui/span/move-closure.stderr
src/test/ui/span/multiline-span-E0072.stderr
src/test/ui/span/multiline-span-simple.stderr
src/test/ui/span/mut-arg-hint.stderr
src/test/ui/span/mut-ptr-cant-outlive-ref.stderr
src/test/ui/span/pub-struct-field.stderr
src/test/ui/span/range-2.stderr
src/test/ui/span/recursive-type-field.stderr
src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr
src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
src/test/ui/span/regions-close-over-type-parameter-2.stderr
src/test/ui/span/regions-escape-loop-via-variable.stderr
src/test/ui/span/regions-escape-loop-via-vec.stderr
src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr
src/test/ui/span/send-is-not-static-ensures-scoping.stderr
src/test/ui/span/send-is-not-static-std-sync-2.stderr
src/test/ui/span/send-is-not-static-std-sync.stderr
src/test/ui/span/slice-borrow.stderr
src/test/ui/span/suggestion-non-ascii.stderr
src/test/ui/span/type-binding.stderr
src/test/ui/span/typo-suggestion.stderr
src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr
src/test/ui/span/vec_refs_data_with_early_death.stderr
src/test/ui/span/wf-method-late-bound-regions.stderr
src/test/ui/static-lifetime.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr
src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr
src/test/ui/suggestions/confuse-field-and-method/private-field.stderr
src/test/ui/suggestions/tuple-float-index.stderr
src/test/ui/token/bounds-obj-parens.stderr
src/test/ui/token/issue-10636-2.stderr
src/test/ui/token/issue-41155.stderr
src/test/ui/token/macro-incomplete-parse.stderr
src/test/ui/token/trailing-plus-in-bounds.stderr
src/test/ui/type-check/cannot_infer_local_or_array.stderr
src/test/ui/type-check/cannot_infer_local_or_vec.stderr
src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr
src/test/ui/type-check/issue-22897.stderr
src/test/ui/type-check/issue-40294.stderr
src/test/ui/type-check/unknown_type_for_closure.stderr
src/tools/cargo
src/tools/tidy/src/features.rs

index 804fd5807735f619c6cc62a7e01fd4665f3e2602..e23bdbd9fd87f0788bc930f5cab9fc85389eb1d2 100644 (file)
@@ -151,7 +151,6 @@ dependencies = [
  "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargotest 0.1.0",
- "chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "crates-io 0.9.0",
  "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -219,15 +218,6 @@ name = "cfg-if"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "chrono"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "clap"
 version = "2.19.3"
@@ -969,11 +959,6 @@ dependencies = [
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "redox_syscall"
-version = "0.1.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "regex"
 version = "0.1.80"
@@ -1844,17 +1829,6 @@ dependencies = [
 name = "tidy"
 version = "0.1.0"
 
-[[package]]
-name = "time"
-version = "0.1.37"
-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.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "toml"
 version = "0.1.30"
@@ -2048,7 +2022,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
 "checksum cargo 0.20.0 (git+https://github.com/rust-lang/cargo)" = "<none>"
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
-"checksum chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9123be86fd2a8f627836c235ecdf331fdd067ecf7ac05aa1a68fbcf2429f056"
 "checksum clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)" = "95b78f3fe0fc94c13c731714363260e04b557a637166f33a4570d3189d642374"
 "checksum cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "92278eb79412c8f75cfc89e707a1bb3a6490b68f7f2e78d15c774f30fe701122"
 "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
@@ -2119,7 +2092,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum racer 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b0d72b3afd67882adfca61d609fafb8d7aa5f9e814f12c32fcc6e171995920e8"
 "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
-"checksum redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "29dbdfd4b9df8ab31dec47c6087b7b13cbf4a776f335e4de8efba8288dda075b"
 "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
 "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
@@ -2163,7 +2135,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df7875b676fddfadffd96deea3b1124e5ede707d4884248931077518cf1f773"
 "checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
 "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
-"checksum time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd7ccbf969a892bf83f1e441126968a07a3941c24ff522a26af9f9f4585d1a3"
 "checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
 "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
 "checksum toml 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd86ad9ebee246fdedd610e0f6d0587b754a3d81438db930a244d0480ed7878f"
index bfba1a0dede24d50cb9929afb0a6d3b1d8b0ec61..0f85ba81d1268c90176e9935ead434cf1fb17daa 100644 (file)
@@ -127,13 +127,13 @@ def unpack(tarball, dst, verbose=False, match=None):
             shutil.move(tp, fp)
     shutil.rmtree(os.path.join(dst, fname))
 
-def run(args, verbose=False, exception=False, cwd=None):
+def run(args, verbose=False, exception=False, cwd=None, env=None):
     if verbose:
         print("running: " + ' '.join(args))
     sys.stdout.flush()
     # Use Popen here instead of call() as it apparently allows powershell on
     # Windows to not lock up waiting for input presumably.
-    ret = subprocess.Popen(args, cwd=cwd)
+    ret = subprocess.Popen(args, cwd=cwd, env=env)
     code = ret.wait()
     if code != 0:
         err = "failed to run: " + ' '.join(args)
@@ -385,17 +385,15 @@ class RustBuild(object):
             raise Exception("no cargo executable found at `%s`" % self.cargo())
         args = [self.cargo(), "build", "--manifest-path",
                 os.path.join(self.rust_root, "src/bootstrap/Cargo.toml")]
+        if self.verbose:
+            args.append("--verbose")
+            if self.verbose > 1:
+                args.append("--verbose")
         if self.use_locked_deps:
             args.append("--locked")
         if self.use_vendored_sources:
             args.append("--frozen")
-        self.run(args, env)
-
-    def run(self, args, env=None, cwd=None):
-        proc = subprocess.Popen(args, env=env, cwd=cwd)
-        ret = proc.wait()
-        if ret != 0:
-            sys.exit(ret)
+        run(args, env=env, verbose=self.verbose)
 
     def output(self, args, env=None, cwd=None):
         default_encoding = sys.getdefaultencoding()
@@ -567,7 +565,7 @@ class RustBuild(object):
             path = line[1:].split(' ')[1]
             submodules.append([path, line[0]])
 
-        self.run(["git", "submodule", "sync"], cwd=self.rust_root)
+        run(["git", "submodule", "sync"], cwd=self.rust_root)
 
         for submod in submodules:
             path, status = submod
@@ -580,15 +578,15 @@ class RustBuild(object):
             submod_path = os.path.join(self.rust_root, path)
 
             if status == ' ':
-                self.run(["git", "reset", "--hard"], cwd=submod_path)
-                self.run(["git", "clean", "-fdx"], cwd=submod_path)
+                run(["git", "reset", "--hard"], cwd=submod_path)
+                run(["git", "clean", "-fdx"], cwd=submod_path)
             elif status == '+':
-                self.run(["git", "submodule", "update", path], cwd=self.rust_root)
-                self.run(["git", "reset", "--hard"], cwd=submod_path)
-                self.run(["git", "clean", "-fdx"], cwd=submod_path)
+                run(["git", "submodule", "update", path], cwd=self.rust_root)
+                run(["git", "reset", "--hard"], cwd=submod_path)
+                run(["git", "clean", "-fdx"], cwd=submod_path)
             elif status == '-':
-                self.run(["git", "submodule", "init", path], cwd=self.rust_root)
-                self.run(["git", "submodule", "update", path], cwd=self.rust_root)
+                run(["git", "submodule", "init", path], cwd=self.rust_root)
+                run(["git", "submodule", "update", path], cwd=self.rust_root)
             else:
                 raise ValueError('unknown submodule status: ' + status)
 
@@ -620,6 +618,11 @@ def bootstrap():
     except:
         pass
 
+    if '\nverbose = 2' in rb.config_toml:
+        rb.verbose = 2
+    elif '\nverbose = 1' in rb.config_toml:
+        rb.verbose = 1
+
     rb.use_vendored_sources = '\nvendor = true' in rb.config_toml or \
                               'CFG_ENABLE_VENDOR' in rb.config_mk
 
@@ -676,7 +679,7 @@ def bootstrap():
     env["BUILD"] = rb.build
     env["SRC"] = rb.rust_root
     env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
-    rb.run(args, env)
+    run(args, env=env, verbose=rb.verbose)
 
 def main():
     start_time = time()
index 511f2c9e80ec72e732caba01da7cbb468850745b..14ddcc7cb323250963c4ff8daca123511ed762a7 100644 (file)
@@ -96,6 +96,140 @@ pub fn docs(build: &Build, stage: u32, host: &str) {
     }
 }
 
+fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> {
+    let mut found = Vec::new();
+
+    for file in files {
+        let file_path =
+            path.iter()
+                .map(|dir| dir.join(file))
+                .find(|p| p.exists());
+
+        if let Some(file_path) = file_path {
+            found.push(file_path);
+        } else {
+            panic!("Could not find '{}' in {:?}", file, path);
+        }
+    }
+
+    found
+}
+
+fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build: &Build) {
+    //Ask gcc where it keeps its stuff
+    let mut cmd = Command::new(build.cc(target_triple));
+    cmd.arg("-print-search-dirs");
+    build.run_quiet(&mut cmd);
+    let gcc_out =
+        String::from_utf8(
+                cmd
+                .output()
+                .expect("failed to execute gcc")
+                .stdout).expect("gcc.exe output was not utf8");
+
+    let mut bin_path: Vec<_> =
+        env::split_paths(&env::var_os("PATH").unwrap_or_default())
+        .collect();
+    let mut lib_path = Vec::new();
+
+    for line in gcc_out.lines() {
+        let idx = line.find(':').unwrap();
+        let key = &line[..idx];
+        let trim_chars: &[_] = &[' ', '='];
+        let value =
+            line[(idx + 1)..]
+                .trim_left_matches(trim_chars)
+                .split(';')
+                .map(|s| PathBuf::from(s));
+
+        if key == "programs" {
+            bin_path.extend(value);
+        } else if key == "libraries" {
+            lib_path.extend(value);
+        }
+    }
+
+    let target_tools = vec!["gcc.exe", "ld.exe", "ar.exe", "dlltool.exe", "libwinpthread-1.dll"];
+    let mut rustc_dlls = vec!["libstdc++-6.dll", "libwinpthread-1.dll"];
+    if target_triple.starts_with("i686-") {
+        rustc_dlls.push("libgcc_s_dw2-1.dll");
+    } else {
+        rustc_dlls.push("libgcc_s_seh-1.dll");
+    }
+
+    let target_libs = vec![ //MinGW libs
+        "libgcc.a",
+        "libgcc_eh.a",
+        "libgcc_s.a",
+        "libm.a",
+        "libmingw32.a",
+        "libmingwex.a",
+        "libstdc++.a",
+        "libiconv.a",
+        "libmoldname.a",
+        "libpthread.a",
+        //Windows import libs
+        "libadvapi32.a",
+        "libbcrypt.a",
+        "libcomctl32.a",
+        "libcomdlg32.a",
+        "libcrypt32.a",
+        "libgdi32.a",
+        "libimagehlp.a",
+        "libiphlpapi.a",
+        "libkernel32.a",
+        "libmsvcrt.a",
+        "libodbc32.a",
+        "libole32.a",
+        "liboleaut32.a",
+        "libopengl32.a",
+        "libpsapi.a",
+        "librpcrt4.a",
+        "libsetupapi.a",
+        "libshell32.a",
+        "libuser32.a",
+        "libuserenv.a",
+        "libuuid.a",
+        "libwinhttp.a",
+        "libwinmm.a",
+        "libwinspool.a",
+        "libws2_32.a",
+        "libwsock32.a",
+    ];
+
+    //Find mingw artifacts we want to bundle
+    let target_tools = find_files(&target_tools, &bin_path);
+    let rustc_dlls = find_files(&rustc_dlls, &bin_path);
+    let target_libs = find_files(&target_libs, &lib_path);
+
+    fn copy_to_folder(src: &Path, dest_folder: &Path) {
+        let file_name = src.file_name().unwrap().to_os_string();
+        let dest = dest_folder.join(file_name);
+        copy(src, &dest);
+    }
+
+    //Copy runtime dlls next to rustc.exe
+    let dist_bin_dir = rust_root.join("bin/");
+    fs::create_dir_all(&dist_bin_dir).expect("creating dist_bin_dir failed");
+    for src in rustc_dlls {
+        copy_to_folder(&src, &dist_bin_dir);
+    }
+
+    //Copy platform tools to platform-specific bin directory
+    let target_bin_dir = plat_root.join("lib").join("rustlib").join(target_triple).join("bin");
+    fs::create_dir_all(&target_bin_dir).expect("creating target_bin_dir failed");
+    for src in target_tools {
+        copy_to_folder(&src, &target_bin_dir);
+    }
+
+    //Copy platform libs to platform-specific lib directory
+    let target_lib_dir = plat_root.join("lib").join("rustlib").join(target_triple).join("lib");
+    fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed");
+    for src in target_libs {
+        copy_to_folder(&src, &target_lib_dir);
+    }
+}
+
 /// Build the `rust-mingw` installer component.
 ///
 /// This contains all the bits and pieces to run the MinGW Windows targets
@@ -109,18 +243,11 @@ pub fn mingw(build: &Build, host: &str) {
     let _ = fs::remove_dir_all(&image);
     t!(fs::create_dir_all(&image));
 
-    // The first argument to the script is a "temporary directory" which is just
+    // The first argument is a "temporary directory" which is just
     // thrown away (this contains the runtime DLLs included in the rustc package
     // above) and the second argument is where to place all the MinGW components
     // (which is what we want).
-    //
-    // FIXME: this script should be rewritten into Rust
-    let mut cmd = Command::new(build.python());
-    cmd.arg(build.src.join("src/etc/make-win-dist.py"))
-       .arg(tmpdir(build))
-       .arg(&image)
-       .arg(host);
-    build.run(&mut cmd);
+    make_win_dist(&tmpdir(build), &image, host, &build);
 
     let mut cmd = rust_installer(build);
     cmd.arg("generate")
@@ -172,15 +299,8 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
     // anything requiring us to distribute a license, but it's likely the
     // install will *also* include the rust-mingw package, which also needs
     // licenses, so to be safe we just include it here in all MinGW packages.
-    //
-    // FIXME: this script should be rewritten into Rust
     if host.contains("pc-windows-gnu") {
-        let mut cmd = Command::new(build.python());
-        cmd.arg(build.src.join("src/etc/make-win-dist.py"))
-           .arg(&image)
-           .arg(tmpdir(build))
-           .arg(host);
-        build.run(&mut cmd);
+        make_win_dist(&image, &tmpdir(build), host, build);
 
         let dst = image.join("share/doc");
         t!(fs::create_dir_all(&dst));
index 64b1abf82a8277d8ebc1a10c54b40fd7be583bd4..27cd064f901a036de2ff41b9922806f06d8a3ec6 100755 (executable)
 set -ex
 source shared.sh
 
-VERSION=1.0.2j
+VERSION=1.0.2k
+URL=https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/openssl-$VERSION.tar.gz
 
-curl https://www.openssl.org/source/openssl-$VERSION.tar.gz | tar xzf -
+curl $URL | tar xzf -
 
 cd openssl-$VERSION
 hide_output ./config --prefix=/rustroot shared -fPIC
index 64b1abf82a8277d8ebc1a10c54b40fd7be583bd4..27cd064f901a036de2ff41b9922806f06d8a3ec6 100755 (executable)
 set -ex
 source shared.sh
 
-VERSION=1.0.2j
+VERSION=1.0.2k
+URL=https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/openssl-$VERSION.tar.gz
 
-curl https://www.openssl.org/source/openssl-$VERSION.tar.gz | tar xzf -
+curl $URL | tar xzf -
 
 cd openssl-$VERSION
 hide_output ./config --prefix=/rustroot shared -fPIC
index 1db2135eb6d868bbf25d45a2b02fe6cb11c6056a..0a17bd3b5710f6430a2817704b7bbfdc51f95dfd 100755 (executable)
@@ -64,6 +64,7 @@ if [ ! -d "$cache_src_dir/.git" ]; then
         git clone https://github.com/rust-lang/rust.git $cache_src_dir"
 fi
 retry sh -c "cd $cache_src_dir && git reset --hard && git pull"
+(cd $cache_src_dir && git rm src/llvm)
 retry sh -c "cd $cache_src_dir && \
     git submodule deinit -f . && git submodule sync && git submodule update --init"
 
@@ -76,6 +77,15 @@ touch "$cache_valid_file"
 # http://stackoverflow.com/questions/12641469/list-submodules-in-a-git-repository
 modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
 for module in $modules; do
+    if [ "$module" = src/llvm ]; then
+        commit="$(git ls-tree HEAD src/llvm | awk '{print $3}')"
+        git rm src/llvm
+        curl -sSL -O "https://github.com/rust-lang/llvm/archive/$commit.tar.gz"
+        tar -C src/ -xf "$commit.tar.gz"
+        rm "$commit.tar.gz"
+        mv "src/llvm-$commit" src/llvm
+        continue
+    fi
     if [ ! -d "$cache_src_dir/$module" ]; then
         echo "WARNING: $module not found in pristine repo"
         retry sh -c "git submodule deinit -f $module && git submodule update --init $module"
index 456a683dc33c89fcc53c5712c4510eec272028d0..3b37c47e392807c65fb223b3f03a278b1ba031c1 100644 (file)
@@ -7,6 +7,7 @@
     - [abi_msp430_interrupt](language-features/abi-msp430-interrupt.md)
     - [abi_ptx](language-features/abi-ptx.md)
     - [abi_sysv64](language-features/abi-sysv64.md)
+    - [abi_thiscall](language-features/abi-thiscall.md)
     - [abi_unadjusted](language-features/abi-unadjusted.md)
     - [abi_vectorcall](language-features/abi-vectorcall.md)
     - [abi_x86_interrupt](language-features/abi-x86-interrupt.md)
@@ -71,7 +72,6 @@
     - [prelude_import](language-features/prelude-import.md)
     - [proc_macro](language-features/proc-macro.md)
     - [quote](language-features/quote.md)
-    - [relaxed_adts](language-features/relaxed-adts.md)
     - [repr_align](language-features/repr-align.md)
     - [repr_simd](language-features/repr-simd.md)
     - [rustc_attrs](language-features/rustc-attrs.md)
diff --git a/src/doc/unstable-book/src/language-features/abi-thiscall.md b/src/doc/unstable-book/src/language-features/abi-thiscall.md
new file mode 100644 (file)
index 0000000..73bc6ea
--- /dev/null
@@ -0,0 +1,12 @@
+# `abi_thiscall`
+
+The tracking issue for this feature is: [#42202]
+
+[#42202]: https://github.com/rust-lang/rust/issues/42202
+
+------------------------
+
+The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
+instance methods by default; it is identical to the usual (C) calling
+convention on x86 Windows except that the first parameter of the method,
+the `this` pointer, is passed in the ECX register.
diff --git a/src/doc/unstable-book/src/language-features/decl-macro.md b/src/doc/unstable-book/src/language-features/decl-macro.md
new file mode 100644 (file)
index 0000000..4700b25
--- /dev/null
@@ -0,0 +1,10 @@
+# `decl_macro`
+
+The tracking issue for this feature is: [#39412]
+
+[#39412]: https://github.com/rust-lang/rust/issues/39412
+
+------------------------
+
+
+
diff --git a/src/doc/unstable-book/src/language-features/relaxed-adts.md b/src/doc/unstable-book/src/language-features/relaxed-adts.md
deleted file mode 100644 (file)
index 170570e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# `relaxed_adts`
-
-The tracking issue for this feature is: [#35626]
-
-[#35626]: https://github.com/rust-lang/rust/issues/35626
-
-------------------------
-
-
-
index e53ca13f7b6f5a6f653a7c631a8df29c0582b3a4..56050c20c69151d117309df59f110f62f2411805 100644 (file)
@@ -1,7 +1,7 @@
 # `step_trait`
 
-The tracking issue for this feature is: [#27741]
+The tracking issue for this feature is: [#42168]
 
-[#27741]: https://github.com/rust-lang/rust/issues/27741
+[#42168]: https://github.com/rust-lang/rust/issues/42168
 
 ------------------------
diff --git a/src/etc/make-win-dist.py b/src/etc/make-win-dist.py
deleted file mode 100644 (file)
index 4699fef..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright 2013-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.
-
-# Script parameters:
-#     argv[1] = rust component root,
-#     argv[2] = gcc component root,
-#     argv[3] = target triple
-# The first two correspond to the two installable components defined in the setup script.
-
-import sys
-import os
-import shutil
-import subprocess
-
-
-def find_files(files, path):
-    found = []
-    for fname in files:
-        for dir in path:
-            filepath = os.path.normpath(os.path.join(dir, fname))
-            if os.path.isfile(filepath):
-                found.append(filepath)
-                break
-        else:
-            raise Exception("Could not find '%s' in %s" % (fname, path))
-    return found
-
-
-# rust_root - root directory of the host binaries image
-# plat_root - root directory of the target platform tools and libs image
-#             (the two get overlayed on top of each other during installation)
-# target_triple - triple of the target image being layed out
-def make_win_dist(rust_root, plat_root, target_triple):
-    # Ask gcc where it keeps its stuff
-    gcc_out = subprocess.check_output(["gcc.exe", "-print-search-dirs"])
-    bin_path = os.environ["PATH"].split(os.pathsep)
-    lib_path = []
-    for line in gcc_out.splitlines():
-        key, val = line.split(':', 1)
-        if key == "programs":
-            bin_path.extend(val.lstrip(' =').split(';'))
-        elif key == "libraries":
-            lib_path.extend(val.lstrip(' =').split(';'))
-
-    target_tools = ["gcc.exe", "ld.exe", "ar.exe", "dlltool.exe",
-                    "libwinpthread-1.dll"]
-
-    rustc_dlls = ["libstdc++-6.dll", "libwinpthread-1.dll"]
-    if target_triple.startswith("i686-"):
-        rustc_dlls.append("libgcc_s_dw2-1.dll")
-    else:
-        rustc_dlls.append("libgcc_s_seh-1.dll")
-
-    target_libs = [ # MinGW libs
-                    "libgcc.a",
-                    "libgcc_eh.a",
-                    "libgcc_s.a",
-                    "libm.a",
-                    "libmingw32.a",
-                    "libmingwex.a",
-                    "libstdc++.a",
-                    "libiconv.a",
-                    "libmoldname.a",
-                    "libpthread.a",
-                    # Windows import libs
-                    "libadvapi32.a",
-                    "libbcrypt.a",
-                    "libcomctl32.a",
-                    "libcomdlg32.a",
-                    "libcrypt32.a",
-                    "libgdi32.a",
-                    "libimagehlp.a",
-                    "libiphlpapi.a",
-                    "libkernel32.a",
-                    "libmsvcrt.a",
-                    "libodbc32.a",
-                    "libole32.a",
-                    "liboleaut32.a",
-                    "libopengl32.a",
-                    "libpsapi.a",
-                    "librpcrt4.a",
-                    "libsetupapi.a",
-                    "libshell32.a",
-                    "libuser32.a",
-                    "libuserenv.a",
-                    "libuuid.a",
-                    "libwinhttp.a",
-                    "libwinmm.a",
-                    "libwinspool.a",
-                    "libws2_32.a",
-                    "libwsock32.a",
-                    ]
-
-    # Find mingw artifacts we want to bundle
-    target_tools = find_files(target_tools, bin_path)
-    rustc_dlls = find_files(rustc_dlls, bin_path)
-    target_libs = find_files(target_libs, lib_path)
-
-    # Copy runtime dlls next to rustc.exe
-    dist_bin_dir = os.path.join(rust_root, "bin")
-    for src in rustc_dlls:
-        shutil.copy(src, dist_bin_dir)
-
-    # Copy platform tools to platform-specific bin directory
-    target_bin_dir = os.path.join(plat_root, "lib", "rustlib", target_triple, "bin")
-    if not os.path.exists(target_bin_dir):
-        os.makedirs(target_bin_dir)
-    for src in target_tools:
-        shutil.copy(src, target_bin_dir)
-
-    # Copy platform libs to platform-specific lib directory
-    target_lib_dir = os.path.join(plat_root, "lib", "rustlib", target_triple, "lib")
-    if not os.path.exists(target_lib_dir):
-        os.makedirs(target_lib_dir)
-    for src in target_libs:
-        shutil.copy(src, target_lib_dir)
-
-if __name__ == "__main__":
-    make_win_dist(sys.argv[1], sys.argv[2], sys.argv[3])
index 8f3209d015b159ad955f6a31ee7eac0109bd45b6..bc8566e8cbeb375b6b066b0ddd368eb7ee883dfb 100644 (file)
@@ -106,16 +106,10 @@ fn end(&self) -> Bound<&T> {
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<T> RangeArgument<T> for RangeInclusive<T> {
     fn start(&self) -> Bound<&T> {
-        match *self {
-            RangeInclusive::Empty{ ref at }            => Included(at),
-            RangeInclusive::NonEmpty { ref start, .. } => Included(start),
-        }
+        Included(&self.start)
     }
     fn end(&self) -> Bound<&T> {
-        match *self {
-            RangeInclusive::Empty{ ref at }            => Excluded(at),
-            RangeInclusive::NonEmpty { ref end, .. }   => Included(end),
-        }
+        Included(&self.end)
     }
 }
 
index 1a3e665a044735202d589f7b46b4d849891d25c4..eb32f4781948df7d2fa99c63cbde502ad75fff13 100644 (file)
@@ -1029,7 +1029,7 @@ pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
     ///
     /// ```
     /// let x = "(///)".to_string();
-    /// let d: Vec<_> = x.split('/').collect();;
+    /// let d: Vec<_> = x.split('/').collect();
     ///
     /// assert_eq!(d, &["(", "", "", ")"]);
     /// ```
index f9b818f5bff357dbac3615b396eb48e1a43305cf..54919a414786d7074a71fd3964ec8c6145473481 100644 (file)
 
 #[unstable(feature = "step_trait",
            reason = "likely to be replaced by finer-grained traits",
-           issue = "27741")]
+           issue = "42168")]
 pub use self::range::Step;
 #[unstable(feature = "step_by", reason = "recent addition",
            issue = "27741")]
index bd831d638c0c4cc24e8573501345ab809c489477..e02823fd81280f7d44011fa9f277f83d0c2a9608 100644 (file)
@@ -20,7 +20,7 @@
 /// two `Step` objects.
 #[unstable(feature = "step_trait",
            reason = "likely to be replaced by finer-grained traits",
-           issue = "27741")]
+           issue = "42168")]
 pub trait Step: PartialOrd + Sized {
     /// Steps `self` if possible.
     fn step(&self, by: &Self) -> Option<Self>;
@@ -55,7 +55,7 @@ macro_rules! step_impl_unsigned {
     ($($t:ty)*) => ($(
         #[unstable(feature = "step_trait",
                    reason = "likely to be replaced by finer-grained traits",
-                   issue = "27741")]
+                   issue = "42168")]
         impl Step for $t {
             #[inline]
             fn step(&self, by: &$t) -> Option<$t> {
@@ -115,7 +115,7 @@ macro_rules! step_impl_signed {
     ($($t:ty)*) => ($(
         #[unstable(feature = "step_trait",
                    reason = "likely to be replaced by finer-grained traits",
-                   issue = "27741")]
+                   issue = "42168")]
         impl Step for $t {
             #[inline]
             fn step(&self, by: &$t) -> Option<$t> {
@@ -187,7 +187,7 @@ macro_rules! step_impl_no_between {
     ($($t:ty)*) => ($(
         #[unstable(feature = "step_trait",
                    reason = "likely to be replaced by finer-grained traits",
-                   issue = "27741")]
+                   issue = "42168")]
         impl Step for $t {
             #[inline]
             fn step(&self, by: &$t) -> Option<$t> {
@@ -403,61 +403,35 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // this function has a sort of odd structure due to borrowck issues
-        // we may need to replace self.range, so borrows of start and end need to end early
-
-        let (finishing, n) = match self.range {
-            Empty { .. } => return None, // empty iterators yield no values
-
-            NonEmpty { ref mut start, ref mut end } => {
-                let rev = self.step_by.is_negative();
-
-                // march start towards (maybe past!) end and yield the old value
-                if (rev && start >= end) ||
-                   (!rev && start <= end)
-                {
-                    match start.step(&self.step_by) {
-                        Some(mut n) => {
-                            mem::swap(start, &mut n);
-                            (None, Some(n)) // yield old value, remain non-empty
-                        },
-                        None => {
-                            let mut n = end.clone();
-                            mem::swap(start, &mut n);
-                            (None, Some(n)) // yield old value, remain non-empty
-                        }
-                    }
-                } else {
-                    // found range in inconsistent state (start at or past end), so become empty
-                    (Some(end.replace_zero()), None)
-                }
-            }
-        };
+        let rev = self.step_by.is_negative();
 
-        // turn into an empty iterator if we've reached the end
-        if let Some(end) = finishing {
-            self.range = Empty { at: end };
+        if (rev && self.range.start >= self.range.end) ||
+           (!rev && self.range.start <= self.range.end)
+        {
+            match self.range.start.step(&self.step_by) {
+                Some(n) => {
+                    Some(mem::replace(&mut self.range.start, n))
+                },
+                None => {
+                    let last = self.range.start.replace_one();
+                    self.range.end.replace_zero();
+                    self.step_by.replace_one();
+                    Some(last)
+                },
+            }
+        }
+        else {
+            None
         }
-
-        n
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        use ops::RangeInclusive::*;
-
-        match self.range {
-            Empty { .. } => (0, Some(0)),
-
-            NonEmpty { ref start, ref end } =>
-                match Step::steps_between(start,
-                                          end,
-                                          &self.step_by) {
-                    Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
-                    None       => (0, None)
-                }
+        match Step::steps_between(&self.range.start,
+                                  &self.range.end,
+                                  &self.step_by) {
+            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
+            None       => (0, None)
         }
     }
 }
@@ -583,56 +557,31 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> where
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // this function has a sort of odd structure due to borrowck issues
-        // we may need to replace self, so borrows of self.start and self.end need to end early
-
-        let (finishing, n) = match *self {
-            Empty { .. } => (None, None), // empty iterators yield no values
-
-            NonEmpty { ref mut start, ref mut end } => {
-                if start == end {
-                    (Some(end.replace_one()), Some(start.replace_one()))
-                } else if start < end {
-                    let mut n = start.add_one();
-                    mem::swap(&mut n, start);
-
-                    // if the iterator is done iterating, it will change from
-                    // NonEmpty to Empty to avoid unnecessary drops or clones,
-                    // we'll reuse either start or end (they are equal now, so
-                    // it doesn't matter which) to pull out end, we need to swap
-                    // something back in
-
-                    (if n == *end { Some(end.replace_one()) } else { None },
-                    // ^ are we done yet?
-                    Some(n)) // < the value to output
-                } else {
-                    (Some(start.replace_one()), None)
-                }
-            }
-        };
-
-        // turn into an empty iterator if this is the last value
-        if let Some(end) = finishing {
-            *self = Empty { at: end };
+        use cmp::Ordering::*;
+
+        match self.start.partial_cmp(&self.end) {
+            Some(Less) => {
+                let n = self.start.add_one();
+                Some(mem::replace(&mut self.start, n))
+            },
+            Some(Equal) => {
+                let last = self.start.replace_one();
+                self.end.replace_zero();
+                Some(last)
+            },
+            _ => None,
         }
-
-        n
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        use ops::RangeInclusive::*;
-
-        match *self {
-            Empty { .. } => (0, Some(0)),
+        if !(self.start <= self.end) {
+            return (0, Some(0));
+        }
 
-            NonEmpty { ref start, ref end } =>
-                match Step::steps_between_by_one(start, end) {
-                    Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
-                    None => (0, None),
-                }
+        match Step::steps_between_by_one(&self.start, &self.end) {
+            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
+            None => (0, None),
         }
     }
 }
@@ -644,33 +593,20 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
 {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // see Iterator::next for comments
-
-        let (finishing, n) = match *self {
-            Empty { .. } => return None,
-
-            NonEmpty { ref mut start, ref mut end } => {
-                if start == end {
-                    (Some(start.replace_one()), Some(end.replace_one()))
-                } else if start < end {
-                    let mut n = end.sub_one();
-                    mem::swap(&mut n, end);
-
-                    (if n == *start { Some(start.replace_one()) } else { None },
-                     Some(n))
-                } else {
-                    (Some(end.replace_one()), None)
-                }
-            }
-        };
-
-        if let Some(start) = finishing {
-            *self = Empty { at: start };
+        use cmp::Ordering::*;
+
+        match self.start.partial_cmp(&self.end) {
+            Some(Less) => {
+                let n = self.end.sub_one();
+                Some(mem::replace(&mut self.end, n))
+            },
+            Some(Equal) => {
+                let last = self.end.replace_zero();
+                self.start.replace_one();
+                Some(last)
+            },
+            _ => None,
         }
-
-        n
     }
 }
 
index 3f32db122351c2ddbeaf13d25741442b59d8d62b..6602fccd5898282fd59d94450cfa2d07603dd45e 100644 (file)
@@ -120,7 +120,7 @@ pub trait Sized {
 /// [coerceunsized]: ../ops/trait.CoerceUnsized.html
 /// [rc]: ../../std/rc/struct.Rc.html
 /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
-
+/// [nomicon-coerce]: ../../nomicon/coercions.html
 #[unstable(feature = "unsize", issue = "27732")]
 #[lang="unsize"]
 pub trait Unsize<T: ?Sized> {
index fc3af096b183880c4b3a61910e4fe5eae73e904d..c76cff4dc34d10bf506188bdd29e79de45e5c9a7 100644 (file)
 /// The `Drop` trait is used to run some code when a value goes out of scope.
 /// This is sometimes called a 'destructor'.
 ///
+/// When a value goes out of scope, if it implements this trait, it will have
+/// its `drop` method called. Then any fields the value contains will also
+/// be dropped recursively.
+///
+/// Because of the recursive dropping, you do not need to implement this trait
+/// unless your type needs its own destructor logic.
+///
 /// # Examples
 ///
 /// A trivial implementation of `Drop`. The `drop` method is called when `_x`
 ///     let _x = HasDrop;
 /// }
 /// ```
+///
+/// Showing the recursive nature of `Drop`. When `outer` goes out of scope, the
+/// `drop` method will be called first for `Outer`, then for `Inner`. Therefore
+/// `main` prints `Dropping Outer!` and then `Dropping Inner!`.
+///
+/// ```
+/// struct Inner;
+/// struct Outer(Inner);
+///
+/// impl Drop for Inner {
+///     fn drop(&mut self) {
+///         println!("Dropping Inner!");
+///     }
+/// }
+///
+/// impl Drop for Outer {
+///     fn drop(&mut self) {
+///         println!("Dropping Outer!");
+///     }
+/// }
+///
+/// fn main() {
+///     let _x = Outer(Inner);
+/// }
+/// ```
+///
+/// Because variables are dropped in the reverse order they are declared,
+/// `main` will print `Declared second!` and then `Declared first!`.
+///
+/// ```
+/// struct PrintOnDrop(&'static str);
+///
+/// fn main() {
+///     let _first = PrintOnDrop("Declared first!");
+///     let _second = PrintOnDrop("Declared second!");
+/// }
+/// ```
 #[lang = "drop"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Drop {
@@ -2271,7 +2315,7 @@ pub fn contains(&self, item: Idx) -> bool {
 /// ```
 /// #![feature(inclusive_range,inclusive_range_syntax)]
 /// fn main() {
-///     assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 });
+///     assert_eq!((3...5), std::ops::RangeInclusive{ start: 3, end: 5 });
 ///     assert_eq!(3+4+5, (3...5).sum());
 ///
 ///     let arr = [0, 1, 2, 3];
@@ -2281,45 +2325,23 @@ pub fn contains(&self, item: Idx) -> bool {
 /// ```
 #[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-pub enum RangeInclusive<Idx> {
-    /// Empty range (iteration has finished)
+pub struct RangeInclusive<Idx> {
+    /// The lower bound of the range (inclusive).
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
-    Empty {
-        /// The point at which iteration finished
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        at: Idx
-    },
-    /// Non-empty range (iteration will yield value(s))
+    pub start: Idx,
+    /// The upper bound of the range (inclusive).
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
-    NonEmpty {
-        /// The lower bound of the range (inclusive).
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        start: Idx,
-        /// The upper bound of the range (inclusive).
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        end: Idx,
-    },
+    pub end: Idx,
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        use self::RangeInclusive::*;
-
-        match *self {
-            Empty { ref at } => write!(fmt, "[empty range @ {:?}]", at),
-            NonEmpty { ref start, ref end } => write!(fmt, "{:?}...{:?}", start, end),
-        }
+        write!(fmt, "{:?}...{:?}", self.start, self.end)
     }
 }
 
@@ -2341,9 +2363,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// }
     /// ```
     pub fn contains(&self, item: Idx) -> bool {
-        if let &RangeInclusive::NonEmpty{ref start, ref end} = self {
-            (*start <= item) && (item <= *end)
-        } else { false }
+        self.start <= item && item <= self.end
     }
 }
 
index 24ebfeb62e2eec23eec5fe573fa01ed819ace068..cef3682fd94d74859a69f0207b2796555520154a 100644 (file)
@@ -981,95 +981,82 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&[T]> {
-        match self {
-            ops::RangeInclusive::Empty { .. } => Some(&[]),
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None,
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get(slice),
-        }
+        if self.end == usize::max_value() { None }
+        else { (self.start..self.end + 1).get(slice) }
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
-        match self {
-            ops::RangeInclusive::Empty { .. } => Some(&mut []),
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None,
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_mut(slice),
-        }
+        if self.end == usize::max_value() { None }
+        else { (self.start..self.end + 1).get_mut(slice) }
     }
 
     #[inline]
     unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &[],
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_unchecked(slice),
-        }
+        (self.start..self.end + 1).get_unchecked(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &mut [],
-            ops::RangeInclusive::NonEmpty { start, end } => {
-                (start..end + 1).get_unchecked_mut(slice)
-            }
-        }
+        (self.start..self.end + 1).get_unchecked_mut(slice)
     }
 
     #[inline]
     fn index(self, slice: &[T]) -> &[T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &[],
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => {
-                panic!("attempted to index slice up to maximum usize");
-            },
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index(slice),
-        }
+        assert!(self.end != usize::max_value(),
+            "attempted to index slice up to maximum usize");
+        (self.start..self.end + 1).index(slice)
     }
 
     #[inline]
     fn index_mut(self, slice: &mut [T]) -> &mut [T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &mut [],
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => {
-                panic!("attempted to index slice up to maximum usize");
-            },
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index_mut(slice),
-        }
+        assert!(self.end != usize::max_value(),
+            "attempted to index slice up to maximum usize");
+        (self.start..self.end + 1).index_mut(slice)
     }
 }
 
+#[cfg(stage0)] // The bootstrap compiler has a different `...` desugar
+fn inclusive(start: usize, end: usize) -> ops::RangeInclusive<usize> {
+    ops::RangeInclusive { start, end }
+}
+#[cfg(not(stage0))]
+fn inclusive(start: usize, end: usize) -> ops::RangeInclusive<usize> {
+    start...end
+}
+
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
     type Output = [T];
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&[T]> {
-        (0...self.end).get(slice)
+        inclusive(0, self.end).get(slice)
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
-        (0...self.end).get_mut(slice)
+        inclusive(0, self.end).get_mut(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
-        (0...self.end).get_unchecked(slice)
+        inclusive(0, self.end).get_unchecked(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
-        (0...self.end).get_unchecked_mut(slice)
+        inclusive(0, self.end).get_unchecked_mut(slice)
     }
 
     #[inline]
     fn index(self, slice: &[T]) -> &[T] {
-        (0...self.end).index(slice)
+        inclusive(0, self.end).index(slice)
     }
 
     #[inline]
     fn index_mut(self, slice: &mut [T]) -> &mut [T] {
-        (0...self.end).index_mut(slice)
+        inclusive(0, self.end).index_mut(slice)
     }
 }
 
index 7fb941c091fbc4fab90ed623b90ff54db4bb3142..547a4899c7118c85e9bf6ceffaaab190401ac988 100644 (file)
@@ -1724,15 +1724,12 @@ impl ops::Index<ops::RangeInclusive<usize>> for str {
 
         #[inline]
         fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
-            match index {
-                ops::RangeInclusive::Empty { .. } => "",
-                ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
-                    panic!("attempted to index slice up to maximum usize"),
-                ops::RangeInclusive::NonEmpty { start, end } =>
-                    self.index(start .. end+1)
-            }
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index(index.start .. index.end+1)
         }
     }
+
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
@@ -1741,7 +1738,9 @@ impl ops::Index<ops::RangeToInclusive<usize>> for str {
 
         #[inline]
         fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
-            self.index(0...index.end)
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index(.. index.end+1)
         }
     }
 
@@ -1751,13 +1750,9 @@ fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
     impl ops::IndexMut<ops::RangeInclusive<usize>> for str {
         #[inline]
         fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
-            match index {
-                ops::RangeInclusive::Empty { .. } => &mut self[0..0], // `&mut ""` doesn't work
-                ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
-                    panic!("attempted to index str up to maximum usize"),
-                    ops::RangeInclusive::NonEmpty { start, end } =>
-                        self.index_mut(start .. end+1)
-            }
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index_mut(index.start .. index.end+1)
         }
     }
     #[unstable(feature = "inclusive_range",
@@ -1766,7 +1761,9 @@ fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
     impl ops::IndexMut<ops::RangeToInclusive<usize>> for str {
         #[inline]
         fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
-            self.index_mut(0...index.end)
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index_mut(.. index.end+1)
         }
     }
 
@@ -1948,45 +1945,27 @@ impl SliceIndex<str> for ops::RangeInclusive<usize> {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get(slice)
+            (self.start..self.end+1).get(slice)
         }
         #[inline]
         fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_mut(slice)
+            (self.start..self.end+1).get_mut(slice)
         }
         #[inline]
         unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_unchecked(slice)
+            (self.start..self.end+1).get_unchecked(slice)
         }
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_unchecked_mut(slice)
+            (self.start..self.end+1).get_unchecked_mut(slice)
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.index(slice)
+            (self.start..self.end+1).index(slice)
         }
         #[inline]
         fn index_mut(self, slice: &mut str) -> &mut Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.index_mut(slice)
+            (self.start..self.end+1).index_mut(slice)
         }
     }
 
index c52155ead4f0b2774fe73db9cb4f73048a475dc4..8c4cd1d0c84583b20e961f9151c0e363686dbcac 100644 (file)
@@ -22,6 +22,7 @@
 #![feature(fmt_internals)]
 #![feature(iterator_step_by)]
 #![feature(i128_type)]
+#![feature(inclusive_range)]
 #![feature(iter_rfind)]
 #![feature(libc)]
 #![feature(nonzero)]
index 1c6c13b0d02e8b6e5417bbfbc900d4ca78f21f67..b81b3878c9d6e1d4c82a117f46107a17cf170b0b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::ops::{Range, RangeFull, RangeFrom, RangeTo};
+use core::ops::{Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
 
 // Test the Range structs without the syntactic sugar.
 
@@ -47,3 +47,24 @@ fn test_full_range() {
     // Not much to test.
     let _ = RangeFull;
 }
+
+#[test]
+fn test_range_inclusive() {
+    let mut r = RangeInclusive { start: 1i8, end: 2 };
+    assert_eq!(r.next(), Some(1));
+    assert_eq!(r.next(), Some(2));
+    assert_eq!(r.next(), None);
+
+    r = RangeInclusive { start: 127i8, end: 127 };
+    assert_eq!(r.next(), Some(127));
+    assert_eq!(r.next(), None);
+
+    r = RangeInclusive { start: -128i8, end: -128 };
+    assert_eq!(r.next_back(), Some(-128));
+    assert_eq!(r.next_back(), None);
+
+    // degenerate
+    r = RangeInclusive { start: 1, end: -1 };
+    assert_eq!(r.size_hint(), (0, Some(0)));
+    assert_eq!(r.next(), None);
+}
\ No newline at end of file
index 771031db0c045f99e985f96b2e7caf05332c55da..feded417ce17fb7910d62a4e671c7ea0a48575be 100644 (file)
@@ -117,7 +117,7 @@ pub fn kind_name(&self) -> &'static str {
 
 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct Export {
-    pub name: ast::Name, // The name of the target.
+    pub ident: ast::Ident, // The name of the target.
     pub def: Def, // The definition of the target.
     pub span: Span, // The span of the target definition.
 }
index 8f4dce5a78303d51d2c5850fd4fceb6af612df39..91cfbc38aa0ece054207968b2844c7dfcd942885 100644 (file)
@@ -47,7 +47,7 @@
 use hir::def::{Def, PathResolution};
 use rustc_data_structures::indexed_vec::IndexVec;
 use session::Session;
-use util::nodemap::{DefIdMap, NodeMap};
+use util::nodemap::{DefIdMap, FxHashMap, NodeMap};
 
 use std::collections::BTreeMap;
 use std::fmt::Debug;
@@ -77,6 +77,7 @@ pub struct LoweringContext<'a> {
     // a definition, then we can properly create the def id.
     parent_def: Option<DefIndex>,
     resolver: &'a mut Resolver,
+    name_map: FxHashMap<Ident, Name>,
 
     /// The items being lowered are collected here.
     items: BTreeMap<NodeId, hir::Item>,
@@ -126,6 +127,7 @@ pub fn lower_crate(sess: &Session,
         sess: sess,
         parent_def: None,
         resolver: resolver,
+        name_map: FxHashMap(),
         items: BTreeMap::new(),
         trait_items: BTreeMap::new(),
         impl_items: BTreeMap::new(),
@@ -393,7 +395,7 @@ fn str_to_ident(&self, s: &'static str) -> Name {
     }
 
     fn allow_internal_unstable(&self, reason: &'static str, mut span: Span) -> Span {
-        let mark = Mark::fresh();
+        let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(codemap::ExpnInfo {
             call_site: span,
             callee: codemap::NameAndSpan {
@@ -495,6 +497,14 @@ fn def_key(&mut self, id: DefId) -> DefKey {
         }
     }
 
+    fn lower_ident(&mut self, ident: Ident) -> Name {
+        let ident = ident.modern();
+        if ident.ctxt == SyntaxContext::empty() {
+            return ident.name;
+        }
+        *self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident))
+    }
+
     fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
         o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name))
     }
@@ -546,7 +556,7 @@ fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
     fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
         hir::TypeBinding {
             id: self.lower_node_id(b.id),
-            name: b.ident.name,
+            name: self.lower_ident(b.ident),
             ty: self.lower_ty(&b.ty),
             span: b.span,
         }
@@ -844,7 +854,7 @@ fn lower_path_segment(&mut self,
         }
 
         hir::PathSegment {
-            name: segment.identifier.name,
+            name: self.lower_ident(segment.identifier),
             parameters: parameters,
         }
     }
@@ -941,7 +951,7 @@ fn lower_ty_param_bound(&mut self, tpb: &TyParamBound) -> hir::TyParamBound {
     }
 
     fn lower_ty_param(&mut self, tp: &TyParam, add_bounds: &[TyParamBound]) -> hir::TyParam {
-        let mut name = tp.ident.name;
+        let mut name = self.lower_ident(tp.ident);
 
         // Don't expose `Self` (recovered "keyword used as ident" parse error).
         // `rustc::ty` expects `Self` to be only used for a trait's `Self`.
@@ -975,7 +985,7 @@ fn lower_ty_params(&mut self, tps: &Vec<TyParam>, add_bounds: &NodeMap<Vec<TyPar
     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
         hir::Lifetime {
             id: self.lower_node_id(l.id),
-            name: l.name,
+            name: self.lower_ident(l.ident),
             span: l.span,
         }
     }
@@ -1137,7 +1147,11 @@ fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::Stru
         hir::StructField {
             span: f.span,
             id: self.lower_node_id(f.id),
-            name: f.ident.map(|ident| ident.name).unwrap_or(Symbol::intern(&index.to_string())),
+            name: self.lower_ident(match f.ident {
+                Some(ident) => ident,
+                // FIXME(jseyfried) positional field hygiene
+                None => Ident { name: Symbol::intern(&index.to_string()), ctxt: f.span.ctxt },
+            }),
             vis: self.lower_visibility(&f.vis, None),
             ty: self.lower_ty(&f.ty),
             attrs: self.lower_attrs(&f.attrs),
@@ -1146,7 +1160,7 @@ fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::Stru
 
     fn lower_field(&mut self, f: &Field) -> hir::Field {
         hir::Field {
-            name: respan(f.ident.span, f.ident.node.name),
+            name: respan(f.ident.span, self.lower_ident(f.ident.node)),
             expr: P(self.lower_expr(&f.expr)),
             span: f.span,
             is_shorthand: f.is_shorthand,
@@ -1371,7 +1385,7 @@ fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
         self.with_parent_def(i.id, |this| {
             hir::TraitItem {
                 id: this.lower_node_id(i.id),
-                name: i.ident.name,
+                name: this.lower_ident(i.ident),
                 attrs: this.lower_attrs(&i.attrs),
                 node: match i.node {
                     TraitItemKind::Const(ref ty, ref default) => {
@@ -1421,7 +1435,7 @@ fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
         };
         hir::TraitItemRef {
             id: hir::TraitItemId { node_id: i.id },
-            name: i.ident.name,
+            name: self.lower_ident(i.ident),
             span: i.span,
             defaultness: self.lower_defaultness(Defaultness::Default, has_default),
             kind: kind,
@@ -1432,7 +1446,7 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
         self.with_parent_def(i.id, |this| {
             hir::ImplItem {
                 id: this.lower_node_id(i.id),
-                name: i.ident.name,
+                name: this.lower_ident(i.ident),
                 attrs: this.lower_attrs(&i.attrs),
                 vis: this.lower_visibility(&i.vis, None),
                 defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
@@ -1461,7 +1475,7 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
     fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
         hir::ImplItemRef {
             id: hir::ImplItemId { node_id: i.id },
-            name: i.ident.name,
+            name: self.lower_ident(i.ident),
             span: i.span,
             vis: self.lower_visibility(&i.vis, Some(i.id)),
             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
@@ -1501,17 +1515,23 @@ fn lower_item_id(&mut self, i: &Item) -> SmallVector<hir::ItemId> {
 
     pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
         let mut name = i.ident.name;
+        let mut vis = self.lower_visibility(&i.vis, None);
         let attrs = self.lower_attrs(&i.attrs);
-        if let ItemKind::MacroDef(ref tts) = i.node {
-            if i.attrs.iter().any(|attr| attr.path == "macro_export") {
+        if let ItemKind::MacroDef(ref def) = i.node {
+            if !def.legacy || i.attrs.iter().any(|attr| attr.path == "macro_export") {
                 self.exported_macros.push(hir::MacroDef {
-                    name: name, attrs: attrs, id: i.id, span: i.span, body: tts.clone().into(),
+                    name: name,
+                    vis: vis,
+                    attrs: attrs,
+                    id: i.id,
+                    span: i.span,
+                    body: def.stream(),
+                    legacy: def.legacy,
                 });
             }
             return None;
         }
 
-        let mut vis = self.lower_visibility(&i.vis, None);
         let node = self.with_parent_def(i.id, |this| {
             this.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node)
         });
@@ -1654,7 +1674,7 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                                        Spanned {
                                            span: f.span,
                                            node: hir::FieldPat {
-                                               name: f.node.ident.name,
+                                               name: self.lower_ident(f.node.ident),
                                                pat: self.lower_pat(&f.node.pat),
                                                is_shorthand: f.node.is_shorthand,
                                            },
@@ -1824,7 +1844,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
             ExprKind::MethodCall(i, ref tps, ref args) => {
                 let tps = tps.iter().map(|x| self.lower_ty(x)).collect();
                 let args = args.iter().map(|x| self.lower_expr(x)).collect();
-                hir::ExprMethodCall(respan(i.span, i.node.name), tps, args)
+                hir::ExprMethodCall(respan(i.span, self.lower_ident(i.node)), tps, args)
             }
             ExprKind::Binary(binop, ref lhs, ref rhs) => {
                 let binop = self.lower_binop(binop);
@@ -1923,7 +1943,8 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                                   P(self.lower_expr(er)))
             }
             ExprKind::Field(ref el, ident) => {
-                hir::ExprField(P(self.lower_expr(el)), respan(ident.span, ident.node.name))
+                hir::ExprField(P(self.lower_expr(el)),
+                               respan(ident.span, self.lower_ident(ident.node)))
             }
             ExprKind::TupField(ref el, ident) => {
                 hir::ExprTupField(P(self.lower_expr(el)), ident)
@@ -1934,13 +1955,13 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
             ExprKind::Range(ref e1, ref e2, lims) => {
                 use syntax::ast::RangeLimits::*;
 
-                let (path, variant) = match (e1, e2, lims) {
-                    (&None, &None, HalfOpen) => ("RangeFull", None),
-                    (&Some(..), &None, HalfOpen) => ("RangeFrom", None),
-                    (&None, &Some(..), HalfOpen) => ("RangeTo", None),
-                    (&Some(..), &Some(..), HalfOpen) => ("Range", None),
-                    (&None, &Some(..), Closed) => ("RangeToInclusive", None),
-                    (&Some(..), &Some(..), Closed) => ("RangeInclusive", Some("NonEmpty")),
+                let path = match (e1, e2, lims) {
+                    (&None, &None, HalfOpen) => "RangeFull",
+                    (&Some(..), &None, HalfOpen) => "RangeFrom",
+                    (&None, &Some(..), HalfOpen) => "RangeTo",
+                    (&Some(..), &Some(..), HalfOpen) => "Range",
+                    (&None, &Some(..), Closed) => "RangeToInclusive",
+                    (&Some(..), &Some(..), Closed) => "RangeInclusive",
                     (_, &None, Closed) =>
                         panic!(self.diagnostic().span_fatal(
                             e.span, "inclusive range with no end")),
@@ -1957,7 +1978,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let is_unit = fields.is_empty();
                 let unstable_span = self.allow_internal_unstable("...", e.span);
                 let struct_path =
-                    iter::once("ops").chain(iter::once(path)).chain(variant)
+                    iter::once("ops").chain(iter::once(path))
                     .collect::<Vec<_>>();
                 let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
@@ -2641,11 +2662,9 @@ fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMod
         let parent_def = self.parent_def.unwrap();
         let def_id = {
             let defs = self.resolver.definitions();
-            let def_path_data = DefPathData::Binding(name.as_str());
-            let def_index = defs.create_def_with_parent(parent_def,
-                                                        id,
-                                                        def_path_data,
-                                                        REGULAR_SPACE);
+            let def_path_data = DefPathData::Binding(Ident::with_empty_ctxt(name));
+            let def_index = defs
+                .create_def_with_parent(parent_def, id, def_path_data, REGULAR_SPACE, Mark::root());
             DefId::local(def_index)
         };
 
index 7ff5152c71a2cd6f29e306f01502dc68ed775a0b..cb25b462b6e243e791514e80316b73e29d5647c2 100644 (file)
@@ -14,7 +14,7 @@
 use syntax::ast::*;
 use syntax::ext::hygiene::Mark;
 use syntax::visit;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::keywords;
 
 use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE};
 
@@ -22,6 +22,7 @@
 pub struct DefCollector<'a> {
     definitions: &'a mut Definitions,
     parent_def: Option<DefIndex>,
+    expansion: Mark,
     pub visit_macro_invoc: Option<&'a mut FnMut(MacroInvocationData)>,
 }
 
@@ -32,9 +33,10 @@ pub struct MacroInvocationData {
 }
 
 impl<'a> DefCollector<'a> {
-    pub fn new(definitions: &'a mut Definitions) -> Self {
+    pub fn new(definitions: &'a mut Definitions, expansion: Mark) -> Self {
         DefCollector {
             definitions: definitions,
+            expansion: expansion,
             parent_def: None,
             visit_macro_invoc: None,
         }
@@ -54,7 +56,8 @@ fn create_def(&mut self,
                   -> DefIndex {
         let parent_def = self.parent_def.unwrap();
         debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
-        self.definitions.create_def_with_parent(parent_def, node_id, data, address_space)
+        self.definitions
+            .create_def_with_parent(parent_def, node_id, data, address_space, self.expansion)
     }
 
     pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
@@ -100,14 +103,14 @@ fn visit_item(&mut self, i: &'a Item) {
                 DefPathData::Impl,
             ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) |
             ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
-                DefPathData::TypeNs(i.ident.name.as_str()),
+                DefPathData::TypeNs(i.ident.modern()),
             ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
                 return visit::walk_item(self, i);
             }
-            ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_str()),
+            ItemKind::Mod(..) => DefPathData::Module(i.ident.modern()),
             ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
-                DefPathData::ValueNs(i.ident.name.as_str()),
-            ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name.as_str()),
+                DefPathData::ValueNs(i.ident.modern()),
+            ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.modern()),
             ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false),
             ItemKind::GlobalAsm(..) => DefPathData::Misc,
             ItemKind::Use(ref view_path) => {
@@ -135,15 +138,13 @@ fn visit_item(&mut self, i: &'a Item) {
                     for v in &enum_definition.variants {
                         let variant_def_index =
                             this.create_def(v.node.data.id(),
-                                            DefPathData::EnumVariant(v.node.name.name.as_str()),
+                                            DefPathData::EnumVariant(v.node.name.modern()),
                                             REGULAR_SPACE);
                         this.with_parent(variant_def_index, |this| {
                             for (index, field) in v.node.data.fields().iter().enumerate() {
-                                let name = field.ident.map(|ident| ident.name)
-                                    .unwrap_or_else(|| Symbol::intern(&index.to_string()));
-                                this.create_def(field.id,
-                                                DefPathData::Field(name.as_str()),
-                                                REGULAR_SPACE);
+                                let ident = field.ident.map(Ident::modern)
+                                    .unwrap_or_else(|| Ident::from_str(&index.to_string()));
+                                this.create_def(field.id, DefPathData::Field(ident), REGULAR_SPACE);
                             }
 
                             if let Some(ref expr) = v.node.disr_expr {
@@ -161,9 +162,9 @@ fn visit_item(&mut self, i: &'a Item) {
                     }
 
                     for (index, field) in struct_def.fields().iter().enumerate() {
-                        let name = field.ident.map(|ident| ident.name.as_str())
-                            .unwrap_or(Symbol::intern(&index.to_string()).as_str());
-                        this.create_def(field.id, DefPathData::Field(name), REGULAR_SPACE);
+                        let ident = field.ident.map(Ident::modern)
+                            .unwrap_or_else(|| Ident::from_str(&index.to_string()));
+                        this.create_def(field.id, DefPathData::Field(ident), REGULAR_SPACE);
                     }
                 }
                 _ => {}
@@ -174,7 +175,7 @@ fn visit_item(&mut self, i: &'a Item) {
 
     fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
         let def = self.create_def(foreign_item.id,
-                                  DefPathData::ValueNs(foreign_item.ident.name.as_str()),
+                                  DefPathData::ValueNs(foreign_item.ident.modern()),
                                   REGULAR_SPACE);
 
         self.with_parent(def, |this| {
@@ -185,7 +186,7 @@ fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
     fn visit_generics(&mut self, generics: &'a Generics) {
         for ty_param in generics.ty_params.iter() {
             self.create_def(ty_param.id,
-                            DefPathData::TypeParam(ty_param.ident.name.as_str()),
+                            DefPathData::TypeParam(ty_param.ident.modern()),
                             REGULAR_SPACE);
         }
 
@@ -195,8 +196,8 @@ fn visit_generics(&mut self, generics: &'a Generics) {
     fn visit_trait_item(&mut self, ti: &'a TraitItem) {
         let def_data = match ti.node {
             TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
-                DefPathData::ValueNs(ti.ident.name.as_str()),
-            TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name.as_str()),
+                DefPathData::ValueNs(ti.ident.modern()),
+            TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.modern()),
             TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
         };
 
@@ -213,8 +214,8 @@ fn visit_trait_item(&mut self, ti: &'a TraitItem) {
     fn visit_impl_item(&mut self, ii: &'a ImplItem) {
         let def_data = match ii.node {
             ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
-                DefPathData::ValueNs(ii.ident.name.as_str()),
-            ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name.as_str()),
+                DefPathData::ValueNs(ii.ident.modern()),
+            ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.modern()),
             ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
         };
 
@@ -235,7 +236,7 @@ fn visit_pat(&mut self, pat: &'a Pat) {
             PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false),
             PatKind::Ident(_, id, _) => {
                 let def = self.create_def(pat.id,
-                                          DefPathData::Binding(id.node.name.as_str()),
+                                          DefPathData::Binding(id.node.modern()),
                                           REGULAR_SPACE);
                 self.parent_def = Some(def);
             }
@@ -280,7 +281,7 @@ fn visit_ty(&mut self, ty: &'a Ty) {
 
     fn visit_lifetime_def(&mut self, def: &'a LifetimeDef) {
         self.create_def(def.lifetime.id,
-                        DefPathData::LifetimeDef(def.lifetime.name.as_str()),
+                        DefPathData::LifetimeDef(def.lifetime.ident.modern()),
                         REGULAR_SPACE);
     }
 
index 9537b40b28a0bec7234ccf31c8aec309c0dd135b..c86b140fbc61462d6723c5a61dbb140351c7b631 100644 (file)
@@ -23,7 +23,8 @@
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 use std::fmt::Write;
 use std::hash::Hash;
-use syntax::ast;
+use syntax::ast::{self, Ident};
+use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::symbol::{Symbol, InternedString};
 use ty::TyCtxt;
 use util::nodemap::NodeMap;
@@ -180,6 +181,8 @@ pub struct Definitions {
     node_to_def_index: NodeMap<DefIndex>,
     def_index_to_node: [Vec<ast::NodeId>; 2],
     pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
+    macro_def_scopes: FxHashMap<Mark, DefId>,
+    expansions: FxHashMap<DefIndex, Mark>,
 }
 
 // Unfortunately we have to provide a manual impl of Clone because of the
@@ -194,6 +197,8 @@ fn clone(&self) -> Self {
                 self.def_index_to_node[1].clone(),
             ],
             node_to_hir_id: self.node_to_hir_id.clone(),
+            macro_def_scopes: self.macro_def_scopes.clone(),
+            expansions: self.expansions.clone(),
         }
     }
 }
@@ -322,7 +327,7 @@ pub fn to_string_no_crate(&self) -> String {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum DefPathData {
     // Root: these should only be used for the root nodes, because
     // they are treated specially by the `def_path` function.
@@ -336,31 +341,31 @@ pub enum DefPathData {
     /// An impl
     Impl,
     /// Something in the type NS
-    TypeNs(InternedString),
+    TypeNs(Ident),
     /// Something in the value NS
-    ValueNs(InternedString),
+    ValueNs(Ident),
     /// A module declaration
-    Module(InternedString),
+    Module(Ident),
     /// A macro rule
-    MacroDef(InternedString),
+    MacroDef(Ident),
     /// A closure expression
     ClosureExpr,
 
     // Subportions of items
     /// A type parameter (generic parameter)
-    TypeParam(InternedString),
+    TypeParam(Ident),
     /// A lifetime definition
-    LifetimeDef(InternedString),
+    LifetimeDef(Ident),
     /// A variant of a enum
-    EnumVariant(InternedString),
+    EnumVariant(Ident),
     /// A struct field
-    Field(InternedString),
+    Field(Ident),
     /// Implicit ctor for a tuple-like struct
     StructCtor,
     /// Initializer for a const
     Initializer,
     /// Pattern binding
-    Binding(InternedString),
+    Binding(Ident),
     /// An `impl Trait` type node.
     ImplTrait,
     /// A `typeof` type node.
@@ -379,6 +384,8 @@ pub fn new() -> Definitions {
             node_to_def_index: NodeMap(),
             def_index_to_node: [vec![], vec![]],
             node_to_hir_id: IndexVec::new(),
+            macro_def_scopes: FxHashMap(),
+            expansions: FxHashMap(),
         }
     }
 
@@ -472,7 +479,8 @@ pub fn create_def_with_parent(&mut self,
                                   parent: DefIndex,
                                   node_id: ast::NodeId,
                                   data: DefPathData,
-                                  address_space: DefIndexAddressSpace)
+                                  address_space: DefIndexAddressSpace,
+                                  expansion: Mark)
                                   -> DefIndex {
         debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
                parent, node_id, data);
@@ -510,6 +518,9 @@ pub fn create_def_with_parent(&mut self,
         assert_eq!(index.as_array_index(),
                    self.def_index_to_node[address_space.index()].len());
         self.def_index_to_node[address_space.index()].push(node_id);
+        if expansion.is_modern() {
+            self.expansions.insert(index, expansion);
+        }
 
         debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
         self.node_to_def_index.insert(node_id, index);
@@ -525,21 +536,33 @@ pub fn init_node_id_to_hir_id_mapping(&mut self,
                 "Trying initialize NodeId -> HirId mapping twice");
         self.node_to_hir_id = mapping;
     }
+
+    pub fn expansion(&self, index: DefIndex) -> Mark {
+        self.expansions.get(&index).cloned().unwrap_or(Mark::root())
+    }
+
+    pub fn macro_def_scope(&self, mark: Mark) -> DefId {
+        self.macro_def_scopes[&mark]
+    }
+
+    pub fn add_macro_def_scope(&mut self, mark: Mark, scope: DefId) {
+        self.macro_def_scopes.insert(mark, scope);
+    }
 }
 
 impl DefPathData {
-    pub fn get_opt_name(&self) -> Option<ast::Name> {
+    pub fn get_opt_ident(&self) -> Option<Ident> {
         use self::DefPathData::*;
         match *self {
-            TypeNs(ref name) |
-            ValueNs(ref name) |
-            Module(ref name) |
-            MacroDef(ref name) |
-            TypeParam(ref name) |
-            LifetimeDef(ref name) |
-            EnumVariant(ref name) |
-            Binding(ref name) |
-            Field(ref name) => Some(Symbol::intern(name)),
+            TypeNs(ident) |
+            ValueNs(ident) |
+            Module(ident) |
+            MacroDef(ident) |
+            TypeParam(ident) |
+            LifetimeDef(ident) |
+            EnumVariant(ident) |
+            Binding(ident) |
+            Field(ident) => Some(ident),
 
             Impl |
             CrateRoot |
@@ -552,19 +575,23 @@ pub fn get_opt_name(&self) -> Option<ast::Name> {
         }
     }
 
+    pub fn get_opt_name(&self) -> Option<ast::Name> {
+        self.get_opt_ident().map(|ident| ident.name)
+    }
+
     pub fn as_interned_str(&self) -> InternedString {
         use self::DefPathData::*;
         let s = match *self {
-            TypeNs(ref name) |
-            ValueNs(ref name) |
-            Module(ref name) |
-            MacroDef(ref name) |
-            TypeParam(ref name) |
-            LifetimeDef(ref name) |
-            EnumVariant(ref name) |
-            Binding(ref name) |
-            Field(ref name) => {
-                return name.clone();
+            TypeNs(ident) |
+            ValueNs(ident) |
+            Module(ident) |
+            MacroDef(ident) |
+            TypeParam(ident) |
+            LifetimeDef(ident) |
+            EnumVariant(ident) |
+            Binding(ident) |
+            Field(ident) => {
+                return ident.name.as_str();
             }
 
             // note that this does not show up in user printouts
@@ -586,3 +613,25 @@ pub fn to_string(&self) -> String {
         self.as_interned_str().to_string()
     }
 }
+
+impl Eq for DefPathData {}
+impl PartialEq for DefPathData {
+    fn eq(&self, other: &DefPathData) -> bool {
+        ::std::mem::discriminant(self) == ::std::mem::discriminant(other) &&
+        self.get_opt_ident() == other.get_opt_ident()
+    }
+}
+
+impl ::std::hash::Hash for DefPathData {
+    fn hash<H: ::std::hash::Hasher>(&self, hasher: &mut H) {
+        ::std::mem::discriminant(self).hash(hasher);
+        if let Some(ident) = self.get_opt_ident() {
+            if ident.ctxt == SyntaxContext::empty() && ident.name == ident.name.interned() {
+                ident.name.as_str().hash(hasher)
+            } else {
+                // FIXME(jseyfried) implement stable hashing for idents with macros 2.0 hygiene info
+                ident.hash(hasher)
+            }
+        }
+    }
+}
index 868730edfedda83b1d4d10ef586ca3f37b75dc58..09e9d7c5b2f7d81cd8355e0bfc1254cec19e4721 100644 (file)
@@ -637,14 +637,15 @@ pub fn get_parent(&self, id: NodeId) -> NodeId {
 
     /// Returns the NodeId of `id`'s nearest module parent, or `id` itself if no
     /// module parent is in this map.
-    pub fn get_module_parent(&self, id: NodeId) -> NodeId {
-        match self.walk_parent_nodes(id, |node| match *node {
+    pub fn get_module_parent(&self, id: NodeId) -> DefId {
+        let id = match self.walk_parent_nodes(id, |node| match *node {
             NodeItem(&Item { node: Item_::ItemMod(_), .. }) => true,
             _ => false,
         }) {
             Ok(id) => id,
             Err(id) => id,
-        }
+        };
+        self.local_def_id(id)
     }
 
     /// Returns the nearest enclosing scope. A scope is an item or block.
index cb7f530b9952f779011e899b13dbde7fde04b977..500e95a8a778ee46d99b7342eff8c77268fa0464 100644 (file)
@@ -162,7 +162,7 @@ pub fn is_elided(&self) -> bool {
     }
 
     pub fn is_static(&self) -> bool {
-        self.name == keywords::StaticLifetime.name()
+        self.name == "'static"
     }
 }
 
@@ -532,10 +532,12 @@ pub fn body(&self, id: BodyId) -> &Body {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct MacroDef {
     pub name: Name,
+    pub vis: Visibility,
     pub attrs: HirVec<Attribute>,
     pub id: NodeId,
     pub span: Span,
     pub body: TokenStream,
+    pub legacy: bool,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
index abc51601b6ecef814c2ea2e95da8e37739367521..dbe91e2725deffec2a377df2602646edbb886d79 100644 (file)
@@ -329,9 +329,11 @@ fn hash_stable<W: StableHasherResult>(&self,
 
 impl_stable_hash_for!(struct hir::MacroDef {
     name,
+    vis,
     attrs,
     id,
     span,
+    legacy,
     body
 });
 
@@ -1116,7 +1118,7 @@ fn hash_stable<W: StableHasherResult>(&self,
 }
 
 impl_stable_hash_for!(struct hir::def::Export {
-    name,
+    ident,
     def,
     span
 });
index 7138db01339f6a89489a6204526c24fb26c96b87..f6ad97445e8bfed57368219e40f382d274c63a88 100644 (file)
@@ -63,6 +63,7 @@ fn hash_stable<W: StableHasherResult>(&self,
     Stdcall,
     Fastcall,
     Vectorcall,
+    Thiscall,
     Aapcs,
     Win64,
     SysV64,
@@ -130,7 +131,7 @@ fn hash_stable<W: StableHasherResult>(&self,
 impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
 impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
 impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
-impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, name });
+impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, ident });
 impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
 impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
 
index 2b4b5cc73337b7306dc5d6a9d3c3bda7ce9fd7a9..d1d9dd4853d7baa19ee5a43266f8d8321f1ec131 100644 (file)
@@ -28,6 +28,7 @@
 #![feature(conservative_impl_trait)]
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
+#![feature(discriminant_value)]
 #![feature(i128_type)]
 #![feature(libc)]
 #![feature(never_type)]
index 9d5ba2c8f950101547a810d5ea2a398f044249f0..4c25a455f292d4a9d62033e833c0957b48c19246 100644 (file)
@@ -40,6 +40,7 @@
 use std::default::Default as StdDefault;
 use std::mem;
 use std::fmt;
+use std::cell::{Ref, RefCell};
 use syntax::attr;
 use syntax::ast;
 use syntax::symbol::Symbol;
@@ -49,7 +50,6 @@
 use hir::def_id::LOCAL_CRATE;
 use hir::intravisit as hir_visit;
 use syntax::visit as ast_visit;
-use syntax::tokenstream::ThinTokenStream;
 
 /// Information about the registered lints.
 ///
@@ -61,8 +61,8 @@ pub struct LintStore {
     lints: Vec<(&'static Lint, bool)>,
 
     /// Trait objects for each lint pass.
-    /// This is only `None` while iterating over the objects. See the definition
-    /// of run_lints.
+    /// This is only `None` while performing a lint pass. See the definition
+    /// of `LintSession::new`.
     early_passes: Option<Vec<EarlyLintPassObject>>,
     late_passes: Option<Vec<LateLintPassObject>>,
 
@@ -70,7 +70,7 @@ pub struct LintStore {
     by_name: FxHashMap<String, TargetLint>,
 
     /// Current levels of each lint, and where they were set.
-    levels: FxHashMap<LintId, LevelSource>,
+    levels: LintLevels,
 
     /// Map of registered lint groups to what lints they expand to. The bool
     /// is true if the lint group was added by a plugin.
@@ -79,11 +79,36 @@ pub struct LintStore {
     /// Extra info for future incompatibility lints, descibing the
     /// issue or RFC that caused the incompatibility.
     future_incompatible: FxHashMap<LintId, FutureIncompatibleInfo>,
+}
+
+
+#[derive(Default)]
+struct LintLevels {
+    /// Current levels of each lint, and where they were set.
+    levels: FxHashMap<LintId, LevelSource>,
 
     /// Maximum level a lint can be
     lint_cap: Option<Level>,
 }
 
+
+pub struct LintSession<'a, PassObject> {
+    /// Reference to the store of registered lints.
+    lints: Ref<'a, LintStore>,
+
+    /// The current lint levels.
+    levels: LintLevels,
+
+    /// When recursing into an attributed node of the ast which modifies lint
+    /// levels, this stack keeps track of the previous lint levels of whatever
+    /// was modified.
+    stack: Vec<(LintId, LevelSource)>,
+
+    /// Trait objects for each lint pass.
+    passes: Option<Vec<PassObject>>,
+}
+
+
 /// When you call `add_lint` on the session, you wind up storing one
 /// of these, which records a "potential lint" at a particular point.
 #[derive(PartialEq, RustcEncodable, RustcDecodable)]
@@ -157,34 +182,15 @@ enum FindLintError {
 }
 
 impl LintStore {
-    fn get_level_source(&self, lint: LintId) -> LevelSource {
-        match self.levels.get(&lint) {
-            Some(&s) => s,
-            None => (Allow, Default),
-        }
-    }
-
-    fn set_level(&mut self, lint: LintId, mut lvlsrc: LevelSource) {
-        if let Some(cap) = self.lint_cap {
-            lvlsrc.0 = cmp::min(lvlsrc.0, cap);
-        }
-        if lvlsrc.0 == Allow {
-            self.levels.remove(&lint);
-        } else {
-            self.levels.insert(lint, lvlsrc);
-        }
-    }
-
     pub fn new() -> LintStore {
         LintStore {
             lints: vec![],
             early_passes: Some(vec![]),
             late_passes: Some(vec![]),
             by_name: FxHashMap(),
-            levels: FxHashMap(),
+            levels: LintLevels::default(),
             future_incompatible: FxHashMap(),
             lint_groups: FxHashMap(),
-            lint_cap: None,
         }
     }
 
@@ -236,9 +242,7 @@ fn push_pass<P: LintPass + ?Sized + 'static>(&mut self,
                 }
             }
 
-            if lint.default_level != Allow {
-                self.levels.insert(id, (lint.default_level, Default));
-            }
+            self.levels.set(id, (lint.default_level, Default));
         }
     }
 
@@ -310,7 +314,7 @@ pub fn process_command_line(&mut self, sess: &Session) {
 
             let lint_flag_val = Symbol::intern(&lint_name);
             match self.find_lint(&lint_name[..], sess, None) {
-                Ok(lint_id) => self.set_level(lint_id, (level, CommandLine(lint_flag_val))),
+                Ok(lint_id) => self.levels.set(lint_id, (level, CommandLine(lint_flag_val))),
                 Err(FindLintError::Removed) => { }
                 Err(_) => {
                     match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone()))
@@ -318,10 +322,9 @@ pub fn process_command_line(&mut self, sess: &Session) {
                                                                       Vec<LintId>>>()
                                                  .get(&lint_name[..]) {
                         Some(v) => {
-                            v.iter()
-                             .map(|lint_id: &LintId|
-                                     self.set_level(*lint_id, (level, CommandLine(lint_flag_val))))
-                             .collect::<Vec<()>>();
+                            for lint_id in v {
+                                self.levels.set(*lint_id, (level, CommandLine(lint_flag_val)));
+                            }
                         }
                         None => {
                             // The lint or lint group doesn't exist.
@@ -333,15 +336,73 @@ pub fn process_command_line(&mut self, sess: &Session) {
             }
         }
 
-        self.lint_cap = sess.opts.lint_cap;
+        self.levels.set_lint_cap(sess.opts.lint_cap);
+    }
+}
+
+
+impl LintLevels {
+    fn get_source(&self, lint: LintId) -> LevelSource {
+        match self.levels.get(&lint) {
+            Some(&s) => s,
+            None => (Allow, Default),
+        }
+    }
+
+    fn set(&mut self, lint: LintId, mut lvlsrc: LevelSource) {
         if let Some(cap) = self.lint_cap {
-            for level in self.levels.iter_mut().map(|p| &mut (p.1).0) {
-                *level = cmp::min(*level, cap);
+            lvlsrc.0 = cmp::min(lvlsrc.0, cap);
+        }
+        if lvlsrc.0 == Allow {
+            self.levels.remove(&lint);
+        } else {
+            self.levels.insert(lint, lvlsrc);
+        }
+    }
+
+    fn set_lint_cap(&mut self, lint_cap: Option<Level>) {
+        self.lint_cap = lint_cap;
+        if let Some(cap) = lint_cap {
+            for (_, level) in &mut self.levels {
+                level.0 = cmp::min(level.0, cap);
             }
         }
     }
 }
 
+
+impl<'a, PassObject: LintPassObject> LintSession<'a, PassObject> {
+    /// Creates a new `LintSession`, by moving out the `LintStore`'s initial
+    /// lint levels and pass objects. These can be restored using the `restore`
+    /// method.
+    fn new(store: &'a RefCell<LintStore>) -> LintSession<'a, PassObject> {
+        let mut s = store.borrow_mut();
+        let levels = mem::replace(&mut s.levels, LintLevels::default());
+        let passes = PassObject::take_passes(&mut *s);
+        drop(s);
+        LintSession {
+            lints: store.borrow(),
+            stack: Vec::new(),
+            levels,
+            passes,
+        }
+    }
+
+    /// Restores the levels back to the original lint store.
+    fn restore(self, store: &RefCell<LintStore>) {
+        drop(self.lints);
+        let mut s = store.borrow_mut();
+        s.levels = self.levels;
+        PassObject::restore_passes(&mut *s, self.passes);
+    }
+
+    fn get_source(&self, lint_id: LintId) -> LevelSource {
+        self.levels.get_source(lint_id)
+    }
+}
+
+
+
 /// Context for lint checking after type checking.
 pub struct LateContext<'a, 'tcx: 'a> {
     /// Type context we're checking in.
@@ -356,13 +417,8 @@ pub struct LateContext<'a, 'tcx: 'a> {
     /// Items accessible from the crate being checked.
     pub access_levels: &'a AccessLevels,
 
-    /// The store of registered lints.
-    lints: LintStore,
-
-    /// When recursing into an attributed node of the ast which modifies lint
-    /// levels, this stack keeps track of the previous lint levels of whatever
-    /// was modified.
-    level_stack: Vec<(LintId, LevelSource)>,
+    /// The store of registered lints and the lint levels.
+    lint_sess: LintSession<'tcx, LateLintPassObject>,
 }
 
 /// Context for lint checking of the AST, after expansion, before lowering to
@@ -374,24 +430,19 @@ pub struct EarlyContext<'a> {
     /// The crate being checked.
     pub krate: &'a ast::Crate,
 
-    /// The store of registered lints.
-    lints: LintStore,
-
-    /// When recursing into an attributed node of the ast which modifies lint
-    /// levels, this stack keeps track of the previous lint levels of whatever
-    /// was modified.
-    level_stack: Vec<(LintId, LevelSource)>,
+    /// The store of registered lints and the lint levels.
+    lint_sess: LintSession<'a, EarlyLintPassObject>,
 }
 
 /// Convenience macro for calling a `LintPass` method on every pass in the context.
 macro_rules! run_lints { ($cx:expr, $f:ident, $ps:ident, $($args:expr),*) => ({
     // Move the vector of passes out of `$cx` so that we can
     // iterate over it mutably while passing `$cx` to the methods.
-    let mut passes = $cx.mut_lints().$ps.take().unwrap();
+    let mut passes = $cx.lint_sess_mut().passes.take().unwrap();
     for obj in &mut passes {
         obj.$f($cx, $($args),*);
     }
-    $cx.mut_lints().$ps = Some(passes);
+    $cx.lint_sess_mut().passes = Some(passes);
 }) }
 
 /// Parse the lint attributes into a vector, with `Err`s for malformed lint
@@ -522,25 +573,55 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
     err
 }
 
+
+pub trait LintPassObject: Sized {
+    fn take_passes(store: &mut LintStore) -> Option<Vec<Self>>;
+    fn restore_passes(store: &mut LintStore, passes: Option<Vec<Self>>);
+}
+
+impl LintPassObject for EarlyLintPassObject {
+    fn take_passes(store: &mut LintStore) -> Option<Vec<Self>> {
+        store.early_passes.take()
+    }
+
+    fn restore_passes(store: &mut LintStore, passes: Option<Vec<Self>>) {
+        store.early_passes = passes;
+    }
+}
+
+impl LintPassObject for LateLintPassObject {
+    fn take_passes(store: &mut LintStore) -> Option<Vec<Self>> {
+        store.late_passes.take()
+    }
+
+    fn restore_passes(store: &mut LintStore, passes: Option<Vec<Self>>) {
+        store.late_passes = passes;
+    }
+}
+
+
 pub trait LintContext<'tcx>: Sized {
+    type PassObject: LintPassObject;
+
     fn sess(&self) -> &Session;
     fn lints(&self) -> &LintStore;
-    fn mut_lints(&mut self) -> &mut LintStore;
-    fn level_stack(&mut self) -> &mut Vec<(LintId, LevelSource)>;
+    fn lint_sess(&self) -> &LintSession<'tcx, Self::PassObject>;
+    fn lint_sess_mut(&mut self) -> &mut LintSession<'tcx, Self::PassObject>;
     fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]);
     fn exit_attrs(&mut self, attrs: &'tcx [ast::Attribute]);
 
     /// Get the level of `lint` at the current position of the lint
     /// traversal.
     fn current_level(&self, lint: &'static Lint) -> Level {
-        self.lints().levels.get(&LintId::of(lint)).map_or(Allow, |&(lvl, _)| lvl)
+        self.lint_sess().get_source(LintId::of(lint)).0
     }
 
     fn level_src(&self, lint: &'static Lint) -> Option<LevelSource> {
-        self.lints().levels.get(&LintId::of(lint)).map(|ls| match ls {
+        let ref levels = self.lint_sess().levels;
+        levels.levels.get(&LintId::of(lint)).map(|ls| match ls {
             &(Warn, _) => {
                 let lint_id = LintId::of(builtin::WARNINGS);
-                let warn_src = self.lints().get_level_source(lint_id);
+                let warn_src = levels.get_source(lint_id);
                 if warn_src.0 != Warn {
                     warn_src
                 } else {
@@ -674,7 +755,7 @@ fn with_lint_attrs<F>(&mut self,
             let lint_attr_name = result.expect("lint attribute should be well-formed").0;
 
             for (lint_id, level, span) in v {
-                let (now, now_source) = self.lints().get_level_source(lint_id);
+                let (now, now_source) = self.lint_sess().get_source(lint_id);
                 if now == Forbid && level != Forbid {
                     let lint_name = lint_id.to_string();
                     let mut diag_builder = struct_span_err!(self.sess(), span, E0453,
@@ -693,10 +774,10 @@ fn with_lint_attrs<F>(&mut self,
                         }
                     }.emit()
                 } else if now != level {
-                    let src = self.lints().get_level_source(lint_id).1;
-                    self.level_stack().push((lint_id, (now, src)));
+                    let cx = self.lint_sess_mut();
+                    cx.stack.push((lint_id, (now, now_source)));
                     pushed += 1;
-                    self.mut_lints().set_level(lint_id, (level, Node(lint_attr_name, span)));
+                    cx.levels.set(lint_id, (level, Node(lint_attr_name, span)));
                 }
             }
         }
@@ -706,9 +787,10 @@ fn with_lint_attrs<F>(&mut self,
         self.exit_attrs(attrs);
 
         // rollback
+        let cx = self.lint_sess_mut();
         for _ in 0..pushed {
-            let (lint, lvlsrc) = self.level_stack().pop().unwrap();
-            self.mut_lints().set_level(lint, lvlsrc);
+            let (lint, lvlsrc) = cx.stack.pop().unwrap();
+            cx.levels.set(lint, lvlsrc);
         }
     }
 }
@@ -717,35 +799,32 @@ fn with_lint_attrs<F>(&mut self,
 impl<'a> EarlyContext<'a> {
     fn new(sess: &'a Session,
            krate: &'a ast::Crate) -> EarlyContext<'a> {
-        // We want to own the lint store, so move it out of the session. Remember
-        // to put it back later...
-        let lint_store = mem::replace(&mut *sess.lint_store.borrow_mut(),
-                                      LintStore::new());
         EarlyContext {
             sess: sess,
             krate: krate,
-            lints: lint_store,
-            level_stack: vec![],
+            lint_sess: LintSession::new(&sess.lint_store),
         }
     }
 }
 
 impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> {
+    type PassObject = LateLintPassObject;
+
     /// Get the overall compiler `Session` object.
     fn sess(&self) -> &Session {
         &self.tcx.sess
     }
 
     fn lints(&self) -> &LintStore {
-        &self.lints
+        &*self.lint_sess.lints
     }
 
-    fn mut_lints(&mut self) -> &mut LintStore {
-        &mut self.lints
+    fn lint_sess(&self) -> &LintSession<'tcx, Self::PassObject> {
+        &self.lint_sess
     }
 
-    fn level_stack(&mut self) -> &mut Vec<(LintId, LevelSource)> {
-        &mut self.level_stack
+    fn lint_sess_mut(&mut self) -> &mut LintSession<'tcx, Self::PassObject> {
+        &mut self.lint_sess
     }
 
     fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]) {
@@ -760,21 +839,23 @@ fn exit_attrs(&mut self, attrs: &'tcx [ast::Attribute]) {
 }
 
 impl<'a> LintContext<'a> for EarlyContext<'a> {
+    type PassObject = EarlyLintPassObject;
+
     /// Get the overall compiler `Session` object.
     fn sess(&self) -> &Session {
         &self.sess
     }
 
     fn lints(&self) -> &LintStore {
-        &self.lints
+        &*self.lint_sess.lints
     }
 
-    fn mut_lints(&mut self) -> &mut LintStore {
-        &mut self.lints
+    fn lint_sess(&self) -> &LintSession<'a, Self::PassObject> {
+        &self.lint_sess
     }
 
-    fn level_stack(&mut self) -> &mut Vec<(LintId, LevelSource)> {
-        &mut self.level_stack
+    fn lint_sess_mut(&mut self) -> &mut LintSession<'a, Self::PassObject> {
+        &mut self.lint_sess
     }
 
     fn enter_attrs(&mut self, attrs: &'a [ast::Attribute]) {
@@ -1127,7 +1208,7 @@ fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
         run_lints!(self, check_attribute, early_passes, attr);
     }
 
-    fn visit_mac_def(&mut self, _mac: &'a ThinTokenStream, id: ast::NodeId) {
+    fn visit_mac_def(&mut self, _mac: &'a ast::MacroDef, id: ast::NodeId) {
         let lints = self.sess.lints.borrow_mut().take(id);
         for early_lint in lints {
             self.early_lint(&early_lint);
@@ -1191,7 +1272,7 @@ fn check_lint_name_attribute(cx: &LateContext, attr: &ast::Attribute) {
                 continue;
             }
             Ok((lint_name, _, span)) => {
-                match check_lint_name(&cx.lints, &lint_name.as_str()) {
+                match check_lint_name(&cx.lint_sess.lints, &lint_name.as_str()) {
                     CheckLintNameResult::Ok => (),
                     CheckLintNameResult::Warning(ref msg) => {
                         cx.span_lint(builtin::RENAMED_AND_REMOVED_LINTS,
@@ -1246,15 +1327,12 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
 
     let krate = tcx.hir.krate();
 
-    // We want to own the lint store, so move it out of the session.
-    let lint_store = mem::replace(&mut *tcx.sess.lint_store.borrow_mut(), LintStore::new());
     let mut cx = LateContext {
         tcx: tcx,
         tables: &ty::TypeckTables::empty(),
         krate: krate,
         access_levels: access_levels,
-        lints: lint_store,
-        level_stack: vec![],
+        lint_sess: LintSession::new(&tcx.sess.lint_store),
     };
 
     // Visit the whole crate.
@@ -1278,8 +1356,8 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         }
     }
 
-    // Put the lint store back in the session.
-    mem::replace(&mut *tcx.sess.lint_store.borrow_mut(), cx.lints);
+    // Put the lint store levels and passes back in the session.
+    cx.lint_sess.restore(&tcx.sess.lint_store);
 }
 
 pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
@@ -1302,8 +1380,8 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
         run_lints!(cx, check_crate_post, early_passes, krate);
     });
 
-    // Put the lint store back in the session.
-    mem::replace(&mut *sess.lint_store.borrow_mut(), cx.lints);
+    // Put the lint store levels and passes back in the session.
+    cx.lint_sess.restore(&sess.lint_store);
 
     // If we missed any lints added to the session, then there's a bug somewhere
     // in the iteration code.
index 5360a86560d399235a660c877c47090fea23bf3f..2261f296454ef75470a7f648ff1e6c665cc644ab 100644 (file)
@@ -52,6 +52,7 @@ fn type_is_unsafe_function(ty: Ty) -> bool {
 struct EffectCheckVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
+    body_id: hir::BodyId,
 
     /// Whether we're in an unsafe context.
     unsafe_context: UnsafeContext,
@@ -99,10 +100,13 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
         let old_tables = self.tables;
+        let old_body_id = self.body_id;
         self.tables = self.tcx.body_tables(body);
+        self.body_id = body;
         let body = self.tcx.hir.body(body);
         self.visit_body(body);
         self.tables = old_tables;
+        self.body_id = old_body_id;
     }
 
     fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl,
@@ -218,6 +222,25 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
                     }
                 }
             }
+            hir::ExprAssign(ref lhs, ref rhs) => {
+                if let hir::ExprField(ref base_expr, field) = lhs.node {
+                    if let ty::TyAdt(adt, ..) = self.tables.expr_ty_adjusted(base_expr).sty {
+                        if adt.is_union() {
+                            let field_ty = self.tables.expr_ty_adjusted(lhs);
+                            let owner_def_id = self.tcx.hir.body_owner_def_id(self.body_id);
+                            let param_env = self.tcx.param_env(owner_def_id);
+                            if field_ty.moves_by_default(self.tcx, param_env, field.span) {
+                                self.require_unsafe(field.span,
+                                                    "assignment to non-`Copy` union field");
+                            }
+                            // Do not walk the field expr again.
+                            intravisit::walk_expr(self, base_expr);
+                            intravisit::walk_expr(self, rhs);
+                            return
+                        }
+                    }
+                }
+            }
             _ => {}
         }
 
@@ -243,6 +266,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut visitor = EffectCheckVisitor {
         tcx: tcx,
         tables: &ty::TypeckTables::empty(),
+        body_id: hir::BodyId { node_id: ast::CRATE_NODE_ID },
         unsafe_context: UnsafeContext::new(SafeContext),
     };
 
index 7d7308d73bb048a2b5ed81d8e1166d4606e1788b..1a07423bcbc0f88d44224be61db72b5b53a53d92 100644 (file)
@@ -26,7 +26,6 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::ptr::P;
-use syntax::symbol::keywords;
 use syntax_pos::Span;
 use errors::DiagnosticBuilder;
 use util::nodemap::{NodeMap, NodeSet, FxHashSet, FxHashMap, DefIdMap};
@@ -746,7 +745,7 @@ fn add_bounds(set: &mut Set1<ast::Name>, bounds: &[hir::TyParamBound]) {
         match set {
             Set1::Empty => Set1::Empty,
             Set1::One(name) => {
-                if name == keywords::StaticLifetime.name() {
+                if name == "'static" {
                     Set1::One(Region::Static)
                 } else {
                     generics.lifetimes.iter().enumerate().find(|&(_, def)| {
index fa731f6dde638f6fb97f3ff4acf282ad5e5239c9..963ee9b7165e5c28acff4414b27755618f2c81ac 100644 (file)
@@ -45,8 +45,9 @@
 use std::slice;
 use std::vec::IntoIter;
 use std::mem;
-use syntax::ast::{self, DUMMY_NODE_ID, Name, NodeId};
+use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId};
 use syntax::attr;
+use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::symbol::{Symbol, InternedString};
 use syntax_pos::{DUMMY_SP, Span};
 use rustc_const_math::ConstInt;
@@ -268,7 +269,7 @@ pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
                 def => Visibility::Restricted(def.def_id()),
             },
             hir::Inherited => {
-                Visibility::Restricted(tcx.hir.local_def_id(tcx.hir.get_module_parent(id)))
+                Visibility::Restricted(tcx.hir.get_module_parent(id))
             }
         }
     }
@@ -1823,17 +1824,22 @@ fn sized_constraint_for_ty(&self,
 
 impl<'a, 'gcx, 'tcx> VariantDef {
     #[inline]
-    pub fn find_field_named(&self,
-                            name: ast::Name)
-                            -> Option<&FieldDef> {
-        self.fields.iter().find(|f| f.name == name)
+    pub fn find_field_named(&self, name: ast::Name) -> Option<&FieldDef> {
+        self.index_of_field_named(name).map(|index| &self.fields[index])
     }
 
-    #[inline]
-    pub fn index_of_field_named(&self,
-                                name: ast::Name)
-                                -> Option<usize> {
-        self.fields.iter().position(|f| f.name == name)
+    pub fn index_of_field_named(&self, name: ast::Name) -> Option<usize> {
+        if let Some(index) = self.fields.iter().position(|f| f.name == name) {
+            return Some(index);
+        }
+        let mut ident = name.to_ident();
+        while ident.ctxt != SyntaxContext::empty() {
+            ident.ctxt.remove_mark();
+            if let Some(field) = self.fields.iter().position(|f| f.name.to_ident() == ident) {
+                return Some(field);
+            }
+        }
+        None
     }
 
     #[inline]
@@ -2257,10 +2263,6 @@ pub fn def_path_hash(self, def_id: DefId) -> ich::Fingerprint {
         }
     }
 
-    pub fn vis_is_accessible_from(self, vis: Visibility, block: NodeId) -> bool {
-        vis.is_accessible_from(self.hir.local_def_id(self.hir.get_module_parent(block)), self)
-    }
-
     pub fn item_name(self, id: DefId) -> ast::Name {
         if let Some(id) = self.hir.as_local_node_id(id) {
             self.hir.name(id)
@@ -2372,6 +2374,22 @@ pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
             Err(self.sess.cstore.crate_name(impl_did.krate))
         }
     }
+
+    pub fn adjust(self, name: Name, scope: DefId, block: NodeId) -> (Ident, DefId) {
+        self.adjust_ident(name.to_ident(), scope, block)
+    }
+
+    pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: NodeId) -> (Ident, DefId) {
+        let expansion = match scope.krate {
+            LOCAL_CRATE => self.hir.definitions().expansion(scope.index),
+            _ => Mark::root(),
+        };
+        let scope = match ident.ctxt.adjust(expansion) {
+            Some(macro_def) => self.hir.definitions().macro_def_scope(macro_def),
+            None => self.hir.get_module_parent(block),
+        };
+        (ident, scope)
+    }
 }
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
index ad132c27cb8412210f9920c9cb8c11905f9819b1..416e5a0e13a887d49384fa8b20dc3774cbb5d7fc 100644 (file)
@@ -12,5 +12,5 @@
 
 // All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm
 pub fn abi_blacklist() -> Vec<Abi> {
-    vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Win64, Abi::SysV64]
+    vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Thiscall, Abi::Win64, Abi::SysV64]
 }
index 7ed5f620816e11d5cca9c3ddf10fdabf3fdcb47c..b35b0865991659d29b461f44f441bc2991ab9d2d 100644 (file)
@@ -154,7 +154,7 @@ fn check_match(
             }
         }
 
-        let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(scrut.id));
+        let module = self.tcx.hir.get_module_parent(scrut.id);
         MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
             let mut have_errors = false;
 
@@ -182,7 +182,7 @@ fn check_match(
             // Then, if the match has no arms, check whether the scrutinee
             // is uninhabited.
             let pat_ty = self.tables.node_id_to_type(scrut.id);
-            let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(scrut.id));
+            let module = self.tcx.hir.get_module_parent(scrut.id);
             if inlined_arms.is_empty() {
                 let scrutinee_is_uninhabited = if self.tcx.sess.features.borrow().never_type {
                     pat_ty.is_uninhabited_from(module, self.tcx)
@@ -231,7 +231,7 @@ fn check_irrefutable(&self, pat: &Pat, is_fn_arg: bool) {
             "local binding"
         };
 
-        let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(pat.id));
+        let module = self.tcx.hir.get_module_parent(pat.id);
         MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
             let mut patcx = PatternContext::new(self.tcx, self.tables);
             let pattern = patcx.lower_pattern(pat);
index 7ecd7c5412e03920a8297674fa07f8c596b4988f..c5f89e861fa131b759ba227ad2b4ac448143783a 100644 (file)
 fn abort_msg(err_count: usize) -> String {
     match err_count {
         0 => "aborting with no errors (maybe a bug?)".to_owned(),
-        1 => "aborting due to previous error".to_owned(),
-        e => format!("aborting due to {} previous errors", e),
+        _ => "aborting due to previous error(s)".to_owned(),
     }
 }
 
index c91dc9d87978dedb3c1011792010971c70ab0e29..f7191e49216375c6e21da99d2a94d2805f8c00cc 100644 (file)
@@ -501,10 +501,7 @@ pub fn abort_if_errors(&self) {
 
                 return;
             }
-            1 => s = "aborting due to previous error".to_string(),
-            _ => {
-                s = format!("aborting due to {} previous errors", self.err_count.get());
-            }
+            _ => s = "aborting due to previous error(s)".to_string(),
         }
 
         panic!(self.fatal(&s));
diff --git a/src/librustc_llvm/Cargo.lock b/src/librustc_llvm/Cargo.lock
deleted file mode 100644 (file)
index 17678ef..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-[root]
-name = "rustc_llvm"
-version = "0.0.0"
-dependencies = [
- "build_helper 0.1.0",
- "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc_bitflags 0.0.0",
-]
-
-[[package]]
-name = "build_helper"
-version = "0.1.0"
-
-[[package]]
-name = "gcc"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "rustc_bitflags"
-version = "0.0.0"
-
index 5cb5a62c93b35ad6075c289283931ccf8d19b7ec..d7b575d90a68b3807c40501723ecb8cc2b679c25 100644 (file)
@@ -49,6 +49,7 @@ pub enum CallConv {
     X86FastcallCallConv = 65,
     ArmAapcsCallConv = 67,
     Msp430Intr = 69,
+    X86_ThisCall = 70,
     PtxKernel = 71,
     X86_64_SysV = 78,
     X86_64_Win64 = 79,
index 7478f902e061a321614af006535e68a6f129dcae..9d098557367cd48311369dfc59557c7f5a1ee188 100644 (file)
@@ -386,7 +386,10 @@ fn load_macro(&self, id: DefId, sess: &Session) -> LoadedMacro {
             id: ast::DUMMY_NODE_ID,
             span: local_span,
             attrs: attrs.iter().cloned().collect(),
-            node: ast::ItemKind::MacroDef(body.into()),
+            node: ast::ItemKind::MacroDef(ast::MacroDef {
+                tokens: body.into(),
+                legacy: def.legacy,
+            }),
             vis: ast::Visibility::Inherited,
         })
     }
index d8826d87d4d0f4fd0752b05e5b4ff0dd7197d907..1db5821f31878e9ca1bf954e17ae9e69ff642a8f 100644 (file)
@@ -39,7 +39,7 @@
 
 use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
 use syntax::attr;
-use syntax::ast;
+use syntax::ast::{self, Ident};
 use syntax::codemap;
 use syntax::ext::base::MacroKind;
 use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION};
@@ -667,7 +667,8 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                         },
                         ext.kind()
                     );
-                    callback(def::Export { name: name, def: def, span: DUMMY_SP });
+                    let ident = Ident::with_empty_ctxt(name);
+                    callback(def::Export { ident: ident, def: def, span: DUMMY_SP });
                 }
             }
             return
@@ -703,7 +704,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                             if let Some(def) = self.get_def(child_index) {
                                 callback(def::Export {
                                     def: def,
-                                    name: self.item_name(child_index),
+                                    ident: Ident::with_empty_ctxt(self.item_name(child_index)),
                                     span: self.entry(child_index).span.decode(self),
                                 });
                             }
@@ -720,7 +721,8 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                 let span = child.span.decode(self);
                 if let (Some(def), Some(name)) =
                     (self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) {
-                    callback(def::Export { def: def, name: name, span: span });
+                    let ident = Ident::with_empty_ctxt(name);
+                    callback(def::Export { def: def, ident: ident, span: span });
                     // For non-reexport structs and variants add their constructors to children.
                     // Reexport lists automatically contain constructors when necessary.
                     match def {
@@ -728,7 +730,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                             if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) {
                                 let ctor_kind = self.get_ctor_kind(child_index);
                                 let ctor_def = Def::StructCtor(ctor_def_id, ctor_kind);
-                                callback(def::Export { def: ctor_def, name: name, span: span });
+                                callback(def::Export { def: ctor_def, ident: ident, span: span });
                             }
                         }
                         Def::Variant(def_id) => {
@@ -736,7 +738,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                             // value namespace, they are reserved for possible future use.
                             let ctor_kind = self.get_ctor_kind(child_index);
                             let ctor_def = Def::VariantCtor(def_id, ctor_kind);
-                            callback(def::Export { def: ctor_def, name: name, span: span });
+                            callback(def::Export { def: ctor_def, ident: ident, span: span });
                         }
                         _ => {}
                     }
index 93fcdc455e5dd3762dc7dfe7d6f78e13c4e66ea0..07c475949d4357555c41e90dc33776106bc121c1 100644 (file)
@@ -1104,6 +1104,7 @@ fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef) -> Entry<'tcx
         Entry {
             kind: EntryKind::MacroDef(self.lazy(&MacroDef {
                 body: pprust::tts_to_string(&macro_def.body.trees().collect::<Vec<_>>()),
+                legacy: macro_def.legacy,
             })),
             visibility: self.lazy(&ty::Visibility::Public),
             span: self.lazy(&macro_def.span),
index 91a22d922199da6d2e6f3e35192ec9957a9491e1..2ffe7cc02aaacec21feca4538057c9159a306b3b 100644 (file)
@@ -433,9 +433,10 @@ pub struct ModData {
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct MacroDef {
     pub body: String,
+    pub legacy: bool,
 }
 
-impl_stable_hash_for!(struct MacroDef { body });
+impl_stable_hash_for!(struct MacroDef { body, legacy });
 
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct FnData {
index d7fee7f3110f4cdb90e197f16dcfcab5fc0f0b63..79d90210d47f78264425c5e59d828ff3b7cd7621 100644 (file)
@@ -103,11 +103,11 @@ fn no_questions_in_bounds(&self, bounds: &TyParamBounds, where_: &str, is_trait:
 
 impl<'a> Visitor<'a> for AstValidator<'a> {
     fn visit_lifetime(&mut self, lt: &'a Lifetime) {
-        if lt.name == "'_" {
+        if lt.ident.name == "'_" {
             self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE,
                                   lt.id,
                                   lt.span,
-                                  format!("invalid lifetime name `{}`", lt.name));
+                                  format!("invalid lifetime name `{}`", lt.ident));
         }
 
         visit::walk_lifetime(self, lt)
index 25845c5768e8c8629a12efee4bccc4d9894ef8c0..698850f0e9e7fa6e20908930f6b3d3b5a23040d0 100644 (file)
@@ -141,7 +141,7 @@ fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         let outer_penv = self.tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| {
             let param_env = infcx.param_env.clone();
             let outer_penv = mem::replace(&mut self.param_env, param_env);
-            let region_maps = &self.tcx.region_maps(item_def_id);;
+            let region_maps = &self.tcx.region_maps(item_def_id);
             euv::ExprUseVisitor::new(self, region_maps, &infcx).consume_body(body);
             outer_penv
         });
index 2ced61f5753a90c4aaf9c6312ecfd29add334272..153da91db68f8a93de720b475fa9cf8cbdae5963 100644 (file)
@@ -28,7 +28,7 @@
 
 use rustc::hir::{self, PatKind};
 use rustc::hir::def::Def;
-use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
+use rustc::hir::def_id::{LOCAL_CRATE, CrateNum, DefId};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::itemlikevisit::DeepVisitor;
 use rustc::lint;
@@ -37,7 +37,8 @@
 use rustc::ty::fold::TypeVisitor;
 use rustc::ty::maps::Providers;
 use rustc::util::nodemap::NodeSet;
-use syntax::ast;
+use syntax::ast::{self, CRATE_NODE_ID, Ident};
+use syntax::symbol::keywords;
 use syntax_pos::Span;
 
 use std::cmp;
@@ -344,7 +345,35 @@ fn visit_mod(&mut self, m: &'tcx hir::Mod, _sp: Span, id: ast::NodeId) {
     }
 
     fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
-        self.update(md.id, Some(AccessLevel::Public));
+        if md.legacy {
+            self.update(md.id, Some(AccessLevel::Public));
+            return
+        }
+
+        let module_did = ty::DefIdTree::parent(self.tcx, self.tcx.hir.local_def_id(md.id)).unwrap();
+        let mut module_id = self.tcx.hir.as_local_node_id(module_did).unwrap();
+        let level = if md.vis == hir::Public { self.get(module_id) } else { None };
+        let level = self.update(md.id, level);
+        if level.is_none() {
+            return
+        }
+
+        loop {
+            let module = if module_id == ast::CRATE_NODE_ID {
+                &self.tcx.hir.krate().module
+            } else if let hir::ItemMod(ref module) = self.tcx.hir.expect_item(module_id).node {
+                module
+            } else {
+                unreachable!()
+            };
+            for id in &module.item_ids {
+                self.update(id.id, level);
+            }
+            if module_id == ast::CRATE_NODE_ID {
+                break
+            }
+            module_id = self.tcx.hir.get_parent_node(module_id);
+        }
     }
 
     fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
@@ -425,13 +454,15 @@ fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool {
 struct NamePrivacyVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
-    current_item: DefId,
+    current_item: ast::NodeId,
 }
 
 impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
     // Checks that a field is accessible.
     fn check_field(&mut self, span: Span, def: &'tcx ty::AdtDef, field: &'tcx ty::FieldDef) {
-        if !def.is_enum() && !field.vis.is_accessible_from(self.current_item, self.tcx) {
+        let ident = Ident { ctxt: span.ctxt.modern(), ..keywords::Invalid.ident() };
+        let def_id = self.tcx.adjust_ident(ident, def.did, self.current_item).1;
+        if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
             struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
                              field.name, def.variant_descr(), self.tcx.item_path_str(def.did))
                 .span_label(span, format!("field `{}` is private", field.name))
@@ -455,7 +486,7 @@ fn visit_nested_body(&mut self, body: hir::BodyId) {
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let orig_current_item = replace(&mut self.current_item, self.tcx.hir.local_def_id(item.id));
+        let orig_current_item = replace(&mut self.current_item, item.id);
         intravisit::walk_item(self, item);
         self.current_item = orig_current_item;
     }
@@ -1182,7 +1213,7 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut visitor = NamePrivacyVisitor {
         tcx: tcx,
         tables: &ty::TypeckTables::empty(),
-        current_item: DefId::local(CRATE_DEF_INDEX),
+        current_item: CRATE_NODE_ID,
     };
     intravisit::walk_crate(&mut visitor, krate);
 
index 57639a1ecef7b17b359436a928f5a815602e22c7..597a62f86884b94092cd57cb40c1ced511eba780 100644 (file)
@@ -23,7 +23,7 @@
 
 use rustc::middle::cstore::LoadedMacro;
 use rustc::hir::def::*;
-use rustc::hir::def_id::{CrateNum, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefId};
+use rustc::hir::def_id::{BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
 use rustc::ty;
 
 use std::cell::Cell;
@@ -77,7 +77,7 @@ struct LegacyMacroImports {
 impl<'a> Resolver<'a> {
     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
     /// otherwise, reports an error.
-    fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
+    pub fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
         where T: ToNameBinding<'a>,
     {
         let binding = def.to_name_binding(self.arenas);
@@ -150,7 +150,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                                           view_path.span,
                                           ResolutionError::SelfImportsOnlyAllowedWithin);
                         } else if source_name == "$crate" && full_path.segments.len() == 1 {
-                            let crate_root = self.resolve_crate_var(source.ctxt, item.span);
+                            let crate_root = self.resolve_crate_root(source.ctxt);
                             let crate_name = match crate_root.kind {
                                 ModuleKind::Def(_, name) => name,
                                 ModuleKind::Block(..) => unreachable!(),
@@ -247,7 +247,8 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
 
                 // n.b. we don't need to look at the path option here, because cstore already did
                 let crate_id = self.session.cstore.extern_mod_stmt_cnum(item.id).unwrap();
-                let module = self.get_extern_crate_root(crate_id, item.span);
+                let module =
+                    self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
                 self.populate_module_if_necessary(module);
                 let used = self.process_legacy_macro_imports(item, module, expansion);
                 let binding =
@@ -279,7 +280,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                     no_implicit_prelude: parent.no_implicit_prelude || {
                         attr::contains_name(&item.attrs, "no_implicit_prelude")
                     },
-                    ..ModuleData::new(Some(parent), module_kind, def_id, item.span)
+                    ..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span)
                 });
                 self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
                 self.module_map.insert(def_id, module);
@@ -317,6 +318,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                 let module = self.new_module(parent,
                                              module_kind,
                                              parent.normal_ancestor_id,
+                                             expansion,
                                              item.span);
                 self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
 
@@ -376,6 +378,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                 let module = self.new_module(parent,
                                              module_kind,
                                              parent.normal_ancestor_id,
+                                             expansion,
                                              item.span);
                 self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
                 self.current_module = module;
@@ -421,12 +424,13 @@ fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion
         self.define(parent, item.ident, ValueNS, (def, vis, item.span, expansion));
     }
 
-    fn build_reduced_graph_for_block(&mut self, block: &Block) {
+    fn build_reduced_graph_for_block(&mut self, block: &Block, expansion: Mark) {
         let parent = self.current_module;
         if self.block_needs_anonymous_module(block) {
             let module = self.new_module(parent,
                                          ModuleKind::Block(block.id),
                                          parent.normal_ancestor_id,
+                                         expansion,
                                          block.span);
             self.block_map.insert(block.id, module);
             self.current_module = module; // Descend into the block.
@@ -435,28 +439,29 @@ fn build_reduced_graph_for_block(&mut self, block: &Block) {
 
     /// Builds the reduced graph for a single item in an external crate.
     fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, child: Export) {
-        let ident = Ident::with_empty_ctxt(child.name);
+        let ident = child.ident;
         let def = child.def;
         let def_id = def.def_id();
         let vis = self.session.cstore.visibility(def_id);
         let span = child.span;
-
+        let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
         match def {
             Def::Mod(..) | Def::Enum(..) => {
                 let module = self.new_module(parent,
                                              ModuleKind::Def(def, ident.name),
                                              def_id,
+                                             expansion,
                                              span);
-                self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
             }
             Def::Variant(..) | Def::TyAlias(..) => {
-                self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
             }
             Def::Fn(..) | Def::Static(..) | Def::Const(..) | Def::VariantCtor(..) => {
-                self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
             }
             Def::StructCtor(..) => {
-                self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
 
                 if let Some(struct_def_id) =
                         self.session.cstore.def_key(def_id).parent
@@ -469,47 +474,59 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, chi
                 let module = self.new_module(parent,
                                              module_kind,
                                              parent.normal_ancestor_id,
+                                             expansion,
                                              span);
-                self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
 
                 for child in self.session.cstore.item_children(def_id) {
                     let ns = if let Def::AssociatedTy(..) = child.def { TypeNS } else { ValueNS };
-                    let ident = Ident::with_empty_ctxt(child.name);
-                    self.define(module, ident, ns, (child.def, ty::Visibility::Public,
-                                                    DUMMY_SP, Mark::root()));
+                    self.define(module, child.ident, ns,
+                                (child.def, ty::Visibility::Public, DUMMY_SP, expansion));
 
-                    let has_self = self.session.cstore.associated_item_cloned(child.def.def_id())
-                                       .method_has_self_argument;
-                    self.trait_item_map.insert((def_id, child.name, ns), (child.def, has_self));
+                    if self.session.cstore.associated_item_cloned(child.def.def_id())
+                           .method_has_self_argument {
+                        self.has_self.insert(child.def.def_id());
+                    }
                 }
                 module.populated.set(true);
             }
             Def::Struct(..) | Def::Union(..) => {
-                self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
 
                 // Record field names for error reporting.
                 let field_names = self.session.cstore.struct_field_names(def_id);
                 self.insert_field_names(def_id, field_names);
             }
             Def::Macro(..) => {
-                self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, expansion));
             }
             _ => bug!("unexpected definition: {:?}", def)
         }
     }
 
-    fn get_extern_crate_root(&mut self, cnum: CrateNum, span: Span) -> Module<'a> {
-        let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
-        let name = self.session.cstore.crate_name(cnum);
-        let macros_only = self.session.cstore.dep_kind(cnum).macros_only();
-        let module_kind = ModuleKind::Def(Def::Mod(def_id), name);
-        let arenas = self.arenas;
-        *self.extern_crate_roots.entry((cnum, macros_only)).or_insert_with(|| {
-            arenas.alloc_module(ModuleData::new(None, module_kind, def_id, span))
-        })
+    pub fn get_module(&mut self, def_id: DefId) -> Module<'a> {
+        if def_id.krate == LOCAL_CRATE {
+            return self.module_map[&def_id]
+        }
+
+        let macros_only = self.session.cstore.dep_kind(def_id.krate).macros_only();
+        if let Some(&module) = self.extern_module_map.get(&(def_id, macros_only)) {
+            return module;
+        }
+
+        let (name, parent) = if def_id.index == CRATE_DEF_INDEX {
+            (self.session.cstore.crate_name(def_id.krate), None)
+        } else {
+            let def_key = self.session.cstore.def_key(def_id);
+            (def_key.disambiguated_data.data.get_opt_name().unwrap(),
+             Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id })))
+        };
+
+        let kind = ModuleKind::Def(Def::Mod(def_id), name);
+        self.arenas.alloc_module(ModuleData::new(parent, kind, def_id, Mark::root(), DUMMY_SP))
     }
 
-    pub fn macro_def_scope(&mut self, expansion: Mark, span: Span) -> Module<'a> {
+    pub fn macro_def_scope(&mut self, expansion: Mark) -> Module<'a> {
         let def_id = self.macro_defs[&expansion];
         if let Some(id) = self.definitions.as_local_node_id(def_id) {
             self.local_macro_def_scopes[&id]
@@ -518,7 +535,7 @@ pub fn macro_def_scope(&mut self, expansion: Mark, span: Span) -> Module<'a> {
             self.graph_root
         } else {
             let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
-            self.get_extern_crate_root(module_def_id.krate, span)
+            self.get_module(module_def_id)
         }
     }
 
@@ -625,7 +642,7 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expa
             let ident = Ident::with_empty_ctxt(name);
             let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span);
             if let Ok(binding) = result {
-                self.macro_exports.push(Export { name: name, def: binding.def(), span: span });
+                self.macro_exports.push(Export { ident: ident, def: binding.def(), span: span });
             } else {
                 span_err!(self.session, span, E0470, "reexported macro not found");
             }
@@ -730,7 +747,7 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
     fn visit_item(&mut self, item: &'a Item) {
         let macro_use = match item.node {
             ItemKind::MacroDef(..) => {
-                self.resolver.define_macro(item, &mut self.legacy_scope);
+                self.resolver.define_macro(item, self.expansion, &mut self.legacy_scope);
                 return
             }
             ItemKind::Mac(..) => {
@@ -765,7 +782,7 @@ fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
 
     fn visit_block(&mut self, block: &'a Block) {
         let (parent, legacy_scope) = (self.resolver.current_module, self.legacy_scope);
-        self.resolver.build_reduced_graph_for_block(block);
+        self.resolver.build_reduced_graph_for_block(block, self.expansion);
         visit::walk_block(self, block);
         self.resolver.current_module = parent;
         self.legacy_scope = legacy_scope;
@@ -773,7 +790,6 @@ fn visit_block(&mut self, block: &'a Block) {
 
     fn visit_trait_item(&mut self, item: &'a TraitItem) {
         let parent = self.resolver.current_module;
-        let def_id = parent.def_id().unwrap();
 
         if let TraitItemKind::Macro(_) = item.node {
             self.visit_invoc(item.id);
@@ -782,16 +798,18 @@ fn visit_trait_item(&mut self, item: &'a TraitItem) {
 
         // Add the item to the trait info.
         let item_def_id = self.resolver.definitions.local_def_id(item.id);
-        let (def, ns, has_self) = match item.node {
-            TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS, false),
-            TraitItemKind::Method(ref sig, _) =>
-                (Def::Method(item_def_id), ValueNS, sig.decl.has_self()),
-            TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS, false),
+        let (def, ns) = match item.node {
+            TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS),
+            TraitItemKind::Method(ref sig, _) => {
+                if sig.decl.has_self() {
+                    self.resolver.has_self.insert(item_def_id);
+                }
+                (Def::Method(item_def_id), ValueNS)
+            }
+            TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
             TraitItemKind::Macro(_) => bug!(),  // handled above
         };
 
-        self.resolver.trait_item_map.insert((def_id, item.ident.name, ns), (def, has_self));
-
         let vis = ty::Visibility::Public;
         self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion));
 
index 6ea666e21dcdd28fd24ab0bcd4af1e893269d753..f1be821d526e17151a3ffa1d452c0eea08278940 100644 (file)
@@ -43,7 +43,7 @@
 use rustc::session::Session;
 use rustc::lint;
 use rustc::hir::def::*;
-use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
+use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
 use rustc::ty;
 use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
 use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
@@ -51,7 +51,7 @@
 use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::ast::{self, Name, NodeId, Ident, SpannedIdent, FloatTy, IntTy, UintTy};
 use syntax::ext::base::SyntaxExtension;
-use syntax::ext::base::Determinacy::{Determined, Undetermined};
+use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
 use syntax::ext::base::MacroKind;
 use syntax::symbol::{Symbol, keywords};
 use syntax::util::lev_distance::find_best_match_for_name;
@@ -861,6 +861,8 @@ pub struct ModuleData<'a> {
 
     /// Span of the module itself. Used for error reporting.
     span: Span,
+
+    expansion: Mark,
 }
 
 pub type Module<'a> = &'a ModuleData<'a>;
@@ -869,6 +871,7 @@ impl<'a> ModuleData<'a> {
     fn new(parent: Option<Module<'a>>,
            kind: ModuleKind,
            normal_ancestor_id: DefId,
+           expansion: Mark,
            span: Span) -> Self {
         ModuleData {
             parent: parent,
@@ -884,6 +887,7 @@ fn new(parent: Option<Module<'a>>,
             traits: RefCell::new(None),
             populated: Cell::new(normal_ancestor_id.is_local()),
             span: span,
+            expansion: expansion,
         }
     }
 
@@ -1058,6 +1062,13 @@ fn is_importable(&self) -> bool {
             _ => true,
         }
     }
+
+    fn is_macro_def(&self) -> bool {
+        match self.kind {
+            NameBindingKind::Def(Def::Macro(..)) => true,
+            _ => false,
+        }
+    }
 }
 
 /// Interns the names of the primitive types.
@@ -1104,7 +1115,8 @@ pub struct Resolver<'a> {
 
     prelude: Option<Module<'a>>,
 
-    trait_item_map: FxHashMap<(DefId, Name, Namespace), (Def, bool /* has self */)>,
+    // n.b. This is used only for better diagnostics, not name resolution itself.
+    has_self: FxHashSet<DefId>,
 
     // Names of fields of an item `DefId` accessible with dot syntax.
     // Used for hints during error reporting.
@@ -1127,7 +1139,7 @@ pub struct Resolver<'a> {
     label_ribs: Vec<Rib<'a>>,
 
     // The trait that the current context can refer to.
-    current_trait_ref: Option<(DefId, TraitRef)>,
+    current_trait_ref: Option<(Module<'a>, TraitRef)>,
 
     // The current self type if inside an impl (used for better errors).
     current_self_type: Option<Ty>,
@@ -1157,7 +1169,7 @@ pub struct Resolver<'a> {
     // entry block for `f`.
     block_map: NodeMap<Module<'a>>,
     module_map: FxHashMap<DefId, Module<'a>>,
-    extern_crate_roots: FxHashMap<(CrateNum, bool /* MacrosOnly? */), Module<'a>>,
+    extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>,
 
     pub make_glob_map: bool,
     // Maps imports to the names of items actually imported (this actually maps
@@ -1177,9 +1189,9 @@ pub struct Resolver<'a> {
     use_extern_macros: bool, // true if `#![feature(use_extern_macros)]`
 
     crate_loader: &'a mut CrateLoader,
-    macro_names: FxHashSet<Name>,
+    macro_names: FxHashSet<Ident>,
     global_macros: FxHashMap<Name, &'a NameBinding<'a>>,
-    lexical_macro_resolutions: Vec<(Name, &'a Cell<LegacyScope<'a>>)>,
+    lexical_macro_resolutions: Vec<(Ident, &'a Cell<LegacyScope<'a>>)>,
     macro_map: FxHashMap<DefId, Rc<SyntaxExtension>>,
     macro_defs: FxHashMap<Mark, DefId>,
     local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
@@ -1302,13 +1314,13 @@ pub fn new(session: &'a Session,
         let root_module_kind = ModuleKind::Def(Def::Mod(root_def_id), keywords::Invalid.name());
         let graph_root = arenas.alloc_module(ModuleData {
             no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
-            ..ModuleData::new(None, root_module_kind, root_def_id, krate.span)
+            ..ModuleData::new(None, root_module_kind, root_def_id, Mark::root(), krate.span)
         });
         let mut module_map = FxHashMap();
         module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
 
         let mut definitions = Definitions::new();
-        DefCollector::new(&mut definitions)
+        DefCollector::new(&mut definitions, Mark::root())
             .collect_root(crate_name, &session.local_crate_disambiguator().as_str());
 
         let mut invocations = FxHashMap();
@@ -1330,7 +1342,7 @@ pub fn new(session: &'a Session,
             graph_root: graph_root,
             prelude: None,
 
-            trait_item_map: FxHashMap(),
+            has_self: FxHashSet(),
             field_names: FxHashMap(),
 
             determined_imports: Vec::new(),
@@ -1356,7 +1368,7 @@ pub fn new(session: &'a Session,
             trait_map: NodeMap(),
             module_map: module_map,
             block_map: NodeMap(),
-            extern_crate_roots: FxHashMap(),
+            extern_module_map: FxHashMap(),
 
             make_glob_map: make_glob_map == MakeGlobMap::Yes,
             glob_map: NodeMap(),
@@ -1377,8 +1389,9 @@ pub fn new(session: &'a Session,
                 vis: ty::Visibility::Public,
             }),
 
-            // `#![feature(proc_macro)]` implies `#[feature(extern_macros)]`
-            use_extern_macros: features.use_extern_macros || features.proc_macro,
+            // The `proc_macro` and `decl_macro` features imply `use_extern_macros`
+            use_extern_macros:
+                features.use_extern_macros || features.proc_macro || features.decl_macro,
 
             crate_loader: crate_loader,
             macro_names: FxHashSet(),
@@ -1440,9 +1453,11 @@ fn new_module(
         parent: Module<'a>,
         kind: ModuleKind,
         normal_ancestor_id: DefId,
+        expansion: Mark,
         span: Span,
     ) -> Module<'a> {
-        self.arenas.alloc_module(ModuleData::new(Some(parent), kind, normal_ancestor_id, span))
+        let module = ModuleData::new(Some(parent), kind, normal_ancestor_id, expansion, span);
+        self.arenas.alloc_module(module)
     }
 
     fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
@@ -1504,10 +1519,15 @@ fn resolve_ident_in_lexical_scope(&mut self,
                                       path_span: Span)
                                       -> Option<LexicalScopeBinding<'a>> {
         if ns == TypeNS {
-            ident = ident.unhygienize();
+            ident.ctxt = if ident.name == keywords::SelfType.name() {
+                SyntaxContext::empty() // FIXME(jseyfried) improve `Self` hygiene
+            } else {
+                ident.ctxt.modern()
+            }
         }
 
         // Walk backwards up the ribs in scope.
+        let mut module = self.graph_root;
         for i in (0 .. self.ribs[ns].len()).rev() {
             if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
                 // The ident resolves to a type parameter or local variable.
@@ -1516,45 +1536,120 @@ fn resolve_ident_in_lexical_scope(&mut self,
                 ));
             }
 
-            if let ModuleRibKind(module) = self.ribs[ns][i].kind {
-                let item = self.resolve_ident_in_module(module, ident, ns, false,
-                                                        record_used, path_span);
-                if let Ok(binding) = item {
-                    // The ident resolves to an item.
-                    return Some(LexicalScopeBinding::Item(binding));
+            module = match self.ribs[ns][i].kind {
+                ModuleRibKind(module) => module,
+                MacroDefinition(def) if def == self.macro_defs[&ident.ctxt.outer()] => {
+                    // If an invocation of this macro created `ident`, give up on `ident`
+                    // and switch to `ident`'s source from the macro definition.
+                    ident.ctxt.remove_mark();
+                    continue
                 }
+                _ => continue,
+            };
 
-                if let ModuleKind::Block(..) = module.kind { // We can see through blocks
-                } else if !module.no_implicit_prelude {
-                    return self.prelude.and_then(|prelude| {
-                        self.resolve_ident_in_module(prelude, ident, ns, false,
-                                                     false, path_span).ok()
-                    }).map(LexicalScopeBinding::Item)
-                } else {
-                    return None;
-                }
+            let item = self.resolve_ident_in_module_unadjusted(
+                module, ident, ns, false, record_used, path_span,
+            );
+            if let Ok(binding) = item {
+                // The ident resolves to an item.
+                return Some(LexicalScopeBinding::Item(binding));
             }
 
-            if let MacroDefinition(def) = self.ribs[ns][i].kind {
-                // If an invocation of this macro created `ident`, give up on `ident`
-                // and switch to `ident`'s source from the macro definition.
-                let ctxt_data = ident.ctxt.data();
-                if def == self.macro_defs[&ctxt_data.outer_mark] {
-                    ident.ctxt = ctxt_data.prev_ctxt;
-                }
+            match module.kind {
+                ModuleKind::Block(..) => {}, // We can see through blocks
+                _ => break,
             }
         }
 
+        ident.ctxt = ident.ctxt.modern();
+        loop {
+            module = unwrap_or!(self.hygienic_lexical_parent(module, &mut ident.ctxt), break);
+            let orig_current_module = self.current_module;
+            self.current_module = module; // Lexical resolutions can never be a privacy error.
+            let result = self.resolve_ident_in_module_unadjusted(
+                module, ident, ns, false, record_used, path_span,
+            );
+            self.current_module = orig_current_module;
+
+            match result {
+                Ok(binding) => return Some(LexicalScopeBinding::Item(binding)),
+                Err(Undetermined) => return None,
+                Err(Determined) => {}
+            }
+        }
+
+        match self.prelude {
+            Some(prelude) if !module.no_implicit_prelude => {
+                self.resolve_ident_in_module_unadjusted(prelude, ident, ns, false, false, path_span)
+                    .ok().map(LexicalScopeBinding::Item)
+            }
+            _ => None,
+        }
+    }
+
+    fn hygienic_lexical_parent(&mut self, mut module: Module<'a>, ctxt: &mut SyntaxContext)
+                               -> Option<Module<'a>> {
+        if !module.expansion.is_descendant_of(ctxt.outer()) {
+            return Some(self.macro_def_scope(ctxt.remove_mark()));
+        }
+
+        if let ModuleKind::Block(..) = module.kind {
+            return Some(module.parent.unwrap());
+        }
+
+        let mut module_expansion = module.expansion.modern(); // for backward compatability
+        while let Some(parent) = module.parent {
+            let parent_expansion = parent.expansion.modern();
+            if module_expansion.is_descendant_of(parent_expansion) &&
+               parent_expansion != module_expansion {
+                return if parent_expansion.is_descendant_of(ctxt.outer()) {
+                    Some(parent)
+                } else {
+                    None
+                };
+            }
+            module = parent;
+            module_expansion = parent_expansion;
+        }
+
         None
     }
 
-    fn resolve_crate_var(&mut self, crate_var_ctxt: SyntaxContext, span: Span) -> Module<'a> {
-        let mut ctxt_data = crate_var_ctxt.data();
-        while ctxt_data.prev_ctxt != SyntaxContext::empty() {
-            ctxt_data = ctxt_data.prev_ctxt.data();
+    fn resolve_ident_in_module(&mut self,
+                               module: Module<'a>,
+                               mut ident: Ident,
+                               ns: Namespace,
+                               ignore_unresolved_invocations: bool,
+                               record_used: bool,
+                               span: Span)
+                               -> Result<&'a NameBinding<'a>, Determinacy> {
+        ident.ctxt = ident.ctxt.modern();
+        let orig_current_module = self.current_module;
+        if let Some(def) = ident.ctxt.adjust(module.expansion) {
+            self.current_module = self.macro_def_scope(def);
+        }
+        let result = self.resolve_ident_in_module_unadjusted(
+            module, ident, ns, ignore_unresolved_invocations, record_used, span,
+        );
+        self.current_module = orig_current_module;
+        result
+    }
+
+    fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext) -> Module<'a> {
+        let module = match ctxt.adjust(Mark::root()) {
+            Some(def) => self.macro_def_scope(def),
+            None => return self.graph_root,
+        };
+        self.get_module(DefId { index: CRATE_DEF_INDEX, ..module.normal_ancestor_id })
+    }
+
+    fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'a>) -> Module<'a> {
+        let mut module = self.get_module(module.normal_ancestor_id);
+        while module.span.ctxt.modern() != *ctxt {
+            let parent = module.parent.unwrap_or_else(|| self.macro_def_scope(ctxt.remove_mark()));
+            module = self.get_module(parent.normal_ancestor_id);
         }
-        let module = self.macro_def_scope(ctxt_data.outer_mark, span);
-        if module.is_local() { self.graph_root } else { module }
+        module
     }
 
     // AST resolution
@@ -1602,15 +1697,12 @@ fn with_scope<F>(&mut self, id: NodeId, f: F)
     fn search_label(&self, mut ident: Ident) -> Option<Def> {
         for rib in self.label_ribs.iter().rev() {
             match rib.kind {
-                NormalRibKind => {
-                    // Continue
-                }
+                NormalRibKind => {}
+                // If an invocation of this macro created `ident`, give up on `ident`
+                // and switch to `ident`'s source from the macro definition.
                 MacroDefinition(def) => {
-                    // If an invocation of this macro created `ident`, give up on `ident`
-                    // and switch to `ident`'s source from the macro definition.
-                    let ctxt_data = ident.ctxt.data();
-                    if def == self.macro_defs[&ctxt_data.outer_mark] {
-                        ident.ctxt = ctxt_data.prev_ctxt;
+                    if def == self.macro_defs[&ident.ctxt.outer()] {
+                        ident.ctxt.remove_mark();
                     }
                 }
                 _ => {
@@ -1742,22 +1834,21 @@ fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<
                 let mut function_type_rib = Rib::new(rib_kind);
                 let mut seen_bindings = FxHashMap();
                 for type_parameter in &generics.ty_params {
-                    let name = type_parameter.ident.name;
+                    let ident = type_parameter.ident.modern();
                     debug!("with_type_parameter_rib: {}", type_parameter.id);
 
-                    if seen_bindings.contains_key(&name) {
-                        let span = seen_bindings.get(&name).unwrap();
-                        resolve_error(self,
-                                      type_parameter.span,
-                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name,
-                                                                                          span));
+                    if seen_bindings.contains_key(&ident) {
+                        let span = seen_bindings.get(&ident).unwrap();
+                        let err =
+                            ResolutionError::NameAlreadyUsedInTypeParameterList(ident.name, span);
+                        resolve_error(self, type_parameter.span, err);
                     }
-                    seen_bindings.entry(name).or_insert(type_parameter.span);
+                    seen_bindings.entry(ident).or_insert(type_parameter.span);
 
                     // plain insert (no renaming)
                     let def_id = self.definitions.local_def_id(type_parameter.id);
                     let def = Def::TyParam(def_id);
-                    function_type_rib.bindings.insert(Ident::with_empty_ctxt(name), def);
+                    function_type_rib.bindings.insert(ident, def);
                     self.record_def(type_parameter.id, PathResolution::new(def));
                 }
                 self.ribs[TypeNS].push(function_type_rib);
@@ -1817,11 +1908,20 @@ fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f:
         let mut new_val = None;
         let mut new_id = None;
         if let Some(trait_ref) = opt_trait_ref {
-            let def = self.smart_resolve_path(trait_ref.ref_id, None,
-                                              &trait_ref.path, PathSource::Trait).base_def();
+            let path: Vec<_> = trait_ref.path.segments.iter().map(|seg| seg.identifier).collect();
+            let def = self.smart_resolve_path_fragment(trait_ref.ref_id,
+                                                       None,
+                                                       &path,
+                                                       trait_ref.path.span,
+                                                       trait_ref.path.segments.last().unwrap().span,
+                                                       PathSource::Trait)
+                .base_def();
             if def != Def::Err {
-                new_val = Some((def.def_id(), trait_ref.clone()));
                 new_id = Some(def.def_id());
+                let span = trait_ref.path.span;
+                if let PathResult::Module(module) = self.resolve_path(&path, None, false, span) {
+                    new_val = Some((module, trait_ref.clone()));
+                }
             }
         }
         let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
@@ -1872,7 +1972,7 @@ fn resolve_implementation(&mut self,
                                     ImplItemKind::Const(..) => {
                                         // If this is a trait impl, ensure the const
                                         // exists in trait
-                                        this.check_trait_item(impl_item.ident.name,
+                                        this.check_trait_item(impl_item.ident,
                                                             ValueNS,
                                                             impl_item.span,
                                             |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
@@ -1881,7 +1981,7 @@ fn resolve_implementation(&mut self,
                                     ImplItemKind::Method(ref sig, _) => {
                                         // If this is a trait impl, ensure the method
                                         // exists in trait
-                                        this.check_trait_item(impl_item.ident.name,
+                                        this.check_trait_item(impl_item.ident,
                                                             ValueNS,
                                                             impl_item.span,
                                             |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
@@ -1898,7 +1998,7 @@ fn resolve_implementation(&mut self,
                                     ImplItemKind::Type(ref ty) => {
                                         // If this is a trait impl, ensure the type
                                         // exists in trait
-                                        this.check_trait_item(impl_item.ident.name,
+                                        this.check_trait_item(impl_item.ident,
                                                             TypeNS,
                                                             impl_item.span,
                                             |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
@@ -1916,15 +2016,15 @@ fn resolve_implementation(&mut self,
         });
     }
 
-    fn check_trait_item<F>(&self, name: Name, ns: Namespace, span: Span, err: F)
+    fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
         where F: FnOnce(Name, &str) -> ResolutionError
     {
         // If there is a TraitRef in scope for an impl, then the method must be in the
         // trait.
-        if let Some((did, ref trait_ref)) = self.current_trait_ref {
-            if !self.trait_item_map.contains_key(&(did, name, ns)) {
-                let path_str = path_names_to_string(&trait_ref.path);
-                resolve_error(self, span, err(name, &path_str));
+        if let Some((module, _)) = self.current_trait_ref {
+            if self.resolve_ident_in_module(module, ident, ns, false, false, span).is_err() {
+                let path = &self.current_trait_ref.as_ref().unwrap().1.path;
+                resolve_error(self, span, err(ident.name, &path_names_to_string(path)));
             }
         }
     }
@@ -2294,15 +2394,16 @@ fn smart_resolve_path_fragment(&mut self,
             }
 
             // Try to lookup the name in more relaxed fashion for better error reporting.
-            let name = path.last().unwrap().name;
-            let candidates = this.lookup_import_candidates(name, ns, is_expected);
+            let ident = *path.last().unwrap();
+            let candidates = this.lookup_import_candidates(ident.name, ns, is_expected);
             if !candidates.is_empty() {
                 let mut module_span = this.current_module.span;
                 module_span.hi = module_span.lo;
                 // Report import candidates as help and proceed searching for labels.
                 show_candidates(&mut err, module_span, &candidates, def.is_some());
             } else if is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
-                let enum_candidates = this.lookup_import_candidates(name, ns, is_enum_variant);
+                let enum_candidates =
+                    this.lookup_import_candidates(ident.name, ns, is_enum_variant);
                 let mut enum_candidates = enum_candidates.iter()
                     .map(|suggestion| import_candidate_to_paths(&suggestion)).collect::<Vec<_>>();
                 enum_candidates.sort();
@@ -2318,7 +2419,7 @@ fn smart_resolve_path_fragment(&mut self,
                 }
             }
             if path.len() == 1 && this.self_type_is_available(span) {
-                if let Some(candidate) = this.lookup_assoc_candidate(name, ns, is_expected) {
+                if let Some(candidate) = this.lookup_assoc_candidate(ident, ns, is_expected) {
                     let self_is_available = this.self_value_is_available(path[0].ctxt, span);
                     match candidate {
                         AssocSuggestion::Field => {
@@ -2432,7 +2533,7 @@ fn smart_resolve_path_fragment(&mut self,
                 // or `<T>::A::B`. If `B` should be resolved in value namespace then
                 // it needs to be added to the trait map.
                 if ns == ValueNS {
-                    let item_name = path.last().unwrap().name;
+                    let item_name = *path.last().unwrap();
                     let traits = self.get_traits_containing_item(item_name, ns);
                     self.trait_map.insert(id, traits);
                 }
@@ -2486,7 +2587,7 @@ fn resolve_qpath_anywhere(&mut self,
         }
         let is_global = self.global_macros.get(&path[0].name).cloned()
             .map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false);
-        if primary_ns != MacroNS && (is_global || self.macro_names.contains(&path[0].name)) {
+        if primary_ns != MacroNS && (is_global || self.macro_names.contains(&path[0].modern())) {
             // Return some dummy definition, it's enough for error reporting.
             return Some(
                 PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))
@@ -2595,13 +2696,17 @@ fn resolve_path(&mut self,
             let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
 
             if i == 0 && ns == TypeNS && ident.name == keywords::SelfValue.name() {
-                module = Some(self.module_map[&self.current_module.normal_ancestor_id]);
+                let mut ctxt = ident.ctxt.modern();
+                module = Some(self.resolve_self(&mut ctxt, self.current_module));
                 continue
             } else if allow_super && ns == TypeNS && ident.name == keywords::Super.name() {
-                let current_module = if i == 0 { self.current_module } else { module.unwrap() };
-                let self_module = self.module_map[&current_module.normal_ancestor_id];
+                let mut ctxt = ident.ctxt.modern();
+                let self_module = match i {
+                    0 => self.resolve_self(&mut ctxt, self.current_module),
+                    _ => module.unwrap(),
+                };
                 if let Some(parent) = self_module.parent {
-                    module = Some(self.module_map[&parent.normal_ancestor_id]);
+                    module = Some(self.resolve_self(&mut ctxt, parent));
                     continue
                 } else {
                     let msg = "There are too many initial `super`s.".to_string();
@@ -2611,10 +2716,10 @@ fn resolve_path(&mut self,
             allow_super = false;
 
             if i == 0 && ns == TypeNS && ident.name == keywords::CrateRoot.name() {
-                module = Some(self.graph_root);
+                module = Some(self.resolve_crate_root(ident.ctxt.modern()));
                 continue
             } else if i == 0 && ns == TypeNS && ident.name == "$crate" {
-                module = Some(self.resolve_crate_var(ident.ctxt, path_span));
+                module = Some(self.resolve_crate_root(ident.ctxt));
                 continue
             }
 
@@ -2811,7 +2916,7 @@ fn with_empty_ribs<T, F>(&mut self, f: F) -> T
     }
 
     fn lookup_assoc_candidate<FilterFn>(&mut self,
-                                        name: Name,
+                                        ident: Ident,
                                         ns: Namespace,
                                         filter_fn: FilterFn)
                                         -> Option<AssocSuggestion>
@@ -2837,7 +2942,7 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
                         Def::Struct(did) | Def::Union(did)
                                 if resolution.unresolved_segments() == 0 => {
                             if let Some(field_names) = self.field_names.get(&did) {
-                                if field_names.iter().any(|&field_name| name == field_name) {
+                                if field_names.iter().any(|&field_name| ident.name == field_name) {
                                     return Some(AssocSuggestion::Field);
                                 }
                             }
@@ -2849,10 +2954,12 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
         }
 
         // Look for associated items in the current trait.
-        if let Some((trait_did, _)) = self.current_trait_ref {
-            if let Some(&(def, has_self)) = self.trait_item_map.get(&(trait_did, name, ns)) {
+        if let Some((module, _)) = self.current_trait_ref {
+            if let Ok(binding) =
+                    self.resolve_ident_in_module(module, ident, ns, false, false, module.span) {
+                let def = binding.def();
                 if filter_fn(def) {
-                    return Some(if has_self {
+                    return Some(if self.has_self.contains(&def.def_id()) {
                         AssocSuggestion::MethodWithSelf
                     } else {
                         AssocSuggestion::AssocItem
@@ -3073,13 +3180,13 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
                 // field, we need to add any trait methods we find that match
                 // the field name so that we can do some nice error reporting
                 // later on in typeck.
-                let traits = self.get_traits_containing_item(name.node.name, ValueNS);
+                let traits = self.get_traits_containing_item(name.node, ValueNS);
                 self.trait_map.insert(expr.id, traits);
             }
             ExprKind::MethodCall(name, ..) => {
                 debug!("(recording candidate traits for expr) recording traits for {}",
                        expr.id);
-                let traits = self.get_traits_containing_item(name.node.name, ValueNS);
+                let traits = self.get_traits_containing_item(name.node, ValueNS);
                 self.trait_map.insert(expr.id, traits);
             }
             _ => {
@@ -3088,29 +3195,30 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
         }
     }
 
-    fn get_traits_containing_item(&mut self, name: Name, ns: Namespace) -> Vec<TraitCandidate> {
-        debug!("(getting traits containing item) looking for '{}'", name);
+    fn get_traits_containing_item(&mut self, mut ident: Ident, ns: Namespace)
+                                  -> Vec<TraitCandidate> {
+        debug!("(getting traits containing item) looking for '{}'", ident.name);
 
         let mut found_traits = Vec::new();
         // Look for the current trait.
-        if let Some((trait_def_id, _)) = self.current_trait_ref {
-            if self.trait_item_map.contains_key(&(trait_def_id, name, ns)) {
-                found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: None });
+        if let Some((module, _)) = self.current_trait_ref {
+            if self.resolve_ident_in_module(module, ident, ns, false, false, module.span).is_ok() {
+                let def_id = module.def_id().unwrap();
+                found_traits.push(TraitCandidate { def_id: def_id, import_id: None });
             }
         }
 
+        ident.ctxt = ident.ctxt.modern();
         let mut search_module = self.current_module;
         loop {
-            self.get_traits_in_module_containing_item(name, ns, search_module, &mut found_traits);
-            match search_module.kind {
-                ModuleKind::Block(..) => search_module = search_module.parent.unwrap(),
-                _ => break,
-            }
+            self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
+            search_module =
+                unwrap_or!(self.hygienic_lexical_parent(search_module, &mut ident.ctxt), break);
         }
 
         if let Some(prelude) = self.prelude {
             if !search_module.no_implicit_prelude {
-                self.get_traits_in_module_containing_item(name, ns, prelude, &mut found_traits);
+                self.get_traits_in_module_containing_item(ident, ns, prelude, &mut found_traits);
             }
         }
 
@@ -3118,9 +3226,9 @@ fn get_traits_containing_item(&mut self, name: Name, ns: Namespace) -> Vec<Trait
     }
 
     fn get_traits_in_module_containing_item(&mut self,
-                                            name: Name,
+                                            ident: Ident,
                                             ns: Namespace,
-                                            module: Module,
+                                            module: Module<'a>,
                                             found_traits: &mut Vec<TraitCandidate>) {
         let mut traits = module.traits.borrow_mut();
         if traits.is_none() {
@@ -3135,8 +3243,13 @@ fn get_traits_in_module_containing_item(&mut self,
         }
 
         for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
-            let trait_def_id = binding.def().def_id();
-            if self.trait_item_map.contains_key(&(trait_def_id, name, ns)) {
+            let module = binding.module().unwrap();
+            let mut ident = ident;
+            if ident.ctxt.glob_adjust(module.expansion, binding.span.ctxt.modern()).is_none() {
+                continue
+            }
+            if self.resolve_ident_in_module_unadjusted(module, ident, ns, false, false, module.span)
+                   .is_ok() {
                 let import_id = match binding.kind {
                     NameBindingKind::Import { directive, .. } => {
                         self.maybe_unused_trait_imports.insert(directive.id);
@@ -3145,6 +3258,7 @@ fn get_traits_in_module_containing_item(&mut self,
                     }
                     _ => None,
                 };
+                let trait_def_id = module.def_id().unwrap();
                 found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: import_id });
             }
         }
@@ -3326,15 +3440,15 @@ fn report_errors(&mut self) {
     }
 
     fn report_shadowing_errors(&mut self) {
-        for (name, scope) in replace(&mut self.lexical_macro_resolutions, Vec::new()) {
-            self.resolve_legacy_scope(scope, name, true);
+        for (ident, scope) in replace(&mut self.lexical_macro_resolutions, Vec::new()) {
+            self.resolve_legacy_scope(scope, ident, true);
         }
 
         let mut reported_errors = FxHashSet();
         for binding in replace(&mut self.disallowed_shadowing, Vec::new()) {
-            if self.resolve_legacy_scope(&binding.parent, binding.name, false).is_some() &&
-               reported_errors.insert((binding.name, binding.span)) {
-                let msg = format!("`{}` is already in scope", binding.name);
+            if self.resolve_legacy_scope(&binding.parent, binding.ident, false).is_some() &&
+               reported_errors.insert((binding.ident, binding.span)) {
+                let msg = format!("`{}` is already in scope", binding.ident);
                 self.session.struct_span_err(binding.span, &msg)
                     .note("macro-expanded `macro_rules!`s may not shadow \
                            existing macros (see RFC 1560)")
index 231d30cd2a22decfdd8729f4f68f46dfa16fe305..9a37df762327979cca096ffeb6a45b50a9753f08 100644 (file)
@@ -76,7 +76,7 @@ pub enum LegacyScope<'a> {
 
 pub struct LegacyBinding<'a> {
     pub parent: Cell<LegacyScope<'a>>,
-    pub name: ast::Name,
+    pub ident: Ident,
     def_id: DefId,
     pub span: Span,
 }
@@ -110,7 +110,7 @@ fn next_node_id(&mut self) -> ast::NodeId {
     }
 
     fn get_module_scope(&mut self, id: ast::NodeId) -> Mark {
-        let mark = Mark::fresh();
+        let mark = Mark::fresh(Mark::root());
         let module = self.module_map[&self.definitions.local_def_id(id)];
         self.invocations.insert(mark, self.arenas.alloc_invocation_data(InvocationData {
             module: Cell::new(module),
@@ -130,7 +130,7 @@ fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
                 let ident = path.segments[0].identifier;
                 if ident.name == "$crate" {
                     path.segments[0].identifier.name = keywords::CrateRoot.name();
-                    let module = self.0.resolve_crate_var(ident.ctxt, self.1);
+                    let module = self.0.resolve_crate_root(ident.ctxt);
                     if !module.is_local() {
                         let span = path.segments[0].span;
                         path.segments.insert(1, match module.kind {
@@ -158,7 +158,7 @@ fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool {
 
     fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion, derives: &[Mark]) {
         let invocation = self.invocations[&mark];
-        self.collect_def_ids(invocation, expansion);
+        self.collect_def_ids(mark, invocation, expansion);
 
         self.current_module = invocation.module.get();
         self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
@@ -290,9 +290,18 @@ fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
                 Err(determinacy) => return Err(determinacy),
             },
         };
+
         self.macro_defs.insert(invoc.expansion_data.mark, def.def_id());
+        let normal_module_def_id =
+            self.macro_def_scope(invoc.expansion_data.mark).normal_ancestor_id;
+        self.definitions.add_macro_def_scope(invoc.expansion_data.mark, normal_module_def_id);
+
         self.unused_macros.remove(&def.def_id());
-        Ok(Some(self.get_macro(def)))
+        let ext = self.get_macro(def);
+        if ext.is_modern() {
+            invoc.expansion_data.mark.set_modern();
+        }
+        Ok(Some(ext))
     }
 
     fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
@@ -416,8 +425,7 @@ fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKin
             return def;
         }
 
-        let name = path[0].name;
-        let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, name, false);
+        let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, path[0], false);
         let result = if let Some(MacroBinding::Legacy(binding)) = legacy_resolution {
             Ok(Def::Macro(binding.def_id, MacroKind::Bang))
         } else {
@@ -439,26 +447,31 @@ fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKin
 
     // Resolve the initial segment of a non-global macro path (e.g. `foo` in `foo::bar!();`)
     pub fn resolve_lexical_macro_path_segment(&mut self,
-                                              ident: Ident,
+                                              mut ident: Ident,
                                               ns: Namespace,
                                               record_used: bool,
                                               path_span: Span)
                                               -> Result<MacroBinding<'a>, Determinacy> {
+        ident = ident.modern();
         let mut module = Some(self.current_module);
         let mut potential_illegal_shadower = Err(Determinacy::Determined);
         let determinacy =
             if record_used { Determinacy::Determined } else { Determinacy::Undetermined };
         loop {
+            let orig_current_module = self.current_module;
             let result = if let Some(module) = module {
+                self.current_module = module; // Lexical resolutions can never be a privacy error.
                 // Since expanded macros may not shadow the lexical scope and
                 // globs may not shadow global macros (both enforced below),
                 // we resolve with restricted shadowing (indicated by the penultimate argument).
-                self.resolve_ident_in_module(module, ident, ns, true, record_used, path_span)
-                    .map(MacroBinding::Modern)
+                self.resolve_ident_in_module_unadjusted(
+                    module, ident, ns, true, record_used, path_span,
+                ).map(MacroBinding::Modern)
             } else {
                 self.global_macros.get(&ident.name).cloned().ok_or(determinacy)
                     .map(MacroBinding::Global)
             };
+            self.current_module = orig_current_module;
 
             match result.map(MacroBinding::binding) {
                 Ok(binding) => {
@@ -491,10 +504,7 @@ pub fn resolve_lexical_macro_path_segment(&mut self,
             }
 
             module = match module {
-                Some(module) => match module.kind {
-                    ModuleKind::Block(..) => module.parent,
-                    ModuleKind::Def(..) => None,
-                },
+                Some(module) => self.hygienic_lexical_parent(module, &mut ident.ctxt),
                 None => return potential_illegal_shadower,
             }
         }
@@ -502,9 +512,10 @@ pub fn resolve_lexical_macro_path_segment(&mut self,
 
     pub fn resolve_legacy_scope(&mut self,
                                 mut scope: &'a Cell<LegacyScope<'a>>,
-                                name: Name,
+                                ident: Ident,
                                 record_used: bool)
                                 -> Option<MacroBinding<'a>> {
+        let ident = ident.modern();
         let mut possible_time_travel = None;
         let mut relative_depth: u32 = 0;
         let mut binding = None;
@@ -531,7 +542,7 @@ pub fn resolve_legacy_scope(&mut self,
                     scope = &invocation.legacy_scope;
                 }
                 LegacyScope::Binding(potential_binding) => {
-                    if potential_binding.name == name {
+                    if potential_binding.ident == ident {
                         if (!self.use_extern_macros || record_used) && relative_depth > 0 {
                             self.disallowed_shadowing.push(potential_binding);
                         }
@@ -545,9 +556,9 @@ pub fn resolve_legacy_scope(&mut self,
 
         let binding = if let Some(binding) = binding {
             MacroBinding::Legacy(binding)
-        } else if let Some(binding) = self.global_macros.get(&name).cloned() {
+        } else if let Some(binding) = self.global_macros.get(&ident.name).cloned() {
             if !self.use_extern_macros {
-                self.record_use(Ident::with_empty_ctxt(name), MacroNS, binding, DUMMY_SP);
+                self.record_use(ident, MacroNS, binding, DUMMY_SP);
             }
             MacroBinding::Global(binding)
         } else {
@@ -557,7 +568,7 @@ pub fn resolve_legacy_scope(&mut self,
         if !self.use_extern_macros {
             if let Some(scope) = possible_time_travel {
                 // Check for disallowed shadowing later
-                self.lexical_macro_resolutions.push((name, scope));
+                self.lexical_macro_resolutions.push((ident, scope));
             }
         }
 
@@ -578,7 +589,7 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
 
         for &(mark, ident, span, kind) in module.legacy_macro_resolutions.borrow().iter() {
             let legacy_scope = &self.invocations[&mark].legacy_scope;
-            let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident.name, true);
+            let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident, true);
             let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, true, span);
             match (legacy_resolution, resolution) {
                 (Some(MacroBinding::Legacy(legacy_binding)), Ok(MacroBinding::Modern(binding))) => {
@@ -615,7 +626,7 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
                           err: &mut DiagnosticBuilder<'a>, span: Span) {
         // First check if this is a locally-defined bang macro.
         let suggestion = if let MacroKind::Bang = kind {
-            find_best_match_for_name(self.macro_names.iter(), name, None)
+            find_best_match_for_name(self.macro_names.iter().map(|ident| &ident.name), name, None)
         } else {
             None
         // Then check global macros.
@@ -659,7 +670,10 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
         }
     }
 
-    fn collect_def_ids(&mut self, invocation: &'a InvocationData<'a>, expansion: &Expansion) {
+    fn collect_def_ids(&mut self,
+                       mark: Mark,
+                       invocation: &'a InvocationData<'a>,
+                       expansion: &Expansion) {
         let Resolver { ref mut invocations, arenas, graph_root, .. } = *self;
         let InvocationData { def_index, const_expr, .. } = *invocation;
 
@@ -675,7 +689,7 @@ fn collect_def_ids(&mut self, invocation: &'a InvocationData<'a>, expansion: &Ex
             });
         };
 
-        let mut def_collector = DefCollector::new(&mut self.definitions);
+        let mut def_collector = DefCollector::new(&mut self.definitions, mark);
         def_collector.visit_macro_invoc = Some(visit_macro_invoc);
         def_collector.with_parent(def_index, |def_collector| {
             if const_expr {
@@ -687,7 +701,10 @@ fn collect_def_ids(&mut self, invocation: &'a InvocationData<'a>, expansion: &Ex
         });
     }
 
-    pub fn define_macro(&mut self, item: &ast::Item, legacy_scope: &mut LegacyScope<'a>) {
+    pub fn define_macro(&mut self,
+                        item: &ast::Item,
+                        expansion: Mark,
+                        legacy_scope: &mut LegacyScope<'a>) {
         self.local_macro_def_scopes.insert(item.id, self.current_module);
         let ident = item.ident;
         if ident.name == "macro_rules" {
@@ -699,16 +716,26 @@ pub fn define_macro(&mut self, item: &ast::Item, legacy_scope: &mut LegacyScope<
                                                &self.session.features,
                                                item));
         self.macro_map.insert(def_id, ext);
-        *legacy_scope = LegacyScope::Binding(self.arenas.alloc_legacy_binding(LegacyBinding {
-            parent: Cell::new(*legacy_scope), name: ident.name, def_id: def_id, span: item.span,
-        }));
-        self.macro_names.insert(ident.name);
 
-        if attr::contains_name(&item.attrs, "macro_export") {
-            let def = Def::Macro(def_id, MacroKind::Bang);
-            self.macro_exports.push(Export { name: ident.name, def: def, span: item.span });
+        let def = match item.node { ast::ItemKind::MacroDef(ref def) => def, _ => unreachable!() };
+        if def.legacy {
+            let ident = ident.modern();
+            self.macro_names.insert(ident);
+            *legacy_scope = LegacyScope::Binding(self.arenas.alloc_legacy_binding(LegacyBinding {
+                parent: Cell::new(*legacy_scope), ident: ident, def_id: def_id, span: item.span,
+            }));
+            if attr::contains_name(&item.attrs, "macro_export") {
+                let def = Def::Macro(def_id, MacroKind::Bang);
+                self.macro_exports
+                    .push(Export { ident: ident.modern(), def: def, span: item.span });
+            } else {
+                self.unused_macros.insert(def_id);
+            }
         } else {
-            self.unused_macros.insert(def_id);
+            let module = self.current_module;
+            let def = Def::Macro(def_id, MacroKind::Bang);
+            let vis = self.resolve_visibility(&item.vis);
+            self.define(module, ident, MacroNS, (def, vis, item.span, expansion));
         }
     }
 
index 1d4ba4ed100b72e3139fbcf29b42e70e1e9eed13..c077f507932c62e6ac5eb235d3779689be9bb19a 100644 (file)
@@ -134,21 +134,20 @@ fn binding(&self) -> Option<&'a NameBinding<'a>> {
 impl<'a> Resolver<'a> {
     fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
                   -> &'a RefCell<NameResolution<'a>> {
-        let ident = ident.unhygienize();
-        *module.resolutions.borrow_mut().entry((ident, ns))
+        *module.resolutions.borrow_mut().entry((ident.modern(), ns))
                .or_insert_with(|| self.arenas.alloc_name_resolution())
     }
 
     /// Attempts to resolve `ident` in namespaces `ns` of `module`.
     /// Invariant: if `record_used` is `Some`, import resolution must be complete.
-    pub fn resolve_ident_in_module(&mut self,
-                                   module: Module<'a>,
-                                   ident: Ident,
-                                   ns: Namespace,
-                                   restricted_shadowing: bool,
-                                   record_used: bool,
-                                   path_span: Span)
-                                   -> Result<&'a NameBinding<'a>, Determinacy> {
+    pub fn resolve_ident_in_module_unadjusted(&mut self,
+                                              module: Module<'a>,
+                                              ident: Ident,
+                                              ns: Namespace,
+                                              restricted_shadowing: bool,
+                                              record_used: bool,
+                                              path_span: Span)
+                                              -> Result<&'a NameBinding<'a>, Determinacy> {
         self.populate_module_if_necessary(module);
 
         let resolution = self.resolution(module, ident, ns)
@@ -233,20 +232,22 @@ pub fn resolve_ident_in_module(&mut self,
             return Err(Determined);
         }
         for directive in module.globs.borrow().iter() {
-            if self.is_accessible(directive.vis.get()) {
-                if let Some(module) = directive.imported_module.get() {
-                    let result = self.resolve_ident_in_module(module,
-                                                              ident,
-                                                              ns,
-                                                              false,
-                                                              false,
-                                                              path_span);
-                    if let Err(Undetermined) = result {
-                        return Err(Undetermined);
-                    }
-                } else {
-                    return Err(Undetermined);
-                }
+            if !self.is_accessible(directive.vis.get()) {
+                continue
+            }
+            let module = unwrap_or!(directive.imported_module.get(), return Err(Undetermined));
+            let (orig_current_module, mut ident) = (self.current_module, ident.modern());
+            match ident.ctxt.glob_adjust(module.expansion, directive.span.ctxt.modern()) {
+                Some(Some(def)) => self.current_module = self.macro_def_scope(def),
+                Some(None) => {}
+                None => continue,
+            };
+            let result = self.resolve_ident_in_module_unadjusted(
+                module, ident, ns, false, false, path_span,
+            );
+            self.current_module = orig_current_module;
+            if let Err(Undetermined) = result {
+                return Err(Undetermined);
             }
         }
 
@@ -394,7 +395,14 @@ fn update_resolution<T, F>(&mut self, module: Module<'a>, ident: Ident, ns: Name
 
         // Define `binding` in `module`s glob importers.
         for directive in module.glob_importers.borrow_mut().iter() {
-            if self.is_accessible_from(binding.vis, directive.parent) {
+            let mut ident = ident.modern();
+            let scope = match ident.ctxt.reverse_glob_adjust(module.expansion,
+                                                             directive.span.ctxt.modern()) {
+                Some(Some(def)) => self.macro_def_scope(def),
+                Some(None) => directive.parent,
+                None => continue,
+            };
+            if self.is_accessible_from(binding.vis, scope) {
                 let imported_binding = self.import(binding, directive);
                 let _ = self.try_define(directive.parent, ident, ns, imported_binding);
             }
@@ -767,8 +775,14 @@ fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
         let bindings = module.resolutions.borrow().iter().filter_map(|(&ident, resolution)| {
             resolution.borrow().binding().map(|binding| (ident, binding))
         }).collect::<Vec<_>>();
-        for ((ident, ns), binding) in bindings {
-            if binding.pseudo_vis() == ty::Visibility::Public || self.is_accessible(binding.vis) {
+        for ((mut ident, ns), binding) in bindings {
+            let scope = match ident.ctxt.reverse_glob_adjust(module.expansion,
+                                                             directive.span.ctxt.modern()) {
+                Some(Some(def)) => self.macro_def_scope(def),
+                Some(None) => self.current_module,
+                None => continue,
+            };
+            if self.is_accessible_from(binding.pseudo_vis(), scope) {
                 let imported_binding = self.import(binding, directive);
                 let _ = self.try_define(directive.parent, ident, ns, imported_binding);
             }
@@ -789,7 +803,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
         if module as *const _ == self.graph_root as *const _ {
             let macro_exports = mem::replace(&mut self.macro_exports, Vec::new());
             for export in macro_exports.into_iter().rev() {
-                if exported_macro_names.insert(export.name, export.span).is_none() {
+                if exported_macro_names.insert(export.ident.modern(), export.span).is_none() {
                     reexports.push(export);
                 }
             }
@@ -803,14 +817,14 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
             };
 
             if binding.vis == ty::Visibility::Public &&
-               (binding.is_import() || binding.is_extern_crate()) {
+               (binding.is_import() || binding.is_macro_def()) {
                 let def = binding.def();
                 if def != Def::Err {
                     if !def.def_id().is_local() {
                         self.session.cstore.export_macros(def.def_id().krate);
                     }
                     if let Def::Macro(..) = def {
-                        if let Some(&span) = exported_macro_names.get(&ident.name) {
+                        if let Some(&span) = exported_macro_names.get(&ident.modern()) {
                             let msg =
                                 format!("a macro named `{}` has already been exported", ident);
                             self.session.struct_span_err(span, &msg)
@@ -819,7 +833,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
                                 .emit();
                         }
                     }
-                    reexports.push(Export { name: ident.name, def: def, span: binding.span });
+                    reexports.push(Export { ident: ident.modern(), def: def, span: binding.span });
                 }
             }
 
index 5a8acf9abe1d015115a178758e5d479edca497c6..d83740936d5d4dc6ceba451a7ce7add9b4a61fbf 100644 (file)
@@ -828,7 +828,7 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
     if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
         sig.push('<');
         sig.push_str(&generics.lifetimes.iter()
-                              .map(|l| l.lifetime.name.to_string())
+                              .map(|l| l.lifetime.ident.name.to_string())
                               .collect::<Vec<_>>()
                               .join(", "));
         if !generics.lifetimes.is_empty() {
index a6b0eb473eb8e106b2ec731843fdcd858945d127..9b94a3b2f234b39106a8ea5e1e5bedbd7b967785 100644 (file)
@@ -642,6 +642,7 @@ pub fn unadjusted(ccx: &CrateContext<'a, 'tcx>,
             Stdcall => llvm::X86StdcallCallConv,
             Fastcall => llvm::X86FastcallCallConv,
             Vectorcall => llvm::X86_VectorCall,
+            Thiscall => llvm::X86_ThisCall,
             C => llvm::CCallConv,
             Unadjusted => llvm::CCallConv,
             Win64 => llvm::X86_64_Win64,
index d94d7f4430bf006bfb0ed196e888c24e42e06c8b..a3fa1279ffb4575866cb091e27afe236bbfb85ca 100644 (file)
@@ -901,7 +901,7 @@ fn trans_transmute_into(&mut self, bcx: &Builder<'a, 'tcx>,
         let llty = type_of::type_of(bcx.ccx, val.ty);
         let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
         let in_type = val.ty;
-        let out_type = dst.ty.to_ty(bcx.tcx());;
+        let out_type = dst.ty.to_ty(bcx.tcx());
         let llalign = cmp::min(bcx.ccx.align_of(in_type), bcx.ccx.align_of(out_type));
         self.store_operand(bcx, cast_ptr, Some(llalign), val);
     }
index 9e8352fde80617f1d7fb084e66b5ba1811897a15..0c9d74df2485c30eb9aacdceb21642b6d06810c1 100644 (file)
@@ -891,7 +891,8 @@ pub fn associated_path_def_to_ty(&self,
         let item = tcx.associated_items(trait_did).find(|i| i.name == assoc_name)
                                                   .expect("missing associated type");
         let def = Def::AssociatedTy(item.def_id);
-        if !tcx.vis_is_accessible_from(item.vis, ref_id) {
+        let def_scope = tcx.adjust(assoc_name, item.container.id(), ref_id).1;
+        if !item.vis.is_accessible_from(def_scope, tcx) {
             let msg = format!("{} `{}` is private", def.kind_name(), assoc_name);
             tcx.sess.span_err(span, &msg);
         }
@@ -962,7 +963,7 @@ pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
     pub fn prohibit_projection(&self, span: Span) {
         let mut err = struct_span_err!(self.tcx().sess, span, E0229,
                                        "associated type bindings are not allowed here");
-        err.span_label(span, "associate type not allowed here").emit();
+        err.span_label(span, "associated type not allowed here").emit();
     }
 
     // Check a type Path and convert it to a Ty.
index 4d5f67004a7cc0c35bc9bea72fab65e59fa827e2..43bf702935ac31e3d232821aa85bf28c150c99bb 100644 (file)
@@ -338,6 +338,7 @@ pub fn resolve_ufcs(&self,
     /// and return it, or `None`, if no such item was defined there.
     pub fn associated_item(&self, def_id: DefId, item_name: ast::Name)
                            -> Option<ty::AssociatedItem> {
-        self.tcx.associated_items(def_id).find(|item| item.name == item_name)
+        let ident = self.tcx.adjust(item_name, def_id, self.body_id).0;
+        self.tcx.associated_items(def_id).find(|item| item.name.to_ident() == ident)
     }
 }
index 9ad72b2a137ea2ea10112bfb7ddb61ed1a0b9f23..b32eb9ac5fbf6df24a04ca92753c816c369ea325 100644 (file)
@@ -371,7 +371,13 @@ fn reset(&mut self) {
 
     fn push_inherent_candidate(&mut self, xform_self_ty: Ty<'tcx>, item: ty::AssociatedItem,
                                kind: CandidateKind<'tcx>, import_id: Option<ast::NodeId>) {
-        if self.tcx.vis_is_accessible_from(item.vis, self.body_id) {
+        let is_accessible = if let LookingFor::MethodName(name) = self.looking_for {
+            let def_scope = self.tcx.adjust(name, item.container.id(), self.body_id).1;
+            item.vis.is_accessible_from(def_scope, self.tcx)
+        } else {
+            true
+        };
+        if is_accessible {
             self.inherent_candidates.push(Candidate { xform_self_ty, item, kind, import_id });
         } else if self.private_candidate.is_none() {
             self.private_candidate = Some(item.def());
@@ -380,7 +386,13 @@ fn push_inherent_candidate(&mut self, xform_self_ty: Ty<'tcx>, item: ty::Associa
 
     fn push_extension_candidate(&mut self, xform_self_ty: Ty<'tcx>, item: ty::AssociatedItem,
                                kind: CandidateKind<'tcx>, import_id: Option<ast::NodeId>) {
-        if self.tcx.vis_is_accessible_from(item.vis, self.body_id) {
+        let is_accessible = if let LookingFor::MethodName(name) = self.looking_for {
+            let def_scope = self.tcx.adjust(name, item.container.id(), self.body_id).1;
+            item.vis.is_accessible_from(def_scope, self.tcx)
+        } else {
+            true
+        };
+        if is_accessible {
             self.extension_candidates.push(Candidate { xform_self_ty, item, kind, import_id });
         } else if self.private_candidate.is_none() {
             self.private_candidate = Some(item.def());
index 7e70bb92cd6e0f011b57c3baf236412490b09641..edaaa863ecc34f458357cb0ecfe1175c7874edc6 100644 (file)
@@ -195,8 +195,8 @@ pub fn report_method_error(&self,
                                     };
 
                                     let field_ty = field.ty(tcx, substs);
-
-                                    if tcx.vis_is_accessible_from(field.vis, self.body_id) {
+                                    let scope = self.tcx.hir.get_module_parent(self.body_id);
+                                    if field.vis.is_accessible_from(scope, self.tcx) {
                                         if self.is_fn_ty(&field_ty, span) {
                                             err.help(&format!("use `({0}.{1})(...)` if you \
                                                                meant to call the function \
index 24a88140cf041014af2370a1c5345beb4404f29d..1ad3914854d342bff3b54aec232cb24103a1a463 100644 (file)
@@ -2916,9 +2916,12 @@ fn check_field(&self,
             match base_t.sty {
                 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
                     debug!("struct named {:?}",  base_t);
-                    if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
+                    let (ident, def_scope) =
+                        self.tcx.adjust(field.node, base_def.did, self.body_id);
+                    let fields = &base_def.struct_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 self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
+                        if field.vis.is_accessible_from(def_scope, self.tcx) {
                             autoderef.finalize(lvalue_pref, base);
                             self.apply_autoderef_adjustment(base.id, autoderefs, base_t);
 
@@ -3024,16 +3027,25 @@ fn check_tup_field(&self,
                     if !tuple_like { continue }
 
                     debug!("tuple struct named {:?}",  base_t);
-                    base_def.struct_variant().fields.get(idx.node).and_then(|field| {
+                    let ident = ast::Ident {
+                        name: Symbol::intern(&idx.node.to_string()),
+                        ctxt: idx.span.ctxt.modern(),
+                    };
+                    let (ident, def_scope) =
+                        self.tcx.adjust_ident(ident, base_def.did, self.body_id);
+                    let fields = &base_def.struct_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);
-                        private_candidate = Some((base_def.did, field_ty));
-                        if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
+                        if field.vis.is_accessible_from(def_scope, self.tcx) {
                             self.tcx.check_stability(field.did, expr.id, expr.span);
                             Some(field_ty)
                         } else {
+                            private_candidate = Some((base_def.did, field_ty));
                             None
                         }
-                    })
+                    } else {
+                        None
+                    }
                 }
                 ty::TyTuple(ref v, _) => {
                     tuple_like = true;
@@ -3142,7 +3154,7 @@ fn check_expr_struct_fields(&self,
 
         let mut remaining_fields = FxHashMap();
         for field in &variant.fields {
-            remaining_fields.insert(field.name, field);
+            remaining_fields.insert(field.name.to_ident(), field);
         }
 
         let mut seen_fields = FxHashMap();
@@ -3154,7 +3166,8 @@ fn check_expr_struct_fields(&self,
             let final_field_type;
             let field_type_hint;
 
-            if let Some(v_field) = remaining_fields.remove(&field.name.node) {
+            let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
+            if let Some(v_field) = remaining_fields.remove(&ident) {
                 final_field_type = self.field_ty(field.span, v_field, substs);
                 field_type_hint = self.field_ty(field.span, v_field, hint_substs);
 
@@ -3205,7 +3218,7 @@ fn check_expr_struct_fields(&self,
 
             let mut displayable_field_names = remaining_fields
                                               .keys()
-                                              .map(|x| x.as_str())
+                                              .map(|ident| ident.name.as_str())
                                               .collect::<Vec<_>>();
 
             displayable_field_names.sort();
index 141efe471af5fe1cdae32198ed4ea7add4d767e7..5ea3eaa88d7726b6acea1174e48e53e77cb800d2 100644 (file)
@@ -447,7 +447,7 @@ fn fill_in(cx: &DocContext, did: DefId, items: &mut Vec<clean::Item>) {
             let def_id = item.def.def_id();
             if cx.tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public {
                 if !visited.insert(def_id) { continue }
-                if let Some(i) = try_inline(cx, item.def, item.name) {
+                if let Some(i) = try_inline(cx, item.def, item.ident.name) {
                     items.extend(i)
                 }
             }
index f682f6aa763c5cd43e94f38f35724eeadd668256..380ee9c06a7d40f6c3d6bb6de4fb3841e80c5f0d 100644 (file)
@@ -178,9 +178,10 @@ pub fn opts() -> Vec<RustcOptGroup> {
         stable(optopt("", "markdown-playground-url",
                       "URL to send code snippets to", "URL")),
         stable(optflag("", "markdown-no-toc", "don't include table of contents")),
-        unstable(optopt("e", "extend-css",
-                        "to redefine some css rules with a given file to generate doc with your \
-                         own theme", "PATH")),
+        stable(optopt("e", "extend-css",
+                      "To add some CSS rules with a given file to generate doc with your \
+                       own theme. However, your theme might break if the rustdoc's generated HTML \
+                       changes, so be careful!", "PATH")),
         unstable(optmulti("Z", "",
                           "internal and debugging options (only on nightly build)", "FLAG")),
         stable(optopt("", "sysroot", "Override the system root", "PATH")),
index d463e41c58a2a3281206510a116a8d29687ed4e5..39ebe490d0eb28a064821bde1f20c3e37b638db2 100644 (file)
@@ -16,7 +16,6 @@
 use syntax::abi;
 use syntax::ast;
 use syntax::attr;
-use syntax::tokenstream::TokenStream;
 use syntax_pos::Span;
 
 use rustc::hir::map as hir_map;
@@ -214,8 +213,8 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
                         LoadedMacro::ProcMacro(..) => continue,
                     };
 
-                    let matchers = if let ast::ItemKind::MacroDef(ref tokens) = def.node {
-                        let tts: Vec<_> = TokenStream::from(tokens.clone()).into_trees().collect();
+                    let matchers = if let ast::ItemKind::MacroDef(ref def) = def.node {
+                        let tts: Vec<_> = def.stream().into_trees().collect();
                         tts.chunks(4).map(|arm| arm[0].span()).collect()
                     } else {
                         unreachable!()
index f497734e249c5c5d9c0cc3e5628cb85f014ba38e..a5a1b5e5f09191a62c25e3bd04b95335cb9b3f48 100644 (file)
@@ -247,7 +247,9 @@ pub fn shrink_to_fit(&mut self) {
         self.inner.shrink_to_fit()
     }
 
-    /// Converts this `OsString` into a boxed `OsStr`.
+    /// Converts this `OsString` into a boxed [`OsStr`].
+    ///
+    /// [`OsStr`]: struct.OsStr.html
     ///
     /// # Examples
     ///
@@ -482,12 +484,13 @@ pub fn is_empty(&self) -> bool {
     /// Returns the length of this `OsStr`.
     ///
     /// Note that this does **not** return the number of bytes in this string
-    /// as, for example, OS strings on Windows are encoded as a list of `u16`
+    /// as, for example, OS strings on Windows are encoded as a list of [`u16`]
     /// rather than a list of bytes. This number is simply useful for passing to
     /// other methods like [`OsString::with_capacity`] to avoid reallocations.
     ///
     /// See `OsStr` introduction for more information about encoding.
     ///
+    /// [`u16`]: ../primitive.u16.html
     /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
     ///
     /// # Examples
@@ -506,7 +509,10 @@ pub fn len(&self) -> usize {
         self.inner.inner.len()
     }
 
-    /// Converts a `Box<OsStr>` into an `OsString` without copying or allocating.
+    /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
+    ///
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`OsString`]: struct.OsString.html
     #[unstable(feature = "into_boxed_os_str", issue = "40380")]
     pub fn into_os_string(self: Box<OsStr>) -> OsString {
         let inner: Box<Slice> = unsafe { mem::transmute(self) };
index acff7faf8a7d0a853bf3d09e903f360db7c8f721..06fd838ea06d966b047f8e1a257d1acd253433cd 100644 (file)
@@ -35,6 +35,8 @@ fn lang_start(main: fn(), argc: isize, argv: *const *const u8) -> isize {
     use sys_common;
     use sys_common::thread_info;
     use thread::Thread;
+    #[cfg(not(feature = "backtrace"))]
+    use mem;
 
     sys::init();
 
@@ -53,9 +55,12 @@ fn lang_start(main: fn(), argc: isize, argv: *const *const u8) -> isize {
         sys::args::init(argc, argv);
 
         // Let's run some code!
+        #[cfg(feature = "backtrace")]
         let res = panic::catch_unwind(|| {
             ::sys_common::backtrace::__rust_begin_short_backtrace(main)
         });
+        #[cfg(not(feature = "backtrace"))]
+        let res = panic::catch_unwind(mem::transmute::<_, fn()>(main));
         sys_common::cleanup();
         res.is_err()
     };
index 8d80f942ff75cb9f50c29919c75d7beaf6a21466..296773d20f6140542cfdcfe8e7b25e4af1ee402a 100644 (file)
@@ -1,29 +1,12 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * 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 DMITRY VYUKOV "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 DMITRY VYUKOV 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.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
+// 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.
 
 //! A mostly lock-free multi-producer, single consumer queue.
 //!
index 5858e4b6ddb1f2ab35312aaa4a5406baa84ca29c..1148bc66fbabbaa0d0e998f6af203e1f84277588 100644 (file)
@@ -1,31 +1,12 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * 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 DMITRY VYUKOV "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 DMITRY VYUKOV 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.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
-
-// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+// 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.
 
 //! A single-producer single-consumer concurrent queue
 //!
@@ -33,6 +14,8 @@
 //! concurrently between two threads. This data structure is safe to use and
 //! enforces the semantics that there is one pusher and one popper.
 
+// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+
 use alloc::boxed::Box;
 use core::ptr;
 use core::cell::UnsafeCell;
index abdd9ace795f42dea62490944ec7d32c60493fd5..cacd84e21025f5dfaef88eeceec7593311411a17 100644 (file)
@@ -64,3 +64,8 @@ pub unsafe fn set(key: Key, value: *mut u8) {
 pub unsafe fn destroy(key: Key) {
     keys().remove(&key);
 }
+
+#[inline]
+pub fn requires_synchronized_create() -> bool {
+    false
+}
index 154406a1d8bd78ca29965e9f54f49f4af51fc896..d0e3b00d75fac43fdf2ad5f869e0f1add11be067 100644 (file)
@@ -359,9 +359,12 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
             }
             unsafe {
                 thread_info::set(imp::guard::current(), their_thread);
+                #[cfg(feature = "backtrace")]
                 let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                     ::sys_common::backtrace::__rust_begin_short_backtrace(f)
                 }));
+                #[cfg(not(feature = "backtrace"))]
+                let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
                 *their_packet.get() = Some(try_result);
             }
         };
@@ -394,6 +397,26 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
 /// want to specify the stack size or the name of the thread, use this API
 /// instead.
 ///
+/// As you can see in the signature of `spawn` there are two constraints on
+/// both the closure given to `spawn` and its return value, let's explain them:
+///
+/// - The `'static` constraint means that the closure and its return value
+///   must have a lifetime of the whole program execution. The reason for this
+///   is that threads can `detach` and outlive the lifetime they have been
+///   created in.
+///   Indeed if the thread, and by extension its return value, can outlive their
+///   caller, we need to make sure that they will be valid afterwards, and since
+///   we *can't* know when it will return we need to have them valid as long as
+///   possible, that is until the end of the program, hence the `'static`
+///   lifetime.
+/// - The [`Send`] constraint is because the closure will need to be passed
+///   *by value* from the thread where it is spawned to the new thread. Its
+///   return value will need to be passed from the new thread to the thread
+///   where it is `join`ed.
+///   As a reminder, the [`Send`] marker trait, expresses that it is safe to be
+///   passed from thread to thread. [`Sync`] expresses that it is safe to have a
+///   reference be passed from thread to thread.
+///
 /// # Panics
 ///
 /// Panics if the OS fails to create a thread; use [`Builder::spawn`]
@@ -460,6 +483,8 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
 /// [`panic`]: ../../std/macro.panic.html
 /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
 /// [`Builder`]: ../../std/thread/struct.Builder.html
+/// [`Send`]: ../../std/marker/trait.Send.html
+/// [`Sync`]: ../../std/marker/trait.Sync.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
index 30641515a41dd0ca3e3400ba7911bbd2cce70a15..ed2eb209906958a079fef8d48f6b85965a8f7a32 100644 (file)
@@ -20,6 +20,7 @@ pub enum Abi {
     Stdcall,
     Fastcall,
     Vectorcall,
+    Thiscall,
     Aapcs,
     Win64,
     SysV64,
@@ -55,6 +56,7 @@ pub struct AbiData {
     AbiData {abi: Abi::Stdcall, name: "stdcall", generic: false },
     AbiData {abi: Abi::Fastcall, name: "fastcall", generic: false },
     AbiData {abi: Abi::Vectorcall, name: "vectorcall", generic: false},
+    AbiData {abi: Abi::Thiscall, name: "thiscall", generic: false},
     AbiData {abi: Abi::Aapcs, name: "aapcs", generic: false },
     AbiData {abi: Abi::Win64, name: "win64", generic: false },
     AbiData {abi: Abi::SysV64, name: "sysv64", generic: false },
index 24ce99208ed11bc9e89cda6408003e12fa3207d2..2eb39bc26b5cb929b6223423c3067f58de39c8c9 100644 (file)
@@ -37,7 +37,7 @@
 pub struct Lifetime {
     pub id: NodeId,
     pub span: Span,
-    pub name: Name
+    pub ident: Ident,
 }
 
 impl fmt::Debug for Lifetime {
@@ -1019,6 +1019,18 @@ pub fn stream(&self) -> TokenStream {
     }
 }
 
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct MacroDef {
+    pub tokens: ThinTokenStream,
+    pub legacy: bool,
+}
+
+impl MacroDef {
+    pub fn stream(&self) -> TokenStream {
+        self.tokens.clone().into()
+    }
+}
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum StrStyle {
     /// A regular string, like `"foo"`
@@ -1863,7 +1875,7 @@ pub enum ItemKind {
     Mac(Mac),
 
     /// A macro definition.
-    MacroDef(ThinTokenStream),
+    MacroDef(MacroDef),
 }
 
 impl ItemKind {
index 45f891d8dc56db911f325fd6ff90b4034066e834..8e63e219c42c19924914ce01bf1661dc9cfb68aa 100644 (file)
@@ -320,7 +320,7 @@ pub fn meta(&self) -> Option<MetaItem> {
     pub fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
         where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     {
-        let mut parser = Parser::new(sess, self.tokens.clone(), None, false);
+        let mut parser = Parser::new(sess, self.tokens.clone(), None, false, false);
         let result = f(&mut parser)?;
         if parser.token != token::Eof {
             parser.unexpected()?;
index 73aeb40df840064ae0ffd2ea79ee369a9939d498..2a5de3c7382a334984d342b4e9cac5881eb45b88 100644 (file)
@@ -206,7 +206,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         });
 
-    let static_ = ecx.lifetime(span, ecx.name_of("'static"));
+    let static_ = ecx.lifetime(span, Ident::from_str("'static"));
     let ty_str = ecx.ty_rptr(
         span,
         ecx.ty_ident(span, ecx.ident_of("str")),
index 1930f61121bb028113f2dc37d5b037f6ca9f2a47..71dc81c37592322da76ee9bddf245d21577ec2ae 100644 (file)
@@ -550,12 +550,16 @@ pub enum SyntaxExtension {
 
     /// An attribute-like procedural macro that derives a builtin trait.
     BuiltinDerive(BuiltinDeriveFn),
+
+    /// A declarative macro, e.g. `macro m() {}`.
+    DeclMacro(Box<TTMacroExpander>, Option<Span> /* definition site span */),
 }
 
 impl SyntaxExtension {
     /// Return which kind of macro calls this syntax extension.
     pub fn kind(&self) -> MacroKind {
         match *self {
+            SyntaxExtension::DeclMacro(..) |
             SyntaxExtension::NormalTT(..) |
             SyntaxExtension::IdentTT(..) |
             SyntaxExtension::ProcMacro(..) =>
@@ -569,6 +573,13 @@ pub fn kind(&self) -> MacroKind {
                 MacroKind::Derive,
         }
     }
+
+    pub fn is_modern(&self) -> bool {
+        match *self {
+            SyntaxExtension::DeclMacro(..) => true,
+            _ => false,
+        }
+    }
 }
 
 pub type NamedSyntaxExtension = (Name, SyntaxExtension);
index 09f22e8691e4ca481d89e82d03683f44b67cba22..a4580ea3939fbb23803fffdb62e2a760c6e23c98 100644 (file)
@@ -76,10 +76,10 @@ fn typaram(&self,
     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
     fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef;
     fn typarambound(&self, path: ast::Path) -> ast::TyParamBound;
-    fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime;
+    fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime;
     fn lifetime_def(&self,
                     span: Span,
-                    name: ast::Name,
+                    ident: ast::Ident,
                     attrs: Vec<ast::Attribute>,
                     bounds: Vec<ast::Lifetime>)
                     -> ast::LifetimeDef;
@@ -478,19 +478,19 @@ fn typarambound(&self, path: ast::Path) -> ast::TyParamBound {
         ast::TraitTyParamBound(self.poly_trait_ref(path.span, path), ast::TraitBoundModifier::None)
     }
 
-    fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime {
-        ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name }
+    fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime {
+        ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, ident: ident }
     }
 
     fn lifetime_def(&self,
                     span: Span,
-                    name: ast::Name,
+                    ident: ast::Ident,
                     attrs: Vec<ast::Attribute>,
                     bounds: Vec<ast::Lifetime>)
                     -> ast::LifetimeDef {
         ast::LifetimeDef {
             attrs: attrs.into(),
-            lifetime: self.lifetime(span, name),
+            lifetime: self.lifetime(span, ident),
             bounds: bounds
         }
     }
index 25e0aed220ab3fb036e5fb37b890b95bb448d671..be077b481113f12c17fad392137df5465040e1b2 100644 (file)
@@ -288,7 +288,7 @@ fn expand(&mut self, expansion: Expansion) -> Expansion {
                     let derives = derives.entry(invoc.expansion_data.mark).or_insert_with(Vec::new);
 
                     for path in &traits {
-                        let mark = Mark::fresh();
+                        let mark = Mark::fresh(self.cx.current_expansion.mark);
                         derives.push(mark);
                         let item = match self.cx.resolver.resolve_macro(
                                 Mark::root(), path, MacroKind::Derive, false) {
@@ -455,25 +455,37 @@ fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) ->
         let path = &mac.node.path;
 
         let ident = ident.unwrap_or_else(|| keywords::Invalid.ident());
+        let validate_and_set_expn_info = |def_site_span, allow_internal_unstable| {
+            if ident.name != keywords::Invalid.name() {
+                return Err(format!("macro {}! expects no ident argument, given '{}'", path, ident));
+            }
+            mark.set_expn_info(ExpnInfo {
+                call_site: span,
+                callee: NameAndSpan {
+                    format: MacroBang(Symbol::intern(&format!("{}", path))),
+                    span: def_site_span,
+                    allow_internal_unstable: allow_internal_unstable,
+                },
+            });
+            Ok(())
+        };
+
         let marked_tts = noop_fold_tts(mac.node.stream(), &mut Marker(mark));
         let opt_expanded = match *ext {
-            NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
-                if ident.name != keywords::Invalid.name() {
-                    let msg =
-                        format!("macro {}! expects no ident argument, given '{}'", path, ident);
+            SyntaxExtension::DeclMacro(ref expand, def_site_span) => {
+                if let Err(msg) = validate_and_set_expn_info(def_site_span, false) {
                     self.cx.span_err(path.span, &msg);
                     return kind.dummy(span);
                 }
+                kind.make_from(expand.expand(self.cx, span, marked_tts))
+            }
 
-                invoc.expansion_data.mark.set_expn_info(ExpnInfo {
-                    call_site: span,
-                    callee: NameAndSpan {
-                        format: MacroBang(Symbol::intern(&format!("{}", path))),
-                        span: exp_span.map(|(_, s)| s),
-                        allow_internal_unstable: allow_internal_unstable,
-                    },
-                });
-
+            NormalTT(ref expandfun, def_info, allow_internal_unstable) => {
+                if let Err(msg) = validate_and_set_expn_info(def_info.map(|(_, s)| s),
+                                                             allow_internal_unstable) {
+                    self.cx.span_err(path.span, &msg);
+                    return kind.dummy(span);
+                }
                 kind.make_from(expandfun.expand(self.cx, span, marked_tts))
             }
 
@@ -687,7 +699,7 @@ macro_rules! fully_configure {
 
 impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn collect(&mut self, expansion_kind: ExpansionKind, kind: InvocationKind) -> Expansion {
-        let mark = Mark::fresh();
+        let mark = Mark::fresh(self.cx.current_expansion.mark);
         self.invocations.push(Invocation {
             kind: kind,
             expansion_kind: expansion_kind,
index bf66aa0f00bed42409ffbdc7ffe8cc3341d2a787..0b6a2eb536a20d7769721ee16a07f4de716ebefd 100644 (file)
@@ -418,9 +418,13 @@ fn inner_parse_loop(sess: &ParseSess,
     Success(())
 }
 
-pub fn parse(sess: &ParseSess, tts: TokenStream, ms: &[TokenTree], directory: Option<Directory>)
+pub fn parse(sess: &ParseSess,
+             tts: TokenStream,
+             ms: &[TokenTree],
+             directory: Option<Directory>,
+             recurse_into_modules: bool)
              -> NamedParseResult {
-    let mut parser = Parser::new(sess, tts, directory, true);
+    let mut parser = Parser::new(sess, tts, directory, recurse_into_modules, true);
     let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(), parser.span.lo));
     let mut next_eis = Vec::new(); // or proceed normally
 
index a208f530602a5f0b05677e27c261e29971871e78..a9252d0818e38039a1152589515cc821b1a156d3 100644 (file)
@@ -121,7 +121,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
                     path: cx.current_expansion.module.directory.clone(),
                     ownership: cx.current_expansion.directory_ownership,
                 };
-                let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), false);
+                let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false);
                 p.root_module_name = cx.current_expansion.module.mod_path.last()
                     .map(|id| id.name.as_str().to_string());
 
@@ -162,6 +162,12 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
     let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs"));
     let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs"));
 
+    // Parse the macro_rules! invocation
+    let body = match def.node {
+        ast::ItemKind::MacroDef(ref body) => body,
+        _ => unreachable!(),
+    };
+
     // The pattern that macro_rules matches.
     // The grammar for macro_rules! is:
     // $( $lhs:tt => $rhs:tt );+
@@ -174,7 +180,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
                 quoted::TokenTree::Token(DUMMY_SP, token::FatArrow),
                 quoted::TokenTree::MetaVarDecl(DUMMY_SP, rhs_nm, ast::Ident::from_str("tt")),
             ],
-            separator: Some(token::Semi),
+            separator: Some(if body.legacy { token::Semi } else { token::Comma }),
             op: quoted::KleeneOp::OneOrMore,
             num_captures: 2,
         })),
@@ -187,12 +193,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
         })),
     ];
 
-    // Parse the macro_rules! invocation
-    let body = match def.node {
-        ast::ItemKind::MacroDef(ref body) => body.clone().into(),
-        _ => unreachable!(),
-    };
-    let argument_map = match parse(sess, body, &argument_gram, None) {
+    let argument_map = match parse(sess, body.stream(), &argument_gram, None, true) {
         Success(m) => m,
         Failure(sp, tok) => {
             let s = parse_failure_msg(tok);
@@ -252,9 +253,12 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
         valid: valid,
     });
 
-    NormalTT(exp,
-             Some((def.id, def.span)),
-             attr::contains_name(&def.attrs, "allow_internal_unstable"))
+    if body.legacy {
+        let allow_internal_unstable = attr::contains_name(&def.attrs, "allow_internal_unstable");
+        NormalTT(exp, Some((def.id, def.span)), allow_internal_unstable)
+    } else {
+        SyntaxExtension::DeclMacro(exp, Some(def.span))
+    }
 }
 
 fn check_lhs_nt_follows(sess: &ParseSess,
index e1b7d4681ad160c38c613af52e931c48b0a5ff49..ca579409be430d62e0e26a70380f925348b22b2d 100644 (file)
@@ -269,9 +269,6 @@ pub fn new() -> Features {
     // Allows `impl Trait` in function return types.
     (active, conservative_impl_trait, "1.12.0", Some(34511)),
 
-    // Permits numeric fields in struct expressions and patterns.
-    (active, relaxed_adts, "1.12.0", Some(35626)),
-
     // The `!` type
     (active, never_type, "1.13.0", Some(35121)),
 
@@ -309,9 +306,12 @@ pub fn new() -> Features {
     // The `unadjusted` ABI. Perma unstable.
     (active, abi_unadjusted, "1.16.0", None),
 
-    // Macros 1.1
+    // Procedural macros 2.0.
     (active, proc_macro, "1.16.0", Some(38356)),
 
+    // Declarative macros 2.0 (`macro`).
+    (active, decl_macro, "1.17.0", Some(39412)),
+
     // Allows attributes on struct literal fields.
     (active, struct_field_attributes, "1.16.0", Some(38814)),
 
@@ -352,6 +352,9 @@ pub fn new() -> Features {
 
     // Allows use of the :vis macro fragment specifier
     (active, macro_vis_matcher, "1.18.0", Some(41022)),
+
+    // rustc internal
+    (active, abi_thiscall, "1.19.0", None),
 );
 
 declare_features! (
@@ -422,7 +425,10 @@ pub fn new() -> Features {
     (accepted, windows_subsystem, "1.18.0", Some(37499)),
     // Allows `break {expr}` with a value inside `loop`s.
     (accepted, loop_break_value, "1.19.0", Some(37339)),
+    // Permits numeric fields in struct expressions and patterns.
+    (accepted, relaxed_adts, "1.19.0", Some(35626)),
 );
+
 // If you change this, please modify src/doc/unstable-book as well. You must
 // move that documentation into the relevant place in the other docs, and
 // remove the chapter on the flag.
@@ -1051,6 +1057,10 @@ fn check_abi(&self, abi: Abi, span: Span) {
                 gate_feature_post!(&self, abi_vectorcall, span,
                                    "vectorcall is experimental and subject to change");
             },
+            Abi::Thiscall => {
+                gate_feature_post!(&self, abi_thiscall, span,
+                                   "thiscall is experimental and subject to change");
+            },
             Abi::RustCall => {
                 gate_feature_post!(&self, unboxed_closures, span,
                                    "rust-call ABI is subject to change");
@@ -1104,10 +1114,6 @@ fn contains_novel_literal(item: &ast::MetaItem) -> bool {
     }
 }
 
-fn starts_with_digit(s: &str) -> bool {
-    s.as_bytes().first().cloned().map_or(false, |b| b >= b'0' && b <= b'9')
-}
-
 impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_attribute(&mut self, attr: &ast::Attribute) {
         if !attr.span.allows_unstable() {
@@ -1229,6 +1235,11 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                 }
             }
 
+            ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => {
+                let msg = "`macro` is experimental";
+                gate_feature_post!(&self, decl_macro, i.span, msg);
+            }
+
             _ => {}
         }
 
@@ -1291,15 +1302,6 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
             ast::ExprKind::InPlace(..) => {
                 gate_feature_post!(&self, placement_in_syntax, e.span, EXPLAIN_PLACEMENT_IN);
             }
-            ast::ExprKind::Struct(_, ref fields, _) => {
-                for field in fields {
-                    if starts_with_digit(&field.ident.node.name.as_str()) {
-                        gate_feature_post!(&self, relaxed_adts,
-                                          field.span,
-                                          "numeric fields in struct expressions are unstable");
-                    }
-                }
-            }
             ast::ExprKind::Lit(ref lit) => {
                 if let ast::LitKind::Int(_, ref ty) = lit.node {
                     match *ty {
@@ -1339,15 +1341,6 @@ fn visit_pat(&mut self, pattern: &'a ast::Pat) {
                                   pattern.span,
                                   "box pattern syntax is experimental");
             }
-            PatKind::Struct(_, ref fields, _) => {
-                for field in fields {
-                    if starts_with_digit(&field.node.ident.name.as_str()) {
-                        gate_feature_post!(&self, relaxed_adts,
-                                          field.span,
-                                          "numeric fields in struct patterns are unstable");
-                    }
-                }
-            }
             PatKind::Range(_, _, RangeEnd::Excluded) => {
                 gate_feature_post!(&self, exclusive_range_pattern, pattern.span,
                                    "exclusive range pattern syntax is experimental");
index 58cf50cdc000ce3026dda2ad2ec1814926237378..4c6cf49a8db43d1b14981a263e2b4507f24672ac 100644 (file)
@@ -189,6 +189,10 @@ fn fold_mac(&mut self, _mac: Mac) -> Mac {
         // fold::noop_fold_mac(_mac, self)
     }
 
+    fn fold_macro_def(&mut self, def: MacroDef) -> MacroDef {
+        noop_fold_macro_def(def, self)
+    }
+
     fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime {
         noop_fold_lifetime(l, self)
     }
@@ -424,7 +428,7 @@ pub fn noop_fold_global_asm<T: Folder>(ga: P<GlobalAsm>,
 pub fn noop_fold_variant<T: Folder>(v: Variant, fld: &mut T) -> Variant {
     Spanned {
         node: Variant_ {
-            name: v.node.name,
+            name: fld.fold_ident(v.node.name),
             attrs: fold_attrs(v.node.attrs, fld),
             data: fld.fold_variant_data(v.node.data),
             disr_expr: v.node.disr_expr.map(|e| fld.fold_expr(e)),
@@ -515,6 +519,13 @@ pub fn noop_fold_mac<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac {
     }
 }
 
+pub fn noop_fold_macro_def<T: Folder>(def: MacroDef, fld: &mut T) -> MacroDef {
+    MacroDef {
+        tokens: fld.fold_tts(def.tokens.into()).into(),
+        legacy: def.legacy,
+    }
+}
+
 pub fn noop_fold_meta_list_item<T: Folder>(li: NestedMetaItem, fld: &mut T)
     -> NestedMetaItem {
     Spanned {
@@ -683,7 +694,7 @@ pub fn noop_fold_ty_params<T: Folder>(tps: Vec<TyParam>, fld: &mut T) -> Vec<TyP
 pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime {
     Lifetime {
         id: fld.new_id(l.id),
-        name: l.name,
+        ident: fld.fold_ident(l.ident),
         span: fld.new_span(l.span)
     }
 }
@@ -919,7 +930,7 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
             items.move_flat_map(|item| folder.fold_trait_item(item)),
         ),
         ItemKind::Mac(m) => ItemKind::Mac(folder.fold_mac(m)),
-        ItemKind::MacroDef(tts) => ItemKind::MacroDef(folder.fold_tts(tts.into()).into()),
+        ItemKind::MacroDef(def) => ItemKind::MacroDef(folder.fold_macro_def(def)),
     }
 }
 
index 4df23da3c9ce3464bf1cb760352e5bd7df68b144..83a164bdb9693c66b67cd46300331d0839f703a4 100644 (file)
@@ -238,7 +238,7 @@ pub fn check_for_substitution<'a>(reader: &StringReader<'a>,
         match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) {
             Some(&(ascii_char, ascii_name)) => {
                 let msg =
-                    format!("unicode character '{}' ({}) looks much like '{}' ({}), but it's not",
+                    format!("unicode character '{}' ({}) looks like '{}' ({}), but it's not",
                             ch, u_name, ascii_char, ascii_name);
                 err.span_help(span, &msg);
             },
index 1eff819d755493f33f713b6281100591bab78413..3a68a6ba7646c98de89a8cd8354b4db1fab175ef 100644 (file)
@@ -149,7 +149,9 @@ pub fn parse_stream_from_source_str(name: String, source: String, sess: &ParseSe
 // Create a new parser from a source string
 pub fn new_parser_from_source_str(sess: &ParseSess, name: String, source: String)
                                       -> Parser {
-    filemap_to_parser(sess, sess.codemap().new_filemap(name, source))
+    let mut parser = filemap_to_parser(sess, sess.codemap().new_filemap(name, source));
+    parser.recurse_into_file_modules = false;
+    parser
 }
 
 /// Create a new parser, handling errors as appropriate
@@ -218,7 +220,7 @@ pub fn filemap_to_stream(sess: &ParseSess, filemap: Rc<FileMap>) -> TokenStream
 
 /// Given stream and the `ParseSess`, produce a parser
 pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser {
-    Parser::new(sess, stream, None, false)
+    Parser::new(sess, stream, None, true, false)
 }
 
 /// Parse a string representing a character literal into its final form.
@@ -1032,4 +1034,23 @@ fn ttdelim_span() {
             Err(_) => panic!("could not get snippet"),
         }
     }
+
+    // This tests that when parsing a string (rather than a file) we don't try
+    // and read in a file for a module declaration and just parse a stub.
+    // See `recurse_into_file_modules` in the parser.
+    #[test]
+    fn out_of_line_mod() {
+        let sess = ParseSess::new(FilePathMapping::empty());
+        let item = parse_item_from_source_str(
+            "foo".to_owned(),
+            "mod foo { struct S; mod this_does_not_exist; }".to_owned(),
+            &sess,
+        ).unwrap().unwrap();
+
+        if let ast::ItemKind::Mod(ref m) = item.node {
+            assert!(m.items.len() == 2);
+        } else {
+            panic!();
+        }
+    }
 }
index 4741f896d3cc0c8c6ce38501dd2e1cb1a7dcfe0e..8d7c8c5248bb9e69977a8184dc6a9e623aeb99c7 100644 (file)
@@ -179,6 +179,8 @@ pub struct Parser<'a> {
     pub obsolete_set: HashSet<ObsoleteSyntax>,
     /// Used to determine the path to externally loaded source files
     pub directory: Directory,
+    /// Whether to parse sub-modules in other files.
+    pub recurse_into_file_modules: bool,
     /// Name of the root module this parser originated from. If `None`, then the
     /// name is not known. This does not change while the parser is descending
     /// into modules, and sub-parsers have new values for this name.
@@ -190,6 +192,7 @@ pub struct Parser<'a> {
     pub cfg_mods: bool,
 }
 
+
 struct TokenCursor {
     frame: TokenCursorFrame,
     stack: Vec<TokenCursorFrame>,
@@ -439,6 +442,7 @@ impl<'a> Parser<'a> {
     pub fn new(sess: &'a ParseSess,
                tokens: TokenStream,
                directory: Option<Directory>,
+               recurse_into_file_modules: bool,
                desugar_doc_comments: bool)
                -> Self {
         let mut parser = Parser {
@@ -450,6 +454,7 @@ pub fn new(sess: &'a ParseSess,
             prev_token_kind: PrevTokenKind::Other,
             restrictions: Restrictions::empty(),
             obsolete_set: HashSet::new(),
+            recurse_into_file_modules: recurse_into_file_modules,
             directory: Directory { path: PathBuf::new(), ownership: DirectoryOwnership::Owned },
             root_module_name: None,
             expected_tokens: Vec::new(),
@@ -467,12 +472,14 @@ pub fn new(sess: &'a ParseSess,
         let tok = parser.next_tok();
         parser.token = tok.tok;
         parser.span = tok.sp;
+
         if let Some(directory) = directory {
             parser.directory = directory;
         } else if parser.span != syntax_pos::DUMMY_SP {
             parser.directory.path = PathBuf::from(sess.codemap().span_to_filename(parser.span));
             parser.directory.path.pop();
         }
+
         parser.process_potential_macro_variable();
         parser
     }
@@ -1951,7 +1958,7 @@ fn expect_lifetime(&mut self) -> Lifetime {
             token::Lifetime(ident) => {
                 let ident_span = self.span;
                 self.bump();
-                Lifetime { name: ident.name, span: ident_span, id: ast::DUMMY_NODE_ID }
+                Lifetime { ident: ident, span: ident_span, id: ast::DUMMY_NODE_ID }
             }
             _ => self.span_bug(self.span, "not a lifetime")
         }
@@ -3751,31 +3758,59 @@ fn is_union_item(&self) -> bool {
     fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility)
                      -> PResult<'a, Option<P<Item>>> {
         let lo = self.span;
-        match self.token {
-            token::Ident(ident) if ident.name == "macro_rules" => {
-                if self.look_ahead(1, |t| *t == token::Not) {
-                    let prev_span = self.prev_span;
-                    self.complain_if_pub_macro(vis, prev_span);
-                    self.bump();
-                    self.bump();
+        let (ident, def) = match self.token {
+            token::Ident(ident) if ident.name == keywords::Macro.name() => {
+                self.bump();
+                let ident = self.parse_ident()?;
+                let tokens = if self.check(&token::OpenDelim(token::Brace)) {
+                    match self.parse_token_tree() {
+                        TokenTree::Delimited(_, ref delimited) => delimited.stream(),
+                        _ => unreachable!(),
+                    }
+                } else if self.check(&token::OpenDelim(token::Paren)) {
+                    let args = self.parse_token_tree();
+                    let body = if self.check(&token::OpenDelim(token::Brace)) {
+                        self.parse_token_tree()
+                    } else {
+                        self.unexpected()?;
+                        unreachable!()
+                    };
+                    TokenStream::concat(vec![
+                        args.into(),
+                        TokenTree::Token(lo.to(self.prev_span), token::FatArrow).into(),
+                        body.into(),
+                    ])
+                } else {
+                    self.unexpected()?;
+                    unreachable!()
+                };
+
+                (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
+            }
+            token::Ident(ident) if ident.name == "macro_rules" &&
+                                   self.look_ahead(1, |t| *t == token::Not) => {
+                let prev_span = self.prev_span;
+                self.complain_if_pub_macro(vis, prev_span);
+                self.bump();
+                self.bump();
+
+                let ident = self.parse_ident()?;
+                let (delim, tokens) = self.expect_delimited_token_tree()?;
+                if delim != token::Brace {
+                    if !self.eat(&token::Semi) {
+                        let msg = "macros that expand to items must either \
+                                   be surrounded with braces or followed by a semicolon";
+                        self.span_err(self.prev_span, msg);
+                    }
                 }
+
+                (ident, ast::MacroDef { tokens: tokens, legacy: true })
             }
             _ => return Ok(None),
         };
 
-        let id = self.parse_ident()?;
-        let (delim, tts) = self.expect_delimited_token_tree()?;
-        if delim != token::Brace {
-            if !self.eat(&token::Semi) {
-                let msg = "macros that expand to items must either be surrounded with braces \
-                           or followed by a semicolon";
-                self.span_err(self.prev_span, msg);
-            }
-        }
-
         let span = lo.to(self.prev_span);
-        let kind = ItemKind::MacroDef(tts);
-        Ok(Some(self.mk_item(span, id, kind, Visibility::Inherited, attrs.to_owned())))
+        Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
     }
 
     fn parse_stmt_without_recovery(&mut self,
@@ -3921,6 +3956,7 @@ fn parse_stmt_without_recovery(&mut self,
                 mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock);
             let item = self.parse_item_(attrs.clone(), false, true)?;
             self.directory.ownership = old_directory_ownership;
+
             match item {
                 Some(i) => Stmt {
                     id: ast::DUMMY_NODE_ID,
@@ -5254,7 +5290,7 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
         let id = self.parse_ident()?;
         if self.check(&token::Semi) {
             self.bump();
-            if in_cfg {
+            if in_cfg && self.recurse_into_file_modules {
                 // This mod is in an external file. Let's go get it!
                 let ModulePathSuccess { path, directory_ownership, warn } =
                     self.submod_path(id, &outer_attrs, id_span)?;
@@ -5281,10 +5317,12 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
         } else {
             let old_directory = self.directory.clone();
             self.push_directory(id, &outer_attrs);
+
             self.expect(&token::OpenDelim(token::Brace))?;
             let mod_inner_lo = self.span;
             let attrs = self.parse_inner_attributes()?;
             let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
+
             self.directory = old_directory;
             Ok((id, ItemKind::Mod(module), Some(attrs)))
         }
@@ -5347,7 +5385,8 @@ pub fn default_submod_path(id: ast::Ident, dir_path: &Path, codemap: &CodeMap) -
     fn submod_path(&mut self,
                    id: ast::Ident,
                    outer_attrs: &[ast::Attribute],
-                   id_sp: Span) -> PResult<'a, ModulePathSuccess> {
+                   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()) {
index 83c289ff80b9251bd2df854ebed1207b7f5a09f0..073ededcb0ce777cdd388557f8fb463e4b8d8606 100644 (file)
@@ -1392,7 +1392,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                 self.print_ident(item.ident)?;
                 self.cbox(INDENT_UNIT)?;
                 self.popen()?;
-                self.print_tts(tts.clone().into())?;
+                self.print_tts(tts.stream())?;
                 self.pclose()?;
                 word(&mut self.s, ";")?;
                 self.end()?;
@@ -2764,7 +2764,7 @@ pub fn print_lifetime(&mut self,
                           lifetime: &ast::Lifetime)
                           -> io::Result<()>
     {
-        self.print_name(lifetime.name)
+        self.print_name(lifetime.ident.name)
     }
 
     pub fn print_lifetime_bounds(&mut self,
index 8e257102e1c13367d281d01cce701e94bb0bacf5..a8a9ae556f1084509a43ecd8c961ca7d3d93346e 100644 (file)
@@ -21,7 +21,7 @@
 /// call to codemap's `is_internal` check.
 /// The expanded code uses the unstable `#[prelude_import]` attribute.
 fn ignored_span(sp: Span) -> Span {
-    let mark = Mark::fresh();
+    let mark = Mark::fresh(Mark::root());
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
         callee: NameAndSpan {
index bb1a6ff65a596018a263bc7aa94e941e24da1b78..837c3eb0100c60ed1859d706d6c387a0c0a78ab4 100644 (file)
@@ -276,7 +276,7 @@ fn generate_test_harness(sess: &ParseSess,
     let mut cleaner = EntryPointCleaner { depth: 0 };
     let krate = cleaner.fold_crate(krate);
 
-    let mark = Mark::fresh();
+    let mark = Mark::fresh(Mark::root());
     let mut cx: TestCtxt = TestCtxt {
         sess: sess,
         span_diagnostic: sd,
@@ -591,7 +591,7 @@ fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
     let struct_type = ecx.ty_path(ecx.path(sp, vec![ecx.ident_of("self"),
                                                     ecx.ident_of("test"),
                                                     ecx.ident_of("TestDescAndFn")]));
-    let static_lt = ecx.lifetime(sp, keywords::StaticLifetime.name());
+    let static_lt = ecx.lifetime(sp, keywords::StaticLifetime.ident());
     // &'static [self::test::TestDescAndFn]
     let static_type = ecx.ty_rptr(sp,
                                   ecx.ty(sp, ast::TyKind::Slice(struct_type)),
index 9c1371a31fec7a9287f9f874c5d59defe042056e..339e7c0b628adcf5a9c9298cd93423c138ae20a5 100644 (file)
@@ -109,7 +109,7 @@ pub fn parse(cx: &base::ExtCtxt, mtch: &[quoted::TokenTree], tts: TokenStream)
             path: cx.current_expansion.module.directory.clone(),
             ownership: cx.current_expansion.directory_ownership,
         };
-        macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory))
+        macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory), true)
     }
 
     /// Check if this TokenTree is equal to the other, regardless of span information.
index 0fa0753b22c8298276987aa44eff0d5d6c39f5bd..18a0949af0eb136c5a25dabba2417dbc5840fe5e 100644 (file)
@@ -27,7 +27,6 @@
 use ast::*;
 use syntax_pos::Span;
 use codemap::Spanned;
-use tokenstream::ThinTokenStream;
 
 #[derive(Copy, Clone, PartialEq, Eq)]
 pub enum FnKind<'a> {
@@ -113,7 +112,7 @@ fn visit_mac(&mut self, _mac: &'ast Mac) {
         // definition in your trait impl:
         // visit::walk_mac(self, _mac)
     }
-    fn visit_mac_def(&mut self, _mac: &'ast ThinTokenStream, _id: NodeId) {
+    fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) {
         // Nothing to do
     }
     fn visit_path(&mut self, path: &'ast Path, _id: NodeId) {
@@ -196,7 +195,7 @@ pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) {
 }
 
 pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) {
-    visitor.visit_name(lifetime.span, lifetime.name);
+    visitor.visit_ident(lifetime.span, lifetime.ident);
 }
 
 pub fn walk_lifetime_def<'a, V: Visitor<'a>>(visitor: &mut V, lifetime_def: &'a LifetimeDef) {
index cfd52381538cb6808661071c0363dbf489551410..9c89f99cbb5b3d6d652551d07499349bba8f4f0f 100644 (file)
@@ -118,14 +118,14 @@ pub fn nil_ty<'r>() -> Ty<'r> {
 
 fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
     match *lt {
-        Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s).name)),
+        Some(s) => Some(cx.lifetime(span, Ident::from_str(s))),
         None => None,
     }
 }
 
 fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
     match *lt {
-        Some(ref s) => vec![cx.lifetime(span, cx.ident_of(*s).name)],
+        Some(s) => vec![cx.lifetime(span, Ident::from_str(s))],
         None => vec![],
     }
 }
@@ -243,11 +243,11 @@ pub fn to_generics(&self,
                        -> Generics {
         let lifetimes = self.lifetimes
             .iter()
-            .map(|&(ref lt, ref bounds)| {
+            .map(|&(lt, ref bounds)| {
                 let bounds = bounds.iter()
-                    .map(|b| cx.lifetime(span, cx.ident_of(*b).name))
+                    .map(|b| cx.lifetime(span, Ident::from_str(b)))
                     .collect();
-                cx.lifetime_def(span, cx.ident_of(*lt).name, vec![], bounds)
+                cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds)
             })
             .collect();
         let ty_params = self.bounds
@@ -277,7 +277,7 @@ pub fn get_explicit_self(cx: &ExtCtxt,
                 respan(span,
                        match *ptr {
                            Borrowed(ref lt, mutbl) => {
-                               let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
+                               let lt = lt.map(|s| cx.lifetime(span, Ident::from_str(s)));
                                SelfKind::Region(lt, mutbl)
                            }
                            Raw(_) => {
index 31c7cc33676776487a41e6247add158c0edf673a..00dcfc7a587069a2294d750d2a92a2a2ecba14ae 100644 (file)
@@ -162,7 +162,7 @@ fn call_intrinsic(cx: &ExtCtxt,
     } else { // Avoid instability errors with user defined curstom derives, cc #36316
         let mut info = cx.current_expansion.mark.expn_info().unwrap();
         info.callee.allow_internal_unstable = true;
-        let mark = Mark::fresh();
+        let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(info);
         span.ctxt = SyntaxContext::empty().apply_mark(mark);
     }
index ecf0a8f377ea3dc3c81f220cc3688020525778bf..affebbabbbda4d22398157c6513ea5d7bf933860 100644 (file)
@@ -13,7 +13,7 @@
 // interface.
 //
 
-use syntax::ast;
+use syntax::ast::{self, Ident};
 use syntax::ext::base::*;
 use syntax::ext::base;
 use syntax::ext::build::AstBuilder;
@@ -39,10 +39,9 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
                                      cx.std_path(&["option", "Option", "None"]),
                                      Vec::new(),
                                      vec![cx.ty_rptr(sp,
-                                                     cx.ty_ident(sp, cx.ident_of("str")),
+                                                     cx.ty_ident(sp, Ident::from_str("str")),
                                                      Some(cx.lifetime(sp,
-                                                                      cx.ident_of("'static")
-                                                                          .name)),
+                                                                      Ident::from_str("'static"))),
                                                      ast::Mutability::Immutable)],
                                      Vec::new()))
         }
index 6f5ab50b2fe6fd410b2d48d12ec5e462d0f854a7..24c1dfe289b1ed15c6494b77f28fd286a12a64e8 100644 (file)
@@ -508,7 +508,7 @@ fn static_array(ecx: &mut ExtCtxt,
         let sp = piece_ty.span;
         let ty = ecx.ty_rptr(sp,
                              ecx.ty(sp, ast::TyKind::Slice(piece_ty)),
-                             Some(ecx.lifetime(sp, keywords::StaticLifetime.name())),
+                             Some(ecx.lifetime(sp, keywords::StaticLifetime.ident())),
                              ast::Mutability::Immutable);
         let slice = ecx.expr_vec_slice(sp, pieces);
         // static instead of const to speed up codegen by not requiring this to be inlined
@@ -536,7 +536,7 @@ fn into_expr(mut self) -> P<ast::Expr> {
 
         // First, build up the static array which will become our precompiled
         // format "string"
-        let static_lifetime = self.ecx.lifetime(self.fmtsp, keywords::StaticLifetime.name());
+        let static_lifetime = self.ecx.lifetime(self.fmtsp, keywords::StaticLifetime.ident());
         let piece_ty = self.ecx.ty_rptr(self.fmtsp,
                                         self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
                                         Some(static_lifetime),
index 6318abec69f06526c158e74da6454a12fa36b364..ab6d73e5061a0a5252834ca345137a95c3b46dc2 100644 (file)
@@ -361,7 +361,7 @@ fn mk_registrar(cx: &mut ExtCtxt,
                 custom_derives: &[ProcMacroDerive],
                 custom_attrs: &[ProcMacroDef],
                 custom_macros: &[ProcMacroDef]) -> P<ast::Item> {
-    let mark = Mark::fresh();
+    let mark = Mark::fresh(Mark::root());
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
         callee: NameAndSpan {
index 8a9ff647b3ea1b9a4504aa55f3ccd4f0766a212c..f2ccc3f051e9289eb3f3a14567b06ecf6415eb63 100644 (file)
@@ -16,7 +16,7 @@
 //! DOI=10.1017/S0956796812000093 http://dx.doi.org/10.1017/S0956796812000093
 
 use Span;
-use symbol::Symbol;
+use symbol::{Ident, Symbol};
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 use std::cell::RefCell;
 use std::fmt;
 
 /// A SyntaxContext represents a chain of macro expansions (represented by marks).
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
 pub struct SyntaxContext(u32);
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Default)]
 pub struct SyntaxContextData {
     pub outer_mark: Mark,
     pub prev_ctxt: SyntaxContext,
+    pub modern: SyntaxContext,
 }
 
 /// A mark is a unique id associated with a macro expansion.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default, RustcEncodable, RustcDecodable)]
 pub struct Mark(u32);
 
+#[derive(Default)]
+struct MarkData {
+    parent: Mark,
+    modern: bool,
+    expn_info: Option<ExpnInfo>,
+}
+
 impl Mark {
-    pub fn fresh() -> Self {
+    pub fn fresh(parent: Mark) -> Self {
         HygieneData::with(|data| {
-            data.marks.push(None);
+            data.marks.push(MarkData { parent: parent, modern: false, expn_info: None });
             Mark(data.marks.len() as u32 - 1)
         })
     }
@@ -59,29 +67,59 @@ pub fn from_u32(raw: u32) -> Mark {
     }
 
     pub fn expn_info(self) -> Option<ExpnInfo> {
-        HygieneData::with(|data| data.marks[self.0 as usize].clone())
+        HygieneData::with(|data| data.marks[self.0 as usize].expn_info.clone())
     }
 
     pub fn set_expn_info(self, info: ExpnInfo) {
-        HygieneData::with(|data| data.marks[self.0 as usize] = Some(info))
+        HygieneData::with(|data| data.marks[self.0 as usize].expn_info = Some(info))
+    }
+
+    pub fn modern(mut self) -> Mark {
+        HygieneData::with(|data| {
+            loop {
+                if self == Mark::root() || data.marks[self.0 as usize].modern {
+                    return self;
+                }
+                self = data.marks[self.0 as usize].parent;
+            }
+        })
+    }
+
+    pub fn is_modern(self) -> bool {
+        HygieneData::with(|data| data.marks[self.0 as usize].modern)
+    }
+
+    pub fn set_modern(self) {
+        HygieneData::with(|data| data.marks[self.0 as usize].modern = true)
+    }
+
+    pub fn is_descendant_of(mut self, ancestor: Mark) -> bool {
+        HygieneData::with(|data| {
+            while self != ancestor {
+                if self == Mark::root() {
+                    return false;
+                }
+                self = data.marks[self.0 as usize].parent;
+            }
+            true
+        })
     }
 }
 
 struct HygieneData {
-    marks: Vec<Option<ExpnInfo>>,
+    marks: Vec<MarkData>,
     syntax_contexts: Vec<SyntaxContextData>,
     markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
+    gensym_to_ctxt: HashMap<Symbol, SyntaxContext>,
 }
 
 impl HygieneData {
     fn new() -> Self {
         HygieneData {
-            marks: vec![None],
-            syntax_contexts: vec![SyntaxContextData {
-                outer_mark: Mark::root(),
-                prev_ctxt: SyntaxContext::empty(),
-            }],
+            marks: vec![MarkData::default()],
+            syntax_contexts: vec![SyntaxContextData::default()],
             markings: HashMap::new(),
+            gensym_to_ctxt: HashMap::new(),
         }
     }
 
@@ -102,30 +140,146 @@ pub const fn empty() -> Self {
         SyntaxContext(0)
     }
 
-    pub fn data(self) -> SyntaxContextData {
-        HygieneData::with(|data| data.syntax_contexts[self.0 as usize])
-    }
-
     /// Extend a syntax context with a given mark
     pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
-        // Applying the same mark twice is a no-op
-        let ctxt_data = self.data();
-        if mark == ctxt_data.outer_mark {
-            return ctxt_data.prev_ctxt;
-        }
-
         HygieneData::with(|data| {
             let syntax_contexts = &mut data.syntax_contexts;
+            let ctxt_data = syntax_contexts[self.0 as usize];
+            if mark == ctxt_data.outer_mark {
+                return ctxt_data.prev_ctxt;
+            }
+
+            let modern = if data.marks[mark.0 as usize].modern {
+                *data.markings.entry((ctxt_data.modern, mark)).or_insert_with(|| {
+                    let modern = SyntaxContext(syntax_contexts.len() as u32);
+                    syntax_contexts.push(SyntaxContextData {
+                        outer_mark: mark,
+                        prev_ctxt: ctxt_data.modern,
+                        modern: modern,
+                    });
+                    modern
+                })
+            } else {
+                ctxt_data.modern
+            };
+
             *data.markings.entry((self, mark)).or_insert_with(|| {
                 syntax_contexts.push(SyntaxContextData {
                     outer_mark: mark,
                     prev_ctxt: self,
+                    modern: modern,
                 });
                 SyntaxContext(syntax_contexts.len() as u32 - 1)
             })
         })
     }
 
+    pub fn remove_mark(&mut self) -> Mark {
+        HygieneData::with(|data| {
+            let outer_mark = data.syntax_contexts[self.0 as usize].outer_mark;
+            *self = data.syntax_contexts[self.0 as usize].prev_ctxt;
+            outer_mark
+        })
+    }
+
+    /// Adjust this context for resolution in a scope created by the given expansion.
+    /// For example, consider the following three resolutions of `f`:
+    /// ```rust
+    /// mod foo { pub fn f() {} } // `f`'s `SyntaxContext` is empty.
+    /// m!(f);
+    /// macro m($f:ident) {
+    ///     mod bar {
+    ///         pub fn f() {} // `f`'s `SyntaxContext` has a single `Mark` from `m`.
+    ///         pub fn $f() {} // `$f`'s `SyntaxContext` is empty.
+    ///     }
+    ///     foo::f(); // `f`'s `SyntaxContext` has a single `Mark` from `m`
+    ///     //^ Since `mod foo` is outside this expansion, `adjust` removes the mark from `f`,
+    ///     //| and it resolves to `::foo::f`.
+    ///     bar::f(); // `f`'s `SyntaxContext` has a single `Mark` from `m`
+    ///     //^ Since `mod bar` not outside this expansion, `adjust` does not change `f`,
+    ///     //| and it resolves to `::bar::f`.
+    ///     bar::$f(); // `f`'s `SyntaxContext` is empty.
+    ///     //^ Since `mod bar` is not outside this expansion, `adjust` does not change `$f`,
+    ///     //| and it resolves to `::bar::$f`.
+    /// }
+    /// ```
+    /// This returns the expansion whose definition scope we use to privacy check the resolution,
+    /// or `None` if we privacy check as usual (i.e. not w.r.t. a macro definition scope).
+    pub fn adjust(&mut self, expansion: Mark) -> Option<Mark> {
+        let mut scope = None;
+        while !expansion.is_descendant_of(self.outer()) {
+            scope = Some(self.remove_mark());
+        }
+        scope
+    }
+
+    /// Adjust this context for resolution in a scope created by the given expansion
+    /// via a glob import with the given `SyntaxContext`.
+    /// For example,
+    /// ```rust
+    /// m!(f);
+    /// macro m($i:ident) {
+    ///     mod foo {
+    ///         pub fn f() {} // `f`'s `SyntaxContext` has a single `Mark` from `m`.
+    ///         pub fn $i() {} // `$i`'s `SyntaxContext` is empty.
+    ///     }
+    ///     n(f);
+    ///     macro n($j:ident) {
+    ///         use foo::*;
+    ///         f(); // `f`'s `SyntaxContext` has a mark from `m` and a mark from `n`
+    ///         //^ `glob_adjust` removes the mark from `n`, so this resolves to `foo::f`.
+    ///         $i(); // `$i`'s `SyntaxContext` has a mark from `n`
+    ///         //^ `glob_adjust` removes the mark from `n`, so this resolves to `foo::$i`.
+    ///         $j(); // `$j`'s `SyntaxContext` has a mark from `m`
+    ///         //^ This cannot be glob-adjusted, so this is a resolution error.
+    ///     }
+    /// }
+    /// ```
+    /// This returns `None` if the context cannot be glob-adjusted.
+    /// Otherwise, it returns the scope to use when privacy checking (see `adjust` for details).
+    pub fn glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext)
+                       -> Option<Option<Mark>> {
+        let mut scope = None;
+        while !expansion.is_descendant_of(glob_ctxt.outer()) {
+            scope = Some(glob_ctxt.remove_mark());
+            if self.remove_mark() != scope.unwrap() {
+                return None;
+            }
+        }
+        if self.adjust(expansion).is_some() {
+            return None;
+        }
+        Some(scope)
+    }
+
+    /// Undo `glob_adjust` if possible:
+    /// ```rust
+    /// if let Some(privacy_checking_scope) = self.reverse_glob_adjust(expansion, glob_ctxt) {
+    ///     assert!(self.glob_adjust(expansion, glob_ctxt) == Some(privacy_checking_scope));
+    /// }
+    /// ```
+    pub fn reverse_glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext)
+                               -> Option<Option<Mark>> {
+        if self.adjust(expansion).is_some() {
+            return None;
+        }
+
+        let mut marks = Vec::new();
+        while !expansion.is_descendant_of(glob_ctxt.outer()) {
+            marks.push(glob_ctxt.remove_mark());
+        }
+
+        let scope = marks.last().cloned();
+        while let Some(mark) = marks.pop() {
+            *self = self.apply_mark(mark);
+        }
+        Some(scope)
+    }
+
+    pub fn modern(self) -> SyntaxContext {
+        HygieneData::with(|data| data.syntax_contexts[self.0 as usize].modern)
+    }
+
     pub fn outer(self) -> Mark {
         HygieneData::with(|data| data.syntax_contexts[self.0 as usize].outer_mark)
     }
@@ -200,3 +354,22 @@ fn decode<D: Decoder>(_: &mut D) -> Result<SyntaxContext, D::Error> {
         Ok(SyntaxContext::empty()) // FIXME(jseyfried) intercrate hygiene
     }
 }
+
+impl Symbol {
+    pub fn from_ident(ident: Ident) -> Symbol {
+        HygieneData::with(|data| {
+            let gensym = ident.name.gensymed();
+            data.gensym_to_ctxt.insert(gensym, ident.ctxt);
+            gensym
+        })
+    }
+
+    pub fn to_ident(self) -> Ident {
+        HygieneData::with(|data| {
+            match data.gensym_to_ctxt.get(&self) {
+                Some(&ctxt) => Ident { name: self.interned(), ctxt: ctxt },
+                None => Ident::with_empty_ctxt(self),
+            }
+        })
+    }
+}
index b866652c49f854c67d7ab415c2753cc508bb4710..73c0256f2c1f50babdde07d8a7a5c8c6e0e8f196 100644 (file)
@@ -35,8 +35,8 @@ pub fn from_str(string: &str) -> Ident {
         Ident::with_empty_ctxt(Symbol::intern(string))
     }
 
-    pub fn unhygienize(self) -> Ident {
-        Ident { name: self.name, ctxt: SyntaxContext::empty() }
+    pub fn modern(self) -> Ident {
+        Ident { name: self.name, ctxt: self.ctxt.modern() }
     }
 }
 
@@ -54,13 +54,24 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl Encodable for Ident {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        self.name.encode(s)
+        if self.ctxt.modern() == SyntaxContext::empty() {
+            s.emit_str(&self.name.as_str())
+        } else { // FIXME(jseyfried) intercrate hygiene
+            let mut string = "#".to_owned();
+            string.push_str(&self.name.as_str());
+            s.emit_str(&string)
+        }
     }
 }
 
 impl Decodable for Ident {
     fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
-        Ok(Ident::with_empty_ctxt(Symbol::decode(d)?))
+        let string = d.read_str()?;
+        Ok(if !string.starts_with('#') {
+            Ident::from_str(&string)
+        } else { // FIXME(jseyfried) intercrate hygiene
+            Ident::with_empty_ctxt(Symbol::gensym(&string[1..]))
+        })
     }
 }
 
@@ -77,11 +88,19 @@ pub fn intern(string: &str) -> Self {
         with_interner(|interner| interner.intern(string))
     }
 
+    pub fn interned(self) -> Self {
+        with_interner(|interner| interner.interned(self))
+    }
+
     /// gensym's a new usize, using the current interner.
     pub fn gensym(string: &str) -> Self {
         with_interner(|interner| interner.gensym(string))
     }
 
+    pub fn gensymed(self) -> Self {
+        with_interner(|interner| interner.gensymed(self))
+    }
+
     pub fn as_str(self) -> InternedString {
         with_interner(|interner| unsafe {
             InternedString {
@@ -129,6 +148,7 @@ fn eq(&self, other: &T) -> bool {
 pub struct Interner {
     names: HashMap<Box<str>, Symbol>,
     strings: Vec<Box<str>>,
+    gensyms: Vec<Symbol>,
 }
 
 impl Interner {
@@ -156,15 +176,29 @@ pub fn intern(&mut self, string: &str) -> Symbol {
         name
     }
 
+    pub fn interned(&self, symbol: Symbol) -> Symbol {
+        if (symbol.0 as usize) < self.strings.len() {
+            symbol
+        } else {
+            self.interned(self.gensyms[(!0 - symbol.0) as usize])
+        }
+    }
+
     fn gensym(&mut self, string: &str) -> Symbol {
-        let gensym = Symbol(self.strings.len() as u32);
-        // leave out of `names` to avoid colliding
-        self.strings.push(string.to_string().into_boxed_str());
-        gensym
+        let symbol = self.intern(string);
+        self.gensymed(symbol)
     }
 
-    pub fn get(&self, name: Symbol) -> &str {
-        &self.strings[name.0 as usize]
+    fn gensymed(&mut self, symbol: Symbol) -> Symbol {
+        self.gensyms.push(symbol);
+        Symbol(!0 - self.gensyms.len() as u32 + 1)
+    }
+
+    pub fn get(&self, symbol: Symbol) -> &str {
+        match self.strings.get(symbol.0 as usize) {
+            Some(ref string) => string,
+            None => self.get(self.gensyms[(!0 - symbol.0) as usize]),
+        }
     }
 }
 
@@ -379,11 +413,10 @@ fn interner_tests() {
         assert_eq!(i.intern("cat"), Symbol(1));
         // dog is still at zero
         assert_eq!(i.intern("dog"), Symbol(0));
-        // gensym gets 3
-        assert_eq!(i.gensym("zebra"), Symbol(2));
+        assert_eq!(i.gensym("zebra"), Symbol(4294967295));
         // gensym of same string gets new number :
-        assert_eq!(i.gensym("zebra"), Symbol(3));
+        assert_eq!(i.gensym("zebra"), Symbol(4294967294));
         // gensym of *existing* string gets new number:
-        assert_eq!(i.gensym("dog"), Symbol(4));
+        assert_eq!(i.gensym("dog"), Symbol(4294967293));
     }
 }
index 7e32800e0f9b8a915e597c5936e905f4dd0882f5..eeede4b8aa13c9ed7826b35fe3ceb63f7ca46c27 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attr_proc_macro.rs
-// gate-test-proc_macro
 #![feature(use_extern_macros)]
 
 extern crate attr_proc_macro;
@@ -21,4 +20,4 @@
 
 fn main() {
     let _ = Foo;
-}
\ No newline at end of file
+}
index 6ff0baeeb4d4bd25c16e420febcebf7f2fb41af3..d15f9937f13828faff915c8a195fc907cd7b12b9 100644 (file)
@@ -22,7 +22,7 @@ fn boo(&self) -> usize { 42 }
 
 fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
 //~^ ERROR associated type bindings are not allowed here [E0229]
-//~| NOTE associate type not allowed here
+//~| NOTE associated type not allowed here
 
 fn main() {
 }
index b77c9fab7169f6add4cedb9cecc13ee304495b8d..45c715f51fe4810f8ca8868d5e8842519a185def 100644 (file)
@@ -11,6 +11,7 @@
 // gate-test-intrinsics
 // gate-test-platform_intrinsics
 // gate-test-abi_vectorcall
+// gate-test-abi_thiscall
 // gate-test-abi_ptx
 // gate-test-abi_x86_interrupt
 
@@ -22,6 +23,7 @@ extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change
 extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental
 extern "ptx-kernel" fn f6() {} //~ ERROR PTX ABIs are experimental and subject to change
 extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental
+extern "thiscall" fn f8() {} //~ ERROR thiscall is experimental and subject to change
 
 // Methods in trait definition
 trait Tr {
@@ -32,6 +34,7 @@ trait Tr {
     extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental
     extern "ptx-kernel" fn m6(); //~ ERROR PTX ABIs are experimental and subject to change
     extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental
+    extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change
 
     extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change
     extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental
@@ -40,6 +43,7 @@ extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental
     extern "ptx-kernel" fn dm6() {} //~ ERROR PTX ABIs are experimental and subject to change
     extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental
+    extern "thiscall" fn dm8() {} //~ ERROR thiscall is experimental and subject to change
 }
 
 struct S;
@@ -53,6 +57,7 @@ extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental
     extern "ptx-kernel" fn m6() {} //~ ERROR PTX ABIs are experimental and subject to change
     extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental
+    extern "thiscall" fn m8() {} //~ ERROR thiscall is experimental and subject to change
 }
 
 // Methods in inherent impl
@@ -64,6 +69,7 @@ extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental
     extern "ptx-kernel" fn im6() {} //~ ERROR PTX ABIs are experimental and subject to change
     extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
+    extern "thiscall" fn im8() {} //~ ERROR thiscall is experimental and subject to change
 }
 
 // Function pointer types
@@ -74,6 +80,7 @@ extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
 type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental
 type A6 = extern "ptx-kernel" fn (); //~ ERROR PTX ABIs are experimental and subject to change
 type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental
+type A8 = extern "thiscall" fn(); //~ ERROR thiscall is experimental and subject to change
 
 // Foreign modules
 extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
@@ -83,5 +90,6 @@ extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
 extern "msp430-interrupt" {} //~ ERROR msp430-interrupt ABI is experimental
 extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental and subject to change
 extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental
+extern "thiscall" {} //~ ERROR thiscall is experimental and subject to change
 
 fn main() {}
diff --git a/src/test/compile-fail/feature-gate-decl_macro.rs b/src/test/compile-fail/feature-gate-decl_macro.rs
new file mode 100644 (file)
index 0000000..af7d5fe
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 m() {} //~ ERROR `macro` is experimental (see issue #39412)
+//~| HELP add #![feature(decl_macro)] to the crate attributes to enable
+
+fn main() {}
index 0560abb6af498fb1e8e6b6d76af34f156dae70b9..77f61ba47b005ebe9b077ec302f412ba0a2a2e11 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// gate-test-global_asm
-
 global_asm!(""); //~ ERROR `global_asm!` is not stable
 
 fn main() {}
diff --git a/src/test/compile-fail/hygiene/globs.rs b/src/test/compile-fail/hygiene/globs.rs
new file mode 100644 (file)
index 0000000..7ba2170
--- /dev/null
@@ -0,0 +1,68 @@
+// 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(decl_macro)]
+
+mod foo {
+    pub fn f() {}
+}
+
+mod bar {
+    pub fn g() {}
+}
+
+macro m($($t:tt)*) {
+    $($t)*
+    use foo::*;
+    f();
+    g(); //~ ERROR cannot find function `g` in this scope
+}
+
+fn main() {
+    m! {
+        use bar::*;
+        g();
+        f(); //~ ERROR cannot find function `f` in this scope
+    }
+}
+
+n!(f);
+macro n($i:ident) {
+    mod foo {
+        pub fn $i() -> u32 { 0 }
+        pub fn f() {}
+
+        mod test {
+            use super::*;
+            fn g() {
+                let _: u32 = $i();
+                let _: () = f();
+            }
+        }
+
+        macro n($j:ident) {
+            mod test {
+                use super::*;
+                fn g() {
+                    let _: u32 = $i();
+                    let _: () = f();
+                    $j();
+                }
+            }
+        }
+
+        n!(f);
+        mod test2 {
+            super::n! {
+                f //~ ERROR cannot find function `f` in this scope
+            }
+        }
+    }
+}
diff --git a/src/test/compile-fail/hygiene/nested_macro_privacy.rs b/src/test/compile-fail/hygiene/nested_macro_privacy.rs
new file mode 100644 (file)
index 0000000..6612359
--- /dev/null
@@ -0,0 +1,27 @@
+// 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(decl_macro)]
+
+macro n($foo:ident, $S:ident, $i:ident, $m:ident) {
+    mod $foo {
+        #[derive(Default)]
+        pub struct $S { $i: u32 }
+        pub macro $m($e:expr) { $e.$i }
+    }
+}
+
+n!(foo, S, i, m);
+
+fn main() {
+    use foo::{S, m};
+    S::default().i; //~ ERROR field `i` of struct `foo::S` is private
+    m!(S::default()); // ok
+}
diff --git a/src/test/compile-fail/hygiene/no_implicit_prelude.rs b/src/test/compile-fail/hygiene/no_implicit_prelude.rs
new file mode 100644 (file)
index 0000000..c90c7b3
--- /dev/null
@@ -0,0 +1,25 @@
+// 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(decl_macro)]
+
+mod foo {
+    pub macro m() { Vec::new(); ().clone() }
+    fn f() { ::bar::m!(); }
+}
+
+#[no_implicit_prelude]
+mod bar {
+    pub macro m() {
+        Vec::new(); //~ ERROR failed to resolve
+        ().clone() //~ ERROR no method named `clone` found
+    }
+    fn f() { ::foo::m!(); }
+}
diff --git a/src/test/compile-fail/hygiene/privacy.rs b/src/test/compile-fail/hygiene/privacy.rs
new file mode 100644 (file)
index 0000000..987cad1
--- /dev/null
@@ -0,0 +1,28 @@
+// 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(decl_macro)]
+
+mod foo {
+    fn f() {}
+
+    pub macro m($e:expr) {
+        f();
+        self::f();
+        ::foo::f();
+        $e
+    }
+}
+
+fn main() {
+    foo::m!(
+        foo::f() //~ ERROR `f` is private
+    );
+}
diff --git a/src/test/compile-fail/hygiene/trait_items.rs b/src/test/compile-fail/hygiene/trait_items.rs
new file mode 100644 (file)
index 0000000..3bd19cb
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(decl_macro)]
+
+mod foo {
+    pub trait T {
+        fn f(&self) {}
+    }
+    impl T for () {}
+}
+
+mod bar {
+    use foo::*;
+    pub macro m() { ().f() }
+    fn f() { ::baz::m!(); }
+}
+
+mod baz {
+    pub macro m() { ().f() } //~ ERROR no method named `f` found for type `()` in the current scope
+    fn f() { ::bar::m!(); }
+}
+
+fn main() {}
index f1c559b6b889f207cdc7e4542cd60de3895775a3..e1acc8eb475ac1cfe883573d5cba87425e2a4611 100644 (file)
@@ -16,7 +16,7 @@ pub trait D {
     fn f<T>(self)
         where T<Bogus = Foo>: A;
         //~^ ERROR associated type bindings are not allowed here [E0229]
-        //~| NOTE associate type not allowed here
+        //~| NOTE associated type not allowed here
 }
 
 fn main() {}
index 3959c22d1d489384a9baccac9b838ad467fcd2af..3cd6f9ebc7185b8992c53c8cc37c0d29257eb549 100644 (file)
@@ -14,7 +14,7 @@ pub trait D {
     fn f<T>(self)
         where T<Bogus = Self::AlsoBogus>: A;
         //~^ ERROR associated type bindings are not allowed here [E0229]
-        //~| NOTE associate type not allowed here
+        //~| NOTE associated type not allowed here
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-36379.rs b/src/test/compile-fail/issue-36379.rs
new file mode 100644 (file)
index 0000000..2f513b0
--- /dev/null
@@ -0,0 +1,16 @@
+// 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(conservative_impl_trait, rustc_attrs)]
+
+fn _test() -> impl Default { }
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/issue-37550.rs b/src/test/compile-fail/issue-37550.rs
new file mode 100644 (file)
index 0000000..e1f7f64
--- /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(const_fn)]
+
+const fn x() {
+    let t = true; //~ ERROR blocks in constant functions are limited to items and tail expressions
+    let x = || t; //~ ERROR blocks in constant functions are limited to items and tail expressions
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-37665.rs b/src/test/compile-fail/issue-37665.rs
new file mode 100644 (file)
index 0000000..f86f570
--- /dev/null
@@ -0,0 +1,20 @@
+// 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 unstable-options --unpretty=mir
+
+use std::path::MAIN_SEPARATOR;
+
+fn main() {
+    let mut foo : String = "hello".to_string();
+    foo.push(MAIN_SEPARATOR);
+    println!("{}", foo);
+    let x: () = 0; //~ ERROR: mismatched types
+}
diff --git a/src/test/compile-fail/issue-38160.rs b/src/test/compile-fail/issue-38160.rs
new file mode 100644 (file)
index 0000000..311d0ce
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_consts, rustc_attrs)]
+#![allow(warnings)]
+
+trait MyTrait {
+    const MY_CONST: &'static str;
+}
+
+macro_rules! my_macro {
+    () => {
+        struct MyStruct;
+
+        impl MyTrait for MyStruct {
+            const MY_CONST: &'static str = stringify!(abc);
+        }
+    }
+}
+
+my_macro!();
+
+#[rustc_error]
+fn main() {} //~ ERROR compilation successful
diff --git a/src/test/compile-fail/issue-38954.rs b/src/test/compile-fail/issue-38954.rs
new file mode 100644 (file)
index 0000000..65b17a3
--- /dev/null
@@ -0,0 +1,16 @@
+// 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(rustc_attrs)]
+
+fn _test(ref _p: str) {}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/issue-39362.rs b/src/test/compile-fail/issue-39362.rs
new file mode 100644 (file)
index 0000000..9d8abbf
--- /dev/null
@@ -0,0 +1,28 @@
+// 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.
+
+enum Foo {
+    Bar { bar: Bar, id: usize }
+}
+
+enum Bar {
+    A, B, C, D, E, F
+}
+
+fn test(f: Foo) {
+    match f {
+        //~^ ERROR non-exhaustive patterns
+        //~| patterns
+        Foo::Bar { bar: Bar::A, .. } => (),
+        Foo::Bar { bar: Bar::B, .. } => (),
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/numeric-fields-feature-gate.rs b/src/test/compile-fail/numeric-fields-feature-gate.rs
deleted file mode 100644 (file)
index bd8ec16..0000000
+++ /dev/null
@@ -1,20 +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.
-
-// gate-test-relaxed_adts
-
-struct S(u8);
-
-fn main() {
-    let s = S{0: 10}; //~ ERROR numeric fields in struct expressions are unstable
-    match s {
-        S{0: a, ..} => {} //~ ERROR numeric fields in struct patterns are unstable
-    }
-}
index 0dc5c4bcfa201a1d539707791787f945cd25d3d2..00fde3025a630e8512178c1c66cf42f10f811fff 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(relaxed_adts)]
-
 struct S(u8, u16);
 
 fn main() {
index 97e1ec2cba865d24d9d8dcd52daf163a4f8a41e1..2e018e696a4155b6c53a6b3885cf06782cec8bb6 100644 (file)
 
 #![feature(untagged_unions)]
 
-union U {
+union U1 {
     a: u8
 }
 
+union U2 {
+    a: String
+}
+
+union U3<T> {
+    a: T
+}
+
+union U4<T: Copy> {
+    a: T
+}
+
+fn generic_noncopy<T: Default>() {
+    let mut u3 = U3 { a: T::default() };
+    u3.a = T::default(); //~ ERROR assignment to non-`Copy` union field requires unsafe
+}
+
+fn generic_copy<T: Copy + Default>() {
+    let mut u3 = U3 { a: T::default() };
+    u3.a = T::default(); // OK
+    let mut u4 = U4 { a: T::default() };
+    u4.a = T::default(); // OK
+}
+
 fn main() {
-    let mut u = U { a: 10 }; // OK
-    let a = u.a; //~ ERROR access to union field requires unsafe function or block
-    u.a = 11; //~ ERROR access to union field requires unsafe function or block
-    let U { a } = u; //~ ERROR matching on union field requires unsafe function or block
-    if let U { a: 12 } = u {} //~ ERROR matching on union field requires unsafe function or block
-    // let U { .. } = u; // OK
+    let mut u1 = U1 { a: 10 }; // OK
+    let a = u1.a; //~ ERROR access to union field requires unsafe
+    u1.a = 11; // OK
+    let U1 { a } = u1; //~ ERROR matching on union field requires unsafe
+    if let U1 { a: 12 } = u1 {} //~ ERROR matching on union field requires unsafe
+    // let U1 { .. } = u1; // OK
+
+    let mut u2 = U2 { a: String::from("old") }; // OK
+    u2.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field requires unsafe
+    let mut u3 = U3 { a: 0 }; // OK
+    u3.a = 1; // OK
+    let mut u3 = U3 { a: String::from("old") }; // OK
+    u3.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field requires unsafe
 }
index adfaf62b5d3cc04aa203f3ee2810725f63d45450..1bdeb121a55d5ed555246cdf69d2d4a1448dc694 100644 (file)
@@ -9,10 +9,9 @@
 // except according to those terms.
 
 // compile-flags: -Z parse-only
-// ignore-tidy-linelength
 
 fn main() {
     let y = 0;
     //~^ ERROR unknown start of token: \u{37e}
-    //~^^ HELP unicode character ';' (Greek Question Mark) looks much like ';' (Semicolon), but it's not
+    //~^^ HELP unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it's not
 }
diff --git a/src/test/run-pass/auxiliary/issue_42007_s.rs b/src/test/run-pass/auxiliary/issue_42007_s.rs
new file mode 100644 (file)
index 0000000..b965e91
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+#[repr(u8)]
+pub enum E {
+    B = 1 as u8,
+}
\ No newline at end of file
diff --git a/src/test/run-pass/extern-thiscall.rs b/src/test/run-pass/extern-thiscall.rs
new file mode 100644 (file)
index 0000000..a669f29
--- /dev/null
@@ -0,0 +1,35 @@
+// 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.
+
+// ignore-arm
+// ignore-aarch64
+
+#![feature(abi_thiscall)]
+
+trait A {
+    extern "thiscall" fn test1(i: i32);
+}
+
+struct S;
+
+impl A for S {
+    extern "thiscall" fn test1(i: i32) {
+        assert_eq!(i, 1);
+    }
+}
+
+extern "thiscall" fn test2(i: i32) {
+    assert_eq!(i, 2);
+}
+
+fn main() {
+    <S as A>::test1(1);
+    test2(2);
+}
diff --git a/src/test/run-pass/hygiene/arguments.rs b/src/test/run-pass/hygiene/arguments.rs
new file mode 100644 (file)
index 0000000..5d9e186
--- /dev/null
@@ -0,0 +1,27 @@
+// 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
+
+#![feature(decl_macro)]
+
+macro m($t:ty, $e:expr) {
+    mod foo {
+        #[allow(unused)]
+        struct S;
+        pub(super) fn f(_: $t) {}
+    }
+    foo::f($e);
+}
+
+fn main() {
+    struct S;
+    m!(S, S);
+}
diff --git a/src/test/run-pass/hygiene/auxiliary/intercrate.rs b/src/test/run-pass/hygiene/auxiliary/intercrate.rs
new file mode 100644 (file)
index 0000000..aa67e5c
--- /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.
+
+#![feature(decl_macro)]
+
+pub mod foo {
+    pub use self::bar::m;
+    mod bar {
+        fn f() -> u32 { 1 }
+        pub macro m() {
+            f();
+        }
+    }
+}
diff --git a/src/test/run-pass/hygiene/fields.rs b/src/test/run-pass/hygiene/fields.rs
new file mode 100644 (file)
index 0000000..d7f99ba
--- /dev/null
@@ -0,0 +1,40 @@
+// 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
+
+#![feature(decl_macro)]
+
+mod foo {
+    struct S { x: u32 }
+    struct T(u32);
+
+    pub macro m($S:ident, $x:ident) {{
+        struct $S {
+            $x: u32,
+            x: i32,
+        }
+
+        let s = S { x: 0 };
+        let _ = s.x;
+
+        let t = T(0);
+        let _ = t.0;
+
+        let s = $S { $x: 0, x: 1 };
+        assert_eq!((s.$x, s.x), (0, 1));
+        s
+    }}
+}
+
+fn main() {
+    let s = foo::m!(S, x);
+    assert_eq!(s.x, 0);
+}
diff --git a/src/test/run-pass/hygiene/impl_items.rs b/src/test/run-pass/hygiene/impl_items.rs
new file mode 100644 (file)
index 0000000..a5780a5
--- /dev/null
@@ -0,0 +1,44 @@
+// 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
+
+#![feature(decl_macro)]
+
+mod foo {
+    struct S;
+    impl S {
+        fn f(&self) {}
+    }
+
+    pub macro m() {
+        let _: () = S.f();
+    }
+}
+
+struct S;
+
+macro m($f:ident) {
+    impl S {
+        fn f(&self) -> u32 { 0 }
+        fn $f(&self) -> i32 { 0 }
+    }
+    fn f() {
+        let _: u32 = S.f();
+        let _: i32 = S.$f();
+    }
+}
+
+m!(f);
+
+fn main() {
+    let _: i32 = S.f();
+    foo::m!();
+}
diff --git a/src/test/run-pass/hygiene/intercrate.rs b/src/test/run-pass/hygiene/intercrate.rs
new file mode 100644 (file)
index 0000000..3a75085
--- /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.
+
+// ignore-pretty pretty-printing is unhygienic
+
+// aux-build:intercrate.rs
+
+#![feature(decl_macro)]
+
+extern crate intercrate;
+
+fn main() {
+    assert_eq!(intercrate::foo::m!(), 1);
+}
diff --git a/src/test/run-pass/hygiene/items.rs b/src/test/run-pass/hygiene/items.rs
new file mode 100644 (file)
index 0000000..121c341
--- /dev/null
@@ -0,0 +1,36 @@
+// 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
+
+#![feature(decl_macro)]
+
+pub macro m($foo:ident, $f:ident, $e:expr) {
+    mod foo {
+        pub fn f() -> u32 { 0 }
+        pub fn $f() -> u64 { 0 }
+    }
+
+    mod $foo {
+        pub fn f() -> i32 { 0 }
+        pub fn $f() -> i64 { 0  }
+    }
+
+    let _: u32 = foo::f();
+    let _: u64 = foo::$f();
+    let _: i32 = $foo::f();
+    let _: i64 = $foo::$f();
+    let _: i64 = $e;
+}
+
+fn main() {
+    m!(foo, f, foo::f());
+    let _: i64 = foo::f();
+}
diff --git a/src/test/run-pass/hygiene/lexical.rs b/src/test/run-pass/hygiene/lexical.rs
new file mode 100644 (file)
index 0000000..cb02a17
--- /dev/null
@@ -0,0 +1,33 @@
+// 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
+
+#![feature(decl_macro)]
+
+mod bar {
+    mod baz {
+        pub fn f() {}
+    }
+
+    pub macro m($f:ident) {
+        baz::f();
+        let _: i32 = $f();
+        {
+            fn $f() -> u32 { 0 }
+            let _: u32 = $f();
+        }
+    }
+}
+
+fn main() {
+    fn f() -> i32 { 0 }
+    bar::m!(f);
+}
diff --git a/src/test/run-pass/hygiene/trait_items.rs b/src/test/run-pass/hygiene/trait_items.rs
new file mode 100644 (file)
index 0000000..2344c97
--- /dev/null
@@ -0,0 +1,29 @@
+// 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
+
+#![feature(decl_macro)]
+
+macro m($T:ident, $f:ident) {
+    pub trait $T {
+        fn f(&self) -> u32 { 0 }
+        fn $f(&self) -> i32 { 0 }
+    }
+    impl $T for () {}
+
+    let _: u32 = ().f();
+    let _: i32 = ().$f();
+}
+
+fn main() {
+    m!(T, f);
+    let _: i32 = ().f();
+}
diff --git a/src/test/run-pass/hygiene/ty_params.rs b/src/test/run-pass/hygiene/ty_params.rs
new file mode 100644 (file)
index 0000000..510528e
--- /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.
+
+// ignore-pretty pretty-printing is unhygienic
+
+#![feature(decl_macro)]
+
+macro m($T:ident) {
+    fn f<T, $T>(t: T, t2: $T) -> (T, $T) {
+        (t, t2)
+    }
+}
+
+m!(T);
+
+fn main() {}
index 71a19d98190548f8ba068b968eeff75895b25d92..49dc970ba3f0dfbe1e6c7ead8b0b144c1ef0ad8c 100644 (file)
@@ -13,7 +13,7 @@
 fn foo<F: FnOnce()>(_f: F) { }
 
 fn main() {
-    let mut var = Vec::new();;
+    let mut var = Vec::new();
     foo(move|| {
         var.push(1);
     });
diff --git a/src/test/run-pass/issue-42007.rs b/src/test/run-pass/issue-42007.rs
new file mode 100644 (file)
index 0000000..cc7e3bc
--- /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.
+
+// aux-build:issue_42007_s.rs
+
+extern crate issue_42007_s;
+
+enum I {
+    E(issue_42007_s::E),
+}
+
+fn main() {}
index 25e5a2a0fd5baeef69214cfce9b28f40a805cdc0..15f054de79d13e6559c07400f9e5a68c6e66f816 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(relaxed_adts)]
-
 struct S(u8, u16);
 
 fn main() {
index cfa9f6e36e9bcb37fce6b735ed61b6e3d925ff08..372d4a8b732acfb44151cd560e3d489653ffd179 100644 (file)
@@ -82,7 +82,7 @@ pub fn main() {
     short.next();
     assert_eq!(long.size_hint(), (255, Some(255)));
     assert_eq!(short.size_hint(), (0, Some(0)));
-    assert_eq!(short, RangeInclusive::Empty { at: 42 });
+    assert_eq!(short, 1...0);
 
     assert_eq!(long.len(), 255);
     assert_eq!(short.len(), 0);
@@ -97,28 +97,28 @@ pub fn main() {
     for i in 3...251 {
         assert_eq!(long.next(), Some(i));
     }
-    assert_eq!(long, RangeInclusive::Empty { at: 251 });
+    assert_eq!(long, 1...0);
 
     // check underflow
     let mut narrow = 1...0;
     assert_eq!(narrow.next_back(), None);
-    assert_eq!(narrow, RangeInclusive::Empty { at: 0 });
+    assert_eq!(narrow, 1...0);
     let mut zero = 0u8...0;
     assert_eq!(zero.next_back(), Some(0));
     assert_eq!(zero.next_back(), None);
-    assert_eq!(zero, RangeInclusive::Empty { at: 0 });
+    assert_eq!(zero, 1...0);
     let mut high = 255u8...255;
     assert_eq!(high.next_back(), Some(255));
     assert_eq!(high.next_back(), None);
-    assert_eq!(high, RangeInclusive::Empty { at: 255 });
+    assert_eq!(high, 1...0);
 
     // what happens if you have a nonsense range?
     let mut nonsense = 10...5;
     assert_eq!(nonsense.next(), None);
-    assert_eq!(nonsense, RangeInclusive::Empty { at: 10 });
+    assert_eq!(nonsense, 10...5);
 
     // output
     assert_eq!(format!("{:?}", 0...10), "0...10");
     assert_eq!(format!("{:?}", ...10), "...10");
-    assert_eq!(format!("{:?}", long), "[empty range @ 251]");
+    assert_eq!(format!("{:?}", long), "1...0");
 }
index 6083a82b1b6de29eb926114b8b6a37a58b31884c..a30d4cbd64c22e84e4362a5230c496d944c63568 100644 (file)
@@ -6,5 +6,5 @@ error[E0507]: cannot move out of captured outer variable in an `Fn` closure
 15 |     Box::new(|| x) //~ ERROR cannot move out of captured outer variable
    |                 ^ cannot move out of captured outer variable in an `Fn` closure
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index dbfcb2e0c2f95fbef0c71d52e7ed596c37c334eb..a13971d32de084bc50f950fcd466c44074828eb8 100644 (file)
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of captured outer variable in an `Fn` closure
 21 |         y.into_iter();
    |         ^ cannot move out of captured outer variable in an `Fn` closure
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0aafe3f17b3d0f6310b30d10baedc9eb00d19cef..0cb264ff35e4eb0ffd5b491e6611a19b2c38d92d 100644 (file)
@@ -46,5 +46,5 @@ error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 mor
 49 |     match Some(A) {
    |           ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
index 87255dfe7747673b7be9b215df55da55c16fb64c..cddc7df85ae3e763d8336c0705a015323cb4010d 100644 (file)
@@ -22,5 +22,5 @@ error: expected token: `,`
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 7f1ab929c6fc2b32fcbd4e0a18cd4341d08da5e8..1c32ce44109ed2002e047b0bc9414d61a27ef45d 100644 (file)
@@ -6,5 +6,5 @@ error[E0592]: duplicate definitions with name `f`
 15 | impl C { fn f() {} }
    |          --------- other definition for `f`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b33dee6b4a472ed04086888a61d93accf8f11e91..84e6e336b9343dfcad1ff05d48f97dade5f97f01 100644 (file)
@@ -4,5 +4,5 @@ error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`,
 17 |     unsafe impl Send for &'static Foo { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7bb69caa1024af4c060687c83e5bc9ba41a59a5e..059215157ec52ba715e106d6bfecc11c8e6feceb 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `x` as mutable
 100 |     let y = &mut x;
     |                  ^ cannot borrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4947cbedd200e45ec424e508881480505c313b57..dcc21672c56323b3c4d6f95505bf9a396463a9a8 100644 (file)
@@ -8,5 +8,5 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
 101 | }
     | - first borrow ends here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d65b34f3f4164cf8dd7b912d4c777155240b9813..5e611d42a1491236eadd99dfc2f5c75e1edd3640 100644 (file)
@@ -6,5 +6,5 @@ error: cannot apply unary operator `!` to type `&'static str`
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index a73575a8d57f1ae65783eec6492c758db02c3c5c..e2e0537226a92cff78795cff18bb17bb17c22eef 100644 (file)
@@ -7,5 +7,5 @@ error[E0499]: cannot borrow `v` as mutable more than once at a time
    |     |      second mutable borrow occurs here
    |     first mutable borrow occurs here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index de8a24cf33f44c12f0e70d3dbf57e99101a67e09..0af8c06cfdae71c0bbaa57991bbde19c68450313 100644 (file)
@@ -25,5 +25,5 @@ error[E0592]: duplicate definitions with name `baz`
 43 |     fn baz(&self) {}
    |     ---------------- other definition for `baz`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index d32b18d670308c4379da0ed8060db3694a1f1bdd..9778015766ce55489807c5376526b84e30a1a04c 100644 (file)
@@ -7,5 +7,5 @@ error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
    |         |    hint: to prevent move, use `ref _s` or `ref mut _s`
    |         cannot move out of here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 657deca4e6d491afc2398aa5e4c4da6bda8df00a..a3b76159b463fa9d3de9db2a82740d40d286e192 100644 (file)
@@ -4,5 +4,5 @@ error[E0425]: cannot find value `bar` in this scope
 14 | \tbar;
    | \t^^^ not found in this scope
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index eef8793511529fab5d904d6b766ce8b8a263d96b..0f1e008d5893ff17bfcd011779d57792356b5e2f 100644 (file)
@@ -1,8 +1,8 @@
-error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́`
+error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́`
   --> $DIR/unicode.rs:11:8
    |
 11 | extern "路濫狼á́́" fn foo() {}
    |        ^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 8f08ff34637707851e48ec63c00a0745e980aa6a..28a99e58eca89d954f8aedb62625a15eb96ea9ac 100644 (file)
@@ -15,5 +15,5 @@ help: consider removing this semicolon:
 14 |     x + 1;
    |          ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2a707c6eb8b103b428de32c4fb5f2c64f848b38a..63c48ffe26b28478f36a2149c9dc29b26c5e3411 100644 (file)
@@ -11,5 +11,5 @@ error[E0276]: impl has stricter requirements than trait
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #37166 <https://github.com/rust-lang/rust/issues/37166>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index af974d501839b35cb76d8ac7c746c244e25d4b6a..7adcc66d75c892b2eee2c83344b9ddc2eef7e855 100644 (file)
@@ -10,5 +10,5 @@ error[E0276]: impl has stricter requirements than trait
 22 | |     }
    | |_____^ impl has extra requirement `'a: 'b`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index e657813221a1265e9854a8728e4055a91be39df2..a29a292ac655656eaa3f1559ff9e0f3d0fbf9adb 100644 (file)
@@ -7,5 +7,5 @@ error[E0276]: impl has stricter requirements than trait
 22 |     fn foo() where 'a: 'b { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9e822bd8b0790097ff4832bd78edadf41677b8e9..04de54cd05de215017b8fcf7d49680cab1eb33b9 100644 (file)
@@ -11,5 +11,5 @@ error[E0276]: impl has stricter requirements than trait
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #37166 <https://github.com/rust-lang/rust/issues/37166>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4620248e2efeae50747b5af688ea1fabb96e008f..b5e9c89f2f591293daaac81bc912b65b7a01fea8 100644 (file)
@@ -10,5 +10,5 @@ error[E0053]: method `b` has an incompatible type for trait
    = note: expected type `fn(&E, F) -> F`
               found type `fn(&E, G) -> G`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7112a00c7b7900fd7f305fbc1b79f71a044d21e4..c4a4921289b3b56100d0da4946316f603b470af2 100644 (file)
@@ -7,5 +7,5 @@ error[E0276]: impl has stricter requirements than trait
 25 |     fn b<F: Sync, G>(&self, _x: F) -> F { panic!() } //~ ERROR E0276
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `F: std::marker::Sync`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f221ebe3302c019dadf23280d4904b519a7955a6..6374b83e7946a10402671a5cec8b74832a48d3a0 100644 (file)
@@ -61,5 +61,5 @@ error[E0276]: impl has stricter requirements than trait
 76 |     fn method<G: Getter<usize>>(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `G: Getter<usize>`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index 622e144c53a040447103654b7fb552c79d68c5b0..7ff2d93d820dbde51ca05bac13433999749ee20b 100644 (file)
@@ -10,5 +10,5 @@ error[E0276]: impl has stricter requirements than trait
 26 | |     }
    | |_____^ impl has extra requirement `U: Iterator<B>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 84db85ac092dbfbf3d199d7d489ca97983da83db..3642a702a82955838cafc8b01e27df0e3cf247d1 100644 (file)
@@ -6,5 +6,5 @@ error: invalid reference to argument `0` (no arguments given)
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 15e7131cfd3be41a75621b24e212971643909267..bcf00df98323bd96a98b2f463bdc9c16698975ad 100644 (file)
@@ -22,5 +22,5 @@ error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo`
 17 |     z: fn() -> Foo + 'a,
    |        ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 9010de081da46b602e3db93efa77d54165c9f1c6..73b8e06183b25cf07732cffaae678c30989ff805 100644 (file)
@@ -8,5 +8,5 @@ error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
              <Bar as Foo<i32>>
              <Bar as Foo<u8>>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index e9591a64784d5ad6dff8f3a96648d5a7b16194ce..e1e4e14b215c08617a251ae4253cc5c6b2270c29 100644 (file)
@@ -11,5 +11,5 @@ error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
              <Bar as Foo<u8>>
            and 2 others
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 60fa06d314ff7bcf7da74a8c2f8a7fa53f1750d7..1bd8d5128337ac96d6fff5420232e759482a701f 100644 (file)
@@ -15,5 +15,5 @@ error: cannot borrow immutable argument `self` as mutable
 23 |         (&mut self).bar();
    |               ^^^^ cannot borrow mutably
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 8011298c80cdded1bf74963020c99171972c61ea..606d6b2b259861455ce179b65e710d9ef7714cb4 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable argument `self` as mutable
    |                       try removing `&mut` here
    |                       cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d658912835b9c438ae889474b8ceccb589b0ad09..c32fb56f61be0b042878d24d3e67cf2c9f590b1a 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `key` as mutable
    |              try removing `&mut` here
    |              cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index bea3d1291433db20d39470c6b61ecb951edad56d..09a9b796c6a461824ad6b443fcbc3bcdcf67f4dd 100644 (file)
@@ -22,5 +22,5 @@ error: cannot assign to immutable field `s.x`
 30 |     s.x += 1;
    |     ^^^^^^^^ cannot mutably borrow immutable field
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index c124747c801d87dcb595a4436541dd0dec905e7e..ea628f10e0fd615571442c423842dc1586c66bd3 100644 (file)
@@ -4,5 +4,5 @@ error: no field `baz` on type `Foo`
 17 |     f.baz;
    |       ^^^ did you mean `bar`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4e02f8bd0cfb2d1a81087215074cd7ebfdbc7ff5..a9090e3911b07e65464a53c4c9715a45c77fffb1 100644 (file)
@@ -4,5 +4,5 @@ error: no field `zz` on type `Foo`
 17 |     f.zz;
    |       ^^ unknown field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b1a8231fdb6cfd613ed8d206733d147307992b7b..acbeaafdf798d66fbc48d4fda09c51a8d6dd1c8b 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `x` as mutable
    |                       try removing `&mut` here
    |                       cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 325f55e686c622e12ec5772512392b0a1e70f460..10f5972e36946554f4f304dbcc2cfc9a1ac38982 100644 (file)
@@ -10,5 +10,5 @@ error[E0432]: unresolved import `Foo1`
 13 | use Foo1;
    |     ^^^^ no `Foo1` in the root
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index e9f2b1dad806d52429b48060b5a1136315856584..85eecd037dd7badbe71bfbe844e7a2b8923a39cb 100644 (file)
@@ -6,5 +6,5 @@ error[E0389]: cannot borrow data mutably in a `&` reference
 27 |         self.s.push('x');
    |         ^^^^^^ assignment into an immutable reference
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 855feaf7d2d5e6931e58b0081234dfb866e4a70a..83d46e3fc47271409a4e3c2dbf43dc9fdf9f7e72 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*self.s` as mutable
 17 |         self.s.push('x');
    |         ^^^^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d970d078df8d96c395d088d5a32b442df964ee88..ca6f376ffd301c9682b0740b6d2767e63d4b98a2 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*self.s` as mutable
 17 |         self.s.push('x');
    |         ^^^^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9a8853f4fbbdb15dfe2bfa8330db4c5b4d4e8344..6fa152c970bdfe2227ff41634a4818cb52170ae3 100644 (file)
@@ -6,5 +6,5 @@ error[E0389]: cannot borrow data mutably in a `&` reference
 16 |     f.s.push('x');
    |     ^^^ assignment into an immutable reference
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2e98bc65e9e9f0c268e3badf0b5e61bdc11f914a..9ae240bf420a5bfc176bcba5ef36e3a284d878ea 100644 (file)
@@ -96,5 +96,5 @@ error: cannot assign to immutable borrowed content `*x.0`
 58 |     *x.0 = 1;
    |     ^^^^^^^^ cannot borrow as mutable
 
-error: aborting due to 12 previous errors
+error: aborting due to previous error(s)
 
index 4ea4adfcfe0fc68260f9dc047f487db7cc6eea17..6a0e94bf13803d3cd74e02c22a2ace99d1f6384a 100644 (file)
@@ -39,5 +39,5 @@ error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
            and 2 others
    = note: required by `Foo::bar`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 8e8773eba3e222feb5c31bbe4f2029a69ef5df5d..b1dab01d81ff2637d5b8bdeba494846ba52f6c56 100644 (file)
@@ -64,5 +64,5 @@ error[E0038]: the trait `X` cannot be made into an object
    |
    = note: method `xxx` has no receiver
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 1a0c74dc01a09d4eb96735e0253f8215220ed082..daee8df7ed89b219618a15b1321cc2b82837713d 100644 (file)
@@ -30,5 +30,5 @@ error: chained comparison operators require parentheses
    |
    = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 8e77ebd9b6da3c1920166533f804014793c63703..5718471527d88459b31e6948d0cb45b76d55093c 100644 (file)
@@ -4,5 +4,5 @@ error: cannot borrow immutable borrowed content `*buf` as mutable
 13 |     buf.iter_mut();
    |     ^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2abbbf65ba9b507254cef20ec002e58cf760aea5..4f210bb0b11b2d7ca60a359eb2c83961dee8a07b 100644 (file)
@@ -6,5 +6,5 @@ error: `~` can not be used as a unary operator
    |
    = help: use `!` instead of `~` if you meant to perform bitwise negation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d157c5de6c7f57f98fd213b5da51db9a6015e9be..32f9d90ec2d8d5ea39bbeb72f69536e3dcbcae2e 100644 (file)
@@ -17,5 +17,5 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send`
    = note: required because it appears within the type `A`
    = note: required by `is_send`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 57b28d037362239f237591faf6eb9dd7d7aa6456..ba8d3815181ac84c282682f0f290826d1fe13663 100644 (file)
@@ -19,5 +19,5 @@ error[E0308]: mismatched types
    = note: expected type `&Bottom`
               found type `&Top`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index c4858b63c2d930e4a3af534edf1961a4e17386f8..50e296a1bc53758b491bd1f753e670f9ddcf1a43 100644 (file)
@@ -18,5 +18,5 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object
    |
    = note: the trait cannot require that `Self : Sized`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2a4ba22ecc46711cf4cb6f1e06ba5f81eb900c95..b69b4f9f32117957a7f5861a2ed0e3889aa5bf79 100644 (file)
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 2c788e952edbfd455b29645f875bdded8cf4eedd..e1bfb4d8c1e181a4feb734c89e70252c9ad0f0c1 100644 (file)
@@ -20,5 +20,5 @@ error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attri
 43 | | }
    | |_^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index cfcf988f31f7b1295ea73bac6d32b2eb44c554cb..ddd213dd9ad7088feaefa06af61e1cae46c0da27 100644 (file)
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index cd420756b444c81f207a8785b121e04637cf9dd1..d9d00919b6dcac704d56ef4928822d86f5127e82 100644 (file)
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 58b392f0b8d658fc1df9896a3568b05b9338bf23..2466d2b43b6fcd648f325d5f44b146a2177cfaa4 100644 (file)
@@ -16,5 +16,5 @@ error: invalid format string: unmatched `}` found
    = note: if you intended to print `}`, you can escape it using `}}`
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 322ab64ebd4eac2424b1e0eceefe84a5f0075ae9..91c89e55c54a824d205081ab9c8c44d8557beb5c 100644 (file)
@@ -8,5 +8,5 @@ error[E0382]: use of moved value: `debug_dump_dict`
    |
    = help: closure was moved because it only implements `FnOnce`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 08d9043f65ecd9d4a5e47b854e0629dbd149ca98..a08e77a2151e210c98916a99200a1848e2b9a60e 100644 (file)
@@ -51,5 +51,5 @@ error[E0308]: mismatched types
    = note: expected type `impl Foo` (i32)
               found type `impl Foo` (u32)
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index 3e9b21cdb740fc072a1779e128acb49be55d7df2..a444d5f5a40308bbae8a182f8392b831e1db5b5c 100644 (file)
@@ -10,5 +10,5 @@ note: maybe move this module `$DIR/auxiliary/foo/bar.rs` to its own directory vi
 11 | pub mod baz;
    |         ^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b51b683a1ac3a5de798a8e3feaea1d315159574d..62223c553e377a7e9f91cd6adea6c238fb9d82a2 100644 (file)
@@ -8,5 +8,5 @@ error: reached the type-length limit while instantiating `<T as Foo><(&(&(&(&(&(
    |
    = note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index de110ac12b70398a3fc7f8d6ca7f051f71ff73b1..80f608c1d371040075d466165e1a1b6e75419f88 100644 (file)
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of indexed content
    |             help: consider using a reference instead `&f.v[0]`
    |             cannot move out of indexed content
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0060b683bba43637789a732186b8de60b21e75f5..d35800ac1e766f67d9dfca9ad611d5ac56b8ec77 100644 (file)
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of indexed content
    |          |  ...and here (use `ref b` or `ref mut b`)
    |          hint: to prevent move, use `ref a` or `ref mut a`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4d33a99f6a38c47b37981666bd7d45df1edce3bf..a0177e79ac467b4445e94011d51f6d4bb7ba40ba 100644 (file)
@@ -8,5 +8,5 @@ error: no method named `f` found for type `{integer}` in the current scope
 note: candidate #1 is defined in the trait `issue_41652_b::Tr`
    = help: to disambiguate the method call, write `issue_41652_b::Tr::f(3)` instead
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f325d10b548735ca04af219b6f7a044777fd9786..0ab24b0b3e6c417bb035f4df923ad9865b523c85 100644 (file)
@@ -19,5 +19,5 @@ note: ...but the borrowed content is only valid for the anonymous lifetime #1 de
 13 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index fccc44caac81a5f7e25b11cdb0ca893266387bd7..d005eeb40451ad8f9855665c8f10368510bc031d 100644 (file)
@@ -6,5 +6,5 @@ error[E0106]: missing lifetime specifier
    |
    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index df484a14927c737ce514e9ab27e550585b7a6330..7d0947b364e03ff2318b3aaa4421f460d6667a09 100644 (file)
@@ -21,5 +21,5 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the function
 17 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 6764c58f4bb59aeb1b9b345eab5f840ba0032c48..6380a885f4467ddaf2a783ccb7716c454782fb4e 100644 (file)
@@ -21,5 +21,5 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the f
 17 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7356fc11862f6e104d004cd642852161b18e5e1b..b28a3c0c1351da9662f025cbb0f832a961146a13 100644 (file)
@@ -31,5 +31,5 @@ note: ...so that expression is assignable (expected Ref<'b, _>, found Ref<'_, _>
 17 |     x.push(z);
    |            ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 38b0acf9339e0e89595a6c0ee889abca1f2c221e..dd716bac513d2eab4fceba362c4f54de6983295a 100644 (file)
@@ -33,5 +33,5 @@ note: ...so that expression is assignable (expected &mut std::vec::Vec<Ref<'_, i
 16 |     let a: &mut Vec<Ref<i32>> = x;
    |                                 ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 035e516e8628e9b933157645e651ef281f272c01..141f5a7c4528b1e55ec504aae50ab10bac9f3f41 100644 (file)
@@ -33,5 +33,5 @@ note: ...so that expression is assignable (expected &mut std::vec::Vec<Ref<'_, i
 16 |     let a: &mut Vec<Ref<i32>> = x;
    |                                 ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d85483f43c9e02dfb57a38b5551da5e8d475237a..768057301d1263dfc79fc1ef70b09786203a5723 100644 (file)
@@ -10,5 +10,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 23fac66cc6c98f60ba85966bc8c10f565bd4ee3e..d441702374b74dc42a3b8796a93ea26daf05f801 100644 (file)
@@ -6,5 +6,5 @@ error: variable `_InappropriateCamelCasing` should have a snake case name such a
    |
    = note: `-D non-snake-case` implied by `-D bad-style`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0babd7f6fe47a06dbaccf37ad6790a8b15d2bb45..9d4d0b12b187071d0311e4ed3e81faeb3f13ded1 100644 (file)
@@ -6,5 +6,5 @@ error: variable `_InappropriateCamelCasing` should have a snake case name such a
    |
    = note: `-F non-snake-case` implied by `-F bad-style`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9c0f4866af6902e43ff1eac30e998fcb0d0543d8..dec44c317e4b2f4c1eafb54251d74d4b443e685e 100644 (file)
@@ -63,5 +63,5 @@ note: lint level defined here
 28 |         #![warn(bad_style)]
    |                 ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index c154ea6f8c2d68e76a7ff04e24ad6b2a5b2b5017..7a4a9c3f012bf9d082a30af769b45f3614a861cc 100644 (file)
@@ -4,5 +4,5 @@ error[E0571]: `break` with value from a `for` loop
 22 |         break 22
    |         ^^^^^^^^ can only break with a value inside `loop`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index bffb33f468fc886c7c10433111713bb242add472..b8337c81834b89e6efcf9ae2857838405f526216 100644 (file)
@@ -4,5 +4,5 @@ error: expected a literal
 12 |     println!(3 + 4);
    |              ^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0283052a89f53d19a128cd8cb4836f7dbae769c2..a964b92712ddb00711621b6f2eb3c0ef8e9861e3 100644 (file)
@@ -48,5 +48,5 @@ error: named argument never used
    = help: `$NAME` should be written as `{NAME}`
    = note: shell formatting not supported; see the documentation for `std::fmt`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 48f9bac906ecf56a0108f03059234f9f346e47a8..304d4459e4975dda4306e604f88961676e2b80bc 100644 (file)
@@ -52,5 +52,5 @@ error: attempted tuple index `0` on type `{integer}`, but the type was not a tup
 56 |     let _ = fake_anon_field_expr!();
    |             ----------------------- in this macro invocation
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index 8b69d112d4d42b8390db27b5a03056557656aa02..7835b85eafc0e8821889ec8abb9f7222a50de6ee 100644 (file)
@@ -16,5 +16,5 @@ error[E0425]: cannot find value `fake` in this scope
 28 |     call_nested_expr_sum!();
    |     ------------------------ in this macro invocation
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index f21253bb67fb0c10e46458e63aa3997d639283cf..4177240d97696d2693bff7b8824de62c0bca7425 100644 (file)
@@ -7,5 +7,5 @@ error: invalid reference to argument `0` (no arguments given)
 28 |     myprintln!("{}");
    |     ----------------- in this macro invocation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d9871b8970c5cf22b1cd32b70b5b34bbc8f4c32d..2ba2069677e3d9f1cb41225fb6995acbe84e5f88 100644 (file)
@@ -22,5 +22,5 @@ error[E0053]: method `bar` has an incompatible type for trait
    = note: expected type `fn(&Bar)`
               found type `fn(&mut Bar)`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 28a649d4c91a471acb22e8c8e1220fe5ecd71da2..fab48e9a740a29ed4de52b1010d09368dde86432 100644 (file)
@@ -20,5 +20,5 @@ error[E0281]: type mismatch: `[closure@$DIR/E0281.rs:14:9: 14:24]` implements th
    |
    = note: required by `foo`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 45a42b1c271f8678920ca841580d814aa62f6498..a5f63aca13e2170128675f077be1d1e3a3d588d0 100644 (file)
@@ -15,5 +15,5 @@ error[E0308]: mismatched types
    = note: expected type `&{integer}`
               found type `{integer}`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 36bdec8d43afef1b9ca5fba171743cca1963002b..78b5dcda1d9d24be75b73276e29c1cdc7a77b8ab 100644 (file)
@@ -64,5 +64,5 @@ error[E0308]: mismatched types
    = note: expected type `X<X<_, std::string::String>, _>`
               found type `X<X<_, {integer}>, _>`
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index 773bf0593c51390f2ca205b19d14dac6425c0957..d97c78137089ec721e9ee55db27a960e5077f963 100644 (file)
@@ -54,5 +54,5 @@ error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<std::result::Resul
    |
    = help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index 8853b35eb8b33d67ac4b266b14831426be5bda59..8d31dd7500a34f81dcb6fb58dc562a8188fd9089 100644 (file)
@@ -236,5 +236,5 @@ help: did you mean `*s`?
 81 |     vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
    |                              ^
 
-error: aborting due to 34 previous errors
+error: aborting due to previous error(s)
 
index c1b880b6162734e5a720e3452086e4a222831800..cd16e5d70b68b6eb423b26e31ae15d6a116308b3 100644 (file)
@@ -55,5 +55,5 @@ error[E0593]: closure takes 1 argument but 2 arguments are required
    |               |
    |               expected closure that takes 2 arguments
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index 5b3eb5931896aee60c50c0e36b8efa0c97379607..2c9c918168d0299989fe7b508f10199863f19799 100644 (file)
@@ -20,5 +20,5 @@ error[E0281]: type mismatch: `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` im
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
    = note: required by `baz`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index f7b7635e41aecfec70ad91f99b95fac6a0d944f2..5f67a66eb325fa7e287cf2537d32f24478fcc813 100644 (file)
@@ -10,5 +10,5 @@ error[E0379]: trait fns cannot be declared const
 21 |     const fn f() -> u32 { 22 }
    |     ^^^^^ trait fns cannot be const
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 120fb87cdc89820ea2264348dea853e069c8d105..2030ad6c13b56af2ea42f0c0292875a523665914 100644 (file)
@@ -14,5 +14,5 @@ error[E0281]: type mismatch: `fn(&isize) {takes_imm}` implements the trait `for<
    |
    = note: required by `apply`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 4067507c9644568ae3767e92b9aa5b2b1152dcf2..cbce4f810c5312469d168dd7e31798c42ead8e28 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `*mut Trait`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5d07ee1648a3ecfffe90986405e78bec9e8abfb5..dc3764a376cde4d8443f780a649f194146a1a445 100644 (file)
@@ -16,5 +16,5 @@ error: non-scalar cast: `{integer}` as `()`
 38 |     cast!(2);
    |     --------- in this macro invocation
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 46d690c5f037b97ee2235cc51364c663ae642b4a..463d9fdf1717b3cac825bc248ad496976f37cf58 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `bool` (type parameter)
               found type `bool` (bool)
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 78e0f7e619b12791e7f52b917eb205959da36f9f..d72ab326ce644168cdf3a5cb885ce86b034bbf80 100644 (file)
@@ -26,5 +26,5 @@ error[E0281]: type mismatch: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53]` impl
    |                                requires `for<'r> std::ops::FnOnce<(&'r &str,)>`
    |                                expected &str, found str
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 9efee4cc5593cb2ed8c9056c6ff3b985be3d7298..76ffa6e50e133d2e58cad02b4802bf75db98b40e 100644 (file)
@@ -32,5 +32,5 @@ error[E0529]: expected an array or slice, found `u32`
 34 | fn ugh(&[bar]: &u32) {
    |         ^^^^^ pattern cannot match with input type `u32`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index c8941fbf950734c021621508ef1ef3129a95af14..b4e688e025e52b23ef87cc54223b8a86f3261375 100644 (file)
@@ -9,5 +9,5 @@ error[E0308]: mismatched types
    = note: expected type `u32`
               found type `()`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2bd786c20fef0285d8050e44ab0eec7f1c1969d7..c7a52fea3bc8c3e0219e69ac0927424fcc6269d4 100644 (file)
@@ -7,5 +7,5 @@ error: no method named `unwrap` found for type `std::result::Result<(), Foo>` in
    = note: the method `unwrap` exists but the following trait bounds were not satisfied:
            `Foo : std::fmt::Debug`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index cd05684f15d55d71c2157558b6380c8de90f615b..7c644e3a72dcd637e079bb6074c6d3e0c4934d75 100644 (file)
@@ -19,5 +19,5 @@ error[E0057]: this function takes 1 parameter but 2 parameters were supplied
 45 |     let ans = s("burma", "shave");
    |                 ^^^^^^^^^^^^^^^^ expected 1 parameter
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index ccc9fb56772f5b4e1c6b67b5be3d7bf509caed8e..9e7f79df35aee136652f733d095930b292dc876f 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `std::boxed::Box<Foo + std::marker::Send + 'static>`
               found type `std::boxed::Box<Foo + 'static>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 349432f64bbc20cf4af4839fe604639f2c6f7124..8741589f8464ed8b9a629ebc8975ff2bb9dcc450 100644 (file)
@@ -22,5 +22,5 @@ error[E0053]: method `bar` has an incompatible type for trait
    = note: expected type `fn(&mut Bar, &mut Bar)`
               found type `fn(&mut Bar, &Bar)`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index e100520e561f579a25819bdf2d45476275506f40..c5bfb6e45e77e468aabcd6086ed53dc4e5ef9e7b 100644 (file)
@@ -26,5 +26,5 @@ error[E0281]: type mismatch: `[closure@$DIR/unboxed-closures-vtable-mismatch.rs:
    |
    = note: required by `call_it`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index fc90c8a2b20bebc39cc4029febe377213a1c61da..878544937905d0907f6a10af8510a54e4ea10c32 100644 (file)
@@ -4,5 +4,5 @@ error[E0004]: non-exhaustive patterns: `C(QA)` not covered
 21 |     match proto {
    |           ^^^^^ pattern `C(QA)` not covered
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 503ce5618d486db165587ec6ccd283399e0ac5f2..26748d18ffa954ac004fa583d92c45abebce771f 100644 (file)
@@ -11,5 +11,5 @@ error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `met
    = note: `Type` from trait: `type Type;`
    = note: `method` from trait: `fn(&Self, std::string::String) -> <Self as m1::X>::Type`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index a16ae5538bf92d2038afae65670a6d6d909c7b1a..ce38178bf87bbfcb962ad807b93761e656f73ca2 100644 (file)
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 14 |     foo();
    |     ^^^ cannot infer type for `X`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 470e8331247851848b2cecf66b5c87c66d1fd863..94fc8f15c2b9e23346ecd1e71f0d2652051ba2ba 100644 (file)
@@ -4,5 +4,5 @@ error: unmatched visibility `pub`
 13 | pub(crate) () fn foo() {}
    |          ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b8b4c80778d968d05f5296d9a8acb2459e8974dd..eebb2428ba3a5f023d5c2fba73465eefedb7838d 100644 (file)
@@ -4,5 +4,5 @@ error: expected identifier, found `(`
 16 |     pub(crate) () foo: usize,
    |                ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index ebfccc4d720451f0e168d5c606792cdb64c68d45..865b1d409e131bfa2e86ed0df3b3a25994047f7b 100644 (file)
@@ -4,5 +4,5 @@ error: expected identifier, found `.`
 13 | pub (.) fn afn() {}
    |      ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index ae283f1fb636a151fb913cc8134a623ffff96f9b..34cc80fcc752796e9f480fbe276d64af615b95df 100644 (file)
@@ -48,5 +48,5 @@ error: visibilities can only be restricted to ancestor modules
 33 |         pub (in x) non_parent_invalid: usize,
    |                 ^
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
index 1a2cc252051bfb9dffc07e18fdf0b86b2ff0ed71..cbcbf88d86e7f6c39a3ba88843aee6d4df80ec8a 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 13 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index bf4e4dc4711cbcfbd6ef39069ae3536ac956a924..20640c0a897b44c562c8658e7bc9847fa34098c5 100644 (file)
@@ -11,5 +11,5 @@ note: lint level defined here
    |         ^^^^^^^^^^^^^^^^
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f8dbdb5f8bb66aa9c6097c5a6d18cb6944e80920..c778aec08108e84c9afd5ec71ca43f3e3be67763 100644 (file)
@@ -16,5 +16,5 @@ error: unreachable expression
 25 |     let x: [usize; 2] = [22, return];
    |                         ^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 807f6a1c1d5847eb383d2e1f6bcfcb24ee2f2ea2..9310c000192739124476794271e214c4587f98f9 100644 (file)
@@ -22,5 +22,5 @@ error: unreachable expression
 36 |     *{return; &mut i} = 22;
    |               ^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 542ce1c3fd9cb5b49e7f41743d623128be4505bc..ea7b962e190d190c03a7a8237ee776f3e20529c3 100644 (file)
@@ -18,5 +18,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 78ba231cef9fcf2121f0173688ab3710823c13fa..ee89104df9e92413bdac699125cbffb35e9f30ac 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 13 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5526827f59fc9965853df9bc66eb3674e29572ea..5e072ed1dc7abe766ec0e2ef41636a50eda5aba2 100644 (file)
@@ -16,5 +16,5 @@ error: unreachable expression
 28 |     bar(return);
    |     ^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index a22300dcc1398f37c6c0dbee1b349266864a90a1..a8668dc7355c12f6d6ae17d8f06f8f9adf6acbaa 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2cf17474f6e9dd2ab1ddd152addf393ab004971a..7f901511f7206f281972cdcd1be72ed9cf47926b 100644 (file)
@@ -11,5 +11,5 @@ note: lint level defined here
    |         ^^^^^^^^^^^^^^^^
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 6e98e754c54db30d1078dd882e45d004bfaeec0a..4fb6392f405c218eb4858fe9b6e2ac139aac957c 100644 (file)
@@ -27,5 +27,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index f5857a5b345eccbb27c0ee1159574737e9897002..387f7900f4948d86d53b3be53adbee9e24472f5a 100644 (file)
@@ -26,5 +26,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 177d4352a376ddb175125c1425e7e57891a8d659..68fd4973414151cf00e4c4985146e6cf108b552d 100644 (file)
@@ -16,5 +16,5 @@ error: unreachable expression
 31 |     Foo.bar(return);
    |     ^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 19afc5dd7b5ee192dc8307c046a6fabaa6d08100..01b2e1009ee0c5507e2cf6c0d41df7c8a877f003 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 3eb70a4dd7c848ecc53b7b50d5ce47035c876da5..ee958aa9089d8e3350705265f9339b47f153bf80 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4b7ac6604132c165b255200be13f61c49b0ae77f..08866bf32b873abf1d4a0437318e12309183b4de 100644 (file)
@@ -28,5 +28,5 @@ error: unreachable expression
 40 |     let x = Foo { a: 22, b: return };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 63f477fd0c373a9a8b37111b1657380e410b8733..780fb02f79037861879cc53c5441e81b1217acc5 100644 (file)
@@ -16,5 +16,5 @@ error: unreachable expression
 25 |     let x: (usize, usize) = (2, return);
    |                             ^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 6ed79974ccb77c1aea43d4eddfbecc92102215fd..1216ec2676eefe106e40ca1dec343bfa82e3e8da 100644 (file)
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 11172652d84450bde5cfa592d09b015c78f99ad1..889e3e01c6daaedd42dcd630cdc4529be745367a 100644 (file)
@@ -4,5 +4,5 @@ error: cannot apply unary operator `!` to type `!`
 18 |     let x: ! = ! { return; 22 };
    |                ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 066cfc86c6462c534a35260d76975bd5c40b091a..3da057f4bbd364ec61a0667518c4ecd378802fc0 100644 (file)
@@ -27,5 +27,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 0c7b44af949b6315588759e19418a5ea30064d01..121a50d0eda172dd0e61a0283b61c9bb9b704880 100644 (file)
@@ -9,5 +9,5 @@ error[E0308]: mismatched types
    = note: lifetime parameter `'b` declared on fn `bar` appears only in the return type, but here is required to be higher-ranked, which means that `'b` must appear in both argument and return types
    = note: this error is the result of a recent bug fix; for more information, see issue #33685 <https://github.com/rust-lang/rust/issues/33685>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 17c5d5d15d40479415e0c5503c248ace94e25045..03e80046f679cb69140ee979474c762d8ba1b45a 100644 (file)
@@ -25,5 +25,5 @@ error[E0422]: cannot find struct, variant or union type `C` in module `namespace
 help: possible candidate is found in another module, you can import it into scope
    | use namespaced_enums::Foo::C;
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 18eb2fabdacb541d351401a235a146ac198948b1..8aaad906ea28a477e8c7324b2815ed46e1469ade 100644 (file)
@@ -144,5 +144,5 @@ error[E0425]: cannot find value `bah` in this scope
 
 error: main function not found
 
-error: aborting due to 25 previous errors
+error: aborting due to previous error(s)
 
index 63d2ce109142c70116181304aad38511fcb51325..2fbf7d7185da3d3de70cdafcee7a45b43cc8a689 100644 (file)
@@ -9,5 +9,5 @@ help: possible better candidates are found in other modules, you can import them
    | use std::io::Result;
    | use std::thread::Result;
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index c0438abfe43b45cd5458eb302868063ff96c15df..69eeb178dffcca4abf6b12637628fba7e6bafdc0 100644 (file)
@@ -7,5 +7,5 @@ error[E0422]: cannot find struct, variant or union type `E` in this scope
 help: possible candidate is found in another module, you can import it into scope
    | use SomeEnum::E;
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index edc7196d8464570222f235bd0a0b9b3e10947f20..225e31010dabbfd4c0665d04df35e013fcc71b3d 100644 (file)
@@ -4,5 +4,5 @@ error[E0423]: expected function, found struct variant `Foo::Variant`
 16 |     let f = Foo::Variant(42);
    |             ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7b14d49af51dd8c79cddd54c83372dd9b8929395..25ee3a02146a70f5c614ae3dd6012440955b7962 100644 (file)
@@ -10,5 +10,5 @@ error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Mad
 22 |     let homura = issue_19452_aux::Homura::Madoka;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`?
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index fda87de9b9c500bb2f3d151ec33aa14cc7d9ca59..2ca541c161badea97dea7256ca4c1c9a2759c63d 100644 (file)
@@ -11,5 +11,5 @@ note: the cycle begins when processing `<impl at $DIR/issue-23305.rs:15:1: 15:20
    | ^^^^^^^^^^^^^^^^^^^
    = note: ...which then again requires processing `<impl at $DIR/issue-23305.rs:15:1: 15:20>`, completing the cycle.
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 039887d8da65fe169b5695d5b880f6d1a47f2724..559598dd38ae92cbb882a31d38b240e6babd38e6 100644 (file)
@@ -106,5 +106,5 @@ error[E0424]: expected value, found module `self`
 122 |     self += 1;
     |     ^^^^ `self` value is only available in methods with `self` parameter
 
-error: aborting due to 17 previous errors
+error: aborting due to previous error(s)
 
index 111710d515a92f28c3e4a479913e9fac3bd76c6b..14a2413feee23265c375b56bda9a2de934a9a09a 100644 (file)
@@ -4,5 +4,5 @@ error[E0411]: cannot find type `Self` in this scope
 11 | fn foo(_: Self) {
    |           ^^^^ `Self` is only available in traits and impls
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5dbecc4f0c5fa1ca937092b80d39cbb57de8282c..a950075715ac014417aa46f2d1d2cdb57b4b766d 100644 (file)
@@ -4,5 +4,5 @@ error[E0423]: expected value, found trait `Bar`
 20 |     let any: &Any = &Bar; //~ ERROR expected value, found trait `Bar`
    |                      ^^^ not a value
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2ef8c830eb2fe5173c8f774a0a1053f75d74a33c..4e1ef25f8033307f32eb48cf52d41fa3c71a8c34 100644 (file)
@@ -6,5 +6,5 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
    |
    = note: method `bar` has no receiver
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f6ee0b025bb2e9a78c688d761626b8e03a0b6490..134a4540a8d9e39538814de39db8c61625d6be00 100644 (file)
@@ -7,5 +7,5 @@ error[E0423]: expected value, found struct `Handle`
    |                 did you mean `handle`?
    |                 did you mean `Handle { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 791b20725f3bcbb5d11ac164da22aa02812e56bf..9bdd7ee4fd4b588eff1181c3324aec71b8dd8bf8 100644 (file)
@@ -7,5 +7,5 @@ error[E0277]: the trait bound `I + 'static: std::marker::Sized` is not satisfied
    = help: the trait `std::marker::Sized` is not implemented for `I + 'static`
    = note: all local variables must have a statically known size
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b50295752f2e0a1632558b7d6de3a25a17d4b57d..620958190caf8f739343e3a38ad13dd1d702da1a 100644 (file)
@@ -4,5 +4,5 @@ error[E0423]: expected function, found struct `Monster`
 17 |     let _m = Monster(); //~ ERROR expected function, found struct `Monster`
    |              ^^^^^^^ did you mean `Monster { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4dff2620319e4607dcee7cf5fe92c79bd922a8ab..d25c52eeab3ce9cb31b6464e31cbc464c74a970b 100644 (file)
@@ -46,5 +46,5 @@ error[E0425]: cannot find value `second` in module `m`
 32 |     let b: m::first = m::second; // Misspelled item in module.
    |                          ^^^^^^ did you mean `Second`?
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
index 19940ff4586d2e3baf028f71ebecec7ba96804f9..b21b10c63b02b7567082762656e09e57253edae6 100644 (file)
@@ -65,5 +65,5 @@ error: tuple struct `Z` is private
 45 |     xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
    |     ^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
index 7975c168de7d4d39075ed8e349aeeec795b8f249..c346612a68bb62a04353ef3fb401cacfc5a61a20 100644 (file)
@@ -52,5 +52,5 @@ error[E0425]: cannot find value `method` in this scope
 52 |         method;
    |         ^^^^^^ did you mean `self.method(...)`?
 
-error: aborting due to 9 previous errors
+error: aborting due to previous error(s)
 
index ffb3f8484306f72b66f857cc1a634233deb6c1c2..92f13f705b079adf766dee79291467c6319f5986 100644 (file)
@@ -4,5 +4,5 @@ error[E0423]: expected function, found macro `assert`
 12 |     assert(true);
    |     ^^^^^^ did you mean `assert!(...)`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index e7df8140bc577bbb0d207cf85801c736c330d6a9..04c8087ace9ffa5e937fe36d8f6792971afc3621 100644 (file)
@@ -22,5 +22,5 @@ error[E0425]: cannot find function `method` in this scope
 38 |         method();
    |         ^^^^^^ did you mean `self.method(...)`?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index f254ad3d87d86ec8cd7368416c917f88606f1fb3..24cef694737e05e8cc32825e0954ed7de2504d24 100644 (file)
@@ -74,5 +74,5 @@ error[E0423]: expected function, found module `a::b`
 
 error: main function not found
 
-error: aborting due to 10 previous errors
+error: aborting due to previous error(s)
 
index feb12612e660419a04b8db46ad4da603f9ead61d..7307f19c74de3ecb3347f92f37050a73c9014346 100644 (file)
@@ -16,5 +16,5 @@ error[E0425]: cannot find value `foo` in this scope
 14 |     if foo {
    |        ^^^ not found in this scope
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 849787e383f107d2140ed9c97dcce388f2b9b140..d234c8538fe27a23d8128a70fbb317c7b31043d3 100644 (file)
@@ -40,5 +40,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `std::result::Result<bool, std::io::Error>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 226fa6469bc740f9403c0f8aa75050a68693574e..1dd263affd4c3c6f923cf9b58f705fc2abbe2b86 100644 (file)
@@ -52,5 +52,5 @@ error[E0425]: cannot find function `bar` in this scope
 14 |     foo(bar(;
    |         ^^^ not found in this scope
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index e2ef8f0e568fcf4f47ca1ed331d22eb9fa5b6dbe..2fc5979a6065ebc4b42be1f855c6789dfaed7e44 100644 (file)
@@ -28,5 +28,5 @@ error[E0532]: expected tuple struct/variant, found type alias `A`
    |         did you mean `S`?
    |         did you mean `A { /* fields */ }`?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 5fbaf66e014af073f45aef78a325c8347a7c1cef..ff6bcf2a53205ecb9f5c4b4a8fd153e77712088f 100644 (file)
@@ -7,5 +7,5 @@ error[E0425]: cannot find value `cx` in this scope
    |           did you mean `self.cx`?
    |           `self` value is only available in methods with `self` parameter
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 729a515612463396cf588abc8c38f174ed0c092f..f722908ec108a07099a4db10567e1f27a8f89a96 100644 (file)
@@ -7,5 +7,5 @@ error[E0046]: not all trait items implemented, missing: `foo`
 18 | impl Foo for Bar {}
    | ^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 0d6b0a552e4de981733df0af246a7dc0848b50cf..bc3a3908dcaefef6033c4a40114732dc37acda19 100644 (file)
@@ -10,5 +10,5 @@ error[E0057]: this function takes 1 parameter but 2 parameters were supplied
 15 |     let c = f(2, 3); //~ ERROR E0057
    |               ^^^^ expected 1 parameter
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 1f6dd6b1d165f52c9eb3f5e257ccce7dcafd4718..14e6bcb73b02b69c62058b93fc3861924f24afd7 100644 (file)
@@ -9,5 +9,5 @@ error[E0072]: recursive type `ListNode` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4fe6afaca8ec658a4eae9fdba79b35dc37cacb29..fab2436922dda318fd5f2d16716b69ba17407645 100644 (file)
@@ -34,5 +34,5 @@ error[E0204]: the trait `Copy` may not be implemented for this type
 31 |     Bar(&'a mut bool),
    |         ------------- this field does not implement `Copy`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index afcc9a240eb4e6c266a4decb0e110c8e2b80ad99..5f8b57294d548e6aa6fb38133abb7adbc0017ba4 100644 (file)
@@ -7,5 +7,5 @@ error[E0493]: constants are not allowed to have destructors
 27 | const F : Foo = Foo { a : 0 };
    |                 ^^^^^^^^^^^^^ constants cannot have destructors
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 23070e1555b9b89f101cd7440fd30e9d06554978..64c0016085f07c1de13792dfe77ddd532828bbc4 100644 (file)
@@ -4,5 +4,5 @@ error[E0535]: invalid argument
 11 | #[inline(unknown)] //~ ERROR E0535
    |          ^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b2da0c6a296d8fc5119d4f68560f799f9947408d..8a4cf34e565f5016348dd7b7b33efa26b2b42c5b 100644 (file)
@@ -4,5 +4,5 @@ error[E0536]: expected 1 cfg-pattern
 11 | #[cfg(not())] //~ ERROR E0536
    |       ^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 29873943f444d8e65a7fc59f27af530744919307..1bd54a6a007ed94c2c18c128270da0be691bec71 100644 (file)
@@ -4,5 +4,5 @@ error[E0537]: invalid predicate `unknown`
 11 | #[cfg(unknown())] //~ ERROR E0537
    |       ^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index edf1635a6b84fe7f1b0f187bf865cc4fccc9e787..7cd9f30f42c1743a8d9d824fc3ca392a578d9785 100644 (file)
@@ -82,5 +82,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 143 |     *x.y_mut() = 3; //~ ERROR cannot borrow
     |      ^ cannot borrow as mutable
 
-error: aborting due to 10 previous errors
+error: aborting due to previous error(s)
 
index 2ec01168721798684e360cd3a54fca6aa53868dc..83c49409049d8610410377c2dc816c6f7153cfad 100644 (file)
@@ -30,5 +30,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 63 |     **x = 3; //~ ERROR cannot borrow
    |      ^^ cannot borrow as mutable
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 4ece8bc6af10fb06867356f608244c382ff823a5..bfb51ba48166287eb8e1550800aadebfeb3ef927 100644 (file)
@@ -47,5 +47,5 @@ error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
 72 |         foo(f);
    |             ^ cannot move out of captured outer variable in an `FnMut` closure
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
index 2349bfaf75e6f4fe37c3fde7703a554142b6ad4a..00fa6577545daf13fb1e711e70aa4214ff34c806 100644 (file)
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 27 |     x.h(); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 251a9e4aa57555730d0a988b08fd59cf839cd035..75866b7e45e31236bc6d84e393ffeb1b57007f00 100644 (file)
@@ -6,5 +6,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 17 |         x.push(format!("this is broken"));
    |         ^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5bb656878b3f3b7d384a760621b84503453b8e6c..fd2a752c4721be2cc3e50b2a26c6edb2415c6ba3 100644 (file)
@@ -48,5 +48,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 0abdbdc3a21b58f1560763529439ac66aeb5ca35..86316d8980d0ccf010e902e4a04b75dcc4d83cfd 100644 (file)
@@ -16,5 +16,5 @@ error: cannot borrow immutable `Box` content `*x` as mutable
 29 |     x.borrowed_mut(); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index adbf39b3f7580f9d65b27ab52a2f1e18b93f32c5..38ce3d398baaf892505db2e982a6105e976464ae 100644 (file)
@@ -12,5 +12,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 220b2f471da9ad7aef33e4d22a67ab811adbb778..47ede6f2eb1a8a718df6dc5b46835ce37adf7d46 100644 (file)
@@ -47,5 +47,5 @@ error[E0308]: mismatched types
    = note: expected type `_`
               found type `std::boxed::Box<_>`
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
index 3253212c5b87ba389f519a689cc83de4256da09b..bf449518ce70c7c0c1ed9fa3ea86ddcbf19389c5 100644 (file)
@@ -8,5 +8,5 @@ error: `*a` does not live long enough
    |     |
    |     `*a` dropped here while still borrowed
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index e31c36e83dfca125be3a54c98553ddf525b033d7..f098448527905ee8f83ab99d0038a28160ba31a4 100644 (file)
@@ -9,5 +9,5 @@ error: `*m` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index c89da0baef233925862e37f6ca69e28c99a0701e..ea5163cf924729a43d83b81af50f004603291090 100644 (file)
@@ -63,5 +63,5 @@ error: `b2` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index 9eb2a2157717025f3cc7b88f22940b5c4e3b1c91..d5f22a2665049d802830d49e9b35cf6fc5c2f5d4 100644 (file)
@@ -19,5 +19,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 98c1cbbba7b3fa160e5bcf8c0b1f75b9d91551b0..4ad98b429c53b4c3bbdc7067dcc16d1477dcab72 100644 (file)
@@ -19,5 +19,5 @@ error: `v` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 961ac81cf8280dea57688362c8c7762d30bea1d2..e38c49d6a5c36bed9cb88054305cb3733cfa4944 100644 (file)
@@ -63,5 +63,5 @@ error: `c2` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index ae290b3b11aa79c5df19475fbd03aaab7ed839b1..ca7286f50275b7c3899c281718b8b03cb13ddf74 100644 (file)
@@ -85,5 +85,5 @@ error[E0046]: not all trait items implemented, missing: `fmt`
    |
    = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
index 6ad9c27b8b9101418959815e2a929c52f5ed2538..18cbf9332301924aeb42a3258177893472d74c59 100644 (file)
@@ -10,5 +10,5 @@ error: `x` does not live long enough
 23 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 85f6c41c366413320ca85c8d37f1cba702a9f40f..d2534388f7255d3212331a80f72deb00bb67fcd5 100644 (file)
@@ -11,5 +11,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 85a0002f2418081f2d43b4c12082fab811fcf94b..bf7c099187ee64aaaf96f9c3d13e861102ebe42e 100644 (file)
@@ -18,5 +18,5 @@ error: `y` does not live long enough
    |     |
    |     `y` dropped here while still borrowed
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index d9f4bacce35ae0650c9d88c39f58329dab187dcc..d6aed36c8f63f9258323bfb42396d433a7b67ae3 100644 (file)
@@ -12,5 +12,5 @@ error[E0046]: not all trait items implemented, missing: `Item`
    |
    = note: `Item` from trait: `type Item;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 3127af157a62bbb8184673b6398e6f4993db4230..a1d3f5c11df34e91c2d7f34c0069b79209a9e568 100644 (file)
@@ -12,5 +12,5 @@ error[E0046]: not all trait items implemented, missing: `Output`
    |
    = note: `Output` from trait: `type Output;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 71ab82d98b809abee614d08c740e37a5266d8ee6..771ea787304b3c29862b4b7c6dc0c0002b776089 100644 (file)
@@ -11,5 +11,5 @@ error[E0046]: not all trait items implemented, missing: `Target`
    |
    = note: `Target` from trait: `type Target;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index c4f2616f5945b1baa5680d1bc475fc3e8c282f5c..598f9f5130781552806f5301153d12ab512f6628 100644 (file)
@@ -32,5 +32,5 @@ note: lint level defined here
 16 | #![deny(warnings)]
    |         ^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index a622e7cfb7180972bd31b0688a4d90eba4f3ceef..8c2254483e03075c29ce2d0948cb7c1748205e0b 100644 (file)
@@ -9,5 +9,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index d06c8af62ee60938c17c56085acce300e9bc9ece..450bc123e60bc9ab0f86171a9416c22c7ff0b778 100644 (file)
@@ -28,5 +28,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 160bfb63900454cc091e62e6356edb0ecde5971b..dfee66ae546cddee245e3dfce9ba3c78d2bf1cb9 100644 (file)
@@ -8,5 +8,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 3c8ee07a1fdd88beae1b1a395bc2666bb2e9665b..17c05557297530d43f53a3e44896e61877ce4aa5 100644 (file)
@@ -19,5 +19,5 @@ error: `container` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index f960844c818ff7a2b08c9de2661bdfc5e3713749..1f5c64986c7369f1aaf8f8e7e01667e3d5a51b25 100644 (file)
@@ -8,5 +8,5 @@ error: `ticking` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 117b109780b152de90c24f45dd97f8697ea3d84b..443595c6d2c764ae4c62a20c0a16dc56758c9375 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched method receiver
    = note: expected type `&Self`
               found type `&SomeType`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index a7d3b84daba469b841d95c1361d678c9866b8a14..2a7e59f0422e64725e1c55d6e30646354f3e8659 100644 (file)
@@ -18,5 +18,5 @@ error: `x` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index abbac245f89f66b191709212f42738ac9d8e2244..4065c4fb85713f3836cf1172c98672a3d1fd5971 100644 (file)
@@ -6,5 +6,5 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied
    |
    = note: required by `Tr::C`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2a874181c7ad9a03332c073bbde569fce15ebc76..38256ec944b9b9c5debf9ed7f4a9cd55f075381a 100644 (file)
@@ -8,5 +8,5 @@ error[E0308]: mismatched types
               found type `std::string::String`
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 98183e2f082e9f55b33da1dd5443306de6041d29..48ed0b4ac89aa964e62debf10532383fa2873175 100644 (file)
@@ -45,5 +45,5 @@ error[E0061]: this function takes 2 parameters but 3 parameters were supplied
 19 |     bar(1, 2, 3);
    |         ^^^^^^^ expected 2 parameters
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index dc6190c2e76b0f28afee368623308f022d13cb96..5dc9bd8b79b19952cd313f6940e421135ea7eb7d 100644 (file)
@@ -14,5 +14,5 @@ error: The attribute `foo` is currently unknown to the compiler and may have mea
    |
    = help: add #![feature(custom_attribute)] to the crate attributes to enable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index a335194580d4553a9d35256cb41fb99c7e64ad19..dbce171dd9b7e5c14f166385f91b43628445e2f3 100644 (file)
@@ -8,5 +8,5 @@ error: `a` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7cf74eaab8db12c65c7ed2e1266edc152643919d..bd271641e7e3cca949f80c52bee1e71a435e3815 100644 (file)
@@ -55,5 +55,5 @@ note: candidate #2 is defined in the trait `F`
    |     ^^^^^^^^^^^^^^^
    = help: to disambiguate the method call, write `F::foo(a)` instead
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index cd3a41b037c7996e8fa529e8fc805b9bca3e4c61..f0b940cdf3fa9e150e1509ec9562f0dd10734b82 100644 (file)
@@ -15,5 +15,5 @@ error[E0369]: binary operation `+` cannot be applied to type `World`
    |
    = note: an implementation of `std::ops::Add` might be missing for `World`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 97d802f8398311fa3930f046e903224063e1d87e..0d0a07629c49a09309dacb4115d1e6cbafd73f15 100644 (file)
@@ -38,5 +38,5 @@ error[E0408]: variable `c` is not bound in all patterns
    |         |             pattern doesn't bind `c`
    |         pattern doesn't bind `c`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index ad1c149d2e56f7546a7f86cbae68e4ee6a006a3d..160f65fd1b9af499e7d842f484e10439bfc06d5e 100644 (file)
@@ -10,5 +10,5 @@ error: `foo` does not live long enough
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 8b813220d789de781b21f5dc635f3aa882cb2003..c017e38680826d60fc7ddfb201a5b57dd9add551 100644 (file)
@@ -61,5 +61,5 @@ note: candidate #1 is defined in the trait `ManyImplTrait`
    = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `is_str`, perhaps you need to implement it:
    = help: candidate #1: `ManyImplTrait`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index b5fbe99ec72e8ac9fd8824e0b8c5dfce6865e75d..06b7f922b684c538f95c8d127c8648ab6b8f13f7 100644 (file)
@@ -19,5 +19,5 @@ error: `foo.data` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index debb8354568cc453c6d720faa0d65f6e30d6f306..d166af522478e693afb238c9021ceae83e0368b9 100644 (file)
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 7d3ac3e9d0391ab6d69c82e4e562ba7c3da52bc2..6a02d7015733de3cad307dc50acb402728c2d886 100644 (file)
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index ae96cace91c476a4345f009462166878c09ea709..91a410e0f65894ca0c0fa1efd45bdd0ce3a82a3d 100644 (file)
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index f4998e08907a387f55b897ab80f5cc47e203d540..2f5e60a1b3c9d0fbf07bb0899f18db927e6b467c 100644 (file)
@@ -106,5 +106,5 @@ note: because it's nested under this `unsafe` fn
 44 | | }
    | |_^
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
index b0f191e29d1be02da29d0039aedac4fa302514ca..6095a3b6be5cbd27ab75b128c648bf0b2f203519 100644 (file)
@@ -9,5 +9,5 @@ error: `short` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 2294e6476d61fe2dd6c157884821603176b21af3..f76c5b049c4b04c0a65f69885be2573e89c647d3 100644 (file)
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `[closure@$DIR/move-closure.rs:15:17: 15:27]`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index a06cbd04deb4fb4a32bc030387426608e8a913fd..881c2f5df45a2ffaee2e15f8a26870904589379a 100644 (file)
@@ -12,5 +12,5 @@ error[E0072]: recursive type `ListNode` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 44d5379648d5b7e6eceadc7bb1041f16cb107462..057f8fe6ee274f6e22b6682013bc04be2e3a2488 100644 (file)
@@ -11,5 +11,5 @@ error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied
    |
    = help: the trait `std::ops::Add<()>` is not implemented for `u32`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 01364c0714407a029e76bd967554e341a2c11f8a..d5e6b62865586a7547e3e5da155759965a34160a 100644 (file)
@@ -22,5 +22,5 @@ error: cannot borrow immutable borrowed content `*a` as mutable
 25 |         a.push_str("foo");
    |         ^ cannot borrow as mutable
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index 0417eb075af85ab15a799543f41784b07eb82fbd..68dc87d0667e2d2bca63d17034be6b8a683e48be 100644 (file)
@@ -8,5 +8,5 @@ error: `b` does not live long enough
 20 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index c66361c8546b839046fb47b9fcf2556eeba2c395..835b08f890751a853a2407902bdba88e9e702d03 100644 (file)
@@ -15,5 +15,5 @@ error[E0124]: field `bar` is already declared
 17 |     pub(crate) bar: u8,
    |     ^^^^^^^^^^^^^^^^^^ field already declared
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 9f11de77be7e73dd9789ed987ff3c2fc8c99a50d..4f638562bb8014a2e9045b8db0e2a6961ef3eb7f 100644 (file)
@@ -20,5 +20,5 @@ error: `b` does not live long enough
 21 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index b4d0b5a6a25d03557028beec40e27409ccb2b19e..72177754681f80ea3c516f000cd953ffa76db8a2 100644 (file)
@@ -27,5 +27,5 @@ error[E0072]: recursive type `Bar` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 9c369e03e33ab8fdeee92b50327180907be3fb02..6c5007a570535093109be8b70c2036aec8977e87 100644 (file)
@@ -9,5 +9,5 @@ error: `c` does not live long enough
 20 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 205734c25e0e6cd4926fc870e852f62e7032dea0..d6a460d83ab0faa9f054c7b0295aac5485be6bbb 100644 (file)
@@ -9,5 +9,5 @@ error: borrowed value does not live long enough
 23 | }
    | - temporary value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index ea652da7da46f57b6bd68e52bffc284ed9e426f9..099f6df27efc69fca1dbed8f6c945b35503aab43 100644 (file)
@@ -9,5 +9,5 @@ error: `tmp0` does not live long enough
    |     |
    |     `tmp0` dropped here while still borrowed
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 09f2154905f38d7f536c43e7c5db0a500e232e0b..09178ce57e8be951b1d86a8197c3d885041536cd 100644 (file)
@@ -8,5 +8,5 @@ error: `x` does not live long enough
 23 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 58f7849e443f5a52b8e07ac0f10b39adb826ef17..006060f342a38e5e934f7d2a0bfec398ffa5f31e 100644 (file)
@@ -37,5 +37,5 @@ error[E0506]: cannot assign to `x` because it is borrowed
 24 |         x += 1; //~ ERROR cannot assign
    |         ^^^^^^ assignment to borrowed `x` occurs here
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index 0e7b64ec2b36c08db9dca69805871f504a025146..d4dfef36e4afbb6af94fe6a3c549676f01eb1821 100644 (file)
@@ -10,5 +10,5 @@ error: `*x` does not live long enough
 30 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 5897921476d3ffde2d44dbc33e856264923c1148..4a815a58b354da092bd13e4bc06b8483be40fb52 100644 (file)
@@ -24,5 +24,5 @@ error: `y` does not live long enough
 35 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 08f85f17bf8adaa861f8e4d47e8cdf00e826f66a..815f88022675d21ebfcf20f3e6da685a1160c6e3 100644 (file)
@@ -32,5 +32,5 @@ error: `x` does not live long enough
 44 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index a86cf1e58846dbafb935fed38393a402f52f75d2..81f53c7f374eb691a80e7218eb31abe75ba9e069 100644 (file)
@@ -52,5 +52,5 @@ error[E0505]: cannot move out of `y` because it is borrowed
 49 |     drop(y); //~ ERROR cannot move out
    |          ^ move out of `y` occurs here
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
index efe81fd00bf4789b2069fb255d68782041d53b98..ff6d30d670de1ffb4275770da329950b76dc8697 100644 (file)
@@ -9,5 +9,5 @@ error: borrowed value does not live long enough
 19 | }
    | - temporary value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 91e629c44b073572a8a9a8934fcb1b396e31cad4..b6353c0f6a205084c2b88ec2d12dfa1a0e2924fb 100644 (file)
@@ -4,5 +4,5 @@ error: cannot index a value of type `({integer},)`
 14 |     println!("☃{}", tup[0]);
    |                     ^^^^^^ help: to access tuple elements, use `tup.0`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index dc37acaf3f98eb3a5b320bebfb3c4d65bc40dc13..afe069e7aa684cad3bc73dfdb92528c209d0210e 100644 (file)
@@ -4,5 +4,5 @@ error[E0220]: associated type `Trget` not found for `std::ops::Deref`
 16 | fn homura<T: Deref<Trget = i32>>(_: T) {}
    |                    ^^^^^^^^^^^ associated type `Trget` not found
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index dca0a93f897baaa42de4d950161856983dd49876..6556e5b4c001e7f92e86d2ec7b76bbdb1166f2f6 100644 (file)
@@ -10,5 +10,5 @@ error[E0425]: cannot find value `fob` in this scope
 18 |     println!("Hello {}", fob);
    |                          ^^^ did you mean `foo`?
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 11031ee0ab263251655c69c2336430847e7173bf..fad46d5a7d05282242cf3179b58bb8586c1f10fa 100644 (file)
@@ -19,5 +19,5 @@ error: `c1` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index 8cc12c32b9303f0eee2c17c2e4d19f16fe2e5990..c890d4740e6c2aad70316c2b8eca764534d197c4 100644 (file)
@@ -20,5 +20,5 @@ error: `y` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
index aeac3102fbf3a94bb989bb332c55b538b111a8bf..ff1bf47d44d058d198d1c64584c1fc95c138ebb0 100644 (file)
@@ -9,5 +9,5 @@ error: `pointer` does not live long enough
 33 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index f73dff4f73d0ee43ba06369bcfed4a5a6f3ca13a..89008828ac5efaf54178e88ed0bca1c847fac0f8 100644 (file)
@@ -6,5 +6,5 @@ error[E0477]: the type `std::borrow::Cow<'a, A>` does not fulfill the required l
    |
    = note: type must satisfy the static lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9e5e4adb180d5fdb1aef2b9177e42baf4f80db8f..0f2097dfb312c0bed8777ba96c79f33cc08d49c2 100644 (file)
@@ -6,5 +6,5 @@ error: no method named `closure` found for type `Obj<[closure@$DIR/issue-18343.r
    |
    = help: use `(o.closure)(...)` if you meant to call the function stored in the `closure` field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 56e1060bdb95ae2645cd4556e248a690ac1fa804..0191060e837bacef156ace72c52569c12aabc655 100644 (file)
@@ -86,5 +86,5 @@ error: no method named `f3` found for type `FuncContainer` in the current scope
     |
     = help: use `((*self.container).f3)(...)` if you meant to call the function stored in the `f3` field
 
-error: aborting due to 11 previous errors
+error: aborting due to previous error(s)
 
index 0d2a895bad16d31fea4529f0c6c1f52a4166df79..704b7a37e9553cf18b8acc35f46f48f96a0f8744 100644 (file)
@@ -6,5 +6,5 @@ error: no method named `example` found for type `Example` in the current scope
    |
    = help: use `(demo.example)(...)` if you meant to call the function stored in the `example` field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 70d64e3ffa3319d05ec92a62513988d303d8d6be..d827f89cf8d821b6b88684426847726521d76c8b 100644 (file)
@@ -22,5 +22,5 @@ error: no method named `c_fn_ptr` found for type `&D` in the current scope
    |
    = help: use `(s.c_fn_ptr)(...)` if you meant to call the function stored in the `c_fn_ptr` field
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index d07885915d2b7a1139bca563b7c986879ec62ab1..e3c88c1e7bbbd62e07e2397e6ed1a850e123e89b 100644 (file)
@@ -4,5 +4,5 @@ error: no method named `dog_age` found for type `animal::Dog` in the current sco
 26 |     let dog_age = dog.dog_age();
    |                       ^^^^^^^ private field, not a method
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 8a121b145366250abbcd1d39a05c42ca1d4e63d5..47a1b53cc60e0d95a98f78a4e4d2cafdf02636dd 100644 (file)
@@ -7,5 +7,5 @@ error: unexpected token: `1.1`
    |     |           unexpected token
    |     help: try parenthesizing the first index `((1, (2, 3)).1).1`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4d60be15ecaf0aae9a8801d4a1655831da71eb7a..15e4d4c72bc50d926ddae589d8c319e6601ea35f 100644 (file)
@@ -4,5 +4,5 @@ error: expected one of `!` or `::`, found `<eof>`
 15 | FAIL
    | ^^^^ expected one of `!` or `::` here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index b0bae1248b9698442106d8a2654c8473da2c5ffc..faa30dca94581effc840dcc6ba1f3f9f90b4407e 100644 (file)
@@ -24,5 +24,5 @@ error: expected expression, found `)`
 
 error: main function not found
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
index a6ad1206b14d06cfe19311025cef40c60d080f5a..96c2d764e7101f2e76760b84fdd69395ba0b762a 100644 (file)
@@ -14,5 +14,5 @@ error[E0412]: cannot find type `S` in this scope
 
 error: main function not found
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index f23d97586b843437002585034875cd2bca7dddd8..14a7186aab19c2ef249e21d37e062f0270251206 100644 (file)
@@ -28,5 +28,5 @@ note: caused by the macro expansion here; the usage of `ignored_pat!` is likely
 37 |         ignored_pat!() => (), //~ NOTE caused by the macro expansion here
    |         ^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
index c765a434b8ac6e86ef1c6f5cffce28b847dea095..5fe0b3594f67cc1bd86a856de6972ec7928a51e8 100644 (file)
@@ -4,5 +4,5 @@ error: expected one of `!` or `::`, found `<eof>`
 19 | FAIL
    | ^^^^ expected one of `!` or `::` here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 8c52bb5a1d3a51d9401efe7d30800c019f4b8323..007480dc44ff22e7f508008de9ed4d676090620d 100644 (file)
@@ -6,5 +6,5 @@ error[E0282]: type annotations needed
    |         |
    |         consider giving `x` a type
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 4788fad20889e4123904a479d13ed2ade197b7c7..4650df5411b5bc6abba5ec0a5e396d548db00f00 100644 (file)
@@ -8,5 +8,5 @@ error[E0282]: type annotations needed
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index ccffadebe9ee2c177ed408509ae3789ede07e7f9..08b5ae4bbb6fa2e7377b3bdf1f289d89077684f0 100644 (file)
@@ -8,5 +8,5 @@ error[E0282]: type annotations needed
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 9568411885192a04f4002f0ca87a138159b22f1e..b3c736c3b685d3722e066c8bab8b7e5d296b0e93 100644 (file)
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 14 |     [];
    |     ^^ cannot infer type for `[_; 0]`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 7a76799889b97385d114fe863b94ed0573acc925..bf03e52369feb8b4a50423ab0be4230d1c039e59 100644 (file)
@@ -10,5 +10,5 @@ error[E0282]: type annotations needed
 21 | | }
    | |_^ cannot infer type for `&'a T`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index afbd15ca486bd1e66566ee1269341879986d5e45..200864dfbf77aa0467d3f6e75b25c066a51ca7bc 100644 (file)
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 12 |     let x = |_| {    };
    |              ^ consider giving this closure parameter a type
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
index 397359840ecad02d5fe69b2a0cf328e98235ffea..9fcdbb44fec18d10c086b6aba8143bc06a199761 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 397359840ecad02d5fe69b2a0cf328e98235ffea
+Subproject commit 9fcdbb44fec18d10c086b6aba8143bc06a199761
index ad0d2fa0b363567da15144ddaa4de22aee9b62d9..791b8d77e0b907f635782f1d7b33dec9ec09ae83 100644 (file)
@@ -70,7 +70,7 @@ pub fn check(path: &Path, bad: &mut bool) {
         }
 
         let filen_underscore = filename.replace("-","_").replace(".rs","");
-        test_filen_gate(&filen_underscore, &mut features);
+        let filename_is_gate_test = test_filen_gate(&filen_underscore, &mut features);
 
         contents.truncate(0);
         t!(t!(File::open(&file), &file).read_to_string(&mut contents));
@@ -92,17 +92,20 @@ pub fn check(path: &Path, bad: &mut bool) {
                 },
                 None => continue,
             };
-            let found_feature = features.get_mut(feature_name)
-                                        .map(|v| { v.has_gate_test = true; () })
-                                        .is_some();
-
-            let found_lib_feature = features.get_mut(feature_name)
-                                            .map(|v| { v.has_gate_test = true; () })
-                                            .is_some();
-
-            if !(found_feature || found_lib_feature) {
-                err(&format!("gate-test test found referencing a nonexistent feature '{}'",
-                             feature_name));
+            match features.get_mut(feature_name) {
+                Some(f) => {
+                    if filename_is_gate_test {
+                        err(&format!("The file is already marked as gate test \
+                                      through its name, no need for a \
+                                      'gate-test-{}' comment",
+                                     feature_name));
+                    }
+                    f.has_gate_test = true;
+                }
+                None => {
+                    err(&format!("gate-test test found referencing a nonexistent feature '{}'",
+                                 feature_name));
+                }
             }
         }
     });
@@ -265,4 +268,4 @@ pub fn collect_lib_features(base_src_path: &Path,
         }
     });
     lib_features
-}
\ No newline at end of file
+}